diff --git a/src/arch/i386/core/relocate.c b/src/arch/i386/core/relocate.c index b9b02944..5fbf2d2c 100644 --- a/src/arch/i386/core/relocate.c +++ b/src/arch/i386/core/relocate.c @@ -33,8 +33,10 @@ extern char _etextdata[]; /** * Relocate iPXE * - * @v ix86 x86 register dump from prefix - * @ret ix86 x86 registers to return to prefix + * @v ebp Maximum address to use for relocation + * @ret esi Current physical address + * @ret edi New physical address + * @ret ecx Length to copy * * This finds a suitable location for iPXE near the top of 32-bit * address space, and returns the physical address of the new location @@ -59,7 +61,7 @@ __asmcall void relocate ( struct i386_all_regs *ix86 ) { /* Determine maximum usable address */ max = MAX_ADDR; - if ( ix86->regs.ebp && ( ix86->regs.ebp < max ) ) { + if ( ix86->regs.ebp < max ) { max = ix86->regs.ebp; DBG ( "Limiting relocation to [0,%lx)\n", max ); } diff --git a/src/arch/i386/firmware/pcbios/memmap.c b/src/arch/i386/firmware/pcbios/memmap.c index cf659226..0937a7ce 100644 --- a/src/arch/i386/firmware/pcbios/memmap.c +++ b/src/arch/i386/firmware/pcbios/memmap.c @@ -63,6 +63,10 @@ struct e820_entry { static struct e820_entry __bss16 ( e820buf ); #define e820buf __use_data16 ( e820buf ) +/** We are running during POST; inhibit INT 15,e820 and INT 15,e801 */ +uint8_t __bss16 ( memmap_post ); +#define memmap_post __use_data16 ( memmap_post ) + /** * Get size of extended memory via INT 15,e801 * @@ -74,6 +78,12 @@ static unsigned int extmemsize_e801 ( void ) { unsigned int flags; unsigned int extmem; + /* Inhibit INT 15,e801 during POST */ + if ( memmap_post ) { + DBG ( "INT 15,e801 not available during POST\n" ); + return 0; + } + __asm__ __volatile__ ( REAL_CODE ( "stc\n\t" "int $0x15\n\t" "pushfw\n\t" @@ -164,6 +174,12 @@ static int meme820 ( struct memory_map *memmap ) { unsigned int flags; unsigned int discard_D; + /* Inhibit INT 15,e820 during POST */ + if ( memmap_post ) { + DBG ( "INT 15,e820 not available during POST\n" ); + return -ENOTTY; + } + /* Clear the E820 buffer. Do this once before starting, * rather than on each call; some BIOSes rely on the contents * being preserved between calls. diff --git a/src/arch/i386/prefix/exeprefix.S b/src/arch/i386/prefix/exeprefix.S index acd3f83c..cb61287d 100644 --- a/src/arch/i386/prefix/exeprefix.S +++ b/src/arch/i386/prefix/exeprefix.S @@ -114,7 +114,7 @@ _exe_start: call alloc_basemem xorl %esi, %esi movl $EXE_DECOMPRESS_ADDRESS, %edi - xorl %ebp, %ebp + orl $0xffffffff, %ebp /* Allow arbitrary relocation */ call install_prealloc /* Set up real-mode stack */ diff --git a/src/arch/i386/prefix/libprefix.S b/src/arch/i386/prefix/libprefix.S index 0bd80b0a..197a86bc 100644 --- a/src/arch/i386/prefix/libprefix.S +++ b/src/arch/i386/prefix/libprefix.S @@ -622,7 +622,7 @@ install: /* Image destination = default */ xorl %edi, %edi /* Allow arbitrary relocation */ - xorl %ebp, %ebp + orl $0xffffffff, %ebp /* Install text and data segments */ call install_prealloc /* Restore registers and return */ @@ -642,7 +642,9 @@ install: * %bx : .data16 segment address * %esi : Image source physical address (or zero for %cs:0000) * %edi : Decompression temporary area physical address (or zero for default) - * %ebp : Maximum end address for relocation (or zero for no maximum) + * %ebp : Maximum end address for relocation + * - 0xffffffff for no maximum + * - 0x00000000 to inhibit use of INT 15,e820 and INT 15,e801 * Corrupts: * none **************************************************************************** @@ -796,6 +798,13 @@ payload_death_message: movw %ax, (init_librm_vector+2) lcall *init_librm_vector + /* Inhibit INT 15,e820 and INT 15,e801 if applicable */ + testl %ebp, %ebp + jnz 1f + incb memmap_post + decl %ebp +1: + /* Call relocate() to determine target address for relocation. * relocate() will return with %esi, %edi and %ecx set up * ready for the copy to the new location. diff --git a/src/arch/i386/prefix/romprefix.S b/src/arch/i386/prefix/romprefix.S index 35d037ef..18fef75e 100644 --- a/src/arch/i386/prefix/romprefix.S +++ b/src/arch/i386/prefix/romprefix.S @@ -445,7 +445,7 @@ no_pmm: * picked up by the initial shell prompt, and we will drop * into a shell. */ - movl $0xa0000, %ebp /* Inhibit relocation during POST */ + xorl %ebp, %ebp /* Inhibit use of INT 15,e820 and INT 15,e801 */ pushw %cs call exec 2: @@ -630,7 +630,7 @@ decompress_to: * Called by the PnP BIOS when it wants to boot us. */ bev_entry: - xorl %ebp, %ebp /* Allow relocation */ + orl $0xffffffff, %ebp /* Allow arbitrary relocation */ pushw %cs call exec lret @@ -665,7 +665,7 @@ int19_entry: /* Leave keypress in buffer and start iPXE. The keypress will * cause the usual initial Ctrl-B prompt to be skipped. */ - xorl %ebp, %ebp /* Allow relocation */ + orl $0xffffffff, %ebp /* Allow arbitrary relocation */ pushw %cs call exec 1: /* Try to call original INT 19 vector */ diff --git a/src/arch/i386/prefix/undiloader.S b/src/arch/i386/prefix/undiloader.S index bb3d469b..ccdd816e 100644 --- a/src/arch/i386/prefix/undiloader.S +++ b/src/arch/i386/prefix/undiloader.S @@ -31,7 +31,7 @@ undiloader: movw %es:14(%di), %ax movl image_source, %esi movl decompress_to, %edi - xorl %ebp, %ebp /* Allow relocation */ + orl $0xffffffff, %ebp /* Allow arbitrary relocation */ call install_prealloc popw %di /* Call UNDI loader C code */