Browse Source

[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.
tags/v0.9.4
Michael Brown 15 years ago
parent
commit
8b20e5d2b7
1 changed files with 33 additions and 0 deletions
  1. 33
    0
      src/arch/i386/firmware/pcbios/memmap.c

+ 33
- 0
src/arch/i386/firmware/pcbios/memmap.c View File

89
 	DBG ( "INT 15,e801 extended memory size %d+64*%d=%d kB "
89
 	DBG ( "INT 15,e801 extended memory size %d+64*%d=%d kB "
90
 	      "[100000,%llx)\n", extmem_1m_to_16m_k, extmem_16m_plus_64k,
90
 	      "[100000,%llx)\n", extmem_1m_to_16m_k, extmem_16m_plus_64k,
91
 	      extmem, ( 0x100000 + ( ( ( uint64_t ) extmem ) * 1024 ) ) );
91
 	      extmem, ( 0x100000 + ( ( ( uint64_t ) extmem ) * 1024 ) ) );
92
+
93
+	/* Sanity check.  Some BIOSes report the entire 4GB address
94
+	 * space as available, which cannot be correct (since that
95
+	 * would leave no address space available for 32-bit PCI
96
+	 * BARs).
97
+	 */
98
+	if ( extmem == ( 0x400000 - 0x400 ) ) {
99
+		DBG ( "INT 15,e801 reported whole 4GB; assuming insane\n" );
100
+		return 0;
101
+	}
102
+
92
 	return extmem;
103
 	return extmem;
93
 }
104
 }
94
 
105
 
186
 		}
197
 		}
187
 	} while ( next != 0 );
198
 	} while ( next != 0 );
188
 
199
 
200
+	/* Sanity checks.  Some BIOSes report complete garbage via INT
201
+	 * 15,e820 (especially at POST time), despite passing the
202
+	 * signature checks.  We currently check for a base memory
203
+	 * region (starting at 0) and at least one high memory region
204
+	 * (starting at 0x100000).
205
+	 */
206
+	if ( memmap->count < 2 ) {
207
+		DBG ( "INT 15,e820 returned only %d regions; assuming "
208
+		      "insane\n", memmap->count );
209
+		return -EINVAL;
210
+	}
211
+	if ( memmap->regions[0].start != 0 ) {
212
+		DBG ( "INT 15,e820 region 0 starts at %llx (expected 0); "
213
+		      "assuming insane\n", memmap->regions[0].start );
214
+		return -EINVAL;
215
+	}
216
+	if ( memmap->regions[1].start != 0x100000 ) {
217
+		DBG ( "INT 15,e820 region 1 starts at %llx (expected 100000); "
218
+		      "assuming insane\n", memmap->regions[0].start );
219
+		return -EINVAL;
220
+	}
221
+
189
 	return 0;
222
 	return 0;
190
 }
223
 }
191
 
224
 

Loading…
Cancel
Save