[coreboot] r932 - in coreboot-v3: arch/x86 arch/x86/amd arch/x86/amd/k8 arch/x86/geodelx arch/x86/i586 arch/x86/via doc/design include/arch/x86 mainboard/emulation/qemu-x86

svn at coreboot.org svn at coreboot.org
Thu Oct 16 05:00:28 CEST 2008


Author: hailfinger
Date: 2008-10-16 05:00:28 +0200 (Thu, 16 Oct 2008)
New Revision: 932

Added:
   coreboot-v3/include/arch/x86/stage1.h
Modified:
   coreboot-v3/arch/x86/amd/k8/stage1.c
   coreboot-v3/arch/x86/amd/stage0.S
   coreboot-v3/arch/x86/geodelx/stage0.S
   coreboot-v3/arch/x86/geodelx/stage1.c
   coreboot-v3/arch/x86/i586/stage0.S
   coreboot-v3/arch/x86/stage1.c
   coreboot-v3/arch/x86/via/stage0.S
   coreboot-v3/doc/design/newboot.lyx
   coreboot-v3/mainboard/emulation/qemu-x86/stage1.c
Log:
Right now we face the problem that we can't support processors which
have a CAR area outside the usual RAM area. For those processors, we
have to implement a stack copying and switching mechanism. Since gcc
can't be told that the stack just moved, split stage1_main() into
stage1_phase1() and stage1_phase2() and stage1_phase3().
stage1_phase1() is the new entry point in stage1 and will handle
everything up to the point where we want to disable CAR.
Switching the stack, disabling CAR and handling other tasks related to
the stack switch (printk buffer move) is all wrapped in the
stage1_phase2() function.
stage1_phase2() calls disable_car() which then calls stage1_phase3().
stage1_phase3() is the former second half of stage1_main().

Notes about this patch:
- Code flow is almost unchanged for Qemu, K8 and Geode. No extensive new
testing required.
- We can support stack-keeping and stack-relocating architectures at the
same time, so C7 is definitely supportable
- The comment in stage1_phase2 says "some of this is not yet done". That
refers to the nonexisting code for stack switching on C7.
- "Minimal changes, maximum benefit".

Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006 at gmx.net>
Acked-by: Ronald G. Minnich <rminnich at gmail.com>


Modified: coreboot-v3/arch/x86/amd/k8/stage1.c
===================================================================
--- coreboot-v3/arch/x86/amd/k8/stage1.c	2008-10-15 17:46:52 UTC (rev 931)
+++ coreboot-v3/arch/x86/amd/k8/stage1.c	2008-10-16 03:00:28 UTC (rev 932)
@@ -26,6 +26,7 @@
 #include <macros.h>
 #include <cpu.h>
 #include <amd/k8/k8.h>
+#include <stage1.h>
 
 /**
  * Set the MTRR for initial ram access. 
@@ -73,4 +74,5 @@
 	/* we're now running in ram. Although this will be called again, it does no harm to call it here. */
 	set_init_ram_access();
 	banner(BIOS_DEBUG, "disable_car: done");
+	stage1_phase3();
 }

Modified: coreboot-v3/arch/x86/amd/stage0.S
===================================================================
--- coreboot-v3/arch/x86/amd/stage0.S	2008-10-15 17:46:52 UTC (rev 931)
+++ coreboot-v3/arch/x86/amd/stage0.S	2008-10-16 03:00:28 UTC (rev 932)
@@ -341,7 +341,7 @@
 	pushl	%ebx
 	/* First parameter: bist */
 	pushl	%eax
-	call	stage1_main
+	call	stage1_phase1
 	/* We will not go back. */
 
 	movb	$0xAF, %al		/* Should never see this postcode */

Modified: coreboot-v3/arch/x86/geodelx/stage0.S
===================================================================
--- coreboot-v3/arch/x86/geodelx/stage0.S	2008-10-15 17:46:52 UTC (rev 931)
+++ coreboot-v3/arch/x86/geodelx/stage0.S	2008-10-16 03:00:28 UTC (rev 932)
@@ -271,7 +271,7 @@
 	pushl	$0
 	/* First parameter: bist */
 	pushl	%eax
-	call	stage1_main
+	call	stage1_phase1
 	/* We will not go back. */
 
 #include "../stage0_common.S"

