diff options
Diffstat (limited to 'arch/x86_64/kernel/e820.c')
-rw-r--r-- | arch/x86_64/kernel/e820.c | 26 |
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) |