summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brown2008-09-24 00:35:19 +0200
committerMichael Brown2008-09-24 00:35:19 +0200
commit8b20e5d2b766dd6165a34b62f33a6bd92a68ed63 (patch)
treea2537c4f407b2efe237c2f18b2a132abc8092456
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.
-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;
}