comments welcome. Please see notes in the patch.

ron
This is a working (!) we think (!) SMP startup for core2. 
The AP spins up, prints some things, and spins down. 

I am not as interested in comments on this specific code (it needs cleanup)
as I am in two questions: 

1. can artec please test the current svn to make sure there is nothing
I have broken

2. Are the changes to lib/stage2.c ok

The improvements to smp startup are substantial. Here are a few
- secondary.S is now almost completely PIC, can be move to any page-aligned
boundary and run. 
- secondary_cpu_start has a stack with args that are visible to the AP. 
So BSP can now POST to AP-visible variables. Also, the mysterious 
stack computations are gone, replaced by a struct. Overall, this SMP 
startup is way simpler and (I hope) more comprehensible than v2. 
- Designed for auto-config; we should not need cpu descriptions in the dts. 
- cpu init done in phase 2 but not in the device tree any more, which should
reduce a huge source of confusion in v2. 

Anyway, take a look. With luck, we have SMP on the kontron within the week; 
SMI follows, then ACPI, then maybe we can make v3 the preferred kontron
software base. 
Signed-off-by: Ronald G. Minnich <[email protected]>
Index: mainboard/kontron/986lcd-m/initram.c
===================================================================
--- mainboard/kontron/986lcd-m/initram.c	(revision 1143)
+++ mainboard/kontron/986lcd-m/initram.c	(working copy)
@@ -226,8 +226,5 @@
 	}
 #endif
 	MCHBAR16(SSKPD) = 0xCAFE;
-
-	init_cpus(boot_mode, sysinfo);
-	
 	return 0;
 }
Index: mainboard/kontron/986lcd-m/Makefile
===================================================================
--- mainboard/kontron/986lcd-m/Makefile	(revision 1143)
+++ mainboard/kontron/986lcd-m/Makefile	(working copy)
@@ -23,18 +23,17 @@
 STAGE0_MAINBOARD_SRC := $(src)/lib/clog2.c \
 			$(src)/mainboard/$(MAINBOARDDIR)/stage1.c \
 			$(src)/mainboard/$(MAINBOARDDIR)/stage1_debug.c \
+			$(src)/northbridge/intel/i945//reset_test.c \
 
 INITRAM_SRC= $(src)/mainboard/$(MAINBOARDDIR)/initram.c \
-			$(src)/northbridge/intel/i945//reset_test.c \
-			$(src)/arch/x86/intel/core2/init_cpus.c \
 
 INITRAM_OBJ = \
-			$(obj)/arch/x86/secondary.o \
 
-STAGE2_CHIPSET_SRC=
+STAGE2_CHIPSET_SRC= \
+			$(src)/northbridge/intel/i945//reset_test.c \
+			$(src)/arch/x86/intel/core2/init_cpus.c \
+			$(src)/arch/x86/secondary.o \
 
-STAGE2_MAINBOARD_SRC = 
-
 $(obj)/coreboot.vpd:
 	$(Q)printf "  BUILD   DUMMY VPD\n"
 	$(Q)dd if=/dev/zero of=$(obj)/coreboot.vpd bs=256 count=1 $(SILENT)
Index: lib/stage2.c
===================================================================
--- lib/stage2.c	(revision 1143)
+++ lib/stage2.c	(working copy)
@@ -27,7 +27,22 @@
 #include <console.h>
 #include <device/device.h>
 #include <tables.h>
+#include <globalvars.h>
 
+unsigned int __attribute__((weak)) cpu_phase1(unsigned int coldboot,
+			struct sys_info *sysinfo)
+{
+	printk(BIOS_SPEW, "cpu_phase1: nothing to do\n");
+	return 0;
+}
+
+unsigned int __attribute__((weak)) cpu_phase2(unsigned int coldboot,
+			struct sys_info *sysinfo)
+{
+	printk(BIOS_SPEW, "cpu_phase2: nothing to do\n");
+	return 0;
+}
+
 /**
  * Main function of the DRAM part of coreboot.
  *
@@ -44,8 +59,12 @@
 void *stage2(void)
 {
 	void *mbi;
-
+	struct sys_info *sysinfo;
+	int is_coldboot(void);
+	struct global_vars *global_vars(void);
 	post_code(POST_STAGE2_BEGIN);
+	sysinfo = &(global_vars()->sys_info);
+	cpu_phase1(is_coldboot(), sysinfo);
 	dev_init();
 
 	/* Phase 1 was console init and making printk work. Both functions are
@@ -85,6 +104,11 @@
 	dev_phase6();
 	show_all_devs(BIOS_DEBUG, "After phase 6.");
 
+	/* final cleanup: do any remaining CPU setup. This can include memory 
+	 * init, or not, depending on the CPU; it may have been done in phase 1. 
+ 	 */
+	cpu_phase2(is_coldboot(), sysinfo);
+
 	/* Write tables to pass information to the payloads. */
 	post_code(POST_STAGE2_WRITE_TABLES);
 	mbi = write_tables();
Index: arch/x86/secondary.S
===================================================================
--- arch/x86/secondary.S	(revision 1143)
+++ arch/x86/secondary.S	(working copy)
@@ -62,24 +62,28 @@
 	movw	$8, 0
 	movl	%eax, %cr0
 	movw	$9, 0
-	hlt
-	/* tested to this point but not past it */
 
 	/* I am pretty sure this just jumps back into 
 	 * ROM; it's an abs jump
 	 */
-	data32 ljmp	$0x10, $secondary32
+	data32 ljmp	$0x8, $secondary32
 	movw	$0xa, 0
 1:	
 	.code32
 secondary32:
-	hlt
-	movw	$0x18, %ax
+	movw	$0x11, 0
+	movw	$0x10, %ax
+//	movw	$0x12, 0
 	movw	%ax, %ds
