summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichael Brown2008-09-24 00:35:19 +0200
committerMichael Brown2008-09-24 00:35:19 +0200
commit8b20e5d2b766dd6165a34b62f33a6bd92a68ed63 (patch)
treea2537c4f407b2efe237c2f18b2a132abc8092456 /src
parent[phantom] Omit an initialisation step now performed by the firmware (diff)
downloadipxe-8b20e5d2b766dd6165a34b62f33a6bd92a68ed63.tar.gz
ipxe-8b20e5d2b766dd6165a34b62f33a6bd92a68ed63.tar.xz
ipxe-8b20e5d2b766dd6165a34b62f33a6bd92a68ed63.zip
[pcbios] Sanity-check the INT15,e820 and INT15,e801 memory maps
Some systems seem to report insane memory maps (particularly at POST time). Detect and work around some of the common failure cases.
Diffstat (limited to 'src')
-rw-r--r--src/arch/i386/firmware/pcbios/memmap.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/src/arch/i386/firmware/pcbios/memmap.c b/src/arch/i386/firmware/pcbios/memmap.c
index f8813162..e6d6428e 100644
--- a/src/arch/i386/firmware/pcbios/memmap.c
+++ b/src/arch/i386/firmware/pcbios/memmap.c
@@ -89,6 +89,17 @@ static unsigned int extmemsize_e801 ( void ) {
DBG ( "INT 15,e801 extended memory size %d+64*%d=%d kB "
"[100000,%llx)\n", extmem_1m_to_16m_k, extmem_16m_plus_64k,
extmem, ( 0x100000 + ( ( ( uint64_t ) extmem ) * 1024 ) ) );
+
+ /* Sanity check. Some BIOSes report the entire 4GB address
+ * space as available, which cannot be correct (since that
+ * would leave no address space available for 32-bit PCI
+ * BARs).
+ */
+ if ( extmem == ( 0x400000 - 0x400 ) ) {
+ DBG ( "INT 15,e801 reported whole 4GB; assuming insane\n" );
+ return 0;
+ }
+
return extmem;
}
@@ -186,6 +197,28 @@ static int meme820 ( struct memory_map *memmap ) {
}
} while ( next != 0 );
+ /* Sanity checks. Some BIOSes report complete garbage via INT
+ * 15,e820 (especially at POST time), despite passing the
+ * signature checks. We currently check for a base memory
+ * region (starting at 0) and at least one high memory region
+ * (starting at 0x100000).
+ */
+ if ( memmap->count < 2 ) {
+ DBG ( "INT 15,e820 returned only %d regions; assuming "
+ "insane\n", memmap->count );
+ return -EINVAL;
+ }
+ if ( memmap->regions[0].start != 0 ) {
+ DBG ( "INT 15,e820 region 0 starts at %llx (expected 0); "
+ "assuming insane\n", memmap->regions[0].start );
+ return -EINVAL;
+ }
+ if ( memmap->regions[1].start != 0x100000 ) {
+ DBG ( "INT 15,e820 region 1 starts at %llx (expected 100000); "
+ "assuming insane\n", memmap->regions[0].start );
+ return -EINVAL;
+ }
+
return 0;
}