[coreboot] r785 - in coreboot-v3: arch/x86 arch/x86/amd arch/x86/geodelx include

svn at coreboot.org svn at coreboot.org
Mon Aug 18 18:54:12 CEST 2008


Author: hailfinger
Date: 2008-08-18 18:54:12 +0200 (Mon, 18 Aug 2008)
New Revision: 785

Modified:
   coreboot-v3/arch/x86/amd/stage0.S
   coreboot-v3/arch/x86/geodelx/stage0.S
   coreboot-v3/arch/x86/stage0_i586.S
   coreboot-v3/arch/x86/stage1.c
   coreboot-v3/include/console.h
Log:
Move stage1 global variable management from asm to C. The stage0 asm
code now unconditionally pushes an empty pointer to the stack which is a
placeholder for the pointer to global variable storage. That pointer and
the global variable storage are initialized in global_vars_init().

Creating global variables is now a piece of cake. You don't even have to
touch any asm code, just add them to struct global_vars.

Build tested on all targets, boot tested on Qemu.

NOTES:
- The code is not yet MP safe, but that's due to v3 not being MP safe in
general (and the comments contradict the code regarding MP features).
- K8 code now works by accident.

Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006 at gmx.net>
Acked-by: Segher Boessenkool <segher at kernel.crashing.org>


Modified: coreboot-v3/arch/x86/amd/stage0.S
===================================================================
--- coreboot-v3/arch/x86/amd/stage0.S	2008-08-18 16:48:27 UTC (rev 784)
+++ coreboot-v3/arch/x86/amd/stage0.S	2008-08-18 16:54:12 UTC (rev 785)
@@ -23,7 +23,9 @@
 #define CacheBase CONFIG_CARBASE
 #define MEM_TOPK 2048
 
-/* leave some space for global variable to pass to RAM stage */
+/* Leave some space for a pointer to the global variables.
+ * This should most likely be 4.
+ */
 #define GlobalVarSize 32
 
 #ifdef CONFIG_CPU_AMD_K10

Modified: coreboot-v3/arch/x86/geodelx/stage0.S
===================================================================
--- coreboot-v3/arch/x86/geodelx/stage0.S	2008-08-18 16:48:27 UTC (rev 784)
+++ coreboot-v3/arch/x86/geodelx/stage0.S	2008-08-18 16:54:12 UTC (rev 785)
@@ -361,13 +361,10 @@
 	movw	%ax, %ss
 
 lout:
-#ifdef CONFIG_CONSOLE_BUFFER
-	/* Store pointer to start of printk buffer, should really use
-	 * PRINTK_BUF_ADDR_CAR instead.
-	 */
-	movl    $CONFIG_CARBASE, %eax
-	pushl   %eax  /* printk buffer */
-#endif
+	/* Store zero for the pointer to the global variables. */
+	movl    $0, %eax
+	pushl   %eax
+
 	/* Restore the BIST result. */
 	movl	%ebp, %eax
 

Modified: coreboot-v3/arch/x86/stage0_i586.S
===================================================================
--- coreboot-v3/arch/x86/stage0_i586.S	2008-08-18 16:48:27 UTC (rev 784)
+++ coreboot-v3/arch/x86/stage0_i586.S	2008-08-18 16:54:12 UTC (rev 785)
@@ -435,13 +435,10 @@
 	movw    %ax, %ss
 
 lout:
-#ifdef CONFIG_CONSOLE_BUFFER
-	/* Store pointer to start of printk buffer, should really use
-	 * PRINTK_BUF_ADDR_CAR instead.
-	 */
-	movl    $CONFIG_CARBASE, %eax
-	pushl 	%eax  /* printk buffer */
-#endif
+	/* Store zero for the pointer to the global variables. */
+	movl    $0, %eax
+	pushl   %eax
+
 	/* Restore the BIST result */
 	movl	%ebp, %eax
 	/* We need to set ebp ? No need */

Modified: coreboot-v3/arch/x86/stage1.c
===================================================================
--- coreboot-v3/arch/x86/stage1.c	2008-08-18 16:48:27 UTC (rev 784)
+++ coreboot-v3/arch/x86/stage1.c	2008-08-18 16:54:12 UTC (rev 785)
@@ -82,9 +82,15 @@
 
 struct global_vars *global_vars(void)
 {
-	return (struct global_vars *)(bottom_of_stack() - sizeof(struct global_vars));
+	return *(struct global_vars **)(bottom_of_stack() - sizeof(struct global_vars *));
 }
 
+void global_vars_init(struct global_vars *globvars)
+{
+	memset(globvars, 0, sizeof(struct global_vars));
+	*(struct global_vars **)(bottom_of_stack() - sizeof(struct global_vars *)) = globvars;
+}
+
 void dump_mem_range(int msg_level, unsigned char *buf, int size)
 {
 	int i;
@@ -119,9 +125,11 @@
 /*
  * This function is called from assembler code with its argument on the
  * stack. Force the compiler to generate always correct code for this case.
+ * We have cache as ram running and can start executing code in C.
  */
 void __attribute__((stdcall)) stage1_main(u32 bist)
 {
+	struct global_vars globvars;
 	int ret;
 	struct mem_file archive;
 	void *entry;
@@ -150,10 +158,13 @@
 		stop_ap();
 	}
 
-	// We have cache as ram running and can start executing code in C.
+	/* Initialize global variables before we can think of using them.
+	 * NEVER run this on an AP!
+	 */
+	global_vars_init(&globvars);
 
 #ifdef CONFIG_CONSOLE_BUFFER
-	/* Initialize the printk buffer. */
+	/* Initialize the printk buffer. NEVER run this on an AP! */
 	printk_buffer_init();
 #endif
 

Modified: coreboot-v3/include/console.h
===================================================================
--- coreboot-v3/include/console.h	2008-08-18 16:48:27 UTC (rev 784)
+++ coreboot-v3/include/console.h	2008-08-18 16:54:12 UTC (rev 785)
@@ -60,10 +60,10 @@
 #endif
 
 /*
- * If you change struct global_vars in any way, you have to fix all stage0 asm
- * code. The stage0 asm code modification is nontrivial (size of the struct,
- * alignment, initialization, order of struct members, initialization).
- * Depending on your compiler, real breakage may happen.
+ * struct global_vars is managed entirely from C code. Keep in mind that there
+ * is NO buffer at the end of the struct, so having zero-sized arrays at the
+ * end or similar stuff for which the compiler can't determine the final size
+ * will corrupt memory. If you don't try to be clever, everything will be fine.
  */
 struct global_vars {
 #ifdef CONFIG_CONSOLE_BUFFER





More information about the coreboot mailing list