See patch!
On Sat, Aug 02, 2008 at 04:43:34PM +0200, Stefan Reinauer wrote:
Go back to SIPI WAIT state for those CPUS defining the newly introduced CONFIG_AP_IN_SIPI_WAIT flag. Newer Intel CPUs need this to operate with multiple cores.
Signed-off-by: Stefan Reinauer stepan@coresystems.de
Acked-by: Peter Stuge peter@stuge.se
Index: src/include/cpu/x86/lapic.h
--- src/include/cpu/x86/lapic.h (revision 3461) +++ src/include/cpu/x86/lapic.h (working copy) @@ -51,6 +51,11 @@ return lapic_read(LAPIC_ID) >> 24; }
+#if CONFIG_AP_IN_SIPI_WAIT != 1 +/* If we need to go back to sipi wait, we use the long non-inlined version of
- this function in lapic_cpu_init.c
- */
static inline __attribute__((always_inline)) void stop_this_cpu(void) {
@@ -59,6 +64,7 @@ hlt(); } } +#endif
#if ! defined (__ROMCC__)
@@ -98,7 +104,7 @@ }
-extern inline void lapic_write_atomic(unsigned long reg, unsigned long v) +static inline void lapic_write_atomic(unsigned long reg, unsigned long v) { xchg((volatile unsigned long *)(LAPIC_DEFAULT_BASE+reg), v); } Index: src/cpu/x86/lapic/lapic_cpu_init.c =================================================================== --- src/cpu/x86/lapic/lapic_cpu_init.c (revision 3461) +++ src/cpu/x86/lapic/lapic_cpu_init.c (working copy) @@ -1,6 +1,7 @@ /* 2005.12 yhlu add coreboot_ram cross the vga font buffer handling 2005.12 yhlu add _RAMBASE above 1M support for SMP
- 2008.05 stepan add support for going back to sipi wait state
*/
#include <cpu/x86/lapic.h> @@ -16,6 +17,7 @@
#if CONFIG_SMP == 1
+#if _RAMBASE >= 0x100000 /* This is a lot more paranoid now, since Linux can NOT handle
- being told there is a CPU when none exists. So any errors
- will return 0, meaning no CPU.
@@ -27,6 +29,7 @@ { return (unsigned long)orig_start_eip & 0xffff; // 16 bit to avoid 0xa0000 } +#endif
static void copy_secondary_start_to_1m_below(void) { @@ -277,9 +280,73 @@ return result; }
+#if CONFIG_AP_IN_SIPI_WAIT == 1 +/**
- Normally this function is defined in lapic.h as an always inline function
- that just keeps the CPU in a hlt() loop. This does not work on all CPUs.
- I think all hyperthreading CPUs might need this version, but I could only
- verify this on the Intel Core Duo
- */
+void stop_this_cpu(void) +{
- int timeout;
- unsigned long send_status;
- unsigned long lapicid;
- lapicid = lapic_read(LAPIC_ID) >> 24;
- printk_debug("CPU %d going down...\n", lapicid);
- /* send an LAPIC INIT to myself */
- lapic_write_around(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(lapicid));
- lapic_write_around(LAPIC_ICR, LAPIC_INT_LEVELTRIG | LAPIC_INT_ASSERT | LAPIC_DM_INIT);
- /* wait for the ipi send to finish */
+#if 0
- // When these two printk_spew calls are not removed, the
- // machine will hang when log level is SPEW. Why?
- printk_spew("Waiting for send to finish...\n");
+#endif
- timeout = 0;
- do {
+#if 0
printk_spew("+");
+#endif
udelay(100);
send_status = lapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY;
- } while (send_status && (timeout++ < 1000));
- if (timeout >= 1000) {
printk_err("timed out\n");
- }
- mdelay(10);
- printk_spew("Deasserting INIT.\n");
- /* Deassert the LAPIC INIT */
- lapic_write_around(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(lapicid));
- lapic_write_around(LAPIC_ICR, LAPIC_INT_LEVELTRIG | LAPIC_DM_INIT);
- printk_spew("Waiting for send to finish...\n");
- timeout = 0;
- do {
printk_spew("+");
udelay(100);
send_status = lapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY;
- } while (send_status && (timeout++ < 1000));
- if (timeout >= 1000) {
printk_err("timed out\n");
- }
- while(1) {
hlt();
- }
+} +#endif
/* C entry point of secondary cpus */ void secondary_cpu_init(void) {
- unsigned long cpunum;
- atomic_inc(&active_cpus);
#if SERIAL_CPU_INIT == 1 #if CONFIG_MAX_CPUS>2 @@ -294,6 +361,7 @@ #endif
atomic_dec(&active_cpus);
- stop_this_cpu();
}
@@ -356,7 +424,6 @@ if (!cpu->initialized) { printk_err("CPU 0x%02x did not initialize!\n", cpu->path.u.apic.apic_id); -#warning "FIXME do I need a mainboard_cpu_fixup function?" } } printk_debug("All AP CPUs stopped\n"); Index: src/config/Options.lb =================================================================== --- src/config/Options.lb (revision 3461) +++ src/config/Options.lb (working copy) @@ -574,6 +574,11 @@ export always comment "Should multiple cpus per die be enabled?" end +define CONFIG_AP_IN_SIPI_WAIT
- default 0
- export always
- comment "Should application processors go to SIPI wait state after initialization? (Required for Intel Core Duo)"
+end define HAVE_MP_TABLE default none export used