This is the mail archive of the ecos-patches@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] i386 SMP bug fixes


	Hi there,

	These are some bug-fixes against the ecoscentric snapshot on last
sunday, to make i386 SMP support to work on boards with several ioapics
and lapics in non-sequential order.

	I've tested this with redboot, some additional test may be needed with
eCos.

	May be that somebody want to say something about having to enable
CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK in redboot, as far as
I've seen, it is the only way to have the hal_smp_*_istack macros
working with SMP support; but may not be the best approach.

	Have fun.

David.

diff -pr -u -U 5 -x '*~' -x '*.orig' -x CVS ecos/packages/hal/i386/arch/current/cdl/hal_i386.cdl /opt/ecos/packages/hal/i386/arch/current/cdl/hal_i386.cdl
--- ecos/packages/hal/i386/arch/current/cdl/hal_i386.cdl	2005-04-22 18:34:01.000000000 +0100
+++ /opt/ecos/packages/hal/i386/arch/current/cdl/hal_i386.cdl	2006-03-08 09:35:30.000000000 +0000
@@ -85,10 +85,11 @@ cdl_package CYGPKG_HAL_I386 {
 
     cdl_component CYGPKG_HAL_SMP_SUPPORT {
 	display       "SMP support"
 	default_value 0
 	requires { CYGHWR_HAL_I386_FPU_SWITCH_LAZY == 0 }
+	requires { CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK == 1 }
 	
 	cdl_option CYGPKG_HAL_SMP_CPU_MAX {
 	    display       "Max number of CPUs supported"
 	    flavor        data
 	    default_value 2
diff -pr -u -U 5 -x '*~' -x '*.orig' -x CVS ecos/packages/hal/i386/arch/current/ChangeLog /opt/ecos/packages/hal/i386/arch/current/ChangeLog
--- ecos/packages/hal/i386/arch/current/ChangeLog	2005-09-20 13:14:08.000000000 +0100
+++ /opt/ecos/packages/hal/i386/arch/current/ChangeLog	2006-03-09 11:04:10.000000000 +0000
@@ -1,5 +1,39 @@
+2006-03-09  Favid Fernandez  <dfernandez@cct.co.uk>
+
+	* src/hal_misc.c: modified _mcount to make HAL_SMP_CPU_NONE menaingful in a
+	  context where the cpu ids (apic ids) aren't sequencial and have gaps
+	  among them.
+	* include/arch.inc: modified macro hal_smp_cpu_reg to get the ordinal cpu
+	  number instead of the cpu id, as the rest of the code expects that when
+	  dealing with the cpu tables.
+	* include/hal_arch.h: modified HAL_THREAD_INIT_CONTEXT macro to convert
+	  whatever __sparg__ could be into a 32bit unsigned integer in one of the
+	  macro calculi. This fixes a bug at redboot/.../main.c in which,
+	  this macro was being called with l-values casted to (CYG_ADDRWORD) which
+	  turn them into r-values, and so making them useless for the purpose of
+	  the macro, that needs to modify the __sparg__.
+	* include/hal_smp.h:
+	  macros HAL_IOAPIC_READ/WRITE modified to account for more than one
+		ioapic in the system.
+	  ioapic var cyg_hal_smp_io_apic converted in array, and new ones added to
+	    account for the number of ioapics and their ids.
+	  cpu var cyg_hal_smp_lapic[] added to account for the cpu apic ids,
+	    so that every main table including this, is indexed by ordinal
+		cpu number.
+	  var cyg_hal_smp_cpu_4apic[] added to account for the inverse conversion
+	    of local and io apic ids into cpu and ioapic ordinal numbers.
+	  var cyg_hal_isa/pci_bus_ios[] added to account for the ioapic that owns
+	    a particular isa/pci interrupt.
+	  macros HAL_SMP_CPU_ORD/THIS_ORD/IOAPIC_ORD added to conver cpu or ioapic
+	    ids into ordinal numbers
+	  macro HAL_SMP_IOAPIC_COUNT added to match HAL_SMP_CPU_COUNT wherever it
+	    is necessary.
+	* cdl/hal_i386.cdl: added the requirement
+	  CYGIMP_HAL_COMMMON_INTERRUPTS_USE_INTERRUPT_STACK == 1 to SMP support,
+	  so that the proper stack macros get defined.
+
 2005-09-19  David Vrabel  <dvrabel@arcom.com>
 
 	* src/redboot_linux_exec.c: No need to include pcmb_serial.h.
 
 2005-07-18  David Vrabel  <dvrabel@arcom.com>
diff -pr -u -U 5 -x '*~' -x '*.orig' -x CVS ecos/packages/hal/i386/arch/current/include/arch.inc /opt/ecos/packages/hal/i386/arch/current/include/arch.inc
--- ecos/packages/hal/i386/arch/current/include/arch.inc	2002-05-24 00:03:02.000000000 +0100
+++ /opt/ecos/packages/hal/i386/arch/current/include/arch.inc	2006-03-07 15:43:05.000000000 +0000
@@ -100,11 +100,12 @@
 	
 	// Put CPU number in register
 	.macro	hal_smp_cpu reg
 	movl	cyg_hal_smp_local_apic,\reg
 	movl	0x20(\reg),\reg
-	shrl	$24,\reg	
+	shrl	$24,\reg
+	movb	cyg_hal_smp_cpu_4apic(\reg),\reg
 	.endm
 
 #else
 
 	.macro	hal_smp_init
diff -pr -u -U 5 -x '*~' -x '*.orig' -x CVS ecos/packages/hal/i386/arch/current/include/hal_arch.h /opt/ecos/packages/hal/i386/arch/current/include/hal_arch.h
--- ecos/packages/hal/i386/arch/current/include/hal_arch.h	2005-07-18 20:53:14.000000000 +0100
+++ /opt/ecos/packages/hal/i386/arch/current/include/hal_arch.h	2006-02-27 11:05:16.000000000 +0000
@@ -180,11 +180,11 @@ CYG_MACRO_END
 #endif
 
 
 #define HAL_THREAD_INIT_CONTEXT( _sparg_, _thread_, _entry_, _id_ )     \
 CYG_MACRO_START                                                         \
-    register CYG_WORD* _sp_ = ((CYG_WORD*)((_sparg_) &~15));            \
+    register CYG_WORD* _sp_ = ((CYG_WORD*)((CYG_ADDRWORD)(_sparg_) &~15)); \
     register CYG_WORD *_fpspace_ = NULL;                                \
     register HAL_SavedRegisters *_regs_;                                \
                                                                         \
     HAL_THREAD_INIT_FPU_CONTEXT_SPACE( _sp_, _fpspace_ );               \
     *(--_sp_) = (CYG_WORD)(0);                                          \
diff -pr -u -U 5 -x '*~' -x '*.orig' -x CVS ecos/packages/hal/i386/arch/current/include/hal_smp.h /opt/ecos/packages/hal/i386/arch/current/include/hal_smp.h
--- ecos/packages/hal/i386/arch/current/include/hal_smp.h	2002-05-24 00:03:05.000000000 +0100
+++ /opt/ecos/packages/hal/i386/arch/current/include/hal_smp.h	2006-03-06 10:51:18.000000000 +0000
@@ -116,56 +116,70 @@
 #define HAL_IOAPIC_REG_REDIR_HI(n)  (HAL_IOAPIC_REG_REDTBL+((n)*2)+1)
 
 /*------------------------------------------------------------------------*/
 // I/O APIC access macros
 
-#define HAL_IOAPIC_READ( __reg, __val )                                 \
+#define HAL_IOAPIC_READ( __n, __reg, __val )                                 \
 {                                                                       \
-    HAL_WRITEMEM_UINT32( cyg_hal_smp_io_apic+HAL_IOAPIC_REGSEL, __reg );    \
-    HAL_READMEM_UINT32( cyg_hal_smp_io_apic+HAL_IOAPIC_REGWIN, __val );     \
+    HAL_WRITEMEM_UINT32( cyg_hal_smp_io_apic[__n]+HAL_IOAPIC_REGSEL, __reg );    \
+    HAL_READMEM_UINT32( cyg_hal_smp_io_apic[__n]+HAL_IOAPIC_REGWIN, __val );     \
 }
 
-#define HAL_IOAPIC_WRITE( __reg, __val )                                \
+#define HAL_IOAPIC_WRITE( __n, __reg, __val )                                \
 {                                                                       \
-    HAL_WRITEMEM_UINT32( cyg_hal_smp_io_apic+HAL_IOAPIC_REGSEL, __reg );    \
-    HAL_WRITEMEM_UINT32( cyg_hal_smp_io_apic+HAL_IOAPIC_REGWIN, __val );    \
+    HAL_WRITEMEM_UINT32( cyg_hal_smp_io_apic[__n]+HAL_IOAPIC_REGSEL, __reg );    \
+    HAL_WRITEMEM_UINT32( cyg_hal_smp_io_apic[__n]+HAL_IOAPIC_REGWIN, __val );    \
 }
 
 //-----------------------------------------------------------------------------
 // SMP configuration determined from platform during initialization
 
 __externC CYG_ADDRESS cyg_hal_smp_local_apic;
 
-__externC CYG_ADDRESS cyg_hal_smp_io_apic;
+__externC CYG_ADDRESS cyg_hal_smp_io_apic[64];
 
-__externC CYG_WORD32 cyg_hal_smp_cpu_count;
+__externC CYG_WORD32 cyg_hal_smp_ioa_count;
+__externC CYG_BYTE cyg_hal_smp_cpu_iopic[64];
 
+__externC CYG_WORD32 cyg_hal_smp_cpu_count;
+__externC CYG_BYTE cyg_hal_smp_cpu_4apic[256];
+__externC CYG_BYTE cyg_hal_smp_cpu_lapic[CYGPKG_HAL_SMP_CPU_MAX];
 __externC CYG_BYTE cyg_hal_smp_cpu_flags[CYGPKG_HAL_SMP_CPU_MAX];
 
 __externC CYG_BYTE cyg_hal_isa_bus_id;
 __externC CYG_BYTE cyg_hal_isa_bus_irq[16];
+__externC CYG_BYTE cyg_hal_isa_bus_ioa[16];
 
 __externC CYG_BYTE cyg_hal_pci_bus_id;
 __externC CYG_BYTE cyg_hal_pci_bus_irq[4];
+__externC CYG_BYTE cyg_hal_pci_bus_ioa[4];
 
 //-----------------------------------------------------------------------------
 // CPU numbering macros
 
-#define HAL_SMP_CPU_TYPE        cyg_uint32
+#define HAL_SMP_CPU_TYPE            cyg_uint32
+
+#define HAL_SMP_CPU_MAX             CYGPKG_HAL_SMP_CPU_MAX
 
-#define HAL_SMP_CPU_MAX         CYGPKG_HAL_SMP_CPU_MAX
+#define HAL_SMP_CPU_COUNT()         cyg_hal_smp_cpu_count
 
-#define HAL_SMP_CPU_COUNT()     cyg_hal_smp_cpu_count
+#define HAL_SMP_CPU_ORD( __cpu )    cyg_hal_smp_cpu_4apic[__cpu]
 
 #define HAL_SMP_CPU_THIS()                      \
 ({                                              \
     HAL_SMP_CPU_TYPE __id;                      \
     HAL_APIC_READ( HAL_APIC_ID, __id );         \
     (__id>>24)&0xF;                             \
 })
 
-#define HAL_SMP_CPU_NONE        (CYGPKG_HAL_SMP_CPU_MAX+1)
+#define HAL_SMP_CPU_THIS_ORD()		HAL_SMP_CPU_ORD(HAL_SMP_CPU_THIS())
+
+#define HAL_SMP_CPU_NONE            (CYGPKG_HAL_SMP_CPU_MAX+1)
+
+#define HAL_SMP_IOAPIC_COUNT()         cyg_hal_smp_ioa_count
+
+#define HAL_SMP_IOAPIC_ORD( __ioa )    cyg_hal_smp_cpu_4apic[__ioa]
 
 //-----------------------------------------------------------------------------
 // CPU startup
 
 __externC void cyg_hal_cpu_release(HAL_SMP_CPU_TYPE cpu);
diff -pr -u -U 5 -x '*~' -x '*.orig' -x CVS ecos/packages/hal/i386/arch/current/src/hal_misc.c /opt/ecos/packages/hal/i386/arch/current/src/hal_misc.c
--- ecos/packages/hal/i386/arch/current/src/hal_misc.c	2005-03-21 15:05:38.000000000 +0000
+++ /opt/ecos/packages/hal/i386/arch/current/src/hal_misc.c	2006-03-03 14:05:37.000000000 +0000
@@ -187,15 +187,15 @@ _mcount(void)
     HAL_DISABLE_INTERRUPTS(ints_enabled);
 
     // This cpu is now not going to run any other code. So, did it
     // already own the spinlock?
     this_cpu = HAL_SMP_CPU_THIS();
-    if (mcount_cpu != this_cpu) {
+    if (mcount_cpu != HAL_SMP_CPU_ORD( this_cpu )) {
         // Nope, so this cannot be a nested call to mcount()
         HAL_SPINLOCK_SPIN(mcount_lock);
         // And no other cpu is executing inside mcount() either
-        mcount_cpu  = this_cpu;
+        mcount_cpu  = HAL_SMP_CPU_ORD( this_cpu );
         // A possibly-recursive call is now safe.
         __profile_mcount((CYG_ADDRWORD)__builtin_return_address(1),
                          (CYG_ADDRWORD)__builtin_return_address(0));
         // All done.
         mcount_cpu = HAL_SMP_CPU_NONE;
diff -pr -u -U 5 -x '*~' -x '*.orig' -x CVS ecos/packages/hal/i386/pcmb/current/ChangeLog /opt/ecos/packages/hal/i386/pcmb/current/ChangeLog
--- ecos/packages/hal/i386/pcmb/current/ChangeLog	2005-04-27 19:57:51.000000000 +0100
+++ /opt/ecos/packages/hal/i386/pcmb/current/ChangeLog	2006-03-09 11:00:24.000000000 +0000
@@ -1,5 +1,36 @@
+2006-03-09  David Fernandez <dfernandez@cct.co.uk>
+
+	* src/pcmb_smp.c:
+	  ioapic var cyg_hal_smp_io_apic converted in array, and new ones added to
+	    account for the number of ioapics and their ids.
+	  cpu var cyg_hal_smp_lapic[] added to account for the cpu apic ids,
+	    so that every main table including this, is indexed by ordinal
+		cpu number.
+	  var cyg_hal_smp_cpu_4apic[] added to account for the inverse conversion
+	    of local and io apic ids into cpu and ioapic ordinal numbers.
+	  var cyg_hal_isa/pci_bus_ios[] added to account for the ioapic that owns
+	    a particular isa/pci interrupt.
+	  func cyg_hal_find_smp_config: added a return at the end to avoid warning
+	    and possibly some undefined behaviour.
+	  funcs cyg_hal_parse_smp_config, cyg_hal_smp_init_apic,
+	        cyg_hal_cpu_release, cyg_hal_smp_startup,
+			cyg_hal_smp_cpu_start_all, cyg_hal_cpu_message,
+			cyg_hal_cpu_message_isr/dsr, cyg_hal_smp_halt_other_cpus,
+			cyg_hal_smp_release_other_cpus:
+	    modified to account for several ioapics and cpu lapic ids not being
+		sequencial.
+	  func cyg_hal_smp_init_ioapic modified to account for several ioapics and
+	    interrupts being owned by different ioapics in the same bus.
+	  var cyg_hal_smp_cpu_entry definition changed to account for the
+	    volatility of the table contents instead of the volatility of void,
+		that were causing a warning.
+	  func cyg_hal_cpu_start, several debug prints uncommented.
+	* include/pcmb_intr.h:
+	  macros HAL_INTERRUPT_MASK/UNMASK, HAL_INTERRUPT_GET/SET_CPU: modified
+	    to account for several ioapics in the system.
+
 2005-04-27  David Vrabel <dvrabel@arcom.com>
 
 	* cdl/hal_i386_pcmb.cdl (CYGPKG_HAL_I386_PCMB_MEMSIZE): Moved this
 	PC specific option to the pc package.
 
diff -pr -u -U 5 -x '*~' -x '*.orig' -x CVS ecos/packages/hal/i386/pcmb/current/include/pcmb_intr.h /opt/ecos/packages/hal/i386/pcmb/current/include/pcmb_intr.h
--- ecos/packages/hal/i386/pcmb/current/include/pcmb_intr.h	2002-05-24 00:03:15.000000000 +0100
+++ /opt/ecos/packages/hal/i386/pcmb/current/include/pcmb_intr.h	2006-03-06 10:58:40.000000000 +0000
@@ -213,32 +213,34 @@ CYG_MACRO_START                         
     }                                                   \
 CYG_MACRO_END
 
 #else
 
-#define HAL_INTERRUPT_MASK( _vector_ )                          \
-{                                                               \
-    cyg_uint32 __vec, __val;                                    \
-    HAL_TRANSLATE_VECTOR( _vector_, __vec );                    \
-    HAL_SPINLOCK_SPIN( cyg_hal_ioapic_lock );                   \
-    __vec = cyg_hal_isa_bus_irq[__vec];                         \
-    HAL_IOAPIC_READ( HAL_IOAPIC_REG_REDIR_LO(__vec), __val );   \
-    __val |= 0x00010000;                                        \
-    HAL_IOAPIC_WRITE( HAL_IOAPIC_REG_REDIR_LO(__vec), __val );  \
-    HAL_SPINLOCK_CLEAR( cyg_hal_ioapic_lock );                  \
+#define HAL_INTERRUPT_MASK( _vector_ )                                  \
+{                                                                       \
+    cyg_uint32 __vec, __val, __ioan;                                    \
+    HAL_TRANSLATE_VECTOR( _vector_, __vec );                            \
+    HAL_SPINLOCK_SPIN( cyg_hal_ioapic_lock );                           \
+	__ioan = HAL_SMP_IOAPIC_ORD(cyg_hal_isa_bus_ioa[__vec]);            \
+    __vec = cyg_hal_isa_bus_irq[__vec];                                 \
+    HAL_IOAPIC_READ( __ioan, HAL_IOAPIC_REG_REDIR_LO(__vec), __val );   \
+    __val |= 0x00010000;                                                \
+    HAL_IOAPIC_WRITE( __ioan, HAL_IOAPIC_REG_REDIR_LO(__vec), __val );  \
+    HAL_SPINLOCK_CLEAR( cyg_hal_ioapic_lock );                          \
 }
 
-#define HAL_INTERRUPT_UNMASK( _vector_ )                        \
-{                                                               \
-    cyg_uint32 __vec, __val;                                    \
-    HAL_TRANSLATE_VECTOR( _vector_, __vec );                    \
-    HAL_SPINLOCK_SPIN( cyg_hal_ioapic_lock );                   \
-    __vec = cyg_hal_isa_bus_irq[__vec];                         \
-    HAL_IOAPIC_READ( HAL_IOAPIC_REG_REDIR_LO(__vec), __val );   \
-    __val &= ~0x00010000;                                       \
-    HAL_IOAPIC_WRITE( HAL_IOAPIC_REG_REDIR_LO(__vec), __val );  \
-    HAL_SPINLOCK_CLEAR( cyg_hal_ioapic_lock );                  \
+#define HAL_INTERRUPT_UNMASK( _vector_ )                                \
+{                                                                       \
+    cyg_uint32 __vec, __val, __ioan;                                    \
+    HAL_TRANSLATE_VECTOR( _vector_, __vec );                            \
+    HAL_SPINLOCK_SPIN( cyg_hal_ioapic_lock );                           \
+	__ioan = HAL_SMP_IOAPIC_ORD(cyg_hal_isa_bus_ioa[__vec]);            \
+    __vec = cyg_hal_isa_bus_irq[__vec];                                 \
+    HAL_IOAPIC_READ( __ioan, HAL_IOAPIC_REG_REDIR_LO(__vec), __val );   \
+    __val &= ~0x00010000;                                               \
+    HAL_IOAPIC_WRITE( __ioan, HAL_IOAPIC_REG_REDIR_LO(__vec), __val );  \
+    HAL_SPINLOCK_CLEAR( cyg_hal_ioapic_lock );                          \
 }
 
 
 #endif
 
@@ -255,33 +257,35 @@ CYG_MACRO_END
 // Additional SMP interrupt configuration support.
 
 __externC void hal_interrupt_set_cpu( CYG_WORD32 vector, HAL_SMP_CPU_TYPE cpu );
 __externC void hal_interrupt_get_cpu( CYG_WORD32 vector, HAL_SMP_CPU_TYPE *cpu );
 
-#define HAL_INTERRUPT_SET_CPU( _vector_, _cpu_ )                \
-{                                                               \
-    cyg_uint32 __vec, __val;                                    \
-    HAL_TRANSLATE_VECTOR( _vector_, __vec );                    \
-    HAL_SPINLOCK_SPIN( cyg_hal_ioapic_lock );                   \
-    __vec = cyg_hal_isa_bus_irq[__vec];                         \
-    HAL_IOAPIC_READ( HAL_IOAPIC_REG_REDIR_HI(__vec), __val );   \
-    __val &= 0x00FFFFFF;                                        \
-    __val |= (_cpu_)<<24;                                       \
-    HAL_IOAPIC_WRITE( HAL_IOAPIC_REG_REDIR_HI(__vec), __val );  \
-    HAL_SPINLOCK_CLEAR( cyg_hal_ioapic_lock );                  \
+#define HAL_INTERRUPT_SET_CPU( _vector_, _cpu_ )                        \
+{                                                                       \
+    cyg_uint32 __vec, __val, __ioan;                                    \
+    HAL_TRANSLATE_VECTOR( _vector_, __vec );                            \
+    HAL_SPINLOCK_SPIN( cyg_hal_ioapic_lock );                           \
+	__ioan = HAL_SMP_IOAPIC_ORD(cyg_hal_isa_bus_ioa[__vec]);            \
+    __vec = cyg_hal_isa_bus_irq[__vec];                                 \
+    HAL_IOAPIC_READ( __ioan, HAL_IOAPIC_REG_REDIR_HI(__vec), __val );   \
+    __val &= 0x00FFFFFF;                                                \
+    __val |= (_cpu_)<<24;                                               \
+    HAL_IOAPIC_WRITE( __ioan, HAL_IOAPIC_REG_REDIR_HI(__vec), __val );  \
+    HAL_SPINLOCK_CLEAR( cyg_hal_ioapic_lock );                          \
 }
 
 
-#define HAL_INTERRUPT_GET_CPU( _vector_, _cpu_ )                \
-{                                                               \
-    cyg_uint32 __vec, __val;                                    \
-    HAL_TRANSLATE_VECTOR( _vector_, __vec );                    \
-    HAL_SPINLOCK_SPIN( cyg_hal_ioapic_lock );                   \
-    __vec = cyg_hal_isa_bus_irq[__vec];                         \
-    HAL_IOAPIC_READ( HAL_IOAPIC_REG_REDIR_HI(__vec), __val );   \
-    (_cpu_) = (__val>>24) & 0xFF;                               \
-    HAL_SPINLOCK_CLEAR( cyg_hal_ioapic_lock );                  \
+#define HAL_INTERRUPT_GET_CPU( _vector_, _cpu_ )                        \
+{                                                                       \
+    cyg_uint32 __vec, __val, __ioan;                                    \
+    HAL_TRANSLATE_VECTOR( _vector_, __vec );                            \
+    HAL_SPINLOCK_SPIN( cyg_hal_ioapic_lock );                           \
+	__ioan = HAL_SMP_IOAPIC_ORD(cyg_hal_isa_bus_ioa[__vec]);            \
+    __vec = cyg_hal_isa_bus_irq[__vec];                                 \
+    HAL_IOAPIC_READ( __ioan, HAL_IOAPIC_REG_REDIR_HI(__vec), __val );   \
+    (_cpu_) = (__val>>24) & 0xFF;                                       \
+    HAL_SPINLOCK_CLEAR( cyg_hal_ioapic_lock );                          \
 }
 
 
 #endif
 
diff -pr -u -U 5 -x '*~' -x '*.orig' -x CVS ecos/packages/hal/i386/pcmb/current/src/pcmb_smp.c /opt/ecos/packages/hal/i386/pcmb/current/src/pcmb_smp.c
--- ecos/packages/hal/i386/pcmb/current/src/pcmb_smp.c	2002-05-24 00:03:17.000000000 +0100
+++ /opt/ecos/packages/hal/i386/pcmb/current/src/pcmb_smp.c	2006-03-07 16:02:00.000000000 +0000
@@ -189,21 +189,27 @@ static int streq( const char *s1, const 
 /*------------------------------------------------------------------------*/
 // Exported SMP configuration
 
 CYG_ADDRESS cyg_hal_smp_local_apic;
 
-CYG_ADDRESS cyg_hal_smp_io_apic;
+CYG_ADDRESS cyg_hal_smp_io_apic[64];
 
-CYG_WORD32 cyg_hal_smp_cpu_count = 0;
+CYG_WORD32 cyg_hal_smp_ioa_count = 0;
+CYG_BYTE cyg_hal_smp_cpu_iopic[64];
 
+CYG_WORD32 cyg_hal_smp_cpu_count = 0;
+CYG_BYTE cyg_hal_smp_cpu_4apic[256];	// Can't index with lapic anymore
+CYG_BYTE cyg_hal_smp_cpu_lapic[HAL_SMP_CPU_MAX];
 CYG_BYTE cyg_hal_smp_cpu_flags[HAL_SMP_CPU_MAX];
 
 CYG_BYTE cyg_hal_isa_bus_id = 0xff;
 CYG_BYTE cyg_hal_isa_bus_irq[16];
+CYG_BYTE cyg_hal_isa_bus_ioa[16];
 
 CYG_BYTE cyg_hal_pci_bus_id = 0xff;
 CYG_BYTE cyg_hal_pci_bus_irq[4];
+CYG_BYTE cyg_hal_pci_bus_ioa[4];
 
 HAL_SPINLOCK_TYPE cyg_hal_ioapic_lock;
 
 /*------------------------------------------------------------------------*/
 
@@ -290,11 +296,13 @@ static cyg_bool cyg_hal_find_smp_config(
     if( cyg_hal_scan_smp_config(0x9fc00, 0x00400 ) )
         return 1;
 
     // check BIOS ROM
     if( cyg_hal_scan_smp_config(0xf0000, 0x10000 ) )
-        return 1;    
+        return 1;
+		
+	return 0;
 }
 
 /*------------------------------------------------------------------------*/
 
 static cyg_bool cyg_hal_parse_smp_config( void )
@@ -427,17 +435,16 @@ static cyg_bool cyg_hal_parse_smp_config
                     diag_printf("                CPU Signature:            %08x\n",val32);
                     HAL_READMEM_UINT8( entry+MPCT_ENTRY_PROC_FEATURE_FLAGS, val32 );
                     diag_printf("                Feature flags:            %08x\n",val32);
 #endif
                     {
-                        CYG_BYTE cpuid;
-
                         // Index CPUs by their APIC IDs
-                        HAL_READMEM_UINT8( entry+MPCT_ENTRY_PROC_APIC_ID, cpuid );
-
+                        HAL_READMEM_UINT8( entry+MPCT_ENTRY_PROC_APIC_ID, cyg_hal_smp_cpu_lapic[cyg_hal_smp_cpu_count] );
+						cyg_hal_smp_cpu_4apic[cyg_hal_smp_cpu_lapic[cyg_hal_smp_cpu_count]] = cyg_hal_smp_cpu_count;
+						
                         // Get flags for this CPU.
-                        HAL_READMEM_UINT8(entry+MPCT_ENTRY_PROC_CPU_FLAGS, cyg_hal_smp_cpu_flags[cpuid]);
+                        HAL_READMEM_UINT8(entry+MPCT_ENTRY_PROC_CPU_FLAGS, cyg_hal_smp_cpu_flags[cyg_hal_smp_cpu_count]);
                         
                         cyg_hal_smp_cpu_count++;      // count another CPU
                     }
                     
                     entry += MPCT_ENTRY_PROC_SIZE;
@@ -491,37 +498,50 @@ static cyg_bool cyg_hal_parse_smp_config
                     diag_printf("                Flags:                    %02x\n",val8);
                     HAL_READMEM_UINT32( entry+MPCT_ENTRY_IOAPIC_ADDRESS, val32 );
                     diag_printf("                Address:                  %08x\n",val32);
 #endif
 
-                    HAL_READMEM_UINT32( entry+MPCT_ENTRY_IOAPIC_ADDRESS, cyg_hal_smp_io_apic );
+                    {
+                        // Index IOs by their APIC IDs
+                        HAL_READMEM_UINT8( entry+MPCT_ENTRY_IOAPIC_ID, cyg_hal_smp_cpu_iopic[cyg_hal_smp_ioa_count] );
+						cyg_hal_smp_cpu_4apic[cyg_hal_smp_cpu_iopic[cyg_hal_smp_ioa_count]] = cyg_hal_smp_ioa_count;
+						
+	                    HAL_READMEM_UINT32( entry+MPCT_ENTRY_IOAPIC_ADDRESS, cyg_hal_smp_io_apic[cyg_hal_smp_ioa_count] );
+						++cyg_hal_smp_ioa_count;
+					}
                     entry += MPCT_ENTRY_IOAPIC_SIZE;                
                     break;
 
                 case MPCT_ENTRY_TYPE_INTERRUPT_IO:
                     {
-                        CYG_BYTE bus, irq, dst;
+                        CYG_BYTE bus, irq, dst, pic;
                         HAL_READMEM_UINT8( entry+MPCT_ENTRY_IOINT_SOURCE_BUS, bus );
                         HAL_READMEM_UINT8( entry+MPCT_ENTRY_IOINT_SOURCE_IRQ, irq );
                         HAL_READMEM_UINT8( entry+MPCT_ENTRY_IOINT_DEST_INT, dst );
+                        HAL_READMEM_UINT8( entry+MPCT_ENTRY_IOINT_DEST_APIC, pic );
 #if SHOW_DIAGNOSTICS                    
                         diag_printf("        I/O interrupt assignment\n");
                         HAL_READMEM_UINT8( entry+MPCT_ENTRY_IOINT_TYPE, val8 );
                         diag_printf("                Type:                     %02x\n",val8);
                         HAL_READMEM_UINT16( entry+MPCT_ENTRY_IOINT_TYPE, val16 );
                         diag_printf("                Flags:                    %04x\n",val16);
                         diag_printf("                Source bus:               %02x\n",bus);
                         diag_printf("                Source IRQ:               %02x\n",irq);
-                        HAL_READMEM_UINT8( entry+MPCT_ENTRY_IOINT_DEST_APIC, val8 );
-                        diag_printf("                Dest APIC:                %02x\n",val8);
+                        diag_printf("                Dest APIC:                %02x\n",pic);
                         diag_printf("                Dest Interrupt:           %02x\n",dst);
 #endif
 
                         if( bus == cyg_hal_isa_bus_id )
+						{
                             cyg_hal_isa_bus_irq[irq] = dst;
+							cyg_hal_isa_bus_ioa[irq] = pic;
+						}
 //                        if( bus == cyg_hal_pci_bus_id )
+//                        {
 //                            cyg_hal_pci_bus_irq[irq] = dst;
+//                            cyg_hal_pci_bus_ioa[irq] = pic;
+//                        }
                     
                     }
                     entry += MPCT_ENTRY_IOINT_SIZE;
                     break;
 
@@ -559,11 +579,15 @@ static cyg_bool cyg_hal_parse_smp_config
 
 #if SHOW_DIAGNOSTICS
 
     diag_printf("Exported configuration:\n");
     diag_printf("        Local APIC: %08x\n", cyg_hal_smp_local_apic );
-    diag_printf("        I/O APIC:   %08x\n", cyg_hal_smp_io_apic );
+    diag_printf("        IOPIC count:%d\n", cyg_hal_smp_ioa_count );
+	for( i = 0; i < cyg_hal_smp_ioa_count; i++ )
+	{
+        diag_printf("            I/O APIC:   %08x\n", cyg_hal_smp_io_apic[i] );
+    }
     diag_printf("        CPU count:  %d\n", cyg_hal_smp_cpu_count );
 
     for( i = 0; i < cyg_hal_smp_cpu_count; i++ )
     {
         diag_printf("            CPU %d %sactive %s\n",i,
@@ -574,11 +598,11 @@ static cyg_bool cyg_hal_parse_smp_config
 
     diag_printf("        ISA IRQ map:\n");
 
     for( i = 0; i < 16; i++ )
     {
-        diag_printf("            IRQ %2d -> IOAPIC INT %2d\n",i,cyg_hal_isa_bus_irq[i]);
+        diag_printf("            IRQ %2d -> IOAPIC %02X INT %2d\n",i, cyg_hal_isa_bus_ioa[i],cyg_hal_isa_bus_irq[i]);
     }
     
 #endif    
     
     return 1;
@@ -678,21 +702,21 @@ static cyg_bool cyg_hal_smp_init_apic(vo
 
     // Set up logical destination id. We set bit 1<<cpuid in the LDR
     // register.
 
     HAL_APIC_READ( HAL_APIC_LDR, val );
-    val |= 1<<(cpu+24);
+    val |= 1<<(HAL_SMP_CPU_ORD( cpu )+24);
     HAL_APIC_WRITE( HAL_APIC_LDR, val );
 
     // Set TPR register to accept all.
     HAL_APIC_WRITE( HAL_APIC_TPR, 0 );
 
     // Enable APIC in SPIV
     HAL_APIC_WRITE( HAL_APIC_SPIV, 0x00000100 );
 
     
-    if( cyg_hal_smp_cpu_flags[HAL_SMP_CPU_THIS()] & 2 )
+    if( cyg_hal_smp_cpu_flags[HAL_SMP_CPU_ORD( cpu )] & 2 )
     {
         // This is the boot CPU, switch its PIC into APIC mode
         // Non-boot CPUs are already in APIC mode.
         
         HAL_WRITE_UINT8( 0x22, 0x70 );
@@ -706,20 +730,16 @@ static cyg_bool cyg_hal_smp_init_apic(vo
 // Initialize I/O APIC
 
 static cyg_bool cyg_hal_smp_init_ioapic(void)
 {
     CYG_WORD32 val;
-    cyg_uint32 tabsize = 0;
-    int i;
+    int i, j;
     HAL_SMP_CPU_TYPE cpu_this = HAL_SMP_CPU_THIS();
 
     HAL_SPINLOCK_CLEAR( cyg_hal_ioapic_lock );
     HAL_SPINLOCK_SPIN( cyg_hal_ioapic_lock );
     
-    HAL_IOAPIC_READ( HAL_IOAPIC_REG_APICVER, val );
-    tabsize = (val>>16)&0xFF;
-
     // Set up ISA interrupts
     for( i = 0; i < 16; i++ )
     {
         if( cyg_hal_isa_bus_irq[i] != 100 )
         {
@@ -727,37 +747,47 @@ static cyg_bool cyg_hal_smp_init_ioapic(
 
             tehi |= cpu_this<<24;
 
             telo |= CYGNUM_HAL_ISR_MIN+i;
             
-            HAL_IOAPIC_WRITE( HAL_IOAPIC_REG_REDIR_LO(cyg_hal_isa_bus_irq[i]), telo );
-            HAL_IOAPIC_WRITE( HAL_IOAPIC_REG_REDIR_HI(cyg_hal_isa_bus_irq[i]), tehi );
+            HAL_IOAPIC_WRITE( HAL_SMP_IOAPIC_ORD(cyg_hal_isa_bus_ioa[i]), HAL_IOAPIC_REG_REDIR_LO(cyg_hal_isa_bus_irq[i]), telo );
+            HAL_IOAPIC_WRITE( HAL_SMP_IOAPIC_ORD(cyg_hal_isa_bus_ioa[i]), HAL_IOAPIC_REG_REDIR_HI(cyg_hal_isa_bus_irq[i]), tehi );
         }
     }
 
     
-#if SHOW_DIAGNOSTICS    
-    diag_printf("I/O APIC: %08x\n",cyg_hal_smp_io_apic);
-
-    HAL_IOAPIC_READ( HAL_IOAPIC_REG_APICID, val );
-    diag_printf("        ID: %08x\n",val);
-
-    HAL_IOAPIC_READ( HAL_IOAPIC_REG_APICVER, val );
-    diag_printf("        VER: %08x\n",val);
-
-    HAL_IOAPIC_READ( HAL_IOAPIC_REG_APICARB, val );
-    diag_printf("        ARB: %08x\n",val);
-
-    diag_printf("        Redirection Table:\n");
-    for( i = 0; i < tabsize; i++ )
-    {
-        CYG_WORD32 tehi, telo;
-
-        HAL_IOAPIC_READ( HAL_IOAPIC_REG_REDIR_LO(i), telo );
-        HAL_IOAPIC_READ( HAL_IOAPIC_REG_REDIR_HI(i), tehi );
-        diag_printf("            %02d: %08x %08x\n",i,tehi,telo);
-    }
+#if SHOW_DIAGNOSTICS
+	{
+	    cyg_uint32 tabsize = 0;
+		
+		for( i = 0; i < cyg_hal_smp_ioa_count; i++ )
+		{
+	    	HAL_IOAPIC_READ( i, HAL_IOAPIC_REG_APICVER, val );
+	    	tabsize = (val>>16)&0xFF;
+
+	    	diag_printf("I/O APIC: %08x\n",cyg_hal_smp_io_apic[i]);
+
+	    	HAL_IOAPIC_READ( i, HAL_IOAPIC_REG_APICID, val );
+	    	diag_printf("        ID: %08x\n",val);
+
+	    	HAL_IOAPIC_READ( i, HAL_IOAPIC_REG_APICVER, val );
+	    	diag_printf("        VER: %08x\n",val);
+
+	    	HAL_IOAPIC_READ( i, HAL_IOAPIC_REG_APICARB, val );
+	    	diag_printf("        ARB: %08x\n",val);
+
+	    	diag_printf("        Redirection Table:\n");
+	    	for( j = 0; j < tabsize; j++ )
+	    	{
+	        	CYG_WORD32 tehi, telo;
+
+	        	HAL_IOAPIC_READ( i, HAL_IOAPIC_REG_REDIR_LO(j), telo );
+	        	HAL_IOAPIC_READ( i, HAL_IOAPIC_REG_REDIR_HI(j), tehi );
+	        	diag_printf("            %02d: %08x %08x\n",j,tehi,telo);
+	    	}
+		}
+	}
 #endif
 
     HAL_SPINLOCK_CLEAR( cyg_hal_ioapic_lock );
 
     return 1;
@@ -767,11 +797,11 @@ static cyg_bool cyg_hal_smp_init_ioapic(
 
 static volatile CYG_WORD32 init_deasserted;
 
 __externC volatile CYG_WORD32 cyg_hal_smp_cpu_sync_flag[HAL_SMP_CPU_MAX];
 __externC volatile CYG_WORD32 cyg_hal_smp_cpu_sync[HAL_SMP_CPU_MAX];
-__externC volatile void (*cyg_hal_smp_cpu_entry[HAL_SMP_CPU_MAX])(void);
+__externC          void (*volatile cyg_hal_smp_cpu_entry[HAL_SMP_CPU_MAX])(void);
 __externC volatile CYG_WORD32 cyg_hal_smp_vsr_sync_flag;
 __externC volatile CYG_WORD32 cyg_hal_smp_cpu_running[HAL_SMP_CPU_MAX];
 
 /*------------------------------------------------------------------------*/
 
@@ -827,19 +857,23 @@ __externC void cyg_hal_cpu_start( HAL_SM
     // Wait for the ICR to become inactive
     do {
         HAL_APIC_READ( HAL_APIC_ICR_LO, icrlo );
     } while( (icrlo & 0x00001000) != 0 );
 
+    PC_WRITE_SCREEN( PC_SCREEN_LINE(5)+0, '!' );    
+
     // Now de-assert INIT
 
     icrlo = 0x00008500;
 
     HAL_APIC_WRITE( HAL_APIC_ICR_HI, icrhi );    
     HAL_APIC_WRITE( HAL_APIC_ICR_LO, icrlo );
 
     init_deasserted = 1;
 
+    PC_WRITE_SCREEN( PC_SCREEN_LINE(5)+1, '!' );    
+
     // Now we send two STARTUP IPIs
 
     for( i = 0; i < 2; i++ )
     {
         icrlo = 0x00000600 | (HAL_SLAVE_START_ADDRESS>>12);
@@ -854,20 +888,18 @@ __externC void cyg_hal_cpu_start( HAL_SM
         do {
             HAL_APIC_READ( HAL_APIC_ICR_LO, icrlo );
         } while( (icrlo & 0x00001000) != 0 );
 
         hal_delay_us( 300 );
+
+	    PC_WRITE_SCREEN( PC_SCREEN_LINE(5)+2+i, '!' );    
     }
     
     HAL_WRITE_CMOS( 0x0f, old_cmos );
 
-//    PC_WRITE_SCREEN( PC_SCREEN_LINE(5)+0, '!' );    
-
-    hal_delay_us( 300 );
-    
-//    PC_WRITE_SCREEN( PC_SCREEN_LINE(5)+1, '!' );    
-
+    PC_WRITE_SCREEN( PC_SCREEN_LINE(5)+4, '!' );
+	
 #endif    
 }
 
 /*------------------------------------------------------------------------*/
 
@@ -877,83 +909,83 @@ __externC void cyg_hal_smp_startup(void)
 __externC void cyg_hal_cpu_release( HAL_SMP_CPU_TYPE cpu )
 {
 //    PC_WRITE_SCREEN( PC_SCREEN_LINE(13), '!' );            
 //    PC_WRITE_SCREEN_8( PC_SCREEN_LINE(13), cpu );
     
-    cyg_hal_smp_cpu_entry[cpu] = cyg_hal_smp_start;
+    cyg_hal_smp_cpu_entry[HAL_SMP_CPU_ORD( cpu )] = cyg_hal_smp_start;
 
-    while( cyg_hal_smp_cpu_entry[cpu] != 0 )
+    while( cyg_hal_smp_cpu_entry[HAL_SMP_CPU_ORD( cpu )] != 0 )
     {
-//        PC_WRITE_SCREEN_32( PC_SCREEN_LINE(13)+4, cyg_hal_smp_cpu_entry[cpu] );
+        PC_WRITE_SCREEN_32( PC_SCREEN_LINE(13)+4, cyg_hal_smp_cpu_entry[HAL_SMP_CPU_ORD( cpu )] );
         hal_delay_us( 100 );
-         continue;
+        continue;
     }
 }
 
 /*------------------------------------------------------------------------*/
 
 __externC void cyg_hal_smp_startup(void)
 {
     HAL_SMP_CPU_TYPE cpu;
 
-//    PC_WRITE_SCREEN( PC_SCREEN_LINE(2)+0, '!' );
+    PC_WRITE_SCREEN( PC_SCREEN_LINE(2)+0, '!' );
 
 #ifndef CYG_HAL_STARTUP_RAM 
     // Wait for INIT interrupt to be deasserted
     while( !init_deasserted )
         continue;
 #endif
     
-//    PC_WRITE_SCREEN( PC_SCREEN_LINE(2)+1, '!' );
+    PC_WRITE_SCREEN( PC_SCREEN_LINE(2)+1, '!' );
     
     cpu  = HAL_SMP_CPU_THIS();
     
-//    PC_WRITE_SCREEN_8( PC_SCREEN_LINE(2)+6, cpu );
-    
+    PC_WRITE_SCREEN_8( PC_SCREEN_LINE(2)+6, cpu );
+	
 #ifndef CYG_HAL_STARTUP_RAM 
     // Wait 1s for the world to settle
     hal_delay_us( 1000000 );
 
-//    PC_WRITE_SCREEN( PC_SCREEN_LINE(2)+2, '!' );        
+    PC_WRITE_SCREEN( PC_SCREEN_LINE(2)+2, '!' );        
  
     // Setup our APIC
     cyg_hal_smp_init_apic();
 #endif
     
-//    PC_WRITE_SCREEN( PC_SCREEN_LINE(2)+3, '!' );        
+    PC_WRITE_SCREEN( PC_SCREEN_LINE(2)+3, '!' );        
 
 #ifdef CYGPKG_KERNEL_SMP_SUPPORT			
-    cyg_hal_smp_cpu_running[cpu] = 1;
+    cyg_hal_smp_cpu_running[HAL_SMP_CPU_ORD( cpu )] = 1;
     cyg_kernel_smp_startup();
 #else 
     for(;;)
     {
         void (*entry)(void);
 
-        while( (entry = cyg_hal_smp_cpu_entry[cpu]) == 0 )
+        while( (entry = cyg_hal_smp_cpu_entry[HAL_SMP_CPU_ORD( cpu )]) == 0 )
         {
-#if 0 //SCREEN_DIAGNOSTICS                
+#if SCREEN_DIAGNOSTICS                
             static int n;
             PC_WRITE_SCREEN_8( PC_SCREEN_LINE(2)+10, n );
-            PC_WRITE_SCREEN_8( PC_SCREEN_LINE(2)+15, cyg_hal_smp_cpu_sync[cpu] );
+            PC_WRITE_SCREEN_8( PC_SCREEN_LINE(2)+15, cyg_hal_smp_cpu_sync[HAL_SMP_CPU_ORD( cpu )] );
             PC_WRITE_SCREEN_8( PC_SCREEN_LINE(2)+30, cyg_hal_smp_cpu_sync_flag[0] );
             PC_WRITE_SCREEN_8( PC_SCREEN_LINE(2)+35, cyg_hal_smp_cpu_sync_flag[1] );
             PC_WRITE_SCREEN_8( PC_SCREEN_LINE(2)+40, cyg_hal_smp_vsr_sync_flag );
             n++;
 #endif
             hal_delay_us( 100 );            
         }
 
-//        PC_WRITE_SCREEN( PC_SCREEN_LINE(2)+4, '!' );
+        PC_WRITE_SCREEN( PC_SCREEN_LINE(2)+4, '!' );
 
-        cyg_hal_smp_cpu_entry[cpu] = 0; 
+        cyg_hal_smp_cpu_entry[HAL_SMP_CPU_ORD( cpu )] = 0; 
  
-//        PC_WRITE_SCREEN_32( PC_SCREEN_LINE(2)+20, entry );  
+        PC_WRITE_SCREEN_32( PC_SCREEN_LINE(2)+20, entry );  
  
         if( entry != NULL )
         {
-            cyg_hal_smp_cpu_running[cpu] = 1;
+            cyg_hal_smp_cpu_running[HAL_SMP_CPU_ORD( cpu )] = 1;
             entry();
         }
     }
 #endif     
 }
@@ -977,22 +1009,36 @@ __externC void cyg_hal_smp_init(void)
 
 /*------------------------------------------------------------------------*/
 
 __externC void cyg_hal_smp_cpu_start_all(void)
 {
-    HAL_SMP_CPU_TYPE cpu;
+    int i;
 
-    for( cpu = 0; cpu < HAL_SMP_CPU_COUNT(); cpu++ )
+    for( i = 0; i < HAL_SMP_CPU_COUNT(); i++ )
     {
-        cyg_hal_smp_cpu_sync[cpu] = 0;
-        cyg_hal_smp_cpu_sync_flag[cpu] = 0;
-        cyg_hal_smp_cpu_running[cpu] = 0;
-        cyg_hal_smp_cpu_entry[cpu] = 0;
+        cyg_hal_smp_cpu_sync[i] = 0;
+        cyg_hal_smp_cpu_sync_flag[i] = 0;
+        cyg_hal_smp_cpu_running[i] = 0;
+        cyg_hal_smp_cpu_entry[i] = 0;
         
-        if( cpu != HAL_SMP_CPU_THIS() )
-            cyg_hal_cpu_start( cpu );
-        else cyg_hal_smp_cpu_running[cpu] = 1;
+        if( i != HAL_SMP_CPU_THIS_ORD() )
+		{
+#if SHOW_DIAGNOSTICS    
+            diag_printf("Starting CPU%d:%02X...", i, cyg_hal_smp_cpu_lapic[i]);
+#endif
+            cyg_hal_cpu_start( cyg_hal_smp_cpu_lapic[i] );
+		}
+        else
+		{
+#if SHOW_DIAGNOSTICS    
+            diag_printf("Updating CPU%d:%02X...", i, cyg_hal_smp_cpu_lapic[i]);
+#endif
+            cyg_hal_smp_cpu_running[i] = 1;
+		}
+#if SHOW_DIAGNOSTICS
+        diag_printf("Done\n");
+#endif
     }
 }
 
 /*------------------------------------------------------------------------*/
 // SMP message buffers.
@@ -1015,37 +1061,38 @@ static struct smp_msg_t
 
 /*------------------------------------------------------------------------*/
 // Pass a message to another CPU.
 
 #if SCREEN_DIAGNOSTICS
-static int res_msgs[2], tms_msgs[2];
+static int res_msgs[HAL_SMP_CPU_MAX], tms_msgs[HAL_SMP_CPU_MAX];
 #endif
 
 __externC void cyg_hal_cpu_message( HAL_SMP_CPU_TYPE cpu,
                                     CYG_WORD32 msg,
                                     CYG_WORD32 arg,
                                     CYG_WORD32 wait)
 {
 #if 1
     CYG_INTERRUPT_STATE istate;    
-    struct smp_msg_t *m = &smp_msg[cpu];
+    struct smp_msg_t *m = &smp_msg[HAL_SMP_CPU_ORD( cpu )];
     int i;
-    HAL_SMP_CPU_TYPE me = HAL_SMP_CPU_THIS();
  
     HAL_DISABLE_INTERRUPTS( istate );
     
     // Get access to the message buffer for the selected CPU
     HAL_SPINLOCK_SPIN( m->lock );
 
-#if 0 //SCREEN_DIAGNOSTICS    
+#if SCREEN_DIAGNOSTICS    
+    HAL_SMP_CPU_TYPE me = HAL_SMP_CPU_THIS();
+	
     if( msg == HAL_SMP_MESSAGE_RESCHEDULE )
-        res_msgs[me]++;
+        res_msgs[HAL_SMP_CPU_ORD( me )]++;
     else if( msg == HAL_SMP_MESSAGE_TIMESLICE )
-        tms_msgs[me]++;
-    PC_WRITE_SCREEN_8( PC_SCREEN_LINE(18+me), me);     
-    PC_WRITE_SCREEN_16( PC_SCREEN_LINE(18+me)+40, res_msgs[me]); 
-    PC_WRITE_SCREEN_16( PC_SCREEN_LINE(18+me)+45, tms_msgs[me]); 
+        tms_msgs[HAL_SMP_CPU_ORD( me )]++;
+    PC_WRITE_SCREEN_8( PC_SCREEN_LINE(18+HAL_SMP_CPU_ORD( me )), me);     
+    PC_WRITE_SCREEN_16( PC_SCREEN_LINE(18+HAL_SMP_CPU_ORD( me ))+40, res_msgs[HAL_SMP_CPU_ORD( me )]); 
+    PC_WRITE_SCREEN_16( PC_SCREEN_LINE(18+HAL_SMP_CPU_ORD( me ))+45, tms_msgs[HAL_SMP_CPU_ORD( me )]); 
 #endif
  
     if( msg == HAL_SMP_MESSAGE_RESCHEDULE )
         m->reschedule = true;
     else if( msg == HAL_SMP_MESSAGE_TIMESLICE )
@@ -1069,32 +1116,32 @@ __externC void cyg_hal_cpu_message( HAL_
         m->tail = next;
     }
     
     // Now send an interrupt to the CPU.
     
-//    PC_WRITE_SCREEN_16( PC_SCREEN_LINE(18+me)+50, cyg_hal_smp_cpu_running[cpu] );
+    PC_WRITE_SCREEN_16( PC_SCREEN_LINE(18+HAL_SMP_CPU_ORD( me ))+50, cyg_hal_smp_cpu_running[HAL_SMP_CPU_ORD( cpu )] );
     
-    if( cyg_hal_smp_cpu_running[cpu] )
+    if( cyg_hal_smp_cpu_running[HAL_SMP_CPU_ORD( cpu )] )
     {
         CYG_WORD32 icrlo, icrhi;
 
         // Set the ICR fields we want to write. Most fields are zero
         // except the destination in the high word and the vector
         // number in the low.
         icrhi = cpu<<24;
-        icrlo = CYGNUM_HAL_SMP_CPU_INTERRUPT_VECTOR( cpu );
+        icrlo = CYGNUM_HAL_SMP_CPU_INTERRUPT_VECTOR( HAL_SMP_CPU_ORD( cpu ) );
 
         // Write the ICR register. The interrupt will be raised when
         // the low word is written.
         HAL_APIC_WRITE( HAL_APIC_ICR_HI, icrhi );
         HAL_APIC_WRITE( HAL_APIC_ICR_LO, icrlo );
 
         // Wait for the ICR to become inactive
         do {
-#if 0 //SCREEN_DIAGNOSTICS            
+#if SCREEN_DIAGNOSTICS            
             static int n;                
-            PC_WRITE_SCREEN_8( PC_SCREEN_LINE(18+me)+55, n );
+            PC_WRITE_SCREEN_8( PC_SCREEN_LINE(18+HAL_SMP_CPU_ORD( me ))+55, n );
             n++;
 #endif            
             HAL_APIC_READ( HAL_APIC_ICR_LO, icrlo );
         } while( (icrlo & 0x00001000) != 0 );        
     }
@@ -1124,18 +1171,18 @@ __externC void cyg_hal_cpu_message( HAL_
 }
 
 /*------------------------------------------------------------------------*/
 
 #if SCREEN_DIAGNOSTICS
-static int isrs[2];
-static int dsrs[2];
+static int isrs[HAL_SMP_CPU_MAX];
+static int dsrs[HAL_SMP_CPU_MAX];
 #endif
 
 __externC CYG_WORD32 cyg_hal_cpu_message_isr( CYG_WORD32 vector, CYG_ADDRWORD data )
 {
     HAL_SMP_CPU_TYPE me = HAL_SMP_CPU_THIS();
-    struct smp_msg_t *m = &smp_msg[me];
+    struct smp_msg_t *m = &smp_msg[HAL_SMP_CPU_ORD( me )];
     CYG_WORD32 ret = 1;
     CYG_INTERRUPT_STATE istate;
     
     HAL_DISABLE_INTERRUPTS( istate );
 
@@ -1144,13 +1191,13 @@ __externC CYG_WORD32 cyg_hal_cpu_message
     // First, acknowledge the interrupt.
     
     HAL_INTERRUPT_ACKNOWLEDGE( vector );
 
 #if SCREEN_DIAGNOSTICS
-    isrs[me]++;    
-    PC_WRITE_SCREEN_8( PC_SCREEN_LINE(18+me), me); 
-    PC_WRITE_SCREEN_16( PC_SCREEN_LINE(18+me)+5, isrs[me]); 
+    isrs[HAL_SMP_CPU_ORD( me )]++;    
+    PC_WRITE_SCREEN_8( PC_SCREEN_LINE(18+HAL_SMP_CPU_ORD( me )), me); 
+    PC_WRITE_SCREEN_16( PC_SCREEN_LINE(18+HAL_SMP_CPU_ORD( me ))+5, isrs[HAL_SMP_CPU_ORD( me )]); 
 #endif
     
     if( m->reschedule || m->timeslice )
         ret |= 2;               // Ask for the DSR to be called.
     
@@ -1206,28 +1253,28 @@ __externC CYG_WORD32 cyg_hal_cpu_message
 __externC void cyg_scheduler_set_need_reschedule(void);
 __externC void cyg_scheduler_timeslice_cpu(void);
 
 #if SCREEN_DIAGNOSTICS
 __externC int cyg_scheduler_sched_lock;
-static int rescheds[2];
-static int timeslices[2];
+static int rescheds[HAL_SMP_CPU_MAX];
+static int timeslices[HAL_SMP_CPU_MAX];
 #endif
 
 __externC CYG_WORD32 cyg_hal_cpu_message_dsr( CYG_WORD32 vector, CYG_ADDRWORD data )
 {
     HAL_SMP_CPU_TYPE me = HAL_SMP_CPU_THIS();
-    struct smp_msg_t *m = &smp_msg[me];
+    struct smp_msg_t *m = &smp_msg[HAL_SMP_CPU_ORD( me )];
     CYG_INTERRUPT_STATE istate;
     CYG_WORD32 reschedule, timeslice;
     
     HAL_DISABLE_INTERRUPTS( istate );
     HAL_SPINLOCK_SPIN( m->lock );
 
 #if SCREEN_DIAGNOSTICS    
     dsrs[me]++;    
-    PC_WRITE_SCREEN_16( PC_SCREEN_LINE(18+me)+10, dsrs[me]);
-    PC_WRITE_SCREEN_16( PC_SCREEN_LINE(18+me)+15, cyg_scheduler_sched_lock);  
+    PC_WRITE_SCREEN_16( PC_SCREEN_LINE(18+HAL_SMP_CPU_ORD( me ))+10, dsrs[me]);
+    PC_WRITE_SCREEN_16( PC_SCREEN_LINE(18+HAL_SMP_CPU_ORD( me ))+15, cyg_scheduler_sched_lock);  
 #endif
     
     reschedule = m->reschedule;
     timeslice = m->timeslice;
     m->reschedule = m->timeslice = false;
@@ -1236,20 +1283,20 @@ __externC CYG_WORD32 cyg_hal_cpu_message
     HAL_RESTORE_INTERRUPTS( istate );
         
     if( reschedule )
     {
 #if SCREEN_DIAGNOSTICS        
-        rescheds[me]++;
-        PC_WRITE_SCREEN_16( PC_SCREEN_LINE(18+me)+20, rescheds[me]);
+        rescheds[HAL_SMP_CPU_ORD( me )]++;
+        PC_WRITE_SCREEN_16( PC_SCREEN_LINE(18+HAL_SMP_CPU_ORD( me ))+20, rescheds[HAL_SMP_CPU_ORD( me )]);
 #endif        
         cyg_scheduler_set_need_reschedule();
     }
     if( timeslice )
     {
 #if SCREEN_DIAGNOSTICS
-        timeslices[me]++;
-        PC_WRITE_SCREEN_16( PC_SCREEN_LINE(18+me)+25, timeslices[me]);
+        timeslices[HAL_SMP_CPU_ORD( me )]++;
+        PC_WRITE_SCREEN_16( PC_SCREEN_LINE(18+HAL_SMP_CPU_ORD( me ))+25, timeslices[HAL_SMP_CPU_ORD( me )]);
 #endif        
         cyg_scheduler_timeslice_cpu();
     }
 
     return 0;
@@ -1257,34 +1304,34 @@ __externC CYG_WORD32 cyg_hal_cpu_message
 }
 
 /*------------------------------------------------------------------------*/
 
 #if SCREEN_DIAGNOSTICS
-static int x = 0;
+// static int x = 0;
 #endif
 
 __externC void cyg_hal_smp_halt_other_cpus(void)
 {
     int i;
     HAL_SMP_CPU_TYPE me = HAL_SMP_CPU_THIS();
     
-//    PC_WRITE_SCREEN_8( PC_SCREEN_LINE(6+me), me );
+//    PC_WRITE_SCREEN_8( PC_SCREEN_LINE(6+HAL_SMP_CPU_ORD( me )), me );
   
     for( i = 0 ; i < HAL_SMP_CPU_COUNT(); i++ )
     {
-        if( i != me && cyg_hal_smp_cpu_running[i] )
+        if( i != HAL_SMP_CPU_ORD( me ) && cyg_hal_smp_cpu_running[i] )
         {
             CYG_WORD32 icrhi, icrlo;
             CYG_WORD32 oldsync;
             
-//            PC_WRITE_SCREEN_8( PC_SCREEN_LINE(6+me)+40, i );
+//            PC_WRITE_SCREEN_8( PC_SCREEN_LINE(6+HAL_SMP_CPU_ORD( me ))+40, i );
 
             oldsync = cyg_hal_smp_cpu_sync_flag[i]; 
             cyg_hal_smp_cpu_sync[i] = 0;
 
 
-            icrhi = i<<24;
+            icrhi = cyg_hal_smp_cpu_lapic[i]<<24;
             icrlo = CYGNUM_HAL_VECTOR_NMI;  // not really used
             icrlo |= 0x00000400;    // Delivery = NMI
             //icrlo |= 0x000C0000;    // Dest = all excluding self
 
             // Write the ICR register. The interrupt will be raised when
@@ -1294,23 +1341,23 @@ __externC void cyg_hal_smp_halt_other_cp
 
             // Wait for the ICR to become inactive
             do {
 #if 0 //SCREEN_DIAGNOSTICS
                 static int n;                
-                PC_WRITE_SCREEN_8( PC_SCREEN_LINE(6+me)+45, n );
+                PC_WRITE_SCREEN_8( PC_SCREEN_LINE(6+HAL_SMP_CPU_ORD( me ))+45, n );
                 n++;
 #endif                
                 HAL_APIC_READ( HAL_APIC_ICR_LO, icrlo );
             } while( (icrlo & 0x00001000) != 0 );
 
             // Wait for CPU to halt
             while( cyg_hal_smp_cpu_sync_flag[i] == oldsync )
             {
 #if 0 //SCREEN_DIAGNOSTICS                
-                PC_WRITE_SCREEN_8( PC_SCREEN_LINE(6+me)+4, x ); x++;
-                PC_WRITE_SCREEN_8( PC_SCREEN_LINE(6+me)+10+(i*8), cyg_hal_smp_cpu_sync_flag[i] );
-                PC_WRITE_SCREEN_8( PC_SCREEN_LINE(6+me)+10+(i*8)+4, oldsync );
+                PC_WRITE_SCREEN_8( PC_SCREEN_LINE(6+HAL_SMP_CPU_ORD( me ))+4, x ); x++;
+                PC_WRITE_SCREEN_8( PC_SCREEN_LINE(6+HAL_SMP_CPU_ORD( me ))+10+(i*8), cyg_hal_smp_cpu_sync_flag[i] );
+                PC_WRITE_SCREEN_8( PC_SCREEN_LINE(6+HAL_SMP_CPU_ORD( me ))+10+(i*8)+4, oldsync );
 #endif           
                 hal_delay_us( 100 );
             }
             
         }
@@ -1321,11 +1368,11 @@ __externC void cyg_hal_smp_halt_other_cp
 __externC void cyg_hal_smp_release_other_cpus(void)
 {
     int i;
     for( i = 0 ; i < HAL_SMP_CPU_COUNT(); i++ )
     {
-        if( i != HAL_SMP_CPU_THIS() && cyg_hal_smp_cpu_running[i] )
+        if( i != HAL_SMP_CPU_THIS_ORD() && cyg_hal_smp_cpu_running[i] )
         {
             CYG_WORD32 oldsync = cyg_hal_smp_cpu_sync_flag[i];        
             cyg_hal_smp_cpu_sync[i] = 1;
             while( cyg_hal_smp_cpu_sync_flag[i] == oldsync )
                 continue;
diff -pr -u -U 5 -x '*~' -x '*.orig' -x CVS ecos/packages/redboot/current/cdl/redboot.cdl /opt/ecos/packages/redboot/current/cdl/redboot.cdl
--- ecos/packages/redboot/current/cdl/redboot.cdl	2006-02-25 14:21:12.000000000 +0000
+++ /opt/ecos/packages/redboot/current/cdl/redboot.cdl	2006-03-08 09:14:59.000000000 +0000
@@ -57,11 +57,11 @@ cdl_package CYGPKG_REDBOOT {
            This package supports the Redboot \[stand-alone debug monitor\]
            using eCos as the underlying board support mechanism."
 
     # Use of separate interrupt stack causes problems when running
     # programs as they can end up trashing RedBoot's stack
-    requires { CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK == 0 }
+    # requires { CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK == 0 }
 
     # Since the CYGDAT_REDBOOT_CONSOLE_DEV setting ends up in the platform
     # HAL header, we need to include that here (via hal.h).
     define_proc {
         puts $::cdl_header "#include <pkgconf/hal.h>"
diff -pr -u -U 5 -x '*~' -x '*.orig' -x CVS ecos/packages/redboot/current/ChangeLog /opt/ecos/packages/redboot/current/ChangeLog
--- ecos/packages/redboot/current/ChangeLog	2006-02-25 14:21:12.000000000 +0000
+++ /opt/ecos/packages/redboot/current/ChangeLog	2006-03-09 11:16:59.000000000 +0000
@@ -1,5 +1,15 @@
+2006-03-09  David Fernandez <dfernandez@cct.co.uk>
+
+	* src/main.c: functions cyg_start and do_go modified when calling the
+	  macro HAL_THREAD_INIT_CONTEXT, so that they don't cast the l-value
+	  workspace_end, as the macro will cast it whenever it is necessary,
+	  and so, allowing the macro to change it.
+	* cdl/redboot.cdl: commenting the requirement
+	  CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK == 0, as it is needed
+	  by SMP support in redboot.
+ 
 2006-02-25  Oliver Munz  <munz@speag.ch>
 	    Andrew Lunn  <andrew.lunn@ascom.ch>
 	
 	* src/xyzModem.c (xyzModem_stream_open): Fix compiler warnings.
 	* src/flash_load.c (NEW): Implements access to flash
diff -pr -u -U 5 -x '*~' -x '*.orig' -x CVS ecos/packages/redboot/current/src/main.c /opt/ecos/packages/redboot/current/src/main.c
--- ecos/packages/redboot/current/src/main.c	2006-02-25 14:21:12.000000000 +0000
+++ /opt/ecos/packages/redboot/current/src/main.c	2006-02-27 11:07:00.000000000 +0000
@@ -392,11 +392,11 @@ cyg_start(void)
                 }
     
                 CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
 
                 // set up a temporary context that will take us to the trampoline
-                HAL_THREAD_INIT_CONTEXT((CYG_ADDRWORD)workspace_end,
+                HAL_THREAD_INIT_CONTEXT(workspace_end,
                                         breakpoint, trampoline,0);
 
                 // switch context to trampoline (get GDB stubs started)
                 HAL_THREAD_SWITCH_CONTEXT(&saved_context, &workspace_end);
 
@@ -592,11 +592,11 @@ do_go(int argc, char *argv[])
 	HAL_DCACHE_SYNC();
     }
     HAL_ICACHE_INVALIDATE_ALL();
     HAL_DCACHE_INVALIDATE_ALL();
     // set up a temporary context that will take us to the trampoline
-    HAL_THREAD_INIT_CONTEXT((CYG_ADDRWORD)workspace_end, 
+    HAL_THREAD_INIT_CONTEXT(workspace_end, 
                             entry, trampoline, 0);
 
     // switch context to trampoline
     HAL_THREAD_SWITCH_CONTEXT(&saved_context, &workspace_end);
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]