Sven Schnelle (sv...@stackframe.org) just uploaded a new patch set to gerrit, 
which you can find at http://review.coreboot.org/1139

-gerrit

commit 58a421cf0cf09c49ebfe216daa4edc05f360b76e
Author: Sven Schnelle <sv...@stackframe.org>
Date:   Sun Jun 17 10:32:55 2012 +0200

    Use broadcast SIPI to startup siblings
    
    Change-Id: Ic48a1ebab6a7c52aa76765f497268af09fa38c25
    Signed-off-by: Sven Schnelle <sv...@stackframe.org>
---
 src/arch/x86/Kconfig                         |    4 -
 src/arch/x86/include/arch/cpu.h              |   24 --
 src/arch/x86/lib/cpu.c                       |   36 ++-
 src/cpu/amd/model_10xxx/init_cpus.c          |    3 +-
 src/cpu/amd/model_fxx/init_cpus.c            |    3 +-
 src/cpu/intel/hyperthreading/Makefile.inc    |    1 -
 src/cpu/intel/hyperthreading/intel_sibling.c |   73 -----
 src/cpu/intel/model_1067x/model_1067x_init.c |    4 -
 src/cpu/intel/model_106cx/Kconfig            |    1 -
 src/cpu/intel/model_106cx/model_106cx_init.c |    4 -
 src/cpu/intel/model_206ax/Kconfig            |    1 -
 src/cpu/intel/model_206ax/acpi.c             |    9 +-
 src/cpu/intel/model_206ax/model_206ax_init.c |   55 ----
 src/cpu/intel/model_6ex/Kconfig              |    1 -
 src/cpu/intel/model_6ex/model_6ex_init.c     |    3 -
 src/cpu/intel/model_6fx/Kconfig              |    1 -
 src/cpu/intel/model_6fx/model_6fx_init.c     |    3 -
 src/cpu/intel/model_f2x/model_f2x_init.c     |    4 -
 src/cpu/intel/model_f3x/model_f3x_init.c     |    4 -
 src/cpu/intel/model_f4x/model_f4x_init.c     |    4 -
 src/cpu/intel/socket_LGA771/Kconfig          |    1 -
 src/cpu/x86/lapic/lapic_cpu_init.c           |  367 +++++---------------------
 src/cpu/x86/lapic/secondary.S                |   17 +-
 src/cpu/x86/pae/pgtbl.c                      |   12 +
 src/drivers/i2c/w83795/w83795.c              |    5 +-
 src/include/cpu/cpu.h                        |    2 +-
 src/include/cpu/x86/lapic.h                  |   15 -
 src/include/device/path.h                    |    1 +
 28 files changed, 131 insertions(+), 527 deletions(-)

diff --git a/src/arch/x86/Kconfig b/src/arch/x86/Kconfig
index 6d56ec6..4dfbe70 100644
--- a/src/arch/x86/Kconfig
+++ b/src/arch/x86/Kconfig
@@ -3,10 +3,6 @@ menu "Architecture (x86)"
 # This is an SMP option. It relates to starting up APs.
 # It is usually set in mainboard/*/Kconfig.
 # TODO: Improve description.
-config AP_IN_SIPI_WAIT
-       bool
-       default n
-       depends on ARCH_X86
 
 # Aligns 16bit entry code in bootblock so that hyper-threading CPUs
 # can boot AP CPUs to enable their shared caches.
diff --git a/src/arch/x86/include/arch/cpu.h b/src/arch/x86/include/arch/cpu.h
index 0dc92fb..0fe5ea5 100644
--- a/src/arch/x86/include/arch/cpu.h
+++ b/src/arch/x86/include/arch/cpu.h
@@ -158,30 +158,6 @@ struct cpu_driver {
 struct device;
 struct cpu_driver *find_cpu_driver(struct device *cpu);
 
-struct cpu_info {
-       device_t cpu;
-       unsigned long index;
-};
-
-static inline struct cpu_info *cpu_info(void)
-{
-       struct cpu_info *ci;
-       __asm__("andl %%esp,%0; "
-               "orl  %2, %0 "
-               :"=r" (ci)
-               : "0" (~(CONFIG_STACK_SIZE - 1)),
-               "r" (CONFIG_STACK_SIZE - sizeof(struct cpu_info))
-       );
-       return ci;
-}
-
-static inline unsigned long cpu_index(void)
-{
-       struct cpu_info *ci;
-       ci = cpu_info();
-       return ci->index;
-}
-
 struct cpuinfo_x86 {
         uint8_t    x86;            /* CPU family */
         uint8_t    x86_vendor;     /* CPU vendor */
diff --git a/src/arch/x86/lib/cpu.c b/src/arch/x86/lib/cpu.c
index 98ede06..520b2c6 100644
--- a/src/arch/x86/lib/cpu.c
+++ b/src/arch/x86/lib/cpu.c
@@ -9,6 +9,7 @@
 #include <device/path.h>
 #include <device/device.h>
 #include <smp/spinlock.h>
+#include <cpu/x86/lapic.h>
 
 /* Standard macro to see if a specific flag is changeable */
 static inline int flag_is_changeable_p(uint32_t flag)
@@ -234,7 +235,11 @@ static void set_cpu_ops(struct device *cpu)
        cpu->ops = driver ? driver->ops : NULL;
 }
 
-void cpu_initialize(void)
+#if CONFIG_SMP
+static spinlock_t start_cpu_lock = SPIN_LOCK_UNLOCKED;
+#endif
+
+void cpu_initialize(struct bus *cpu_bus)
 {
        /* Because we busy wait at the printk spinlock.
         * It is important to keep the number of printed messages
@@ -242,17 +247,23 @@ void cpu_initialize(void)
         * disabled.
         */
        struct device *cpu;
-       struct cpu_info *info;
        struct cpuinfo_x86 c;
-
-       info = cpu_info();
-
-       printk(BIOS_INFO, "Initializing CPU #%ld\n", info->index);
-
-       cpu = info->cpu;
-       if (!cpu) {
-               die("CPU: missing cpu device structure");
-       }
+       struct device_path cpu_path;
+       static int cpu_index;
+       unsigned char id = lapicid();
+
+       cpu_path.type = DEVICE_PATH_APIC;
+       cpu_path.apic.apic_id = id;
+
+#if CONFIG_SMP
+       spin_lock(&start_cpu_lock);
+#endif
+       cpu_path.apic.index = cpu_index++;
+       cpu = alloc_find_dev(cpu_bus, &cpu_path);
+#if CONFIG_SMP
+       spin_unlock(&start_cpu_lock);
+#endif
+       printk(BIOS_DEBUG, "Initializing CPU #%d\n", id);
 
        /* Find what type of cpu we are dealing with */
        identify_cpu(cpu);
@@ -276,7 +287,6 @@ void cpu_initialize(void)
                printk(BIOS_DEBUG, "Using generic cpu ops (good)\n");
        }
 
-
        /* Initialize the cpu */
        if (cpu->ops && cpu->ops->init) {
                cpu->enabled = 1;
@@ -284,7 +294,7 @@ void cpu_initialize(void)
                cpu->ops->init(cpu);
        }
 
-       printk(BIOS_INFO, "CPU #%ld initialized\n", info->index);
+       printk(BIOS_INFO, "CPU #%d initialized\n", id);
 
        return;
 }
