diff options
author | Huang, Ying <ying.huang@intel.com> | 2008-01-30 07:31:19 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-01-30 07:31:19 -0500 |
commit | 2215e69d2cf5024647f9a034807990590d25dd4e (patch) | |
tree | 89b82b38e515d6e540420347151472d78adc8a51 /arch/x86 | |
parent | e429795c68d3001ecae74f6465420c9f043b0ece (diff) |
x86 boot: use E820 memory map on EFI 32 platform
Because the EFI memory map are converted to e820 memory map in bootloader, the
EFI memory map handling code is removed to clean up.
Signed-off-by: Huang Ying <ying.huang@intel.com>
Cc: Andi Kleen <ak@suse.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/kernel/e820_32.c | 117 | ||||
-rw-r--r-- | arch/x86/kernel/efi_32.c | 150 | ||||
-rw-r--r-- | arch/x86/kernel/setup_32.c | 16 | ||||
-rw-r--r-- | arch/x86/mm/init_32.c | 18 |
4 files changed, 15 insertions, 286 deletions
diff --git a/arch/x86/kernel/e820_32.c b/arch/x86/kernel/e820_32.c index 56335a85a15a..931934a7b353 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> |
@@ -181,7 +180,7 @@ static void __init probe_roms(void) | |||
181 | * Request address space for all standard RAM and ROM resources | 180 | * Request address space for all standard RAM and ROM resources |
182 | * and also for regions reported as reserved by the e820. | 181 | * and also for regions reported as reserved by the e820. |
183 | */ | 182 | */ |
184 | void __init legacy_init_iomem_resources(struct resource *code_resource, | 183 | void __init init_iomem_resources(struct resource *code_resource, |
185 | struct resource *data_resource, | 184 | struct resource *data_resource, |
186 | struct resource *bss_resource) | 185 | struct resource *bss_resource) |
187 | { | 186 | { |
@@ -261,19 +260,17 @@ void __init add_memory_region(unsigned long long start, | |||
261 | { | 260 | { |
262 | int x; | 261 | int x; |
263 | 262 | ||
264 | if (!efi_enabled) { | 263 | x = e820.nr_map; |
265 | x = e820.nr_map; | ||
266 | 264 | ||
267 | if (x == E820MAX) { | 265 | if (x == E820MAX) { |
268 | printk(KERN_ERR "Ooops! Too many entries in the memory map!\n"); | 266 | printk(KERN_ERR "Ooops! Too many entries in the memory map!\n"); |
269 | return; | 267 | return; |
270 | } | ||
271 | |||
272 | e820.map[x].addr = start; | ||
273 | e820.map[x].size = size; | ||
274 | e820.map[x].type = type; | ||
275 | e820.nr_map++; | ||
276 | } | 268 | } |
269 | |||
270 | e820.map[x].addr = start; | ||
271 | e820.map[x].size = size; | ||
272 | e820.map[x].type = type; | ||
273 | e820.nr_map++; | ||
277 | } /* add_memory_region */ | 274 | } /* add_memory_region */ |
278 | 275 | ||
279 | /* | 276 | /* |
@@ -489,29 +486,6 @@ int __init copy_e820_map(struct e820entry * biosmap, int nr_map) | |||
489 | } | 486 | } |
490 | 487 | ||
491 | /* | 488 | /* |
492 | * Callback for efi_memory_walk. | ||
493 | */ | ||
494 | static int __init | ||
495 | efi_find_max_pfn(unsigned long start, unsigned long end, void *arg) | ||
496 | { | ||
497 | unsigned long *max_pfn = arg, pfn; | ||
498 | |||
499 | if (start < end) { | ||
500 | pfn = PFN_UP(end -1); | ||
501 | if (pfn > *max_pfn) | ||
502 | *max_pfn = pfn; | ||
503 | } | ||
504 | return 0; | ||
505 | } | ||
506 | |||
507 | static int __init | ||
508 | efi_memory_present_wrapper(unsigned long start, unsigned long end, void *arg) | ||
509 | { | ||
510 | memory_present(0, PFN_UP(start), PFN_DOWN(end)); | ||
511 | return 0; | ||
512 | } | ||
513 | |||
514 | /* | ||
515 | * Find the highest page frame number we have available | 489 | * Find the highest page frame number we have available |
516 | */ | 490 | */ |
517 | void __init find_max_pfn(void) | 491 | void __init find_max_pfn(void) |
@@ -519,11 +493,6 @@ void __init find_max_pfn(void) | |||
519 | int i; | 493 | int i; |
520 | 494 | ||
521 | max_pfn = 0; | 495 | max_pfn = 0; |
522 | if (efi_enabled) { | ||
523 | efi_memmap_walk(efi_find_max_pfn, &max_pfn); | ||
524 | efi_memmap_walk(efi_memory_present_wrapper, NULL); | ||
525 | return; | ||
526 | } | ||
527 | 496 | ||
528 | for (i = 0; i < e820.nr_map; i++) { | 497 | for (i = 0; i < e820.nr_map; i++) { |
529 | unsigned long start, end; | 498 | unsigned long start, end; |
@@ -541,34 +510,12 @@ void __init find_max_pfn(void) | |||
541 | } | 510 | } |
542 | 511 | ||
543 | /* | 512 | /* |
544 | * Free all available memory for boot time allocation. Used | ||
545 | * as a callback function by efi_memory_walk() | ||
546 | */ | ||
547 | |||
548 | static int __init | ||
549 | free_available_memory(unsigned long start, unsigned long end, void *arg) | ||
550 | { | ||
551 | /* check max_low_pfn */ | ||
552 | if (start >= (max_low_pfn << PAGE_SHIFT)) | ||
553 | return 0; | ||
554 | if (end >= (max_low_pfn << PAGE_SHIFT)) | ||
555 | end = max_low_pfn << PAGE_SHIFT; | ||
556 | if (start < end) | ||
557 | free_bootmem(start, end - start); | ||
558 | |||
559 | return 0; | ||
560 | } | ||
561 | /* | ||
562 | * Register fully available low RAM pages with the bootmem allocator. | 513 | * Register fully available low RAM pages with the bootmem allocator. |
563 | */ | 514 | */ |
564 | void __init register_bootmem_low_pages(unsigned long max_low_pfn) | 515 | void __init register_bootmem_low_pages(unsigned long max_low_pfn) |
565 | { | 516 | { |
566 | int i; | 517 | int i; |
567 | 518 | ||
568 | if (efi_enabled) { | ||
569 | efi_memmap_walk(free_available_memory, NULL); | ||
570 | return; | ||
571 | } | ||
572 | for (i = 0; i < e820.nr_map; i++) { | 519 | for (i = 0; i < e820.nr_map; i++) { |
573 | unsigned long curr_pfn, last_pfn, size; | 520 | unsigned long curr_pfn, last_pfn, size; |
574 | /* | 521 | /* |
@@ -676,56 +623,12 @@ void __init print_memory_map(char *who) | |||
676 | } | 623 | } |
677 | } | 624 | } |
678 | 625 | ||
679 | static __init __always_inline void efi_limit_regions(unsigned long long size) | ||
680 | { | ||
681 | unsigned long long current_addr = 0; | ||
682 | efi_memory_desc_t *md, *next_md; | ||
683 | void *p, *p1; | ||
684 | int i, j; | ||
685 | |||
686 | j = 0; | ||
687 | p1 = memmap.map; | ||
688 | for (p = p1, i = 0; p < memmap.map_end; p += memmap.desc_size, i++) { | ||
689 | md = p; | ||
690 | next_md = p1; | ||
691 | current_addr = md->phys_addr + | ||
692 | PFN_PHYS(md->num_pages); | ||
693 | if (is_available_memory(md)) { | ||
694 | if (md->phys_addr >= size) continue; | ||
695 | memcpy(next_md, md, memmap.desc_size); | ||
696 | if (current_addr >= size) { | ||
697 | next_md->num_pages -= | ||
698 | PFN_UP(current_addr-size); | ||
699 | } | ||
700 | p1 += memmap.desc_size; | ||
701 | next_md = p1; | ||
702 | j++; | ||
703 | } else if ((md->attribute & EFI_MEMORY_RUNTIME) == | ||
704 | EFI_MEMORY_RUNTIME) { | ||
705 | /* In order to make runtime services | ||
706 | * available we have to include runtime | ||
707 | * memory regions in memory map */ | ||
708 | memcpy(next_md, md, memmap.desc_size); | ||
709 | p1 += memmap.desc_size; | ||
710 | next_md = p1; | ||
711 | j++; | ||
712 | } | ||
713 | } | ||
714 | memmap.nr_map = j; | ||
715 | memmap.map_end = memmap.map + | ||
716 | (memmap.nr_map * memmap.desc_size); | ||
717 | } | ||
718 | |||
719 | void __init limit_regions(unsigned long long size) | 626 | void __init limit_regions(unsigned long long size) |
720 | { | 627 | { |
721 | unsigned long long current_addr; | 628 | unsigned long long current_addr; |
722 | int i; | 629 | int i; |
723 | 630 | ||
724 | print_memory_map("limit_regions start"); | 631 | print_memory_map("limit_regions start"); |
725 | if (efi_enabled) { | ||
726 | efi_limit_regions(size); | ||
727 | return; | ||
728 | } | ||
729 | for (i = 0; i < e820.nr_map; i++) { | 632 | for (i = 0; i < e820.nr_map; i++) { |
730 | current_addr = e820.map[i].addr + e820.map[i].size; | 633 | current_addr = e820.map[i].addr + e820.map[i].size; |
731 | if (current_addr < size) | 634 | if (current_addr < size) |
diff --git a/arch/x86/kernel/efi_32.c b/arch/x86/kernel/efi_32.c index 1df13725e519..30f937116288 100644 --- a/arch/x86/kernel/efi_32.c +++ b/arch/x86/kernel/efi_32.c | |||
@@ -125,22 +125,6 @@ void efi_call_phys_epilog(void) __releases(efi_rt_lock) | |||
125 | spin_unlock(&efi_rt_lock); | 125 | spin_unlock(&efi_rt_lock); |
126 | } | 126 | } |
127 | 127 | ||
128 | int is_available_memory(efi_memory_desc_t * md) | ||
129 | { | ||
130 | if (!(md->attribute & EFI_MEMORY_WB)) | ||
131 | return 0; | ||
132 | |||
133 | switch (md->type) { | ||
134 | case EFI_LOADER_CODE: | ||
135 | case EFI_LOADER_DATA: | ||
136 | case EFI_BOOT_SERVICES_CODE: | ||
137 | case EFI_BOOT_SERVICES_DATA: | ||
138 | case EFI_CONVENTIONAL_MEMORY: | ||
139 | return 1; | ||
140 | } | ||
141 | return 0; | ||
142 | } | ||
143 | |||
144 | /* | 128 | /* |
145 | * We need to map the EFI memory map again after paging_init(). | 129 | * We need to map the EFI memory map again after paging_init(). |
146 | */ | 130 | */ |
@@ -155,137 +139,3 @@ void __init efi_map_memmap(void) | |||
155 | 139 | ||
156 | memmap.map_end = memmap.map + (memmap.nr_map * memmap.desc_size); | 140 | memmap.map_end = memmap.map + (memmap.nr_map * memmap.desc_size); |
157 | } | 141 | } |
158 | |||
159 | /* | ||
160 | * Walks the EFI memory map and calls CALLBACK once for each EFI | ||
161 | * memory descriptor that has memory that is available for kernel use. | ||
162 | */ | ||
163 | void efi_memmap_walk(efi_freemem_callback_t callback, void *arg) | ||
164 | { | ||
165 | int prev_valid = 0; | ||
166 | struct range { | ||
167 | unsigned long start; | ||
168 | unsigned long end; | ||
169 | } uninitialized_var(prev), curr; | ||
170 | efi_memory_desc_t *md; | ||
171 | unsigned long start, end; | ||
172 | void *p; | ||
173 | |||
174 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { | ||
175 | md = p; | ||
176 | |||
177 | if ((md->num_pages == 0) || (!is_available_memory(md))) | ||
178 | continue; | ||
179 | |||
180 | curr.start = md->phys_addr; | ||
181 | curr.end = curr.start + (md->num_pages << EFI_PAGE_SHIFT); | ||
182 | |||
183 | if (!prev_valid) { | ||
184 | prev = curr; | ||
185 | prev_valid = 1; | ||
186 | } else { | ||
187 | if (curr.start < prev.start) | ||
188 | printk(KERN_INFO PFX "Unordered memory map\n"); | ||
189 | if (prev.end == curr.start) | ||
190 | prev.end = curr.end; | ||
191 | else { | ||
192 | start = | ||
193 | (unsigned long) (PAGE_ALIGN(prev.start)); | ||
194 | end = (unsigned long) (prev.end & PAGE_MASK); | ||
195 | if ((end > start) | ||
196 | && (*callback) (start, end, arg) < 0) | ||
197 | return; | ||
198 | prev = curr; | ||
199 | } | ||
200 | } | ||
201 | } | ||
202 | if (prev_valid) { | ||
203 | start = (unsigned long) PAGE_ALIGN(prev.start); | ||
204 | end = (unsigned long) (prev.end & PAGE_MASK); | ||
205 | if (end > start) | ||
206 | (*callback) (start, end, arg); | ||
207 | } | ||
208 | } | ||
209 | |||
210 | void __init | ||
211 | efi_initialize_iomem_resources(struct resource *code_resource, | ||
212 | struct resource *data_resource, | ||
213 | struct resource *bss_resource) | ||
214 | { | ||
215 | struct resource *res; | ||
216 | efi_memory_desc_t *md; | ||
217 | void *p; | ||
218 | |||
219 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { | ||
220 | md = p; | ||
221 | |||
222 | if ((md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) > | ||
223 | 0x100000000ULL) | ||
224 | continue; | ||
225 | res = kzalloc(sizeof(struct resource), GFP_ATOMIC); | ||
226 | switch (md->type) { | ||
227 | case EFI_RESERVED_TYPE: | ||
228 | res->name = "Reserved Memory"; | ||
229 | break; | ||
230 | case EFI_LOADER_CODE: | ||
231 | res->name = "Loader Code"; | ||
232 | break; | ||
233 | case EFI_LOADER_DATA: | ||
234 | res->name = "Loader Data"; | ||
235 | break; | ||
236 | case EFI_BOOT_SERVICES_DATA: | ||
237 | res->name = "BootServices Data"; | ||
238 | break; | ||
239 | case EFI_BOOT_SERVICES_CODE: | ||
240 | res->name = "BootServices Code"; | ||
241 | break; | ||
242 | case EFI_RUNTIME_SERVICES_CODE: | ||
243 | res->name = "Runtime Service Code"; | ||
244 | break; | ||
245 | case EFI_RUNTIME_SERVICES_DATA: | ||
246 | res->name = "Runtime Service Data"; | ||
247 | break; | ||
248 | case EFI_CONVENTIONAL_MEMORY: | ||
249 | res->name = "Conventional Memory"; | ||
250 | break; | ||
251 | case EFI_UNUSABLE_MEMORY: | ||
252 | res->name = "Unusable Memory"; | ||
253 | break; | ||
254 | case EFI_ACPI_RECLAIM_MEMORY: | ||
255 | res->name = "ACPI Reclaim"; | ||
256 | break; | ||
257 | case EFI_ACPI_MEMORY_NVS: | ||
258 | res->name = "ACPI NVS"; | ||
259 | break; | ||
260 | case EFI_MEMORY_MAPPED_IO: | ||
261 | res->name = "Memory Mapped IO"; | ||
262 | break; | ||
263 | case EFI_MEMORY_MAPPED_IO_PORT_SPACE: | ||
264 | res->name = "Memory Mapped IO Port Space"; | ||
265 | break; | ||
266 | default: | ||
267 | res->name = "Reserved"; | ||
268 | break; | ||
269 | } | ||
270 | res->start = md->phys_addr; | ||
271 | res->end = res->start + ((md->num_pages << EFI_PAGE_SHIFT) - 1); | ||
272 | res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; | ||
273 | if (request_resource(&iomem_resource, res) < 0) | ||
274 | printk(KERN_ERR PFX "Failed to allocate res %s : " | ||
275 | "0x%llx-0x%llx\n", res->name, | ||
276 | (unsigned long long)res->start, | ||
277 | (unsigned long long)res->end); | ||
278 | /* | ||
279 | * We don't know which region contains kernel data so we try | ||
280 | * it repeatedly and let the resource manager test it. | ||
281 | */ | ||
282 | if (md->type == EFI_CONVENTIONAL_MEMORY) { | ||
283 | request_resource(res, code_resource); | ||
284 | request_resource(res, data_resource); | ||
285 | request_resource(res, bss_resource); | ||
286 | #ifdef CONFIG_KEXEC | ||
287 | request_resource(res, &crashk_res); | ||
288 | #endif | ||
289 | } | ||
290 | } | ||
291 | } | ||
diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 32fc87adc4a3..2e805da337a2 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c | |||
@@ -644,12 +644,12 @@ void __init setup_arch(char **cmdline_p) | |||
644 | rd_doload = ((boot_params.hdr.ram_size & RAMDISK_LOAD_FLAG) != 0); | 644 | rd_doload = ((boot_params.hdr.ram_size & RAMDISK_LOAD_FLAG) != 0); |
645 | #endif | 645 | #endif |
646 | ARCH_SETUP | 646 | ARCH_SETUP |
647 | |||
648 | printk(KERN_INFO "BIOS-provided physical RAM map:\n"); | ||
649 | print_memory_map(memory_setup()); | ||
650 | |||
647 | if (efi_enabled) | 651 | if (efi_enabled) |
648 | efi_init(); | 652 | efi_init(); |
649 | else { | ||
650 | printk(KERN_INFO "BIOS-provided physical RAM map:\n"); | ||
651 | print_memory_map(memory_setup()); | ||
652 | } | ||
653 | 653 | ||
654 | copy_edd(); | 654 | copy_edd(); |
655 | 655 | ||
@@ -769,14 +769,8 @@ static int __init request_standard_resources(void) | |||
769 | int i; | 769 | int i; |
770 | 770 | ||
771 | printk(KERN_INFO "Setting up standard PCI resources\n"); | 771 | printk(KERN_INFO "Setting up standard PCI resources\n"); |
772 | if (efi_enabled) | 772 | init_iomem_resources(&code_resource, &data_resource, &bss_resource); |
773 | efi_initialize_iomem_resources(&code_resource, | ||
774 | &data_resource, &bss_resource); | ||
775 | else | ||
776 | legacy_init_iomem_resources(&code_resource, | ||
777 | &data_resource, &bss_resource); | ||
778 | 773 | ||
779 | /* EFI systems may still have VGA */ | ||
780 | request_resource(&iomem_resource, &video_ram_resource); | 774 | request_resource(&iomem_resource, &video_ram_resource); |
781 | 775 | ||
782 | /* request I/O space for devices used on all i[345]86 PCs */ | 776 | /* request I/O space for devices used on all i[345]86 PCs */ |
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c index e6e34c7dcabf..29130970c193 100644 --- a/arch/x86/mm/init_32.c +++ b/arch/x86/mm/init_32.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/bootmem.h> | 27 | #include <linux/bootmem.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/proc_fs.h> | 29 | #include <linux/proc_fs.h> |
30 | #include <linux/efi.h> | ||
31 | #include <linux/memory_hotplug.h> | 30 | #include <linux/memory_hotplug.h> |
32 | #include <linux/initrd.h> | 31 | #include <linux/initrd.h> |
33 | #include <linux/cpumask.h> | 32 | #include <linux/cpumask.h> |
@@ -216,23 +215,6 @@ int page_is_ram(unsigned long pagenr) | |||
216 | int i; | 215 | int i; |
217 | unsigned long addr, end; | 216 | unsigned long addr, end; |
218 | 217 | ||
219 | if (efi_enabled) { | ||
220 | efi_memory_desc_t *md; | ||
221 | void *p; | ||
222 | |||
223 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { | ||
224 | md = p; | ||
225 | if (!is_available_memory(md)) | ||
226 | continue; | ||
227 | addr = (md->phys_addr+PAGE_SIZE-1) >> PAGE_SHIFT; | ||
228 | end = (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) >> PAGE_SHIFT; | ||
229 | |||
230 | if ((pagenr >= addr) && (pagenr < end)) | ||
231 | return 1; | ||
232 | } | ||
233 | return 0; | ||
234 | } | ||
235 | |||
236 | for (i = 0; i < e820.nr_map; i++) { | 218 | for (i = 0; i < e820.nr_map; i++) { |
237 | 219 | ||
238 | if (e820.map[i].type != E820_RAM) /* not usable memory */ | 220 | if (e820.map[i].type != E820_RAM) /* not usable memory */ |