diff options
| -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) |
