summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoshua Oreman2009-10-06 22:12:22 +0200
committerMarty Connor2010-01-14 16:56:08 +0100
commit5736f5eb329cf9904687915194bd2005ee531064 (patch)
tree8c9a1fa1b8e483f339a7b1396bf6be7acb614421
parent[myri10ge] Native driver for Myricom 10Gb Ethernet NICs (diff)
downloadipxe-5736f5eb329cf9904687915194bd2005ee531064.tar.gz
ipxe-5736f5eb329cf9904687915194bd2005ee531064.tar.xz
ipxe-5736f5eb329cf9904687915194bd2005ee531064.zip
[prefix] Add .hrom prefix for a ROM that loads high under PCI3 without PMM
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>
-rw-r--r--src/Makefile.housekeeping1
-rw-r--r--src/arch/i386/Makefile.pcbios2
-rw-r--r--src/arch/i386/prefix/hromprefix.S12
-rw-r--r--src/arch/i386/prefix/romprefix.S13
4 files changed, 28 insertions, 0 deletions
diff --git a/src/Makefile.housekeeping b/src/Makefile.housekeeping
index e83a3e52..63745ff8 100644
--- a/src/Makefile.housekeeping
+++ b/src/Makefile.housekeeping
@@ -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
#
diff --git a/src/arch/i386/Makefile.pcbios b/src/arch/i386/Makefile.pcbios
index ff555593..55ba11d7 100644
--- a/src/arch/i386/Makefile.pcbios
+++ b/src/arch/i386/Makefile.pcbios
@@ -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
index 00000000..03acf1e2
--- /dev/null
+++ b/src/arch/i386/prefix/hromprefix.S
@@ -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"
diff --git a/src/arch/i386/prefix/romprefix.S b/src/arch/i386/prefix/romprefix.S
index cb474e81..d695fd92 100644
--- a/src/arch/i386/prefix/romprefix.S
+++ b/src/arch/i386/prefix/romprefix.S
@@ -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: