Once we touch the MTRRs in VIA disable_car(), the CPU resets. Since workarounds are better than instant reboots, mangle the code so that it only switches stacks and flushes the cache.
There's also one genuine fix in there: Switch %esp before CAR is disabled. That way, debugging becomes easier and the stack is always valid.
Many thanks to Corey for testing countless iterations of that code.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net Attached for poor gmail users.
Index: corebootv3-via_car/arch/x86/via/stage1.c =================================================================== --- corebootv3-via_car/arch/x86/via/stage1.c (Revision 977) +++ corebootv3-via_car/arch/x86/via/stage1.c (Arbeitskopie) @@ -35,6 +35,7 @@ */ void disable_car(void) { + printk(BIOS_DEBUG, "disable_car entry\n"); /* Determine new global variable location. Stack organization from top * Top 4 bytes are reserved * Pointer to global variables @@ -45,16 +46,25 @@ const struct global_vars *newlocation = (struct global_vars *)((RAM_STACK_BASE - sizeof(struct global_vars *) - sizeof(struct global_vars)) & ~0x7); /* Copy global variables to new location. */ memcpy(newlocation, global_vars(), sizeof(struct global_vars)); + printk(BIOS_DEBUG, "disable_car global_vars copy done\n"); /* Set the new global variable pointer. */ *(struct global_vars **)(RAM_STACK_BASE - sizeof(struct global_vars *)) = newlocation;
+ printk(BIOS_DEBUG, "disable_car global_vars pointer adjusted\n") + printk(BIOS_DEBUG, "entering asm code now\n"); + +#define HALT_AFTER 2 __asm__ __volatile__( + " movl %[newesp], %%esp \n" + +#if ENABLE_BROKEN_CAR_DISABLING /* We don't need cache as ram for now on */ /* disable cache */ " movl %%cr0, %%eax \n" " orl $(0x1<<30),%%eax \n" " movl %%eax, %%cr0 \n"
+ /* The MTRR setup below causes the machine to reset. Must investigate. */ /* disable fixed mtrr from now on, it will be enabled by coreboot_ram again*/ " movl %[_SYSCFG_MSR], %%ecx \n" " rdmsr \n" @@ -75,10 +85,10 @@ " movl %%cr0, %%eax \n" " andl $0x9fffffff,%%eax \n" " movl %%eax, %%cr0 \n" +#endif
" wbinvd \n"
- " movl %[newesp], %%esp \n" " call stage1_phase3 \n" :: [newesp] "i" (newlocation), [_SYSCFG_MSR] "i" (SYSCFG_MSR),