[coreboot] Patch set updated for coreboot: c831bf6 Use broadcast SIPI to startup siblings

Sven Schnelle (svens@stackframe.org) gerrit at coreboot.org
Mon Jun 25 21:42:42 CEST 2012


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

-gerrit

commit c831bf6d7ab4974862b92c3eaefd08361c841353
Author: Sven Schnelle <svens at 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 <svens at stackframe.org>
---
 src/arch/x86/include/arch/cpu.h              |   24 --
 src/arch/x86/lib/cpu.c                       |   30 ++-
 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/model_106cx_init.c |    4 -
 src/cpu/intel/model_6ex/model_6ex_init.c     |    3 -
 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/x86/lapic/lapic_cpu_init.c           |  295 ++++++--------------------
 src/cpu/x86/lapic/secondary.S                |   17 ++-
 src/include/cpu/cpu.h                        |    3 +-
 14 files changed, 98 insertions(+), 371 deletions(-)

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..f63a67b 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,21 @@ void cpu_initialize(void)
 	 * disabled.
 	 */
 	struct device *cpu;
-	struct cpu_info *info;
 	struct cpuinfo_x86 c;
+	struct device_path cpu_path;
+	unsigned char id = lapicid();
 
-	info = cpu_info();
+	cpu_path.type = DEVICE_PATH_APIC;
+	cpu_path.apic.apic_id = id;
 
-	printk(BIOS_INFO, "Initializing CPU #%ld\n", info->index);
-
-	cpu = info->cpu;
-	if (!cpu) {
-		die("CPU: missing cpu device structure");
-	}
+#if CONFIG_SMP
+	spin_lock(&start_cpu_lock);
+#endif
+	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 +285,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 +292,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/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/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_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/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/x86/lapic/lapic_cpu_init.c b/src/cpu/x86/lapic/lapic_cpu_init.c
index e491d46..3c0f5a2 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);
 
-	printk(BIOS_SPEW, "Deasserting INIT.\n");
+	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");
+
+	/*
+	 * 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,73 +165,12 @@ 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;
-
-int start_cpu(device_t cpu)
-{
-	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;
-}
+extern unsigned char _estack[];
 
 #if CONFIG_AP_IN_SIPI_WAIT
 
@@ -383,64 +278,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);
+        /*
+         * 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);
-#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)
@@ -481,10 +331,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 +345,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 +355,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/include/cpu/cpu.h b/src/include/cpu/cpu.h
index c2113c1..b631d4e 100644
--- a/src/include/cpu/cpu.h
+++ b/src/include/cpu/cpu.h
@@ -3,8 +3,9 @@
 
 #include <arch/cpu.h>
 
+struct bus;
 #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);




More information about the coreboot mailing list