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.c118
1 files changed, 56 insertions, 62 deletions
diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c
index 708a3cd9a27e..c0af3828df45 100644
--- a/arch/x86_64/kernel/e820.c
+++ b/arch/x86_64/kernel/e820.c
@@ -25,6 +25,8 @@
25#include <asm/bootsetup.h> 25#include <asm/bootsetup.h>
26#include <asm/sections.h> 26#include <asm/sections.h>
27 27
28struct e820map e820 __initdata;
29
28/* 30/*
29 * PFN of last memory page. 31 * PFN of last memory page.
30 */ 32 */
@@ -41,7 +43,7 @@ unsigned long end_pfn_map;
41/* 43/*
42 * Last pfn which the user wants to use. 44 * Last pfn which the user wants to use.
43 */ 45 */
44unsigned long end_user_pfn = MAXMEM>>PAGE_SHIFT; 46static unsigned long __initdata end_user_pfn = MAXMEM>>PAGE_SHIFT;
45 47
46extern struct resource code_resource, data_resource; 48extern struct resource code_resource, data_resource;
47 49
@@ -70,12 +72,7 @@ static inline int bad_addr(unsigned long *addrp, unsigned long size)
70 return 1; 72 return 1;
71 } 73 }
72#endif 74#endif
73 /* kernel code + 640k memory hole (later should not be needed, but 75 /* kernel code */
74 be paranoid for now) */
75 if (last >= 640*1024 && addr < 1024*1024) {
76 *addrp = 1024*1024;
77 return 1;
78 }
79 if (last >= __pa_symbol(&_text) && last < __pa_symbol(&_end)) { 76 if (last >= __pa_symbol(&_text) && last < __pa_symbol(&_end)) {
80 *addrp = __pa_symbol(&_end); 77 *addrp = __pa_symbol(&_end);
81 return 1; 78 return 1;
@@ -565,13 +562,6 @@ static int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map)
565 * If we're lucky and live on a modern system, the setup code 562 * If we're lucky and live on a modern system, the setup code
566 * will have given us a memory map that we can use to properly 563 * will have given us a memory map that we can use to properly
567 * set up memory. If we aren't, we'll fake a memory map. 564 * set up memory. If we aren't, we'll fake a memory map.
568 *
569 * We check to see that the memory map contains at least 2 elements
570 * before we'll use it, because the detection code in setup.S may
571 * not be perfect and most every PC known to man has two memory
572 * regions: one from 0 to 640k, and one from 1mb up. (The IBM
573 * thinkpad 560x, for example, does not cooperate with the memory
574 * detection code.)
575 */ 565 */
576static int __init copy_e820_map(struct e820entry * biosmap, int nr_map) 566static int __init copy_e820_map(struct e820entry * biosmap, int nr_map)
577{ 567{
@@ -589,34 +579,19 @@ static int __init copy_e820_map(struct e820entry * biosmap, int nr_map)
589 if (start > end) 579 if (start > end)
590 return -1; 580 return -1;
591 581
592 /*
593 * Some BIOSes claim RAM in the 640k - 1M region.
594 * Not right. Fix it up.
595 *
596 * This should be removed on Hammer which is supposed to not
597 * have non e820 covered ISA mappings there, but I had some strange
598 * problems so it stays for now. -AK
599 */
600 if (type == E820_RAM) {
601 if (start < 0x100000ULL && end > 0xA0000ULL) {
602 if (start < 0xA0000ULL)
603 add_memory_region(start, 0xA0000ULL-start, type);
604 if (end <= 0x100000ULL)
605 continue;
606 start = 0x100000ULL;
607 size = end - start;
608 }
609 }
610
611 add_memory_region(start, size, type); 582 add_memory_region(start, size, type);
612 } while (biosmap++,--nr_map); 583 } while (biosmap++,--nr_map);
613 return 0; 584 return 0;
614} 585}
615 586
616void __init setup_memory_region(void) 587void early_panic(char *msg)
617{ 588{
618 char *who = "BIOS-e820"; 589 early_printk(msg);
590 panic(msg);
591}
619 592
593void __init setup_memory_region(void)
594{
620 /* 595 /*
621 * Try to copy the BIOS-supplied E820-map. 596 * Try to copy the BIOS-supplied E820-map.
622 * 597 *
@@ -624,51 +599,70 @@ void __init setup_memory_region(void)
624 * the next section from 1mb->appropriate_mem_k 599 * the next section from 1mb->appropriate_mem_k
625 */ 600 */
626 sanitize_e820_map(E820_MAP, &E820_MAP_NR); 601 sanitize_e820_map(E820_MAP, &E820_MAP_NR);
627 if (copy_e820_map(E820_MAP, E820_MAP_NR) < 0) { 602 if (copy_e820_map(E820_MAP, E820_MAP_NR) < 0)
628 unsigned long mem_size; 603 early_panic("Cannot find a valid memory map");
629
630 /* compare results from other methods and take the greater */
631 if (ALT_MEM_K < EXT_MEM_K) {
632 mem_size = EXT_MEM_K;
633 who = "BIOS-88";
634 } else {
635 mem_size = ALT_MEM_K;
636 who = "BIOS-e801";
637 }
638
639 e820.nr_map = 0;
640 add_memory_region(0, LOWMEMSIZE(), E820_RAM);
641 add_memory_region(HIGH_MEMORY, mem_size << 10, E820_RAM);
642 }
643 printk(KERN_INFO "BIOS-provided physical RAM map:\n"); 604 printk(KERN_INFO "BIOS-provided physical RAM map:\n");
644 e820_print_map(who); 605 e820_print_map("BIOS-e820");
645} 606}
646 607
647void __init parse_memopt(char *p, char **from) 608static int __init parse_memopt(char *p)
648{ 609{
649 end_user_pfn = memparse(p, from); 610 if (!p)
611 return -EINVAL;
612 end_user_pfn = memparse(p, &p);
650 end_user_pfn >>= PAGE_SHIFT; 613 end_user_pfn >>= PAGE_SHIFT;
614 return 0;
651} 615}
616early_param("mem", parse_memopt);
652 617
653void __init parse_memmapopt(char *p, char **from) 618static int userdef __initdata;
619
620static int __init parse_memmap_opt(char *p)
654{ 621{
622 char *oldp;
655 unsigned long long start_at, mem_size; 623 unsigned long long start_at, mem_size;
656 624
657 mem_size = memparse(p, from); 625 if (!strcmp(p, "exactmap")) {
658 p = *from; 626#ifdef CONFIG_CRASH_DUMP
627 /* If we are doing a crash dump, we
628 * still need to know the real mem
629 * size before original memory map is
630 * reset.
631 */
632 saved_max_pfn = e820_end_of_ram();
633#endif
634 end_pfn_map = 0;
635 e820.nr_map = 0;
636 userdef = 1;
637 return 0;
638 }
639
640 oldp = p;
641 mem_size = memparse(p, &p);
642 if (p == oldp)
643 return -EINVAL;
659 if (*p == '@') { 644 if (*p == '@') {
660 start_at = memparse(p+1, from); 645 start_at = memparse(p+1, &p);
661 add_memory_region(start_at, mem_size, E820_RAM); 646 add_memory_region(start_at, mem_size, E820_RAM);
662 } else if (*p == '#') { 647 } else if (*p == '#') {
663 start_at = memparse(p+1, from); 648 start_at = memparse(p+1, &p);
664 add_memory_region(start_at, mem_size, E820_ACPI); 649 add_memory_region(start_at, mem_size, E820_ACPI);
665 } else if (*p == '$') { 650 } else if (*p == '$') {
666 start_at = memparse(p+1, from); 651 start_at = memparse(p+1, &p);
667 add_memory_region(start_at, mem_size, E820_RESERVED); 652 add_memory_region(start_at, mem_size, E820_RESERVED);
668 } else { 653 } else {
669 end_user_pfn = (mem_size >> PAGE_SHIFT); 654 end_user_pfn = (mem_size >> PAGE_SHIFT);
670 } 655 }
671 p = *from; 656 return *p == '\0' ? 0 : -EINVAL;
657}
658early_param("memmap", parse_memmap_opt);
659
660void finish_e820_parsing(void)
661{
662 if (userdef) {
663 printk(KERN_INFO "user-defined physical RAM map:\n");
664 e820_print_map("user");
665 }
672} 666}
673 667
674unsigned long pci_mem_start = 0xaeedbabe; 668unsigned long pci_mem_start = 0xaeedbabe;