aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHuang, Ying <ying.huang@intel.com>2008-01-30 07:31:19 -0500
committerIngo Molnar <mingo@elte.hu>2008-01-30 07:31:19 -0500
commit2215e69d2cf5024647f9a034807990590d25dd4e (patch)
tree89b82b38e515d6e540420347151472d78adc8a51
parente429795c68d3001ecae74f6465420c9f043b0ece (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>
-rw-r--r--arch/x86/kernel/e820_32.c117
-rw-r--r--arch/x86/kernel/efi_32.c150
-rw-r--r--arch/x86/kernel/setup_32.c16
-rw-r--r--arch/x86/mm/init_32.c18
-rw-r--r--include/asm-x86/e820_32.h2
5 files changed, 16 insertions, 287 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 */
184void __init legacy_init_iomem_resources(struct resource *code_resource, 183void __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 */
494static int __init
495efi_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
507static int __init
508efi_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 */
517void __init find_max_pfn(void) 491void __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
548static int __init
549free_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 */
564void __init register_bootmem_low_pages(unsigned long max_low_pfn) 515void __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
679static __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
719void __init limit_regions(unsigned long long size) 626void __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
128int 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 */
163void 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
210void __init
211efi_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 */
diff --git a/include/asm-x86/e820_32.h b/include/asm-x86/e820_32.h
index ae5ea19623fa..e2faf5f3a0bb 100644
--- a/include/asm-x86/e820_32.h
+++ b/include/asm-x86/e820_32.h
@@ -28,7 +28,7 @@ extern void register_bootmem_low_pages(unsigned long max_low_pfn);
28extern void e820_register_memory(void); 28extern void e820_register_memory(void);
29extern void limit_regions(unsigned long long size); 29extern void limit_regions(unsigned long long size);
30extern void print_memory_map(char *who); 30extern void print_memory_map(char *who);
31extern void legacy_init_iomem_resources(struct resource *code_resource, 31extern void init_iomem_resources(struct resource *code_resource,
32 struct resource *data_resource, 32 struct resource *data_resource,
33 struct resource *bss_resource); 33 struct resource *bss_resource);
34 34