diff --git a/src/cpu/amd/model_10xxx/init_cpus.c 
b/src/cpu/amd/model_10xxx/init_cpus.c
index e2a4a64..0ffce53 100644
--- a/src/cpu/amd/model_10xxx/init_cpus.c
+++ b/src/cpu/amd/model_10xxx/init_cpus.c
@@ -241,7 +241,8 @@ static void STOP_CAR_AND_CPU(void)
 
        disable_cache_as_ram(); // inline
        /* stop all cores except node0/core0 the bsp .... */
-       stop_this_cpu();
+       for(;;)
+               hlt();
 }
 
 #if CONFIG_RAMINIT_SYSINFO
diff --git a/src/cpu/amd/model_fxx/init_cpus.c 
b/src/cpu/amd/model_fxx/init_cpus.c
index 7121642..d5e5800 100644
--- a/src/cpu/amd/model_fxx/init_cpus.c
+++ b/src/cpu/amd/model_fxx/init_cpus.c
@@ -190,7 +190,8 @@ static void STOP_CAR_AND_CPU(void)
 {
        disable_cache_as_ram(); // inline
        /* stop all cores except node0/core0 the bsp .... */
-       stop_this_cpu();
+       for(;;)
+               hlt();
 }
 
 #if CONFIG_RAMINIT_SYSINFO
diff --git a/src/cpu/intel/hyperthreading/Makefile.inc 
b/src/cpu/intel/hyperthreading/Makefile.inc
deleted file mode 100644
index 8adbad9..0000000
--- a/src/cpu/intel/hyperthreading/Makefile.inc
+++ /dev/null
@@ -1 +0,0 @@
-ramstage-y += intel_sibling.c
diff --git a/src/cpu/intel/hyperthreading/intel_sibling.c 
b/src/cpu/intel/hyperthreading/intel_sibling.c
deleted file mode 100644
index 2d2e105..0000000
--- a/src/cpu/intel/hyperthreading/intel_sibling.c
+++ /dev/null
@@ -1,73 +0,0 @@
-#include <console/console.h>
-#include <cpu/cpu.h>
-#include <cpu/x86/lapic.h>
-#include <cpu/intel/hyperthreading.h>
-#include <device/device.h>
-#include <pc80/mc146818rtc.h>
-#include <smp/spinlock.h>
-#include <assert.h>
-
-#if !CONFIG_SERIAL_CPU_INIT
-#error Intel hyper-threading requires serialized cpu init
-#endif
-
-static int first_time = 1;
-static int disable_siblings = !CONFIG_LOGICAL_CPUS;
-
-void intel_sibling_init(device_t cpu)
-{
-       unsigned i, siblings;
-       struct cpuid_result result;
-
-       /* On the bootstrap processor see if I want sibling cpus enabled */
-       if (first_time) {
-               first_time = 0;
-               get_option(&disable_siblings, "hyper_threading");
-       }
-       result = cpuid(1);
-       /* Is hyperthreading supported */
-       if (!(result.edx & (1 << 28))) {
-               return;
-       }
-       /* See how many sibling cpus we have */
-       siblings = (result.ebx >> 16) & 0xff;
-       if (siblings < 1) {
-               siblings = 1;
-       }
-
-       printk(BIOS_DEBUG, "CPU: %u %d siblings\n",
-               cpu->path.apic.apic_id,
-               siblings);
-
-       /* See if I am a sibling cpu */
-       if (cpu->path.apic.apic_id & (siblings -1)) {
-               if (disable_siblings) {
-                       cpu->enabled = 0;
-               }
-               return;
-       }
-
-       /* I am the primary cpu start up my siblings */
-       for(i = 1; i < siblings; i++) {
-               struct device_path cpu_path;
-               device_t new;
-               /* Build the cpu device path */
-               cpu_path.type = DEVICE_PATH_APIC;
-               cpu_path.apic.apic_id = cpu->path.apic.apic_id + i;
-
-
-               /* Allocate new cpu device structure iff sibling CPU
-                * was not in static device tree.
-                */
-               new = alloc_find_dev(cpu->bus, &cpu_path);
-
-               if (!new) {
-                       continue;
-               }
-
-               printk(BIOS_DEBUG, "CPU: %u has sibling %u\n",
-                       cpu->path.apic.apic_id,
-                       new->path.apic.apic_id);
-       }
-}
-
diff --git a/src/cpu/intel/model_1067x/model_1067x_init.c 
b/src/cpu/intel/model_1067x/model_1067x_init.c
index c6d716d9..ddd1381 100644
--- a/src/cpu/intel/model_1067x/model_1067x_init.c
+++ b/src/cpu/intel/model_1067x/model_1067x_init.c
@@ -29,7 +29,6 @@
 #include <cpu/x86/lapic.h>
 #include <cpu/intel/microcode.h>
 #include <cpu/intel/speedstep.h>
