From: Kevin O'Connor kevin@koconnor.net
Call maininit() and startBoot() from handle_post(). This reduces the chaining of calls during the relocation phase, and allows maininit() to return (which may be useful when using SeaBIOS as a CSM).
This change relies on reloc_init() modifying the maininit() call in handle_post() when relocations are enabled. It technically may not be safe to modify gcc generated code when in that gcc code, but it should be safe in practice.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/pmm.c | 5 +++++ src/post.c | 46 ++++++++++++++++------------------------------ 2 files changed, 21 insertions(+), 30 deletions(-)
diff --git a/src/pmm.c b/src/pmm.c index 653c9e2..77138dc 100644 --- a/src/pmm.c +++ b/src/pmm.c @@ -265,6 +265,11 @@ malloc_fixupreloc(void) return; dprintf(3, "malloc fixup reloc\n");
+ // Move low-memory initial variable content to new location. + extern u8 datalow_start[], datalow_end[], final_datalow_start[]; + memmove(final_datalow_start, datalow_start, datalow_end - datalow_start); + + // Fixup pointers back to ZoneX globals. int i; for (i=0; i<ARRAY_SIZE(Zones); i++) { struct zone_s *zone = Zones[i]; diff --git a/src/post.c b/src/post.c index f3b56b8..6a91f81 100644 --- a/src/post.c +++ b/src/post.c @@ -200,7 +200,7 @@ init_hw(void) }
// Begin the boot process by invoking an int0x19 in 16bit mode. -void VISIBLE32FLAT +static void startBoot(void) { // Clear low-memory allocations (required by PMM spec). @@ -214,9 +214,12 @@ startBoot(void) }
// Main setup code. -static void +void VISIBLE32INIT maininit(void) { + // Running at new code address - do code relocation fixups + malloc_fixupreloc(); + // Setup romfile items. qemu_cfg_romfile_setup(); coreboot_cbfs_setup(); @@ -287,9 +290,6 @@ maininit(void)
// Write protect bios memory. make_bios_readonly(); - - // Invoke int 19 to start boot process. - startBoot(); }
@@ -297,21 +297,6 @@ maininit(void) * POST entry and code relocation ****************************************************************/
-// Relocation fixup code that runs at new address after relocation complete. -static void -afterReloc(void) -{ - // Running at new code address - do code relocation fixups - malloc_fixupreloc(); - - // Move low-memory initial variable content to new location. - extern u8 datalow_start[], datalow_end[], final_datalow_start[]; - memmove(final_datalow_start, datalow_start, datalow_end - datalow_start); - - // Run main code - maininit(); -} - // Update given relocs for the code at 'dest' with a given 'delta' static void updateRelocs(void *dest, u32 *rstart, u32 *rend, u32 delta) @@ -325,10 +310,8 @@ updateRelocs(void *dest, u32 *rstart, u32 *rend, u32 delta) static void reloc_init(void) { - if (!CONFIG_RELOCATE_INIT) { - maininit(); + if (!CONFIG_RELOCATE_INIT) return; - } // Symbols populated by the build. extern u8 code32flat_start[]; extern u8 _reloc_min_align; @@ -359,15 +342,12 @@ reloc_init(void) updateRelocs(codedest, _reloc_rel_start, _reloc_rel_end, -delta); updateRelocs(code32flat_start, _reloc_init_start, _reloc_init_end, delta);
- // Call maininit() in relocated code. - void (*func)(void) = (void*)afterReloc + delta; barrier(); - func(); }
// Setup for code relocation and then call reloc_init void VISIBLE32INIT -dopost(void) +doreloc(void) { HaveRunPost = 1;
@@ -376,7 +356,7 @@ dopost(void) ram_probe(); malloc_setup();
- // Relocate initialization code and call maininit(). + // Relocate initialization code. reloc_init(); }
@@ -404,6 +384,12 @@ handle_post(void) // Allow writes to modify bios area (0xf0000) make_bios_writable();
- // Now that memory is read/writable - start post process. - dopost(); + // Do pre-relocation setup and then relocate initialization code. + doreloc(); + + // Run main code + maininit(); + + // Invoke int 19 to start boot process. + startBoot(); }