11 #include <linux/kernel.h>
12 #include <linux/types.h>
15 #include <linux/export.h>
26 #include <asm/setup.h>
60 for (i = 0; i <
e820.nr_map; i++) {
63 if (type && ei->
type != type)
83 for (i = 0; i <
e820.nr_map; i++) {
86 if (type && ei->
type != type)
95 if (ei->
addr <= start)
116 printk(
KERN_ERR "e820: too many entries; ignoring [mem %#010llx-%#010llx]\n",
117 (
unsigned long long) start,
118 (
unsigned long long) (start + size - 1));
130 __e820_add_region(&
e820, start, size, type);
133 static void __init e820_print_type(
u32 type)
162 for (i = 0; i <
e820.nr_map; i++) {
164 (
unsigned long long)
e820.map[i].addr,
166 (
e820.map[i].addr +
e820.map[i].size - 1));
167 e820_print_type(
e820.map[i].type);
235 unsigned long long addr;
238 static int __init cpcompare(
const void *
a,
const void *
b)
249 if (ap->
addr != bp->addr)
250 return ap->
addr > bp->addr ? 1 : -1;
252 return (ap->
addr != ap->
pbios->addr) - (bp->addr != bp->pbios->addr);
261 static struct e820entry new_bios[E820_X_MAX] __initdata;
262 unsigned long current_type, last_type;
263 unsigned long long last_addr;
267 int old_nr, new_nr, chg_nr;
275 BUG_ON(old_nr > max_nr_map);
278 for (i = 0; i < old_nr; i++)
279 if (biosmap[i].
addr + biosmap[i].size < biosmap[i].
addr)
283 for (i = 0; i < 2 * old_nr; i++)
284 change_point[i] = &change_point_list[i];
289 for (i = 0; i < old_nr; i++) {
290 if (biosmap[i].size != 0) {
291 change_point[chgidx]->
addr = biosmap[
i].
addr;
292 change_point[chgidx++]->pbios = &biosmap[
i];
293 change_point[chgidx]->
addr = biosmap[
i].
addr +
295 change_point[chgidx++]->pbios = &biosmap[
i];
301 sort(change_point, chg_nr,
sizeof *change_point, cpcompare,
NULL);
310 for (chgidx = 0; chgidx < chg_nr; chgidx++) {
312 if (change_point[chgidx]->addr ==
313 change_point[chgidx]->pbios->addr) {
318 overlap_list[overlap_entries++] =
319 change_point[chgidx]->pbios;
325 for (i = 0; i < overlap_entries; i++) {
326 if (overlap_list[i] ==
327 change_point[chgidx]->pbios)
329 overlap_list[overlap_entries-1];
339 for (i = 0; i < overlap_entries; i++)
340 if (overlap_list[i]->type > current_type)
341 current_type = overlap_list[
i]->type;
346 if (current_type != last_type) {
347 if (last_type != 0) {
348 new_bios[new_bios_entry].
size =
349 change_point[chgidx]->addr - last_addr;
354 if (new_bios[new_bios_entry].size != 0)
359 if (++new_bios_entry >= max_nr_map)
362 if (current_type != 0) {
363 new_bios[new_bios_entry].
addr =
364 change_point[chgidx]->addr;
365 new_bios[new_bios_entry].
type = current_type;
366 last_addr = change_point[chgidx]->addr;
368 last_type = current_type;
372 new_nr = new_bios_entry;
381 static int __init __append_e820_map(
struct e820entry *biosmap,
int nr_map)
410 static int __init append_e820_map(
struct e820entry *biosmap,
int nr_map)
416 return __append_e820_map(biosmap, nr_map);
420 u64 size,
unsigned old_type,
425 u64 real_updated_size = 0;
427 BUG_ON(old_type == new_type);
434 (
unsigned long long) start, (
unsigned long long) (end - 1));
435 e820_print_type(old_type);
437 e820_print_type(new_type);
440 for (i = 0; i < e820x->
nr_map; i++) {
442 u64 final_start, final_end;
445 if (ei->
type != old_type)
450 if (ei->
addr >= start && ei_end <= end) {
452 real_updated_size += ei->
size;
457 if (ei->
addr < start && ei_end > end) {
458 __e820_add_region(e820x, start, size, new_type);
459 __e820_add_region(e820x, end, ei_end - end, ei->
type);
461 real_updated_size +=
size;
466 final_start =
max(start, ei->
addr);
467 final_end =
min(end, ei_end);
468 if (final_start >= final_end)
471 __e820_add_region(e820x, final_start, final_end - final_start,
474 real_updated_size += final_end - final_start;
480 ei->
size -= final_end - final_start;
481 if (ei->
addr < final_start)
483 ei->
addr = final_end;
485 return real_updated_size;
491 return __e820_update_range(&
e820, start, size, old_type, new_type);
495 unsigned old_type,
unsigned new_type)
497 return __e820_update_range(&
e820_saved, start, size, old_type,
507 u64 real_removed_size = 0;
514 (
unsigned long long) start, (
unsigned long long) (end - 1));
516 e820_print_type(old_type);
519 for (i = 0; i <
e820.nr_map; i++) {
521 u64 final_start, final_end;
524 if (checktype && ei->
type != old_type)
529 if (ei->
addr >= start && ei_end <= end) {
530 real_removed_size += ei->
size;
536 if (ei->
addr < start && ei_end > end) {
539 real_removed_size +=
size;
544 final_start =
max(start, ei->
addr);
545 final_end =
min(end, ei_end);
546 if (final_start >= final_end)
548 real_removed_size += final_end - final_start;
554 ei->
size -= final_end - final_start;
555 if (ei->
addr < final_start)
557 ei->
addr = final_end;
559 return real_removed_size;
566 nr_map =
e820.nr_map;
569 e820.nr_map = nr_map;
573 static void __init update_e820_saved(
void)
582 #define MAX_GAP_END 0x100000000ull
587 unsigned long start_addr,
unsigned long long end_addr)
589 unsigned long long last;
596 unsigned long long start =
e820.map[
i].addr;
597 unsigned long long end = start +
e820.map[
i].size;
599 if (end < start_addr)
607 unsigned long gap = last -
end;
609 if (gap >= *gapsize) {
629 unsigned long gapstart, gapsize;
632 gapstart = 0x10000000;
640 "e820: cannot find a gap in the 32bit address range\n"
641 "e820: PCI devices with unassigned 32bit BARs may break!\n");
651 "e820: [mem %#010lx-%#010lx] available for PCI devices\n",
652 gapstart, gapstart + gapsize - 1);
668 __append_e820_map(extmap, entries);
674 #if defined(CONFIG_X86_64) || \
675 (defined(CONFIG_X86_32) && defined(CONFIG_HIBERNATION))
684 void __init e820_mark_nosave_regions(
unsigned long limit_pfn)
690 for (i = 1; i <
e820.nr_map; i++) {
694 register_nosave_region(pfn,
PFN_UP(ei->
addr));
698 register_nosave_region(
PFN_UP(ei->
addr), pfn);
700 if (pfn >= limit_pfn)
711 static int __init e820_mark_nvs_memory(
void)
715 for (i = 0; i <
e820.nr_map; i++) {
745 # ifdef CONFIG_X86_PAE
746 # define MAX_ARCH_PFN (1ULL<<(36-PAGE_SHIFT))
748 # define MAX_ARCH_PFN (1ULL<<(32-PAGE_SHIFT))
751 # define MAX_ARCH_PFN MAXMEM>>PAGE_SHIFT
757 static unsigned long __init e820_end_pfn(
unsigned long limit_pfn,
unsigned type)
760 unsigned long last_pfn = 0;
763 for (i = 0; i <
e820.nr_map; i++) {
765 unsigned long start_pfn;
766 unsigned long end_pfn;
768 if (ei->
type != type)
774 if (start_pfn >= limit_pfn)
776 if (end_pfn > limit_pfn) {
777 last_pfn = limit_pfn;
780 if (end_pfn > last_pfn)
784 if (last_pfn > max_arch_pfn)
785 last_pfn = max_arch_pfn;
788 last_pfn, max_arch_pfn);
810 static int __init parse_memopt(
char *
p)
817 if (!
strcmp(p,
"nopentium")) {
838 static int __init parse_memmap_opt(
char *p)
846 if (!
strncmp(p,
"exactmap", 8)) {
847 #ifdef CONFIG_CRASH_DUMP
869 }
else if (*p ==
'#') {
872 }
else if (*p ==
'$') {
878 return *p ==
'\0' ? 0 : -
EINVAL;
896 static inline const char *e820_type_to_string(
int e820_type)
902 case E820_NVS:
return "ACPI Non-volatile Storage";
904 default:
return "reserved";
911 static struct resource __initdata *e820_res;
920 for (i = 0; i <
e820.nr_map; i++) {
921 end =
e820.map[
i].addr +
e820.map[
i].size - 1;
926 res->
name = e820_type_to_string(
e820.map[i].type);
948 e820_type_to_string(entry->
type));
955 unsigned long mb = pos >> 20;
969 #define MAX_RESOURCE_SIZE ((resource_size_t)-1)
977 for (i = 0; i <
e820.nr_map; i++) {
987 for (i = 0; i <
e820.nr_map; i++) {
994 end =
round_up(start, ram_alignment(start)) - 1;
1000 "e820: reserve RAM buffer [mem %#010llx-%#010llx]\n",
1009 char *who =
"BIOS-e820";
1049 who =
x86_init.resources.memory_setup();
1067 for (i = 0; i <
e820.nr_map; i++) {
1083 memblock_dump_all();
1088 #ifdef CONFIG_X86_64
1089 u64 nr_pages = 0, nr_free_pages = 0;
1090 unsigned long start_pfn, end_pfn;
1103 nr_pages += end_pfn - start_pfn;
1109 if (start_pfn < end_pfn)
1110 nr_free_pages += end_pfn - start_pfn;