Modified: coreboot-v3/arch/x86/geodelx/stage1.c
===================================================================
--- coreboot-v3/arch/x86/geodelx/stage1.c	2008-10-15 17:46:52 UTC (rev 931)
+++ coreboot-v3/arch/x86/geodelx/stage1.c	2008-10-16 03:00:28 UTC (rev 932)
@@ -24,6 +24,7 @@
 #include <amd_geodelx.h>
 #include <console.h>
 #include <msr.h>
+#include <stage1.h>
 
 static const struct msrinit msr_table[] = {
   /* Setup access to cache under 1MB. */
@@ -93,4 +94,5 @@
 	banner(BIOS_DEBUG, "Disable_car: done wbinvd");
 	northbridge_init_early();
 	banner(BIOS_DEBUG, "disable_car: done");
+	stage1_phase3();
 }

Modified: coreboot-v3/arch/x86/i586/stage0.S
===================================================================
--- coreboot-v3/arch/x86/i586/stage0.S	2008-10-15 17:46:52 UTC (rev 931)
+++ coreboot-v3/arch/x86/i586/stage0.S	2008-10-16 03:00:28 UTC (rev 932)
@@ -339,7 +339,7 @@
 	pushl	$0
 	/* First parameter: bist */
 	pushl	%eax
-	call	stage1_main
+	call	stage1_phase1
 	/* We will not go back. */
 
 fixed_mtrr_msr:

Modified: coreboot-v3/arch/x86/stage1.c
===================================================================
--- coreboot-v3/arch/x86/stage1.c	2008-10-15 17:46:52 UTC (rev 931)
+++ coreboot-v3/arch/x86/stage1.c	2008-10-16 03:00:28 UTC (rev 932)
@@ -30,6 +30,7 @@
 #include <mc146818rtc.h>
 #include <cpu.h>
 #include <multiboot.h>
+#include <stage1.h>
 
 #ifdef CONFIG_PAYLOAD_ELF_LOADER
 /* ah, well, what a mess! This is a hard code. FIX ME but how? 
@@ -154,29 +155,13 @@
  * that we are restarting after some sort of reconfiguration. Note that we could use it on geode but 
  * do not at present. 
  */
