Currently v3 allocates a global variable struct on the stack for each processor in stage1_main(). We only have 1k AP stack size for Fam10, but struct global_vars is ~3.6k, so all AP stacks will smash each other. Bad.
The idea is to have a special stage1_main_bsp() which allocates struct global_vars and initializes it. The BSP calls stage1_main_bsp() from stage0, all APs call stage1_main(). stage1_main_bsp() will call stage1_main(), so all processors end up in stage1_main() eventually.
The following snippet illustrates the changes to arch/x86/stage1.c and the changes for an UP configuration of i586/stage0.S.
Index: arch/x86/i586/stage0.S =================================================================== --- arch/x86/i586/stage0.S (Revision 909) +++ arch/x86/i586/stage0.S (Arbeitskopie) @@ -345,7 +345,7 @@ pushl $0 /* First parameter: bist */ pushl %eax - call stage1_main + call stage1_main_bsp /* We will not go back. */
fixed_mtrr_msr: Index: arch/x86/stage1.c =================================================================== --- arch/x86/stage1.c (Revision 909) +++ arch/x86/stage1.c (Arbeitskopie) @@ -143,6 +143,20 @@ return ret; }
+void __attribute__((stdcall)) stage1_main(u32 bist, u32 init_detected); + +void __attribute__((stdcall)) stage1_main_bsp(u32 bist, u32 init_detected) +{ + struct global_vars globvars; + + /* Initialize global variables before we can think of using them. + */ + global_vars_init(&globvars); + globvars.init_detected = init_detected; + + stage1_main(bist, init_detected); +} + /** * This function is called from assembler code with its argument on the * stack. Force the compiler to generate always correct code for this case. @@ -156,7 +170,6 @@ */ void __attribute__((stdcall)) stage1_main(u32 bist, u32 init_detected) { - struct global_vars globvars; int ret; struct mem_file archive; void *entry; @@ -185,11 +198,6 @@ */ stop_ap();
- /* Initialize global variables before we can think of using them. - */ - global_vars_init(&globvars); - globvars.init_detected = init_detected; - hardware_stage1();
//