diff options
Diffstat (limited to 'arch/x86/kernel/e820_32.c')
-rw-r--r-- | arch/x86/kernel/e820_32.c | 241 |
1 files changed, 23 insertions, 218 deletions
diff --git a/arch/x86/kernel/e820_32.c b/arch/x86/kernel/e820_32.c index 18f500d185a..4e16ef4a265 100644 --- a/arch/x86/kernel/e820_32.c +++ b/arch/x86/kernel/e820_32.c | |||
@@ -7,7 +7,6 @@ | |||
7 | #include <linux/kexec.h> | 7 | #include <linux/kexec.h> |
8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
9 | #include <linux/mm.h> | 9 | #include <linux/mm.h> |
10 | #include <linux/efi.h> | ||
11 | #include <linux/pfn.h> | 10 | #include <linux/pfn.h> |
12 | #include <linux/uaccess.h> | 11 | #include <linux/uaccess.h> |
13 | #include <linux/suspend.h> | 12 | #include <linux/suspend.h> |
@@ -17,11 +16,6 @@ | |||
17 | #include <asm/e820.h> | 16 | #include <asm/e820.h> |
18 | #include <asm/setup.h> | 17 | #include <asm/setup.h> |
19 | 18 | ||
20 | #ifdef CONFIG_EFI | ||
21 | int efi_enabled = 0; | ||
22 | EXPORT_SYMBOL(efi_enabled); | ||
23 | #endif | ||
24 | |||
25 | struct e820map e820; | 19 | struct e820map e820; |
26 | struct change_member { | 20 | struct change_member { |
27 | struct e820entry *pbios; /* pointer to original bios entry */ | 21 | struct e820entry *pbios; /* pointer to original bios entry */ |
@@ -37,26 +31,6 @@ unsigned long pci_mem_start = 0x10000000; | |||
37 | EXPORT_SYMBOL(pci_mem_start); | 31 | EXPORT_SYMBOL(pci_mem_start); |
38 | #endif | 32 | #endif |
39 | extern int user_defined_memmap; | 33 | extern int user_defined_memmap; |
40 | struct resource data_resource = { | ||
41 | .name = "Kernel data", | ||
42 | .start = 0, | ||
43 | .end = 0, | ||
44 | .flags = IORESOURCE_BUSY | IORESOURCE_MEM | ||
45 | }; | ||
46 | |||
47 | struct resource code_resource = { | ||
48 | .name = "Kernel code", | ||
49 | .start = 0, | ||
50 | .end = 0, | ||
51 | .flags = IORESOURCE_BUSY | IORESOURCE_MEM | ||
52 | }; | ||
53 | |||
54 | struct resource bss_resource = { | ||
55 | .name = "Kernel bss", | ||
56 | .start = 0, | ||
57 | .end = 0, | ||
58 | .flags = IORESOURCE_BUSY | IORESOURCE_MEM | ||
59 | }; | ||
60 | 34 | ||
61 | static struct resource system_rom_resource = { | 35 | static struct resource system_rom_resource = { |
62 | .name = "System ROM", | 36 | .name = "System ROM", |
@@ -111,60 +85,6 @@ static struct resource video_rom_resource = { | |||
111 | .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM | 85 | .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM |
112 | }; | 86 | }; |
113 | 87 | ||
114 | static struct resource video_ram_resource = { | ||
115 | .name = "Video RAM area", | ||
116 | .start = 0xa0000, | ||
117 | .end = 0xbffff, | ||
118 | .flags = IORESOURCE_BUSY | IORESOURCE_MEM | ||
119 | }; | ||
120 | |||
121 | static struct resource standard_io_resources[] = { { | ||
122 | .name = "dma1", | ||
123 | .start = 0x0000, | ||
124 | .end = 0x001f, | ||
125 | .flags = IORESOURCE_BUSY | IORESOURCE_IO | ||
126 | }, { | ||
127 | .name = "pic1", | ||
128 | .start = 0x0020, | ||
129 | .end = 0x0021, | ||
130 | .flags = IORESOURCE_BUSY | IORESOURCE_IO | ||
131 | }, { | ||
132 | .name = "timer0", | ||
133 | .start = 0x0040, | ||
134 | .end = 0x0043, | ||
135 | .flags = IORESOURCE_BUSY | IORESOURCE_IO | ||
136 | }, { | ||
137 | .name = "timer1", | ||
138 | .start = 0x0050, | ||
139 | .end = 0x0053, | ||
140 | .flags = IORESOURCE_BUSY | IORESOURCE_IO | ||
141 | }, { | ||
142 | .name = "keyboard", | ||
143 | .start = 0x0060, | ||
144 | .end = 0x006f, | ||
145 | .flags = IORESOURCE_BUSY | IORESOURCE_IO | ||
146 | }, { | ||
147 | .name = "dma page reg", | ||
148 | .start = 0x0080, | ||
149 | .end = 0x008f, | ||
150 | .flags = IORESOURCE_BUSY | IORESOURCE_IO | ||
151 | }, { | ||
152 | .name = "pic2", | ||
153 | .start = 0x00a0, | ||
154 | .end = 0x00a1, | ||
155 | .flags = IORESOURCE_BUSY | IORESOURCE_IO | ||
156 | }, { | ||
157 | .name = "dma2", | ||
158 | .start = 0x00c0, | ||
159 | .end = 0x00df, | ||
160 | .flags = IORESOURCE_BUSY | IORESOURCE_IO | ||
161 | }, { | ||
162 | .name = "fpu", | ||
163 | .start = 0x00f0, | ||
164 | .end = 0x00ff, | ||
165 | .flags = IORESOURCE_BUSY | IORESOURCE_IO | ||
166 | } }; | ||
167 | |||
168 | #define ROMSIGNATURE 0xaa55 | 88 | #define ROMSIGNATURE 0xaa55 |
169 | 89 | ||
170 | static int __init romsignature(const unsigned char *rom) | 90 | static int __init romsignature(const unsigned char *rom) |
@@ -260,10 +180,9 @@ static void __init probe_roms(void) | |||
260 | * Request address space for all standard RAM and ROM resources | 180 | * Request address space for all standard RAM and ROM resources |
261 | * and also for regions reported as reserved by the e820. | 181 | * and also for regions reported as reserved by the e820. |
262 | */ | 182 | */ |
263 | static void __init | 183 | void __init init_iomem_resources(struct resource *code_resource, |
264 | legacy_init_iomem_resources(struct resource *code_resource, | 184 | struct resource *data_resource, |
265 | struct resource *data_resource, | 185 | struct resource *bss_resource) |
266 | struct resource *bss_resource) | ||
267 | { | 186 | { |
268 | int i; | 187 | int i; |
269 | 188 | ||
@@ -305,35 +224,6 @@ legacy_init_iomem_resources(struct resource *code_resource, | |||
305 | } | 224 | } |
306 | } | 225 | } |
307 | 226 | ||
308 | /* | ||
309 | * Request address space for all standard resources | ||
310 | * | ||
311 | * This is called just before pcibios_init(), which is also a | ||
312 | * subsys_initcall, but is linked in later (in arch/i386/pci/common.c). | ||
313 | */ | ||
314 | static int __init request_standard_resources(void) | ||
315 | { | ||
316 | int i; | ||
317 | |||
318 | printk("Setting up standard PCI resources\n"); | ||
319 | if (efi_enabled) | ||
320 | efi_initialize_iomem_resources(&code_resource, | ||
321 | &data_resource, &bss_resource); | ||
322 | else | ||
323 | legacy_init_iomem_resources(&code_resource, | ||
324 | &data_resource, &bss_resource); | ||
325 | |||
326 | /* EFI systems may still have VGA */ | ||
327 | request_resource(&iomem_resource, &video_ram_resource); | ||
328 | |||
329 | /* request I/O space for devices used on all i[345]86 PCs */ | ||
330 | for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++) | ||
331 | request_resource(&ioport_resource, &standard_io_resources[i]); | ||
332 | return 0; | ||
333 | } | ||
334 | |||
335 | subsys_initcall(request_standard_resources); | ||
336 | |||
337 | #if defined(CONFIG_PM) && defined(CONFIG_HIBERNATION) | 227 | #if defined(CONFIG_PM) && defined(CONFIG_HIBERNATION) |
338 | /** | 228 | /** |
339 | * e820_mark_nosave_regions - Find the ranges of physical addresses that do not | 229 | * e820_mark_nosave_regions - Find the ranges of physical addresses that do not |
@@ -370,19 +260,17 @@ void __init add_memory_region(unsigned long long start, | |||
370 | { | 260 | { |
371 | int x; | 261 | int x; |
372 | 262 | ||
373 | if (!efi_enabled) { | 263 | x = e820.nr_map; |
374 | x = e820.nr_map; | ||
375 | |||
376 | if (x == E820MAX) { | ||
377 | printk(KERN_ERR "Ooops! Too many entries in the memory map!\n"); | ||
378 | return; | ||
379 | } | ||
380 | 264 | ||
381 | e820.map[x].addr = start; | 265 | if (x == E820MAX) { |
382 | e820.map[x].size = size; | 266 | printk(KERN_ERR "Ooops! Too many entries in the memory map!\n"); |
383 | e820.map[x].type = type; | 267 | return; |
384 | e820.nr_map++; | ||
385 | } | 268 | } |
269 | |||
270 | e820.map[x].addr = start; | ||
271 | e820.map[x].size = size; | ||
272 | e820.map[x].type = type; | ||
273 | e820.nr_map++; | ||
386 | } /* add_memory_region */ | 274 | } /* add_memory_region */ |
387 | 275 | ||
388 | /* | 276 | /* |
@@ -598,29 +486,6 @@ int __init copy_e820_map(struct e820entry * biosmap, int nr_map) | |||
598 | } | 486 | } |
599 | 487 | ||
600 | /* | 488 | /* |
601 | * Callback for efi_memory_walk. | ||
602 | */ | ||
603 | static int __init | ||
604 | efi_find_max_pfn(unsigned long start, unsigned long end, void *arg) | ||
605 | { | ||
606 | unsigned long *max_pfn = arg, pfn; | ||
607 | |||
608 | if (start < end) { | ||
609 | pfn = PFN_UP(end -1); | ||
610 | if (pfn > *max_pfn) | ||
611 | *max_pfn = pfn; | ||
612 | } | ||
613 | return 0; | ||
614 | } | ||
615 | |||
616 | static int __init | ||
617 | efi_memory_present_wrapper(unsigned long start, unsigned long end, void *arg) | ||
618 | { | ||
619 | memory_present(0, PFN_UP(start), PFN_DOWN(end)); | ||
620 | return 0; | ||
621 | } | ||
622 | |||
623 | /* | ||
624 | * Find the highest page frame number we have available | 489 | * Find the highest page frame number we have available |
625 | */ | 490 | */ |
626 | void __init find_max_pfn(void) | 491 | void __init find_max_pfn(void) |
@@ -628,11 +493,6 @@ void __init find_max_pfn(void) | |||
628 | int i; | 493 | int i; |
629 | 494 | ||
630 | max_pfn = 0; | 495 | max_pfn = 0; |
631 | if (efi_enabled) { | ||
632 | efi_memmap_walk(efi_find_max_pfn, &max_pfn); | ||
633 | efi_memmap_walk(efi_memory_present_wrapper, NULL); | ||
634 | return; | ||
635 | } | ||
636 | 496 | ||
637 | for (i = 0; i < e820.nr_map; i++) { | 497 | for (i = 0; i < e820.nr_map; i++) { |
638 | unsigned long start, end; | 498 | unsigned long start, end; |
@@ -650,34 +510,12 @@ void __init find_max_pfn(void) | |||
650 | } | 510 | } |
651 | 511 | ||
652 | /* | 512 | /* |
653 | * Free all available memory for boot time allocation. Used | ||
654 | * as a callback function by efi_memory_walk() | ||
655 | */ | ||
656 | |||
657 | static int __init | ||
658 | free_available_memory(unsigned long start, unsigned long end, void *arg) | ||
659 | { | ||
660 | /* check max_low_pfn */ | ||
661 | if (start >= (max_low_pfn << PAGE_SHIFT)) | ||
662 | return 0; | ||
663 | if (end >= (max_low_pfn << PAGE_SHIFT)) | ||
664 | end = max_low_pfn << PAGE_SHIFT; | ||
665 | if (start < end) | ||
666 | free_bootmem(start, end - start); | ||
667 | |||
668 | return 0; | ||
669 | } | ||
670 | /* | ||
671 | * Register fully available low RAM pages with the bootmem allocator. | 513 | * Register fully available low RAM pages with the bootmem allocator. |
672 | */ | 514 | */ |
673 | void __init register_bootmem_low_pages(unsigned long max_low_pfn) | 515 | void __init register_bootmem_low_pages(unsigned long max_low_pfn) |
674 | { | 516 | { |
675 | int i; | 517 | int i; |
676 | 518 | ||
677 | if (efi_enabled) { | ||
678 | efi_memmap_walk(free_available_memory, NULL); | ||
679 | return; | ||
680 | } | ||
681 | for (i = 0; i < e820.nr_map; i++) { | 519 | for (i = 0; i < e820.nr_map; i++) { |
682 | unsigned long curr_pfn, last_pfn, size; | 520 | unsigned long curr_pfn, last_pfn, size; |
683 | /* | 521 | /* |
@@ -785,56 +623,12 @@ void __init print_memory_map(char *who) | |||
785 | } | 623 | } |
786 | } | 624 | } |
787 | 625 | ||
788 | static __init __always_inline void efi_limit_regions(unsigned long long size) | ||
789 | { | ||
790 | unsigned long long current_addr = 0; | ||
791 | efi_memory_desc_t *md, *next_md; | ||
792 | void *p, *p1; | ||
793 | int i, j; | ||
794 | |||
795 | j = 0; | ||
796 | p1 = memmap.map; | ||
797 | for (p = p1, i = 0; p < memmap.map_end; p += memmap.desc_size, i++) { | ||
798 | md = p; | ||
799 | next_md = p1; | ||
800 | current_addr = md->phys_addr + | ||
801 | PFN_PHYS(md->num_pages); | ||
802 | if (is_available_memory(md)) { | ||
803 | if (md->phys_addr >= size) continue; | ||
804 | memcpy(next_md, md, memmap.desc_size); | ||
805 | if (current_addr >= size) { | ||
806 | next_md->num_pages -= | ||
807 | PFN_UP(current_addr-size); | ||
808 | } | ||
809 | p1 += memmap.desc_size; | ||
810 | next_md = p1; | ||
811 | j++; | ||
812 | } else if ((md->attribute & EFI_MEMORY_RUNTIME) == | ||
813 | EFI_MEMORY_RUNTIME) { | ||
814 | /* In order to make runtime services | ||
815 | * available we have to include runtime | ||
816 | * memory regions in memory map */ | ||
817 | memcpy(next_md, md, memmap.desc_size); | ||
818 | p1 += memmap.desc_size; | ||
819 | next_md = p1; | ||
820 | j++; | ||
821 | } | ||
822 | } | ||
823 | memmap.nr_map = j; | ||
824 | memmap.map_end = memmap.map + | ||
825 | (memmap.nr_map * memmap.desc_size); | ||
826 | } | ||
827 | |||
828 | void __init limit_regions(unsigned long long size) | 626 | void __init limit_regions(unsigned long long size) |
829 | { | 627 | { |
830 | unsigned long long current_addr; | 628 | unsigned long long current_addr; |
831 | int i; | 629 | int i; |
832 | 630 | ||
833 | print_memory_map("limit_regions start"); | 631 | print_memory_map("limit_regions start"); |
834 | if (efi_enabled) { | ||
835 | efi_limit_regions(size); | ||
836 | return; | ||
837 | } | ||
838 | for (i = 0; i < e820.nr_map; i++) { | 632 | for (i = 0; i < e820.nr_map; i++) { |
839 | current_addr = e820.map[i].addr + e820.map[i].size; | 633 | current_addr = e820.map[i].addr + e820.map[i].size; |
840 | if (current_addr < size) | 634 | if (current_addr < size) |
@@ -955,3 +749,14 @@ static int __init parse_memmap(char *arg) | |||
955 | return 0; | 749 | return 0; |
956 | } | 750 | } |
957 | early_param("memmap", parse_memmap); | 751 | early_param("memmap", parse_memmap); |
752 | void __init update_e820(void) | ||
753 | { | ||
754 | u8 nr_map; | ||
755 | |||
756 | nr_map = e820.nr_map; | ||
757 | if (sanitize_e820_map(e820.map, &nr_map)) | ||
758 | return; | ||
759 | e820.nr_map = nr_map; | ||
760 | printk(KERN_INFO "modified physical RAM map:\n"); | ||
761 | print_memory_map("modified"); | ||
762 | } | ||