On 15.10.2008 19:06, ron minnich wrote:
On Wed, Oct 15, 2008 at 10:04 AM, Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net wrote:
I'll be back in ~3 hours. If you have acked this in the meanwhile, I will commit, otherwise I'll rework.
let's get a complete patch set, then I will test on geode and simnow tonight. This all looks fine, but it makes me nervous.
Sure. Final version with lots and lots of comments follows. Test booted in Qemu. The patch even fixes up the documentation!
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@gmx.net
Index: corebootv3-stackrebuild/include/arch/x86/stage1.h =================================================================== --- corebootv3-stackrebuild/include/arch/x86/stage1.h (Revision 0) +++ corebootv3-stackrebuild/include/arch/x86/stage1.h (Revision 0) @@ -0,0 +1,2 @@ +void stage1_phase2(void); +void __attribute__((stdcall)) stage1_phase3(void); Index: corebootv3-stackrebuild/mainboard/emulation/qemu-x86/stage1.c =================================================================== --- corebootv3-stackrebuild/mainboard/emulation/qemu-x86/stage1.c (Revision 931) +++ corebootv3-stackrebuild/mainboard/emulation/qemu-x86/stage1.c (Arbeitskopie) @@ -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(); }
Index: corebootv3-stackrebuild/doc/design/newboot.lyx =================================================================== --- corebootv3-stackrebuild/doc/design/newboot.lyx (Revision 931) +++ corebootv3-stackrebuild/doc/design/newboot.lyx (Arbeitskopie) @@ -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 Index: corebootv3-stackrebuild/arch/x86/via/stage0.S =================================================================== --- corebootv3-stackrebuild/arch/x86/via/stage0.S (Revision 931) +++ corebootv3-stackrebuild/arch/x86/via/stage0.S (Arbeitskopie) @@ -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: Index: corebootv3-stackrebuild/arch/x86/geodelx/stage0.S =================================================================== --- corebootv3-stackrebuild/arch/x86/geodelx/stage0.S (Revision 931) +++ corebootv3-stackrebuild/arch/x86/geodelx/stage0.S (Arbeitskopie) @@ -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" Index: corebootv3-stackrebuild/arch/x86/geodelx/stage1.c =================================================================== --- corebootv3-stackrebuild/arch/x86/geodelx/stage1.c (Revision 931) +++ corebootv3-stackrebuild/arch/x86/geodelx/stage1.c (Arbeitskopie) @@ -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(); } Index: corebootv3-stackrebuild/arch/x86/i586/stage0.S =================================================================== --- corebootv3-stackrebuild/arch/x86/i586/stage0.S (Revision 931) +++ corebootv3-stackrebuild/arch/x86/i586/stage0.S (Arbeitskopie) @@ -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: Index: corebootv3-stackrebuild/arch/x86/amd/k8/stage1.c =================================================================== --- corebootv3-stackrebuild/arch/x86/amd/k8/stage1.c (Revision 931) +++ corebootv3-stackrebuild/arch/x86/amd/k8/stage1.c (Arbeitskopie) @@ -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(); } Index: corebootv3-stackrebuild/arch/x86/amd/stage0.S =================================================================== --- corebootv3-stackrebuild/arch/x86/amd/stage0.S (Revision 931) +++ corebootv3-stackrebuild/arch/x86/amd/stage0.S (Arbeitskopie) @@ -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 */ Index: corebootv3-stackrebuild/arch/x86/stage1.c =================================================================== --- corebootv3-stackrebuild/arch/x86/stage1.c (Revision 931) +++ corebootv3-stackrebuild/arch/x86/stage1.c (Arbeitskopie) @@ -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.");