This is the mail archive of the
ecos-patches@sourceware.org
mailing list for the eCos project.
[PATCH] i386 SMP bug fixes
- From: David Fernandez <dfernandez at cct dot co dot uk>
- To: ecos-patches at sources dot redhat dot com
- Cc: Andrew Lunn <andrew at lunn dot ch>, Nick Garnett <nickg at ecoscentric dot com>
- Date: Thu, 09 Mar 2006 12:14:18 +0000
- Subject: [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);