-void __attribute__((stdcall)) stage1_main(u32 bist, u32 init_detected)
+void __attribute__((stdcall)) stage1_phase1(u32 bist, u32 init_detected)
 {
 	struct global_vars globvars;
 	int ret;
 	struct mem_file archive;
-	void *entry;
 	struct node_core_id me;
-#ifdef CONFIG_PAYLOAD_ELF_LOADER
-	struct mem_file result;
-	int elfboot_mem(struct lb_memory *mem, void *where, int size);
 
-	/* Why can't we statically init this hack? */
-	unsigned char faker[64];
-	struct lb_memory *mem = (struct lb_memory*) faker;
-
-	mem->tag = LB_TAG_MEMORY;
-	mem->size = 28;
-	mem->map[0].start.lo = mem->map[0].start.hi = 0;
-	mem->map[0].size.lo = (32*1024*1024);
-	mem->map[0].size.hi = 0;
-	mem->map[0].type = LB_MEM_RAM;
-#endif /* CONFIG_PAYLOAD_ELF_LOADER */
-
 	post_code(POST_STAGE1_MAIN);
 
 	/* before we do anything, we want to stop if we do not run
@@ -234,14 +219,77 @@
 
 	printk(BIOS_DEBUG, "Done RAM init code\n");
 
-	/* Turn off Cache-As-Ram */
-	disable_car();
+	/* Switch the stack location from CAR to RAM, rebuild the stack,
+	 * disable CAR and continue at stage1_phase3(). This is all wrapped in
+	 * stage1_phase2() to make the code easier to follow.
+	 * We will NEVER return.
+	 */
+	stage1_phase2();
 
+	/* If we reach this point, something went terribly wrong. */
+	die("The world is broken.\n");
+}
+
+/**
+ * This function is called to take care of switching and rebuilding the stack
+ * so that we can cope with processors which don't support a CAR area at low
+ * addresses where CAR could be copied to RAM without problems.
+ * This function handles everything related to switching off CAR and moving
+ * important data from CAR to RAM.
+ * 1.  Perform all work which can be done while CAR and RAM are both active.
+ *     That's mainly moving the printk buffer around.
+ * 2a. Optionally back up the new stack location (desirable for S3).
+ * 2b. Optionally rebuild the stack at another location.
+ * 2c. Switch stack pointer to the new stack if the stack was rebuilt.
+ * 3.  Disable CAR.
+ * 4.  Call or jump to stage1_phase3.
+ * Steps 2a-4 have to be done in asm. That's what the oddly named disable_car()
+ * function does.
+ *
+ * TODO: Some parts of the list above are not yet done, so the code will not
+ * yet work on C7.
+ */
+void stage1_phase2()
+{
 #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);
 #endif
+	/* Turn off Cache-As-Ram */
+	disable_car();
 
+	/* If we reach this point, something went terribly wrong. */
+	die("The world is broken.\n");
+}
+
+/**
+ * This function is the second part of the former stage1_main() after
+ * switching the stack and disabling CAR.
+ */
+void __attribute__((stdcall)) stage1_phase3()
+{
+	void *entry;
+	int ret;
+	struct mem_file archive;
+#ifdef CONFIG_PAYLOAD_ELF_LOADER
+	struct mem_file result;
+	int elfboot_mem(struct lb_memory *mem, void *where, int size);
+
+	/* Why can't we statically init this hack? */
+	unsigned char faker[64];
+	struct lb_memory *mem = (struct lb_memory*) faker;
+
+	mem->tag = LB_TAG_MEMORY;
+	mem->size = 28;
+	mem->map[0].start.lo = mem->map[0].start.hi = 0;
+	mem->map[0].size.lo = (32*1024*1024);
+	mem->map[0].size.hi = 0;
+	mem->map[0].type = LB_MEM_RAM;
+#endif /* CONFIG_PAYLOAD_ELF_LOADER */
+
+	// location and size of image.
+	init_archive(&archive);
+
 	entry = load_file_segments(&archive, "normal/stage2");
 	if (entry == (void *)-1)
 		die("FATAL: Failed loading stage2.");

Modified: coreboot-v3/arch/x86/via/stage0.S
===================================================================
--- coreboot-v3/arch/x86/via/stage0.S	2008-10-15 17:46:52 UTC (rev 931)
+++ coreboot-v3/arch/x86/via/stage0.S	2008-10-16 03:00:28 UTC (rev 932)
@@ -189,7 +189,7 @@
 	pushl	$0
 	/* First parameter: bist */
 	pushl	%eax
-	call	stage1_main
+	call	stage1_phase1
 	/* We will not go back. */
 
 fixed_mtrr_msr:

Modified: coreboot-v3/doc/design/newboot.lyx
===================================================================
--- coreboot-v3/doc/design/newboot.lyx	2008-10-15 17:46:52 UTC (rev 931)
+++ coreboot-v3/doc/design/newboot.lyx	2008-10-16 03:00:28 UTC (rev 932)
@@ -759,7 +759,7 @@
 \end_layout
 
 \begin_layout Standard
-Initial entry point for stage 1 is arch/{architecture}/stage1.c:stage1_main().
+Initial entry point for stage 1 is arch/{architecture}/stage1.c:stage1_phase1().
 \end_layout
 
 \begin_layout Standard

Added: coreboot-v3/include/arch/x86/stage1.h
===================================================================
--- coreboot-v3/include/arch/x86/stage1.h	                        (rev 0)
+++ coreboot-v3/include/arch/x86/stage1.h	2008-10-16 03:00:28 UTC (rev 932)
@@ -0,0 +1,2 @@
+void stage1_phase2(void);
+void __attribute__((stdcall)) stage1_phase3(void);

Modified: coreboot-v3/mainboard/emulation/qemu-x86/stage1.c
===================================================================
--- coreboot-v3/mainboard/emulation/qemu-x86/stage1.c	2008-10-15 17:46:52 UTC (rev 931)
+++ coreboot-v3/mainboard/emulation/qemu-x86/stage1.c	2008-10-16 03:00:28 UTC (rev 932)
@@ -17,6 +17,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
  */
 
+#include <stage1.h>
+
 /* printk() will not yet output anything. */
 
 /** 
@@ -34,6 +36,7 @@
 
 void disable_car(void)
 {
+	stage1_phase3();
 }
 
 





More information about the coreboot mailing list