From f2872767a2afe4d5259c7d971a03efdcb2677e83 Mon Sep 17 00:00:00 2001 From: Marc Jones Date: Tue, 10 Feb 2009 22:41:35 +0000 Subject: [PATCH] Add AP detection to stage0 to prevent APs from re-initializing mainboard setup that has already been done by the BSP. For single processor systems the CPU flag is always 0, BSP. This code also moves the AP stop for K8 mainboards to after memory setup so the AP's MTRRs can be setup to match system memory. Signed-off-by: Marc Jones Acked-by: Peter Stuge git-svn-id: svn://coreboot.org/repository/coreboot-v3@1129 f3766cd6-281f-0410-b1cd-43a5c92072e9 --- arch/x86/amd/stage0.S | 39 +++++++++++++----------- arch/x86/geodelx/stage0.S | 4 +++ arch/x86/i586/stage0.S | 4 +++ arch/x86/intel/core2/stage0.S | 10 ++++++ arch/x86/stage1.c | 47 +++++++++++++---------------- arch/x86/via/stage0.S | 4 +++ mainboard/amd/dbm690t/initram.c | 8 ++--- mainboard/amd/serengeti/initram.c | 8 ++--- mainboard/gigabyte/m57sli/initram.c | 8 ++--- 9 files changed, 73 insertions(+), 59 deletions(-) diff --git a/arch/x86/amd/stage0.S b/arch/x86/amd/stage0.S index 6a8aeb594e..8dfb8c4888 100644 --- a/arch/x86/amd/stage0.S +++ b/arch/x86/amd/stage0.S @@ -78,11 +78,6 @@ cache_as_ram_setup: movb $0xA0, %al outb %al, $0x80 - /* check if cpu_init_detected */ - movl $MTRRdefType_MSR, %ecx - rdmsr - andl $(1 << 11), %eax - movl %eax, %ebx /* We store the status */ #ifdef CONFIG_CPU_AMD_K10 /* for GH, CAR need to set DRAM Base/Limit Registers to direct that to node0 */ @@ -248,11 +243,14 @@ clear_fixed_var_mtrr_out: movl %eax, %cr0 -#ifdef CONFIG_CPU_AMD_K10 - /* So we need to check if it is BSP/BSC */ + /* Check if it is BSP/BSC and put the result in ebx. */ movl $0x1b, %ecx /* APIC BAR */ rdmsr - bt $8, %eax /* BSC */ + movl %eax, %ebx + shrl $8, %ebx + andl $1, %ebx + btc $0, %ebx /* Flip bit zero from BSP/BSC flag to core ID 0. */ +#ifdef CONFIG_CPU_AMD_K10 jnc CAR_FAM10_ap #endif @@ -289,9 +287,6 @@ CAR_FAM10_ap: /* So need to get the NodeID and CoreID at first */ /* If NB_CFG bit 54 is set just use initial apicid, otherwise need to reverse it */ - /* store our init detected */ - movl %ebx, %esi - /* get the coreid bits at first */ movl $0x80000008, %eax cpuid @@ -315,34 +310,42 @@ roll_cfg: /* calculate stack pointer */ movl $CacheSizeAPStack, %eax - mull %ebx + mull %ebx /* core ID. */ movl $(CacheBase + (CacheSize - GlobalVarSize)/2), %esp subl %eax, %esp - /* retrive init detected */ - movl %esi, %ebx - movb $0xA4, %al outb %al, $0x80 -CAR_FAM10_ap_out: #endif movb $0xA5, %al outb %al, $0x80 + /* check if cpu_init_detected */ + movl $MTRRdefType_MSR, %ecx + rdmsr + andl $(1 << 11), %eax + movl %eax, %edx /* We store the status */ + /* Restore the BIST result. */ movl %ebp, %eax /* We need to set ebp? No need. */ movl %esp, %ebp - /* Second parameter: init_detected */ + /* Push the stage1_phase1 variables onto the stack */ + /* Third parameter: cpu #: 0 == BSP all other are APs. + */ pushl %ebx + + /* Second parameter: init_detected */ + pushl %edx + /* First parameter: bist */ pushl %eax call stage1_phase1 - /* We will not go back. */ + /* We will not come back. */ movb $0xAF, %al /* Should never see this postcode */ outb %al, $0x80 diff --git a/arch/x86/geodelx/stage0.S b/arch/x86/geodelx/stage0.S index 4f3a230b7e..195b7c5f6f 100644 --- a/arch/x86/geodelx/stage0.S +++ b/arch/x86/geodelx/stage0.S @@ -266,6 +266,10 @@ lout: /* We need to set ebp? No need. */ movl %esp, %ebp + /* Third parameter: cpu #: 0 == BSP all other are APs. + * Always 0 for Geode. + */ + pushl $0 /* Second parameter: init_detected */ /* Store zero for the unused init_detected parameter. */ pushl $0 diff --git a/arch/x86/i586/stage0.S b/arch/x86/i586/stage0.S index 668420c6a4..51506c07b7 100644 --- a/arch/x86/i586/stage0.S +++ b/arch/x86/i586/stage0.S @@ -334,6 +334,10 @@ lout: /* We need to set ebp? No need. */ movl %esp, %ebp + /* Third parameter: cpu #: 0 == BSP all other are APs. + * 0 until SMP support is added. + */ + pushl $0 /* Second parameter: init_detected */ /* Store zero for the unused init_detected parameter. */ pushl $0 diff --git a/arch/x86/intel/core2/stage0.S b/arch/x86/intel/core2/stage0.S index c2ed2e7671..79c4e03f94 100644 --- a/arch/x86/intel/core2/stage0.S +++ b/arch/x86/intel/core2/stage0.S @@ -159,16 +159,26 @@ clear_mtrrs: movl $(CACHE_AS_RAM_BASE + CACHE_AS_RAM_SIZE - 4), %eax movl %eax, %esp + /* Third parameter: cpu #: 0 == BSP all other are APs. + * 0 until SMP support is added. + */ + pushl $0 + /* Second parameter: init_detected */ + /* Store zero for the unused init_detected parameter. */ + pushl $0 + /* First parameter: bist */ /* Restore the BIST result */ movl %ebp, %eax movl %esp, %ebp pushl %eax + #if 0 /* this will be interpreted as failed bist */ port80_post(0x23) #endif + call stage1_phase1 port80_post(0x2f) diff --git a/arch/x86/stage1.c b/arch/x86/stage1.c index 304ee1ffe7..ea1b30f9ea 100644 --- a/arch/x86/stage1.c +++ b/arch/x86/stage1.c @@ -187,7 +187,7 @@ static int run_address_multiboot(void *f, struct multiboot_info *mbi) * that we are restarting after some sort of reconfiguration. Note that we could use it on geode but * do not at present. */ -void __attribute__((stdcall, regparm(0))) stage1_phase1(u32 bist, u32 init_detected) +void __attribute__((stdcall, regparm(0))) stage1_phase1(u32 bist, u32 init_detected, u32 cpu) { struct global_vars globvars; int ret; @@ -195,40 +195,35 @@ void __attribute__((stdcall, regparm(0))) stage1_phase1(u32 bist, u32 init_detec post_code(POST_STAGE1_MAIN); - /* before we do anything, we want to stop if we do not run - * on the bootstrap processor. - * stop_ap is responsible for NOT stopping the BSP + /* Only the BSP/BSC should do the following mainboard and global vars setup. */ - stop_ap(); + if (cpu == 0) { + /* Initialize global variables before we can think of using them. + */ + global_vars_init(&globvars); + globvars.init_detected = init_detected; - /* Initialize global variables before we can think of using them. - */ - global_vars_init(&globvars); - globvars.init_detected = init_detected; + hardware_stage1(); - hardware_stage1(); + uart_init(); // initialize serial port - // - uart_init(); // initialize serial port - - /* Exactly from now on we can use printk to the serial port. - * Celebrate this by printing a LB banner. - */ - console_init(); + /* Exactly from now on we can use printk to the serial port. + * Celebrate this by printing a LB banner. + */ + console_init(); #ifdef CONFIG_CHECK_STACK_USAGE - printk(BIOS_DEBUG, "Initial lowest stack is %p\n", - global_vars()->loweststack); + printk(BIOS_DEBUG, "Initial lowest stack is %p\n", + global_vars()->loweststack); #endif - if (bist!=0) { - printk(BIOS_INFO, "BIST FAILED: %08x", bist); - die(""); + + enable_rom(); // enable entire ROM area } - // enable rom - enable_rom(); - - // location and size of image. + if (bist != 0) { + printk(BIOS_INFO, "BIST FAILED: %08x on CPU: %08x", bist, cpu); + die(""); + } init_archive(&archive); diff --git a/arch/x86/via/stage0.S b/arch/x86/via/stage0.S index 59f129de39..77746614a1 100644 --- a/arch/x86/via/stage0.S +++ b/arch/x86/via/stage0.S @@ -184,6 +184,10 @@ lout: /* We need to set ebp? No need. */ movl %esp, %ebp + /* Third parameter: cpu #: 0 == BSP all other are APs. + * Always 0 for Via. + */ + pushl $0 /* Second parameter: init_detected */ /* Store zero for the unused init_detected parameter. */ pushl $0 diff --git a/mainboard/amd/dbm690t/initram.c b/mainboard/amd/dbm690t/initram.c index 559aa84012..7e0b6d9e87 100644 --- a/mainboard/amd/dbm690t/initram.c +++ b/mainboard/amd/dbm690t/initram.c @@ -181,7 +181,6 @@ int main(void) soft_reset(); } #endif - allow_all_aps_stop(bsp_apicid); //It's the time to set ctrl in sysinfo now; fill_mem_ctrl(sysinfo->nodes, sysinfo->ctrl, spd_addr); @@ -190,12 +189,11 @@ int main(void) memreset_setup(); - //do we need apci timer, tsc...., only debug need it for better output - /* all ap stopped? */ -// init_timer(); // Need to use TMICT to synconize FID/VID - sdram_initialize(sysinfo->nodes, sysinfo->ctrl, sysinfo); + /* After RAM is setup allow the APs to do RAM and MTRRs setup if needed. */ + allow_all_aps_stop(bsp_apicid); + #if 0 print_pci_devices(); #endif diff --git a/mainboard/amd/serengeti/initram.c b/mainboard/amd/serengeti/initram.c index cc4a91e895..ce20186d4b 100644 --- a/mainboard/amd/serengeti/initram.c +++ b/mainboard/amd/serengeti/initram.c @@ -224,7 +224,6 @@ int main(void) soft_reset_x(sysinfo->sbbusn, sysinfo->sbdn); } #endif - allow_all_aps_stop(bsp_apicid); //It's the time to set ctrl in sysinfo now; fill_mem_ctrl(sysinfo->nodes, sysinfo->ctrl, spd_addr); @@ -233,12 +232,11 @@ int main(void) memreset_setup(); - //do we need apci timer, tsc...., only debug need it for better output - /* all ap stopped? */ -// init_timer(); // Need to use TMICT to synconize FID/VID - sdram_initialize(sysinfo->nodes, sysinfo->ctrl, sysinfo); + /* After RAM is setup allow the APs to do RAM and MTRRs setup if needed. */ + allow_all_aps_stop(bsp_apicid); + #if 0 print_pci_devices(); #endif diff --git a/mainboard/gigabyte/m57sli/initram.c b/mainboard/gigabyte/m57sli/initram.c index 4a68cc5fee..f9ceb1834d 100644 --- a/mainboard/gigabyte/m57sli/initram.c +++ b/mainboard/gigabyte/m57sli/initram.c @@ -134,7 +134,6 @@ int main(void) printk(BIOS_INFO, "ht reset -\n"); soft_reset(); } - allow_all_aps_stop(bsp_apicid); //It's the time to set ctrl in sysinfo now; fill_mem_ctrl(sysinfo->nodes, sysinfo->ctrl, spd_addr); @@ -143,12 +142,11 @@ int main(void) memreset_setup(); - //do we need apci timer, tsc...., only debug need it for better output - /* all ap stopped? */ -// init_timer(); // Need to use TMICT to synconize FID/VID - sdram_initialize(sysinfo->nodes, sysinfo->ctrl, sysinfo); + /* After RAM is setup allow the APs to do RAM and MTRRs setup if needed. */ + allow_all_aps_stop(bsp_apicid); + printk(BIOS_DEBUG, "initram returns\n"); return 0; }