-#include <cpu/intel/hyperthreading.h>
 #include <cpu/x86/cache.h>
 #include <cpu/x86/name.h>
 
@@ -221,9 +220,6 @@ static void model_1067x_init(device_t cpu)
 
        /* PIC thermal sensor control */
        configure_pic_thermal_sensors();
-
-       /* Start up my cpu siblings */
-       intel_sibling_init(cpu);
 }
 
 static struct device_operations cpu_dev_ops = {
diff --git a/src/cpu/intel/model_106cx/Kconfig 
b/src/cpu/intel/model_106cx/Kconfig
index 09449cb..fe44024 100644
--- a/src/cpu/intel/model_106cx/Kconfig
+++ b/src/cpu/intel/model_106cx/Kconfig
@@ -3,4 +3,3 @@ config CPU_INTEL_MODEL_106CX
        select SMP
        select SSE2
        select UDELAY_LAPIC
-       select AP_IN_SIPI_WAIT
diff --git a/src/cpu/intel/model_106cx/model_106cx_init.c 
b/src/cpu/intel/model_106cx/model_106cx_init.c
index 4bf2924..8d2ef3d 100644
--- a/src/cpu/intel/model_106cx/model_106cx_init.c
+++ b/src/cpu/intel/model_106cx/model_106cx_init.c
@@ -27,7 +27,6 @@
 #include <cpu/x86/lapic.h>
 #include <cpu/intel/microcode.h>
 #include <cpu/intel/speedstep.h>
-#include <cpu/intel/hyperthreading.h>
 #include <cpu/x86/cache.h>
 #include <cpu/x86/name.h>
 #include <usbdebug.h>
@@ -178,9 +177,6 @@ static void model_106cx_init(device_t cpu)
        configure_misc();
 
        /* TODO: PIC thermal sensor control */
-
-       /* Start up my cpu siblings */
-       intel_sibling_init(cpu);
 }
 
 static struct device_operations cpu_dev_ops = {
diff --git a/src/cpu/intel/model_206ax/Kconfig 
b/src/cpu/intel/model_206ax/Kconfig
index d2d4c73..e3e4360 100644
--- a/src/cpu/intel/model_206ax/Kconfig
+++ b/src/cpu/intel/model_206ax/Kconfig
@@ -12,7 +12,6 @@ config CPU_SPECIFIC_OPTIONS
        select SSE2
        select UDELAY_LAPIC
        select SMM_TSEG
-       #select AP_IN_SIPI_WAIT
 
 config BOOTBLOCK_CPU_INIT
        string
diff --git a/src/cpu/intel/model_206ax/acpi.c b/src/cpu/intel/model_206ax/acpi.c
index 6153174..dea23e7 100644
--- a/src/cpu/intel/model_206ax/acpi.c
+++ b/src/cpu/intel/model_206ax/acpi.c
@@ -26,6 +26,7 @@
 #include <arch/acpigen.h>
 #include <arch/cpu.h>
 #include <cpu/x86/msr.h>
+#include <cpu/x86/lapic.h>
 #include <cpu/intel/acpi.h>
 #include <cpu/intel/speedstep.h>
 #include <cpu/intel/turbo.h>
@@ -88,8 +89,8 @@ static int generate_cstate_entries(acpi_cstate_t *cstates,
 
 static int generate_C_state_entries(void)
 {
-       struct cpu_info *info;
        struct cpu_driver *cpu;
+       struct device *cpu_dev;
        int len, lenif;
        device_t lapic;
        struct cpu_intel_model_206ax_config *conf = NULL;
@@ -103,10 +104,10 @@ static int generate_C_state_entries(void)
                return 0;
 
        /* Find CPU map of supported C-states */
-       info = cpu_info();
-       if (!info)
+       cpu_dev = dev_find_lapic(lapicid());
+       if (!cpu_dev)
                return 0;
-       cpu = find_cpu_driver(info->cpu);
+       cpu = find_cpu_driver(cpu_dev);
        if (!cpu || !cpu->cstates)
                return 0;
 
diff --git a/src/cpu/intel/model_206ax/model_206ax_init.c 
b/src/cpu/intel/model_206ax/model_206ax_init.c
index 874ce4d..d60c237 100644
--- a/src/cpu/intel/model_206ax/model_206ax_init.c
+++ b/src/cpu/intel/model_206ax/model_206ax_init.c
@@ -414,58 +414,6 @@ static void configure_mca(void)
 static unsigned ehci_debug_addr;
 #endif
 
-/*
- * Initialize any extra cores/threads in this package.
- */
-static void intel_cores_init(device_t cpu)
-{
-       struct cpuid_result result;
-       unsigned cores, threads, i;
-
-       result = cpuid_ext(0xb, 0); /* Threads per core */
-       threads = result.ebx & 0xff;
-
-       result = cpuid_ext(0xb, 1); /* Cores per package */
-       cores = result.ebx & 0xff;
-
-       /* Only initialize extra cores from BSP */
-       if (cpu->path.apic.apic_id)
-               return;
-
-       printk(BIOS_DEBUG, "CPU: %u has %u cores %u threads\n",
-              cpu->path.apic.apic_id, cores, threads);
-
-       for (i = 1; i < cores; ++i) {
-               struct device_path cpu_path;
-               device_t new;
-
-               /* Build the cpu device path */
-               cpu_path.type = DEVICE_PATH_APIC;
-               cpu_path.apic.apic_id =
-                       cpu->path.apic.apic_id + i;
-
-               /* Update APIC ID if no hyperthreading */
-               if (threads == 1)
-                       cpu_path.apic.apic_id <<= 1;
-
-               /* Allocate the new cpu device structure */
-               new = alloc_dev(cpu->bus, &cpu_path);
-               if (!new)
-                       continue;
-
-               printk(BIOS_DEBUG, "CPU: %u has core %u\n",
-                      cpu->path.apic.apic_id,
-                      new->path.apic.apic_id);
-
-               /* Start the new cpu */
-               if (!start_cpu(new)) {
-                       /* Record the error in cpu? */
-                       printk(BIOS_ERR, "CPU %u would not start!\n",
-                              new->path.apic.apic_id);
-               }
-       }
-}
-
 static void model_206ax_init(device_t cpu)
 {
        char processor_name[49];
@@ -528,9 +476,6 @@ static void model_206ax_init(device_t cpu)
 
        /* Enable Turbo */
        enable_turbo();
-
-       /* Start up extra cores */
-       intel_cores_init(cpu);
 }
 
 static struct device_operations cpu_dev_ops = {
diff --git a/src/cpu/intel/model_6ex/Kconfig b/src/cpu/intel/model_6ex/Kconfig
index 31d24bd..c3faa39 100644
--- a/src/cpu/intel/model_6ex/Kconfig
+++ b/src/cpu/intel/model_6ex/Kconfig
@@ -3,4 +3,3 @@ config CPU_INTEL_MODEL_6EX
        select SMP
        select SSE2
        select UDELAY_LAPIC
-       select AP_IN_SIPI_WAIT
diff --git a/src/cpu/intel/model_6ex/model_6ex_init.c 
b/src/cpu/intel/model_6ex/model_6ex_init.c
index 1c8c72b..a0afd2e 100644
--- a/src/cpu/intel/model_6ex/model_6ex_init.c
+++ b/src/cpu/intel/model_6ex/model_6ex_init.c
@@ -205,9 +205,6 @@ static void model_6ex_init(device_t cpu)
 
        /* PIC thermal sensor control */
        configure_pic_thermal_sensors();
-
-       /* Start up my cpu siblings */
-       intel_sibling_init(cpu);
 }
 
 static struct device_operations cpu_dev_ops = {
diff --git a/src/cpu/intel/model_6fx/Kconfig b/src/cpu/intel/model_6fx/Kconfig
index 851685c..065cdd9 100644
--- a/src/cpu/intel/model_6fx/Kconfig
+++ b/src/cpu/intel/model_6fx/Kconfig
@@ -3,4 +3,3 @@ config CPU_INTEL_MODEL_6FX
        select SMP
        select SSE2
        select UDELAY_LAPIC
-       select AP_IN_SIPI_WAIT
diff --git a/src/cpu/intel/model_6fx/model_6fx_init.c 
b/src/cpu/intel/model_6fx/model_6fx_init.c
index 106719e..c5d7a6b 100644
--- a/src/cpu/intel/model_6fx/model_6fx_init.c
+++ b/src/cpu/intel/model_6fx/model_6fx_init.c
@@ -243,9 +243,6 @@ static void model_6fx_init(device_t cpu)
 
        /* PIC thermal sensor control */
        configure_pic_thermal_sensors();
-
-       /* Start up my cpu siblings */
-       intel_sibling_init(cpu);
 }
 
 static struct device_operations cpu_dev_ops = {
diff --git a/src/cpu/intel/model_f2x/model_f2x_init.c 
b/src/cpu/intel/model_f2x/model_f2x_init.c
index ec78672..51b72a3 100644
--- a/src/cpu/intel/model_f2x/model_f2x_init.c
+++ b/src/cpu/intel/model_f2x/model_f2x_init.c
@@ -7,7 +7,6 @@
 #include <cpu/x86/msr.h>
 #include <cpu/x86/lapic.h>
 #include <cpu/intel/microcode.h>
-#include <cpu/intel/hyperthreading.h>
 #include <cpu/x86/cache.h>
 
 /* 512KB cache */
@@ -56,9 +55,6 @@ static void model_f2x_init(device_t cpu)
 
        /* Enable the local cpu apics */
        setup_lapic();
-
-       /* Start up my cpu siblings */
-       intel_sibling_init(cpu);
 };
 
 static struct device_operations cpu_dev_ops = {
diff --git a/src/cpu/intel/model_f3x/model_f3x_init.c 
b/src/cpu/intel/model_f3x/model_f3x_init.c
index 580c98b..ca346da 100644
--- a/src/cpu/intel/model_f3x/model_f3x_init.c
+++ b/src/cpu/intel/model_f3x/model_f3x_init.c
@@ -7,7 +7,6 @@
 #include <cpu/x86/msr.h>
 #include <cpu/x86/lapic.h>
 #include <cpu/intel/microcode.h>
-#include <cpu/intel/hyperthreading.h>
 #include <cpu/x86/cache.h>
 
 static uint32_t microcode_updates[] = {
@@ -39,9 +38,6 @@ static void model_f3x_init(device_t cpu)
 
        /* Enable the local cpu apics */
        setup_lapic();
-
-       /* Start up my cpu siblings */
-       intel_sibling_init(cpu);
 };
 
 static struct device_operations cpu_dev_ops = {
diff --git a/src/cpu/intel/model_f4x/model_f4x_init.c 
b/src/cpu/intel/model_f4x/model_f4x_init.c
index 54edf2e..c857cef 100644
--- a/src/cpu/intel/model_f4x/model_f4x_init.c
+++ b/src/cpu/intel/model_f4x/model_f4x_init.c
@@ -7,7 +7,6 @@
 #include <cpu/x86/msr.h>
 #include <cpu/x86/lapic.h>
 #include <cpu/intel/microcode.h>
-#include <cpu/intel/hyperthreading.h>
 #include <cpu/x86/cache.h>
 
 static uint32_t microcode_updates[] = {
@@ -47,9 +46,6 @@ static void model_f4x_init(device_t cpu)
 
        /* Enable the local cpu apics */
        setup_lapic();
-
-       /* Start up my cpu siblings */
-       intel_sibling_init(cpu);
 };
 
 static struct device_operations cpu_dev_ops = {
diff --git a/src/cpu/intel/socket_LGA771/Kconfig 
b/src/cpu/intel/socket_LGA771/Kconfig
index 62bd17b..f549210 100644
--- a/src/cpu/intel/socket_LGA771/Kconfig
+++ b/src/cpu/intel/socket_LGA771/Kconfig
@@ -3,4 +3,3 @@ config CPU_INTEL_SOCKET_LGA771
         select CPU_INTEL_MODEL_6FX
        select SSE2
        select MMX
-       select AP_IN_SIPI_WAIT
diff --git a/src/cpu/x86/lapic/lapic_cpu_init.c 
b/src/cpu/x86/lapic/lapic_cpu_init.c
index e491d46..60cacd5 100644
--- a/src/cpu/x86/lapic/lapic_cpu_init.c
+++ b/src/cpu/x86/lapic/lapic_cpu_init.c
@@ -66,31 +66,28 @@ static void copy_secondary_start_to_1m_below(void)
        printk(BIOS_DEBUG, "start_eip=0x%08lx, offset=0x%08lx, 
code_size=0x%08lx\n", start_eip, ((unsigned long)_secondary_start - start_eip), 
code_size);
 }
 
-static int lapic_start_cpu(unsigned long apicid)
+static struct bus *current_cpu_bus;
+
+static int lapic_start_cpus(struct bus *cpu_bus)
 {
        int timeout;
        unsigned long send_status, accept_status, start_eip;
-       int j, num_starts, maxlvt;
+       int maxlvt;
 
        /*
         * Starting actual IPI sequence...
         */
 
-       printk(BIOS_SPEW, "Asserting INIT.\n");
-
-       /*
-        * Turn INIT on target chip
-        */
-       lapic_write_around(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(apicid));
+       current_cpu_bus = cpu_bus;
 
-       /*
-        * Send IPI
-        */
+       printk(BIOS_SPEW, "Asserting INIT.\n");
 
-       lapic_write_around(LAPIC_ICR, LAPIC_INT_LEVELTRIG | LAPIC_INT_ASSERT
-                               | LAPIC_DM_INIT);
+       /* Send INIT SIPI to target chip */
+       lapic_write_around(LAPIC_ICR2, 0);
+       lapic_write_around(LAPIC_ICR, LAPIC_INT_ASSERT
+                               | LAPIC_DM_INIT | LAPIC_DEST_ALLBUT);
 
-       printk(BIOS_SPEW, "Waiting for send to finish...\n");
+       printk(BIOS_DEBUG, "Waiting for send to finish...\n");
        timeout = 0;
        do {
                printk(BIOS_SPEW, "+");
@@ -98,108 +95,67 @@ static int lapic_start_cpu(unsigned long apicid)
                send_status = lapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY;
        } while (send_status && (timeout++ < 1000));
        if (timeout >= 1000) {
-               printk(BIOS_ERR, "CPU %ld: First apic write timed out. 
Disabling\n",
-                        apicid);
+               printk(BIOS_DEBUG, "First apic write timed out. Disabling\n");
                // too bad.
-               printk(BIOS_ERR, "ESR is 0x%lx\n", lapic_read(LAPIC_ESR));
+               printk(BIOS_DEBUG, "ESR is 0x%lx\n", lapic_read(LAPIC_ESR));
                if (lapic_read(LAPIC_ESR)) {
-                       printk(BIOS_ERR, "Try to reset ESR\n");
+                       printk(BIOS_DEBUG, "Try to reset ESR\n");
                        lapic_write_around(LAPIC_ESR, 0);
-                       printk(BIOS_ERR, "ESR is 0x%lx\n", 
lapic_read(LAPIC_ESR));
+                       printk(BIOS_DEBUG, "ESR is 0x%lx\n", 
lapic_read(LAPIC_ESR));
                }
                return 0;
        }
-#if !CONFIG_CPU_AMD_MODEL_10XXX && !CONFIG_CPU_INTEL_MODEL_206AX
-       mdelay(10);
-#endif
+       start_eip = get_valid_start_eip((unsigned long)_secondary_start);
+
+       maxlvt = 4;
+
+       printk(BIOS_SPEW, "Sending STARTUP.\n");
+       lapic_read_around(LAPIC_SPIV);
+       lapic_write(LAPIC_ESR, 0);
+       lapic_read(LAPIC_ESR);
+       printk(BIOS_SPEW, "After apic_write.\n");
 
-       printk(BIOS_SPEW, "Deasserting INIT.\n");
+       /*
+        * STARTUP IPI
+        */
 
        /* Target chip */
-       lapic_write_around(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(apicid));
+       lapic_write_around(LAPIC_ICR2, 0);
 
-       /* Send IPI */
-       lapic_write_around(LAPIC_ICR, LAPIC_INT_LEVELTRIG | LAPIC_DM_INIT);
+       /* Boot on the stack */
+       /* Kick the second */
+       lapic_write_around(LAPIC_ICR, LAPIC_INT_ASSERT | LAPIC_DM_STARTUP | 
LAPIC_DEST_ALLBUT
+                          | (start_eip >> 12));
 
-       printk(BIOS_SPEW, "Waiting for send to finish...\n");
+       /*
+        * Give the other CPU some time to accept the IPI.
+        */
+       udelay(300);
+
+       printk(BIOS_DEBUG, "Startup point 1.\n");
+
+       printk(BIOS_DEBUG, "Waiting for send to finish...\n");
        timeout = 0;
        do {
-               printk(BIOS_SPEW, "+");
+               printk(BIOS_DEBUG, "+");
                udelay(100);
                send_status = lapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY;
        } while (send_status && (timeout++ < 1000));
-       if (timeout >= 1000) {
-               printk(BIOS_ERR, "CPU %ld: Second apic write timed out. 
Disabling\n",
-                        apicid);
-               // too bad.
-               return 0;
-       }
-
-       start_eip = get_valid_start_eip((unsigned long)_secondary_start);
-
-#if !CONFIG_CPU_AMD_MODEL_10XXX
-       num_starts = 2;
-#else
-       num_starts = 1;
-#endif
 
        /*
-        * Run STARTUP IPI loop.
+        * Give the other CPU some time to accept the IPI.
         */
-       printk(BIOS_SPEW, "#startup loops: %d.\n", num_starts);
-
-       maxlvt = 4;
-
-       for (j = 1; j <= num_starts; j++) {
-               printk(BIOS_SPEW, "Sending STARTUP #%d to %lu.\n", j, apicid);
+       udelay(200);
+       /*
+        * Due to the Pentium erratum 3AP.
+        */
+       if (maxlvt > 3) {
                lapic_read_around(LAPIC_SPIV);
                lapic_write(LAPIC_ESR, 0);
-               lapic_read(LAPIC_ESR);
-               printk(BIOS_SPEW, "After apic_write.\n");
-
-               /*
-                * STARTUP IPI
-                */
-
-               /* Target chip */
-               lapic_write_around(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(apicid));
-
-               /* Boot on the stack */
-               /* Kick the second */
-               lapic_write_around(LAPIC_ICR, LAPIC_DM_STARTUP
-                                       | (start_eip >> 12));
-
-               /*
-                * Give the other CPU some time to accept the IPI.
-                */
-               udelay(300);
-
-               printk(BIOS_SPEW, "Startup point 1.\n");
-
-               printk(BIOS_SPEW, "Waiting for send to finish...\n");
-               timeout = 0;
-               do {
-                       printk(BIOS_SPEW, "+");
-                       udelay(100);
-                       send_status = lapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY;
-               } while (send_status && (timeout++ < 1000));
-
-               /*
-                * Give the other CPU some time to accept the IPI.
-                */
-               udelay(200);
-               /*
-                * Due to the Pentium erratum 3AP.
-                */
-               if (maxlvt > 3) {
-                       lapic_read_around(LAPIC_SPIV);
-                       lapic_write(LAPIC_ESR, 0);
-               }
-               accept_status = (lapic_read(LAPIC_ESR) & 0xEF);
-               if (send_status || accept_status)
-                       break;
        }
-       printk(BIOS_SPEW, "After Startup.\n");
+       accept_status = (lapic_read(LAPIC_ESR) & 0xEF);
+
+       printk(BIOS_DEBUG, "After Startup.\n");
        if (send_status)
                printk(BIOS_WARNING, "APIC never delivered???\n");
        if (accept_status)
@@ -209,156 +165,34 @@ static int lapic_start_cpu(unsigned long apicid)
        return 1;
 }
 
+
 /* Number of cpus that are currently running in coreboot */
 static atomic_t active_cpus = ATOMIC_INIT(1);
 
-/* start_cpu_lock covers last_cpu_index and secondary_stack.
- * Only starting one cpu at a time let's me remove the logic
- * for select the stack from assembly language.
- *
- * In addition communicating by variables to the cpu I
- * am starting allows me to veryify it has started before
- * start_cpu returns.
- */
-
-static spinlock_t start_cpu_lock = SPIN_LOCK_UNLOCKED;
-static unsigned last_cpu_index = 0;
 volatile unsigned long secondary_stack;
+extern unsigned char _estack[];
 
-int start_cpu(device_t cpu)
+static void stop_all_ap_cpus(void)
 {
-       extern unsigned char _estack[];
-       struct cpu_info *info;
-       unsigned long stack_end;
-       unsigned long apicid;
-       unsigned long index;
-       unsigned long count;
-       int result;
-
-       spin_lock(&start_cpu_lock);
-
-       /* Get the cpu's apicid */
-       apicid = cpu->path.apic.apic_id;
-
-       /* Get an index for the new processor */
-       index = ++last_cpu_index;
-
-       /* Find end of the new processors stack */
-       stack_end = ((unsigned long)_estack) - (CONFIG_STACK_SIZE*index) - 
sizeof(struct cpu_info);
-
-       /* Record the index and which cpu structure we are using */
-       info = (struct cpu_info *)stack_end;
-       info->index = index;
-       info->cpu   = cpu;
-
-       /* Advertise the new stack to start_cpu */
-       secondary_stack = stack_end;
-
-       /* Until the cpu starts up report the cpu is not enabled */
-       cpu->enabled = 0;
-       cpu->initialized = 0;
-
-       /* Start the cpu */
-       result = lapic_start_cpu(apicid);
-
-       if (result) {
-               result = 0;
-               /* Wait 1s or until the new cpu calls in */
-               for(count = 0; count < 100000 ; count++) {
-                       if (secondary_stack == 0) {
-                               result = 1;
-                               break;
-                       }
-                       udelay(10);
-       }
-       }
-       secondary_stack = 0;
-       spin_unlock(&start_cpu_lock);
-       return result;
-}
-
-#if CONFIG_AP_IN_SIPI_WAIT
-
-/**
- * Sending INIT IPI to self is equivalent of asserting #INIT with a bit of 
delay.
- * An undefined number of instruction cycles will complete. All global locks
- * must be released before INIT IPI and no printk is allowed after this.
- * De-asserting INIT IPI is a no-op on later Intel CPUs.
- *
- * If you set DEBUG_HALT_SELF to 1, printk's after INIT IPI are enabled
- * but running thread may halt without releasing the lock and effectively
- * deadlock other CPUs.
- */
-#define DEBUG_HALT_SELF 0
-
-/**
- * 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 id;
-
-       id = lapic_read(LAPIC_ID) >> 24;
-
-       printk(BIOS_DEBUG, "CPU %ld going down...\n", id);
-
-       /* send an LAPIC INIT to myself */
-       lapic_write_around(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(id));
-       lapic_write_around(LAPIC_ICR, LAPIC_INT_LEVELTRIG | LAPIC_INT_ASSERT | 
LAPIC_DM_INIT);
+       int timeout;
+       /* send an LAPIC INIT to all but myself */
+       lapic_write_around(LAPIC_ICR2, 0);
+       lapic_write_around(LAPIC_ICR, LAPIC_INT_ASSERT | LAPIC_DM_INIT | 
LAPIC_DEST_ALLBUT);
 
        /* wait for the ipi send to finish */
-#if DEBUG_HALT_SELF
        printk(BIOS_SPEW, "Waiting for send to finish...\n");
-#endif
        timeout = 0;
        do {
-#if DEBUG_HALT_SELF
                printk(BIOS_SPEW, "+");
-#endif
                udelay(100);
                send_status = lapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY;
        } while (send_status && (timeout++ < 1000));
        if (timeout >= 1000) {
-#if DEBUG_HALT_SELF
                printk(BIOS_ERR, "timed out\n");
-#endif
        }
        mdelay(10);
-
-#if DEBUG_HALT_SELF
-       printk(BIOS_SPEW, "Deasserting INIT.\n");
-#endif
-       /* Deassert the LAPIC INIT */
-       lapic_write_around(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(id));
-       lapic_write_around(LAPIC_ICR, LAPIC_INT_LEVELTRIG | LAPIC_DM_INIT);
-
-#if DEBUG_HALT_SELF
-       printk(BIOS_SPEW, "Waiting for send to finish...\n");
-#endif
-       timeout = 0;
-       do {
-#if DEBUG_HALT_SELF
-               printk(BIOS_SPEW, "+");
-#endif
-               udelay(100);
-               send_status = lapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY;
-       } while (send_status && (timeout++ < 1000));
-       if (timeout >= 1000) {
-#if DEBUG_HALT_SELF
-               printk(BIOS_ERR, "timed out\n");
-#endif
-       }
-
-       while(1) {
-               hlt();
-       }
 }
-#endif
 
 #ifdef __SSE3__
 static __inline__ __attribute__((always_inline)) unsigned long readcr4(void)
@@ -383,64 +217,19 @@ static __inline__ __attribute__((always_inline)) void 
writecr4(unsigned long Dat
 /* C entry point of secondary cpus */
 void secondary_cpu_init(void)
 {
-       atomic_inc(&active_cpus);
-#if CONFIG_SERIAL_CPU_INIT
-       spin_lock(&start_cpu_lock);
-#endif
-
 #ifdef __SSE3__
-       /*
-        * Seems that CR4 was cleared when AP start via lapic_start_cpu()
-        * Turn on CR4.OSFXSR and CR4.OSXMMEXCPT when SSE options enabled
-        */
-       u32 cr4_val;
-       cr4_val = readcr4();
-       cr4_val |= (1 << 9 | 1 << 10);
-       writecr4(cr4_val);
-#endif
-       cpu_initialize();
-#if CONFIG_SERIAL_CPU_INIT
-       spin_unlock(&start_cpu_lock);
+        /*
+         * Seems that CR4 was cleared when AP start via lapic_start_cpu()
+         * Turn on CR4.OSFXSR and CR4.OSXMMEXCPT when SSE options enabled
+         */
+        u32 cr4_val;
+        cr4_val = readcr4();
+        cr4_val |= (1 << 9 | 1 << 10);
+        writecr4(cr4_val);
 #endif
-
+       atomic_inc(&active_cpus);
+       cpu_initialize(current_cpu_bus);
        atomic_dec(&active_cpus);
-
-       stop_this_cpu();
-}
-
-static void start_other_cpus(struct bus *cpu_bus, device_t bsp_cpu)
-{
-       device_t cpu;
-       /* Loop through the cpus once getting them started */
-
-       for(cpu = cpu_bus->children; cpu ; cpu = cpu->sibling) {
-               if (cpu->path.type != DEVICE_PATH_APIC) {
-                       continue;
-               }
-       #if !CONFIG_SERIAL_CPU_INIT
-               if(cpu==bsp_cpu) {
-                       continue;
-               }
-       #endif
-
-               if (!cpu->enabled) {
-                       continue;
-               }
-
-               if (cpu->initialized) {
-                       continue;
-               }
-
-               if (!start_cpu(cpu)) {
-                       /* Record the error in cpu? */
-                       printk(BIOS_ERR, "CPU 0x%02x would not start!\n",
-                               cpu->path.apic.apic_id);
-               }
-#if CONFIG_SERIAL_CPU_INIT
-               udelay(10);
-#endif
-       }
-
 }
 
 static void wait_other_cpus_stop(struct bus *cpu_bus)
@@ -473,6 +262,7 @@ static void wait_other_cpus_stop(struct bus *cpu_bus)
                                cpu->path.apic.apic_id);
                }
        }
+       stop_all_ap_cpus();
        printk(BIOS_DEBUG, "All AP CPUs stopped (%ld loops)\n", loopcount);
 }
 
@@ -481,10 +271,6 @@ static void wait_other_cpus_stop(struct bus *cpu_bus)
 void initialize_cpus(struct bus *cpu_bus)
 {
        struct device_path cpu_path;
-       struct cpu_info *info;
-
-       /* Find the info struct for this cpu */
-       info = cpu_info();
 
 #if NEED_LAPIC == 1
        /* Ensure the local apic is enabled */
@@ -499,9 +285,6 @@ void initialize_cpus(struct bus *cpu_bus)
        cpu_path.cpu.id       = 0;
 #endif
 
-       /* Find the device structure for the boot cpu */
-       info->cpu = alloc_find_dev(cpu_bus, &cpu_path);
-
 #if CONFIG_SMP
        copy_secondary_start_to_1m_below(); // why here? In case some day we 
can start core1 in amd_sibling_init
 #endif
@@ -512,21 +295,11 @@ void initialize_cpus(struct bus *cpu_bus)
 
        cpus_ready_for_init();
 
-#if CONFIG_SMP
-       #if !CONFIG_SERIAL_CPU_INIT
-       /* start all aps at first, so we can init ECC all together */
-       start_other_cpus(cpu_bus, info->cpu);
-       #endif
-#endif
-
        /* Initialize the bootstrap processor */
-       cpu_initialize();
+       cpu_initialize(cpu_bus);
 
 #if CONFIG_SMP
-       #if CONFIG_SERIAL_CPU_INIT
-       start_other_cpus(cpu_bus, info->cpu);
-       #endif
-
+       lapic_start_cpus(cpu_bus);
        /* Now wait the rest of the cpus stop*/
        wait_other_cpus_stop(cpu_bus);
 #endif
diff --git a/src/cpu/x86/lapic/secondary.S b/src/cpu/x86/lapic/secondary.S
index dc00b08..afffbd3 100644
--- a/src/cpu/x86/lapic/secondary.S
+++ b/src/cpu/x86/lapic/secondary.S
@@ -38,10 +38,19 @@ _secondary_start:
        /* Load the Interrupt descriptor table */
        lidt    idtarg
 
-       /* Set the stack pointer, and flag that we are done */
-       xorl    %eax, %eax
-       movl    secondary_stack, %esp
-       movl    %eax, secondary_stack
+cpu:
+       .long 0
+
+       /* increment our cpu index */
+       movl $1, %eax
+       lock xadd %eax, cpu
+       incl    %eax
+
+       /* assign stack for this specific cpu */
+       mov     _stack, %esp
+       mov     $CONFIG_STACK_SIZE, %ebx
+       mul     %ebx
+       add     %eax, %esp
 
        call    secondary_cpu_init
 1:     hlt
diff --git a/src/cpu/x86/pae/pgtbl.c b/src/cpu/x86/pae/pgtbl.c
index 814c5f1..7aa17c2 100644
--- a/src/cpu/x86/pae/pgtbl.c
+++ b/src/cpu/x86/pae/pgtbl.c
@@ -3,8 +3,10 @@
 */
 
 #include <console/console.h>
+#include <device/device.h>
 #include <cpu/cpu.h>
 #include <cpu/x86/pae.h>
+#include <cpu/x86/lapic.h>
 #include <string.h>
 
 static void paging_off(void)
@@ -43,6 +45,14 @@ static void paging_on(void *pdp)
                );
 }
 
+static int cpu_index(void)
+{
+       device_t dev = dev_find_lapic(lapicid());
+       if (!dev)
+               return -1;
+       return dev->path.apic.index;
+}
+
 void *map_2M_page(unsigned long page)
 {
        struct pde {
@@ -60,7 +70,9 @@ void *map_2M_page(unsigned long page)
        unsigned long window;
        void *result;
        int i;
+
        index = cpu_index();
+
        if ((index < 0) || (index >= CONFIG_MAX_CPUS)) {
                return MAPPING_ERROR;
        }
diff --git a/src/drivers/i2c/w83795/w83795.c b/src/drivers/i2c/w83795/w83795.c
index 392471a..12be4da 100644
--- a/src/drivers/i2c/w83795/w83795.c
+++ b/src/drivers/i2c/w83795/w83795.c
@@ -22,6 +22,7 @@
 #include <console/console.h>
 #include <device/device.h>
 #include "southbridge/amd/cimx/sb700/smbus.h" /*SMBUS_IO_BASE*/
+#include <cpu/x86/lapic.h>
 #include "w83795.h"
 
 static u32 w83795_set_bank(u8 bank)
@@ -224,10 +225,8 @@ static void w83795_init(w83795_fan_mode_t mode, u8 dts_src)
 static void w83795_hwm_init(device_t dev)
 {
        struct device *cpu;
-       struct cpu_info *info;
 
-       info = cpu_info();
-       cpu = info->cpu;
+       cpu = dev_find_lapic(lapicid());
        if (!cpu)
                die("CPU: missing cpu device structure");
 
diff --git a/src/include/cpu/cpu.h b/src/include/cpu/cpu.h
index c2113c1..1dc5a58 100644
--- a/src/include/cpu/cpu.h
+++ b/src/include/cpu/cpu.h
@@ -4,7 +4,7 @@
 #include <arch/cpu.h>
 
 #if !defined(__ROMCC__)
-void cpu_initialize(void);
+void cpu_initialize(struct bus *cpu_bus);
 struct bus;
 void initialize_cpus(struct bus *cpu_bus);
 void secondary_cpu_init(void);
diff --git a/src/include/cpu/x86/lapic.h b/src/include/cpu/x86/lapic.h
index 078f2a7..ce61ee5 100644
--- a/src/include/cpu/x86/lapic.h
+++ b/src/include/cpu/x86/lapic.h
@@ -52,21 +52,6 @@ static inline __attribute__((always_inline)) unsigned long 
lapicid(void)
 }
 
 #ifndef __ROMCC__
-#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)
-{
-       /* Called by an AP when it is ready to halt and wait for a new task */
-       for(;;) {
-               hlt();
-       }
-}
-#else
-void stop_this_cpu(void);
-#endif
-
 #if !defined(__PRE_RAM__)
 
 #define xchg(ptr,v) ((__typeof__(*(ptr)))__xchg((unsigned 
long)(v),(ptr),sizeof(*(ptr))))
diff --git a/src/include/device/path.h b/src/include/device/path.h
index 63e9538..018fb93 100644
--- a/src/include/device/path.h
+++ b/src/include/device/path.h
@@ -40,6 +40,7 @@ struct apic_path
        unsigned apic_id;
        unsigned node_id;
        unsigned core_id;
+       unsigned index;
 };
 
 struct apic_cluster_path

-- 
coreboot mailing list: coreboot@coreboot.org
http://www.coreboot.org/mailman/listinfo/coreboot

Reply via email to