aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/efi.c
diff options
context:
space:
mode:
authorMatt Tolentino <metolent@snoqualmie.dp.intel.com>2005-09-03 18:56:27 -0400
committerLinus Torvalds <torvalds@evo.osdl.org>2005-09-05 03:06:09 -0400
commit7ae65fd334232468a9d6b523a4fc141cd6ec5ea4 (patch)
treecbc63abb55033d88f9a631741603a2a379bebee2 /arch/i386/kernel/efi.c
parent4116c527ea9517623369a5b3b037aedde280d672 (diff)
[PATCH] x86: fix EFI memory map parsing
The memory descriptors that comprise the EFI memory map are not fixed in stone such that the size could change in the future. This uses the memory descriptor size obtained from EFI to iterate over the memory map entries during boot. This enables the removal of an x86 specific pad (and ifdef) in the EFI header. I also couldn't stomach the broken up nature of the function to put EFI runtime calls into virtual mode any longer so I fixed that up a bit as well. For reference, this patch only impacts x86. Signed-off-by: Matt Tolentino <matthew.e.tolentino@intel.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/i386/kernel/efi.c')
-rw-r--r--arch/i386/kernel/efi.c101
1 files changed, 50 insertions, 51 deletions
diff --git a/arch/i386/kernel/efi.c b/arch/i386/kernel/efi.c
index 385883ea8c19..850648ae8305 100644
--- a/arch/i386/kernel/efi.c
+++ b/arch/i386/kernel/efi.c
@@ -233,22 +233,23 @@ void __init efi_map_memmap(void)
233{ 233{
234 memmap.map = NULL; 234 memmap.map = NULL;
235 235
236 memmap.map = (efi_memory_desc_t *) 236 memmap.map = bt_ioremap((unsigned long) memmap.phys_map,
237 bt_ioremap((unsigned long) memmap.phys_map, 237 (memmap.nr_map * memmap.desc_size));
238 (memmap.nr_map * sizeof(efi_memory_desc_t)));
239
240 if (memmap.map == NULL) 238 if (memmap.map == NULL)
241 printk(KERN_ERR PFX "Could not remap the EFI memmap!\n"); 239 printk(KERN_ERR PFX "Could not remap the EFI memmap!\n");
240
241 memmap.map_end = memmap.map + (memmap.nr_map * memmap.desc_size);
242} 242}
243 243
244#if EFI_DEBUG 244#if EFI_DEBUG
245static void __init print_efi_memmap(void) 245static void __init print_efi_memmap(void)
246{ 246{
247 efi_memory_desc_t *md; 247 efi_memory_desc_t *md;
248 void *p;
248 int i; 249 int i;
249 250
250 for (i = 0; i < memmap.nr_map; i++) { 251 for (p = memmap.map, i = 0; p < memmap.map_end; p += memmap.desc_size, i++) {
251 md = &memmap.map[i]; 252 md = p;
252 printk(KERN_INFO "mem%02u: type=%u, attr=0x%llx, " 253 printk(KERN_INFO "mem%02u: type=%u, attr=0x%llx, "
253 "range=[0x%016llx-0x%016llx) (%lluMB)\n", 254 "range=[0x%016llx-0x%016llx) (%lluMB)\n",
254 i, md->type, md->attribute, md->phys_addr, 255 i, md->type, md->attribute, md->phys_addr,
@@ -271,10 +272,10 @@ void efi_memmap_walk(efi_freemem_callback_t callback, void *arg)
271 } prev, curr; 272 } prev, curr;
272 efi_memory_desc_t *md; 273 efi_memory_desc_t *md;
273 unsigned long start, end; 274 unsigned long start, end;
274 int i; 275 void *p;
275 276
276 for (i = 0; i < memmap.nr_map; i++) { 277 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
277 md = &memmap.map[i]; 278 md = p;
278 279
279 if ((md->num_pages == 0) || (!is_available_memory(md))) 280 if ((md->num_pages == 0) || (!is_available_memory(md)))
280 continue; 281 continue;
@@ -325,6 +326,7 @@ void __init efi_init(void)
325 memmap.phys_map = EFI_MEMMAP; 326 memmap.phys_map = EFI_MEMMAP;
326 memmap.nr_map = EFI_MEMMAP_SIZE/EFI_MEMDESC_SIZE; 327 memmap.nr_map = EFI_MEMMAP_SIZE/EFI_MEMDESC_SIZE;
327 memmap.desc_version = EFI_MEMDESC_VERSION; 328 memmap.desc_version = EFI_MEMDESC_VERSION;
329 memmap.desc_size = EFI_MEMDESC_SIZE;
328 330
329 efi.systab = (efi_system_table_t *) 331 efi.systab = (efi_system_table_t *)
330 boot_ioremap((unsigned long) efi_phys.systab, 332 boot_ioremap((unsigned long) efi_phys.systab,
@@ -428,22 +430,30 @@ void __init efi_init(void)
428 printk(KERN_ERR PFX "Could not map the runtime service table!\n"); 430 printk(KERN_ERR PFX "Could not map the runtime service table!\n");
429 431
430 /* Map the EFI memory map for use until paging_init() */ 432 /* Map the EFI memory map for use until paging_init() */
431 433 memmap.map = boot_ioremap((unsigned long) EFI_MEMMAP, EFI_MEMMAP_SIZE);
432 memmap.map = (efi_memory_desc_t *)
433 boot_ioremap((unsigned long) EFI_MEMMAP, EFI_MEMMAP_SIZE);
434
435 if (memmap.map == NULL) 434 if (memmap.map == NULL)
436 printk(KERN_ERR PFX "Could not map the EFI memory map!\n"); 435 printk(KERN_ERR PFX "Could not map the EFI memory map!\n");
437 436
438 if (EFI_MEMDESC_SIZE != sizeof(efi_memory_desc_t)) { 437 memmap.map_end = memmap.map + (memmap.nr_map * memmap.desc_size);
439 printk(KERN_WARNING PFX "Warning! Kernel-defined memdesc doesn't " 438
440 "match the one from EFI!\n");
441 }
442#if EFI_DEBUG 439#if EFI_DEBUG
443 print_efi_memmap(); 440 print_efi_memmap();
444#endif 441#endif
445} 442}
446 443
444static inline void __init check_range_for_systab(efi_memory_desc_t *md)
445{
446 if (((unsigned long)md->phys_addr <= (unsigned long)efi_phys.systab) &&
447 ((unsigned long)efi_phys.systab < md->phys_addr +
448 ((unsigned long)md->num_pages << EFI_PAGE_SHIFT))) {
449 unsigned long addr;
450
451 addr = md->virt_addr - md->phys_addr +
452 (unsigned long)efi_phys.systab;
453 efi.systab = (efi_system_table_t *)addr;
454 }
455}
456
447/* 457/*
448 * This function will switch the EFI runtime services to virtual mode. 458 * This function will switch the EFI runtime services to virtual mode.
449 * Essentially, look through the EFI memmap and map every region that 459 * Essentially, look through the EFI memmap and map every region that
@@ -457,43 +467,32 @@ void __init efi_enter_virtual_mode(void)
457{ 467{
458 efi_memory_desc_t *md; 468 efi_memory_desc_t *md;
459 efi_status_t status; 469 efi_status_t status;
460 int i; 470 void *p;
461 471
462 efi.systab = NULL; 472 efi.systab = NULL;
463 473
464 for (i = 0; i < memmap.nr_map; i++) { 474 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
465 md = &memmap.map[i]; 475 md = p;
466 476
467 if (md->attribute & EFI_MEMORY_RUNTIME) { 477 if (!(md->attribute & EFI_MEMORY_RUNTIME))
468 md->virt_addr = 478 continue;
469 (unsigned long)ioremap(md->phys_addr,
470 md->num_pages << EFI_PAGE_SHIFT);
471 if (!(unsigned long)md->virt_addr) {
472 printk(KERN_ERR PFX "ioremap of 0x%lX failed\n",
473 (unsigned long)md->phys_addr);
474 }
475 479
476 if (((unsigned long)md->phys_addr <= 480 md->virt_addr = (unsigned long)ioremap(md->phys_addr,
477 (unsigned long)efi_phys.systab) && 481 md->num_pages << EFI_PAGE_SHIFT);
478 ((unsigned long)efi_phys.systab < 482 if (!(unsigned long)md->virt_addr) {
479 md->phys_addr + 483 printk(KERN_ERR PFX "ioremap of 0x%lX failed\n",
480 ((unsigned long)md->num_pages << 484 (unsigned long)md->phys_addr);
481 EFI_PAGE_SHIFT))) {
482 unsigned long addr;
483
484 addr = md->virt_addr - md->phys_addr +
485 (unsigned long)efi_phys.systab;
486 efi.systab = (efi_system_table_t *)addr;
487 }
488 } 485 }
486 /* update the virtual address of the EFI system table */
487 check_range_for_systab(md);
489 } 488 }
490 489
491 if (!efi.systab) 490 if (!efi.systab)
492 BUG(); 491 BUG();
493 492
494 status = phys_efi_set_virtual_address_map( 493 status = phys_efi_set_virtual_address_map(
495 sizeof(efi_memory_desc_t) * memmap.nr_map, 494 memmap.desc_size * memmap.nr_map,
496 sizeof(efi_memory_desc_t), 495 memmap.desc_size,
497 memmap.desc_version, 496 memmap.desc_version,
498 memmap.phys_map); 497 memmap.phys_map);
499 498
@@ -533,10 +532,10 @@ efi_initialize_iomem_resources(struct resource *code_resource,
533{ 532{
534 struct resource *res; 533 struct resource *res;
535 efi_memory_desc_t *md; 534 efi_memory_desc_t *md;
536 int i; 535 void *p;
537 536
538 for (i = 0; i < memmap.nr_map; i++) { 537 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
539 md = &memmap.map[i]; 538 md = p;
540 539
541 if ((md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) > 540 if ((md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) >
542 0x100000000ULL) 541 0x100000000ULL)
@@ -613,10 +612,10 @@ efi_initialize_iomem_resources(struct resource *code_resource,
613u32 efi_mem_type(unsigned long phys_addr) 612u32 efi_mem_type(unsigned long phys_addr)
614{ 613{
615 efi_memory_desc_t *md; 614 efi_memory_desc_t *md;
616 int i; 615 void *p;
617 616
618 for (i = 0; i < memmap.nr_map; i++) { 617 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
619 md = &memmap.map[i]; 618 md = p;
620 if ((md->phys_addr <= phys_addr) && (phys_addr < 619 if ((md->phys_addr <= phys_addr) && (phys_addr <
621 (md->phys_addr + (md-> num_pages << EFI_PAGE_SHIFT)) )) 620 (md->phys_addr + (md-> num_pages << EFI_PAGE_SHIFT)) ))
622 return md->type; 621 return md->type;
@@ -627,10 +626,10 @@ u32 efi_mem_type(unsigned long phys_addr)
627u64 efi_mem_attributes(unsigned long phys_addr) 626u64 efi_mem_attributes(unsigned long phys_addr)
628{ 627{
629 efi_memory_desc_t *md; 628 efi_memory_desc_t *md;
630 int i; 629 void *p;
631 630
632 for (i = 0; i < memmap.nr_map; i++) { 631 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
633 md = &memmap.map[i]; 632 md = p;
634 if ((md->phys_addr <= phys_addr) && (phys_addr < 633 if ((md->phys_addr <= phys_addr) && (phys_addr <
635 (md->phys_addr + (md-> num_pages << EFI_PAGE_SHIFT)) )) 634 (md->phys_addr + (md-> num_pages << EFI_PAGE_SHIFT)) ))
636 return md->attribute; 635 return md->attribute;