From 8b20e5d2b766dd6165a34b62f33a6bd92a68ed63 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Tue, 23 Sep 2008 23:35:19 +0100 Subject: [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. --- src/arch/i386/firmware/pcbios/memmap.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) 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; } -- cgit v1.2.3-55-g7522