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

