aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64/kernel/e820.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64/kernel/e820.c')
-rw-r--r--arch/x86_64/kernel/e820.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c
index 56516ac92e5d..7c154dfff64a 100644
--- a/arch/x86_64/kernel/e820.c
+++ b/arch/x86_64/kernel/e820.c
@@ -2,6 +2,12 @@
2 * Handle the memory map. 2 * Handle the memory map.
3 * The functions here do the job until bootmem takes over. 3 * The functions here do the job until bootmem takes over.
4 * $Id: e820.c,v 1.4 2002/09/19 19:25:32 ak Exp $ 4 * $Id: e820.c,v 1.4 2002/09/19 19:25:32 ak Exp $
5 *
6 * Getting sanitize_e820_map() in sync with i386 version by applying change:
7 * - Provisions for empty E820 memory regions (reported by certain BIOSes).
8 * Alex Achenbach <xela@slit.de>, December 2002.
9 * Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
10 *
5 */ 11 */
6#include <linux/config.h> 12#include <linux/config.h>
7#include <linux/kernel.h> 13#include <linux/kernel.h>
@@ -277,7 +283,7 @@ static int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map)
277 int chgidx, still_changing; 283 int chgidx, still_changing;
278 int overlap_entries; 284 int overlap_entries;
279 int new_bios_entry; 285 int new_bios_entry;
280 int old_nr, new_nr; 286 int old_nr, new_nr, chg_nr;
281 int i; 287 int i;
282 288
283 /* 289 /*
@@ -331,20 +337,24 @@ static int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map)
331 for (i=0; i < 2*old_nr; i++) 337 for (i=0; i < 2*old_nr; i++)
332 change_point[i] = &change_point_list[i]; 338 change_point[i] = &change_point_list[i];
333 339
334 /* record all known change-points (starting and ending addresses) */ 340 /* record all known change-points (starting and ending addresses),
341 omitting those that are for empty memory regions */
335 chgidx = 0; 342 chgidx = 0;
336 for (i=0; i < old_nr; i++) { 343 for (i=0; i < old_nr; i++) {
337 change_point[chgidx]->addr = biosmap[i].addr; 344 if (biosmap[i].size != 0) {
338 change_point[chgidx++]->pbios = &biosmap[i]; 345 change_point[chgidx]->addr = biosmap[i].addr;
339 change_point[chgidx]->addr = biosmap[i].addr + biosmap[i].size; 346 change_point[chgidx++]->pbios = &biosmap[i];
340 change_point[chgidx++]->pbios = &biosmap[i]; 347 change_point[chgidx]->addr = biosmap[i].addr + biosmap[i].size;
348 change_point[chgidx++]->pbios = &biosmap[i];
349 }
341 } 350 }
351 chg_nr = chgidx;
342 352
343 /* sort change-point list by memory addresses (low -> high) */ 353 /* sort change-point list by memory addresses (low -> high) */
344 still_changing = 1; 354 still_changing = 1;
345 while (still_changing) { 355 while (still_changing) {
346 still_changing = 0; 356 still_changing = 0;
347 for (i=1; i < 2*old_nr; i++) { 357 for (i=1; i < chg_nr; i++) {
348 /* if <current_addr> > <last_addr>, swap */ 358 /* if <current_addr> > <last_addr>, swap */
349 /* or, if current=<start_addr> & last=<end_addr>, swap */ 359 /* or, if current=<start_addr> & last=<end_addr>, swap */
350 if ((change_point[i]->addr < change_point[i-1]->addr) || 360 if ((change_point[i]->addr < change_point[i-1]->addr) ||
@@ -367,7 +377,7 @@ static int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map)
367 last_type = 0; /* start with undefined memory type */ 377 last_type = 0; /* start with undefined memory type */
368 last_addr = 0; /* start with 0 as last starting address */ 378 last_addr = 0; /* start with 0 as last starting address */
369 /* loop through change-points, determining affect on the new bios map */ 379 /* loop through change-points, determining affect on the new bios map */
370 for (chgidx=0; chgidx < 2*old_nr; chgidx++) 380 for (chgidx=0; chgidx < chg_nr; chgidx++)
371 { 381 {
372 /* keep track of all overlapping bios entries */ 382 /* keep track of all overlapping bios entries */
373 if (change_point[chgidx]->addr == change_point[chgidx]->pbios->addr) 383 if (change_point[chgidx]->addr == change_point[chgidx]->pbios->addr)