+	movw	$0x13, 0
 	movw	%ax, %es
+//	movw	$0x14, 0
 	movw	%ax, %ss
+//	movw	$0x15, 0
 	movw	%ax, %fs
+//	movw	$0x16, 0
 	movw	%ax, %gs
+	movw	$0x17, 0
 
 	/* Load the Interrupt descriptor table */
 	lidt	idtarg
@@ -87,6 +91,8 @@
 	/* Set the stack pointer */
 	movl	-4(%ebx),%esp
 	movl	$0, -4(%ebx)
 	call	secondary_cpu_init
 1:	hlt
@@ -108,14 +114,6 @@
 	/* selgdt 0x10, flat data segment */
 	.word	0xffff, 0x0000
 	.byte	0x00, 0x93, 0xcf, 0x00
-
-	/* selgdt 0x18, flat code segment for CAR */
-	.word	0xffff, 0x0000
-	.byte	0x00, 0x9b, 0xcf, 0x00
-
-	/* selgdt 0x20, flat data segment for CAR */
-	.word	0xffff, 0x0000
-	.byte	0x00, 0x93, 0xcf, 0x00
 gdt_end:
 
 
Index: arch/x86/intel/core2/init_cpus.c
===================================================================
--- arch/x86/intel/core2/init_cpus.c	(revision 1143)
+++ arch/x86/intel/core2/init_cpus.c	(working copy)
@@ -21,7 +21,6 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
  */
-#include <mainboard.h>
 #include <types.h>
 #include <lib.h>
 #include <console.h>
@@ -73,6 +72,7 @@
 	int nodes, siblings;
 	result = cpuid(1);
 	/* See how many sibling cpus we have */
+	printk(BIOS_DEBUG, "cpuid(1) %x\n", result.ebx);
 	siblings = (result.ebx >> 16) & 0xff;
 	if (siblings < 1) {
 		siblings = 1;
@@ -204,6 +204,9 @@
 	 * Starting actual IPI sequence...
 	 */
 
+	printk(BIOS_SPEW, "Before Startup.apicid %ld\n",  apicid);
+	printk(BIOS_SPEW, "Before Startup.sb[0] %p @0 %p\n", 
+			 (void *) secondary_base[0], (void *) *(u32 *) 0);
 	printk(BIOS_SPEW, "Asserting INIT.\n");
 
 	/*
@@ -321,7 +324,11 @@
 		if (send_status || accept_status)
 			break;
 	}
+	printk(BIOS_SPEW, "udelay(1000000)\n");
+	udelay(1000000);
 	printk(BIOS_SPEW, "After Startup.sb[-1] %p\n", (void *) secondary_base[-1]);
+	printk(BIOS_SPEW, "After Startup.sb[0] %p @0 %p\n", 
+			 (void *) secondary_base[0], (void *) *(u32 *) 0);
 	if (send_status)
 		printk(BIOS_WARNING, "APIC never delivered???\n");
 	if (accept_status)
@@ -377,18 +384,25 @@
 	stackmem->stacks[index].post   = 0;
 	stackmem->stacks[index].active_cpus  = active_cpus;
 	stackmem->stacks[index].start_cpu_lock = start_cpu_lock;
+	printk(BIOS_SPEW, "stack[index, apicid, post, active_cpus, start_cpu_lock = [%lx, %x, %d, %p, %p]\n", index, apicid, 0, active_cpus, start_cpu_lock);
 	/* Advertise the new stack to start_cpu */
 	printk(BIOS_SPEW, "Set stack @ %p to %p\n", &secondary_base[-1], (void *)stack_end);
 	secondary_base[-1] = stack_end;
 
 	/* Start the cpu */
 	result = lapic_start_cpu(apicid, secondary_base);
+	printk(BIOS_SPEW, "we think we started it. The stack value is 0x%p (should be 0)\n", (void *)secondary_base[-1]);
 
 	if (result) {
+		printk(BIOS_SPEW, "Spinning on post which is now 0x%x\n", 
+				stackmem->stacks[index].post);
 		result = 0;
 		/* Wait 1s or until the new the new cpu calls in */
-		for(count = 0; count < 100000 ; count++) {
-			if (stackmem->stacks[index].post) {
+		for(count = 0; count < 1000000 ; count++) {
+			printk(BIOS_SPEW, 
+				"BSP post 0x%x\n", 
+				stackmem->stacks[index].post);
+			if (stackmem->stacks[index].post >= AP_STOP_OK) {
 				result = 1;
 				break;
 			}
@@ -476,9 +490,12 @@
 	struct atomic *active_cpus,
 	struct spinlock *start_cpu_lock)
 {
+printk(BIOS_SPEW, "secondary start\n");
 	post = AP_START;
+printk(BIOS_SPEW, "secondary post %d\n", post);
 	atomic_inc(active_cpus);
 	post = AP_ACTIVEUP;
+printk(BIOS_SPEW, "secondary post %d\n", post);
 	if (SERIAL_CPU_INIT && (CONFIG_MAX_PHYSICAL_CPUS > 2))
 		spin_lock(start_cpu_lock);
 	post = AP_LOCKED;
@@ -559,7 +576,7 @@
  * @param sysinfo The sys_info pointer
  * @returns the BSP APIC ID
  */
-unsigned int init_cpus(unsigned cpu_init_detectedx,
+unsigned int cpu_phase1(unsigned cpu_init_detectedx,
 			struct sys_info *sysinfo)
 {
 	/* Number of cpus that are currently running in coreboot */
--
coreboot mailing list: [email protected]
http://www.coreboot.org/mailman/listinfo/coreboot

Reply via email to