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 <[EMAIL PROTECTED]>
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),
--
http://www.hailfinger.org/
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),
--
coreboot mailing list: [email protected]
http://www.coreboot.org/mailman/listinfo/coreboot