[prefix] Add .hrom prefix for a ROM that loads high under PCI3 without PMM
authorJoshua Oreman <oremanj@rwcr.net>
Tue, 6 Oct 2009 20:12:22 +0000 (16:12 -0400)
committerMarty Connor <mdc@etherboot.org>
Thu, 14 Jan 2010 15:56:08 +0000 (10:56 -0500)
gPXE currently takes advantage of the feature of PCI3.0 that allows
option ROMs to relocate the bulk of their code to high memory and so
take up only a small amount of space in the option ROM area. Currently,
the relocation can only take place if the BIOS's implementation of PMM
can be made to return blocks aligned to an even megabyte, because of
the A20 gate. AMI BIOSes, in particular, will not return allocations
that gPXE can use.

Ameliorate the situation somewhat by adding a prefix, .hrom, that works
identically to .rom except in the case that PMM allocation fails. Where
.rom would give up and place itself entirely in option ROM space, .hrom
moves to a block (assumed free) at HIGHMEM_LOADPOINT = 4MB. This allows
for the use of larger gPXE ROMs than would otherwise be possible.

Because there is no way to check that the area at HIGHMEM_LOADPOINT is
really free, other devices using that memory during the boot process
will cause failure for gPXE, the other device, or both. In practice
such conflicts will likely not occur, but this prefix should still be
considered EXPERIMENTAL.

Signed-off-by: Marty Connor <mdc@etherboot.org>
src/Makefile.housekeeping
src/arch/i386/Makefile.pcbios
src/arch/i386/prefix/hromprefix.S [new file with mode: 0644]
src/arch/i386/prefix/romprefix.S

index e83a3e5..63745ff 100644 (file)
@@ -830,6 +830,7 @@ endif # defined(BIN)
 #
 FINALISE_rom   = $(MAKEROM) $(MAKEROM_FLAGS) $(TGT_MAKEROM_FLAGS) \
                  -i$(IDENT) -s 0 $@
+FINALISE_hrom  = $(FINALISE_rom)
 
 # Some ROMs require specific flags to be passed to makerom.pl
 #
index ff55559..55ba11d 100644 (file)
@@ -11,6 +11,7 @@ LDFLAGS               += -N --no-check-sections
 # Media types.
 #
 MEDIA          += rom
+MEDIA          += hrom
 MEDIA          += pxe
 MEDIA          += kpxe
 MEDIA          += kkpxe
@@ -30,6 +31,7 @@ MEDIA         += exe
 # Padding rules
 #
 PAD_rom                = $(PADIMG) --blksize=512 --byte=0xff $@
+PAD_hrom       = $(PAD_rom)
 PAD_dsk                = $(PADIMG) --blksize=512 $@
 PAD_hd         = $(PADIMG) --blksize=32768 $@
 
diff --git a/src/arch/i386/prefix/hromprefix.S b/src/arch/i386/prefix/hromprefix.S
new file mode 100644 (file)
index 0000000..03acf1e
--- /dev/null
@@ -0,0 +1,12 @@
+/*****************************************************************************
+ * ROM prefix that relocates to HIGHMEM_LOADPOINT during POST if PMM allocation
+ * fails. Intended to be used, with caution, on BIOSes that support PCI3.00 but
+ * have limited PMM support, such as most AMI BIOSes.
+ *****************************************************************************
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER )
+
+#define SHRINK_WITHOUT_PMM
+
+#include "romprefix.S"
index cb474e8..d695fd9 100644 (file)
@@ -351,6 +351,7 @@ got_pmm: /* PMM allocation succeeded */
        call    print_character
        movw    %si, %ax
        call    print_hex_byte
+pmm_copy:
        /* Copy ROM to PMM block */
        xorw    %ax, %ax
        movw    %ax, %es
@@ -362,7 +363,19 @@ got_pmm: /* PMM allocation succeeded */
        movl    %edi, decompress_to
        /* Shrink ROM */
        movb    $_prefix_memsz_sect, romheader_size
+#ifdef SHRINK_WITHOUT_PMM
+       jmp     pmm_done
 pmm_fail:
+       /* Print marker and copy ourselves to high memory */
+       movl    $HIGHMEM_LOADPOINT, image_source
+       xorw    %di, %di
+       movb    $( '!' ), %al
+       call    print_character
+       jmp     pmm_copy
+pmm_done:
+#else
+pmm_fail:
+#endif
        /* Restore upper register halves */
        popal
 no_pmm: