[coreboot] r978 - in coreboot-v3/arch/x86: . via

svn at coreboot.org svn at coreboot.org
Sun Nov 2 15:47:22 CET 2008


Author: hailfinger
Date: 2008-11-02 15:47:21 +0100 (Sun, 02 Nov 2008)
New Revision: 978

Modified:
   coreboot-v3/arch/x86/stage1.c
   coreboot-v3/arch/x86/via/stage1.c
Log:
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 are two genuine fix in there as well:
We have to switch %esp before CAR is disabled. That way, the stack is
always valid.
And one of the nastier bugs easily happening in C: We had a pointer to a
const struct, but we wanted a const pointer to a struct. This kills the
(correct) warning about that code.

Many thanks to Corey for testing countless iterations of that code.

Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006 at gmx.net>
Tested and
Acked-by: Corey Osgood <corey.osgood at gmail.com>


Modified: coreboot-v3/arch/x86/stage1.c
===================================================================
--- coreboot-v3/arch/x86/stage1.c	2008-11-01 04:33:36 UTC (rev 977)
+++ coreboot-v3/arch/x86/stage1.c	2008-11-02 14:47:21 UTC (rev 978)
@@ -263,6 +263,7 @@
 #ifdef CONFIG_CONSOLE_BUFFER
 	/* Move the printk buffer to PRINTK_BUF_ADDR_RAM */
 	printk_buffer_move((void *)PRINTK_BUF_ADDR_RAM, PRINTK_BUF_SIZE_RAM);
+	printk(BIOS_DEBUG, "Done printk() buffer move\n");
 #endif
 	/* Turn off Cache-As-Ram */
 	disable_car();

Modified: coreboot-v3/arch/x86/via/stage1.c
===================================================================
--- coreboot-v3/arch/x86/via/stage1.c	2008-11-01 04:33:36 UTC (rev 977)
+++ coreboot-v3/arch/x86/via/stage1.c	2008-11-02 14:47:21 UTC (rev 978)
@@ -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
@@ -42,19 +43,27 @@
 	 *
  	 * Align the result to 8 bytes
 	 */
-	const struct global_vars *newlocation = (struct global_vars *)((RAM_STACK_BASE - sizeof(struct global_vars *) - sizeof(struct global_vars)) & ~0x7);
+	struct global_vars *const 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");
+
 	__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 +84,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),





More information about the coreboot mailing list