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

Reply via email to