diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2010-09-25 11:34:06 -0400 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2010-09-25 11:34:06 -0400 |
commit | 7f55fd306854cc305cce6f8d8738a14e4ed01999 (patch) | |
tree | d4ba42ac013214c6fb42c9cebc68d20c251423d4 | |
parent | 025cabd2caa41d567d06a7c43f910621b99e64a4 (diff) | |
download | seabios-hppa-7f55fd306854cc305cce6f8d8738a14e4ed01999.zip seabios-hppa-7f55fd306854cc305cce6f8d8738a14e4ed01999.tar.gz seabios-hppa-7f55fd306854cc305cce6f8d8738a14e4ed01999.tar.bz2 |
Move the 32bit init code to high memory at runtime.
Add support for moving the 32bit init code out of the e/f-segments and
into temporary ram. Update the relocations in the code so that it can
live at its new address.
This frees up memory for other uses in the e/f segments.
-rw-r--r-- | src/config.h | 2 | ||||
-rw-r--r-- | src/post.c | 58 |
2 files changed, 58 insertions, 2 deletions
diff --git a/src/config.h b/src/config.h index 4572ee5..f9bf3b8 100644 --- a/src/config.h +++ b/src/config.h @@ -26,6 +26,8 @@ #define CONFIG_THREADS 1 // Allow hardware init to run in parallel with optionrom execution #define CONFIG_THREAD_OPTIONROMS 0 +// Support relocating the one time initialization code to high memory +#define CONFIG_RELOCATE_INIT 1 // Support int13 disk/floppy drive functions #define CONFIG_DRIVES 1 // Support floppy drive access @@ -183,7 +183,7 @@ init_hw(void) } // Begin the boot process by invoking an int0x19 in 16bit mode. -static void +void VISIBLE32FLAT startBoot(void) { // Clear low-memory allocations (required by PMM spec). @@ -268,9 +268,63 @@ maininit(void) startBoot(); } + +/**************************************************************** + * Code relocation + ****************************************************************/ + +// Update given relocs for the code at 'dest' with a given 'delta' +static void +updateRelocs(void *dest, u32 *rstart, u32 *rend, u32 delta) +{ + u32 *reloc; + for (reloc = rstart; reloc < rend; reloc++) + *((u32*)(dest + *reloc)) += delta; +} + +// Start of Power On Self Test - the BIOS initilization. This +// function sets up for and attempts relocation of the init code. +static void +reloc_init(void) +{ + if (!CONFIG_RELOCATE_INIT) { + maininit(); + return; + } + // Symbols populated by the build. + extern u8 code32flat_start[]; + extern u8 _reloc_min_align[]; + extern u32 _reloc_abs_start[], _reloc_abs_end[]; + extern u32 _reloc_rel_start[], _reloc_rel_end[]; + extern u32 _reloc_init_start[], _reloc_init_end[]; + extern u8 code32init_start[], code32init_end[]; + + // Allocate space for init code. + u32 initsize = code32init_end - code32init_start; + u32 align = (u32)&_reloc_min_align; + void *dest = memalign_tmp(align, initsize); + if (!dest) + panic("No space for init relocation.\n"); + + // Copy code and update relocs (init absolute, init relative, and runtime) + dprintf(1, "Relocating init from %p to %p (size %d)\n" + , code32init_start, dest, initsize); + s32 delta = dest - (void*)code32init_start; + memcpy(dest, code32init_start, initsize); + updateRelocs(dest, _reloc_abs_start, _reloc_abs_end, delta); + updateRelocs(dest, _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*)maininit + delta; + barrier(); + func(); +} + static int HaveRunPost; // Start of Power On Self Test (POST) - the BIOS initilization phase. +// This function sets up for and attempts relocation of the init code. void VISIBLE32INIT post(void) { @@ -285,7 +339,7 @@ post(void) ram_probe(); malloc_setup(); - maininit(); + reloc_init(); } |