diff options
-rw-r--r-- | arch/i386/kernel/efi.c | 101 | ||||
-rw-r--r-- | arch/i386/kernel/setup.c | 14 | ||||
-rw-r--r-- | arch/i386/mm/init.c | 5 | ||||
-rw-r--r-- | include/asm-i386/setup.h | 2 | ||||
-rw-r--r-- | include/linux/efi.h | 14 |
5 files changed, 67 insertions, 69 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 |
245 | static void __init print_efi_memmap(void) | 245 | static 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 | ||
444 | static 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, | |||
613 | u32 efi_mem_type(unsigned long phys_addr) | 612 | u32 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) | |||
627 | u64 efi_mem_attributes(unsigned long phys_addr) | 626 | u64 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; |
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index af4de58cab54..9adbf710ec8d 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c | |||
@@ -370,12 +370,16 @@ static void __init limit_regions(unsigned long long size) | |||
370 | int i; | 370 | int i; |
371 | 371 | ||
372 | if (efi_enabled) { | 372 | if (efi_enabled) { |
373 | for (i = 0; i < memmap.nr_map; i++) { | 373 | efi_memory_desc_t *md; |
374 | current_addr = memmap.map[i].phys_addr + | 374 | void *p; |
375 | (memmap.map[i].num_pages << 12); | 375 | |
376 | if (memmap.map[i].type == EFI_CONVENTIONAL_MEMORY) { | 376 | for (p = memmap.map, i = 0; p < memmap.map_end; |
377 | p += memmap.desc_size, i++) { | ||
378 | md = p; | ||
379 | current_addr = md->phys_addr + (md->num_pages << 12); | ||
380 | if (md->type == EFI_CONVENTIONAL_MEMORY) { | ||
377 | if (current_addr >= size) { | 381 | if (current_addr >= size) { |
378 | memmap.map[i].num_pages -= | 382 | md->num_pages -= |
379 | (((current_addr-size) + PAGE_SIZE-1) >> PAGE_SHIFT); | 383 | (((current_addr-size) + PAGE_SIZE-1) >> PAGE_SHIFT); |
380 | memmap.nr_map = i + 1; | 384 | memmap.nr_map = i + 1; |
381 | return; | 385 | return; |
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index 12216b52e28b..d8b23ab76533 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c | |||
@@ -198,9 +198,10 @@ int page_is_ram(unsigned long pagenr) | |||
198 | 198 | ||
199 | if (efi_enabled) { | 199 | if (efi_enabled) { |
200 | efi_memory_desc_t *md; | 200 | efi_memory_desc_t *md; |
201 | void *p; | ||
201 | 202 | ||
202 | for (i = 0; i < memmap.nr_map; i++) { | 203 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { |
203 | md = &memmap.map[i]; | 204 | md = p; |
204 | if (!is_available_memory(md)) | 205 | if (!is_available_memory(md)) |
205 | continue; | 206 | continue; |
206 | addr = (md->phys_addr+PAGE_SIZE-1) >> PAGE_SHIFT; | 207 | addr = (md->phys_addr+PAGE_SIZE-1) >> PAGE_SHIFT; |
diff --git a/include/asm-i386/setup.h b/include/asm-i386/setup.h index 7a32184d54bf..826a8ca50ac8 100644 --- a/include/asm-i386/setup.h +++ b/include/asm-i386/setup.h | |||
@@ -44,7 +44,7 @@ extern unsigned char boot_params[PARAM_SIZE]; | |||
44 | #define EFI_SYSTAB ((efi_system_table_t *) *((unsigned long *)(PARAM+0x1c4))) | 44 | #define EFI_SYSTAB ((efi_system_table_t *) *((unsigned long *)(PARAM+0x1c4))) |
45 | #define EFI_MEMDESC_SIZE (*((unsigned long *) (PARAM+0x1c8))) | 45 | #define EFI_MEMDESC_SIZE (*((unsigned long *) (PARAM+0x1c8))) |
46 | #define EFI_MEMDESC_VERSION (*((unsigned long *) (PARAM+0x1cc))) | 46 | #define EFI_MEMDESC_VERSION (*((unsigned long *) (PARAM+0x1cc))) |
47 | #define EFI_MEMMAP ((efi_memory_desc_t *) *((unsigned long *)(PARAM+0x1d0))) | 47 | #define EFI_MEMMAP ((void *) *((unsigned long *)(PARAM+0x1d0))) |
48 | #define EFI_MEMMAP_SIZE (*((unsigned long *) (PARAM+0x1d4))) | 48 | #define EFI_MEMMAP_SIZE (*((unsigned long *) (PARAM+0x1d4))) |
49 | #define MOUNT_ROOT_RDONLY (*(unsigned short *) (PARAM+0x1F2)) | 49 | #define MOUNT_ROOT_RDONLY (*(unsigned short *) (PARAM+0x1F2)) |
50 | #define RAMDISK_FLAGS (*(unsigned short *) (PARAM+0x1F8)) | 50 | #define RAMDISK_FLAGS (*(unsigned short *) (PARAM+0x1F8)) |
diff --git a/include/linux/efi.h b/include/linux/efi.h index 73781ec165b4..c7c5dd316182 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h | |||
@@ -91,11 +91,6 @@ typedef struct { | |||
91 | 91 | ||
92 | #define EFI_PAGE_SHIFT 12 | 92 | #define EFI_PAGE_SHIFT 12 |
93 | 93 | ||
94 | /* | ||
95 | * For current x86 implementations of EFI, there is | ||
96 | * additional padding in the mem descriptors. This is not | ||
97 | * the case in ia64. Need to have this fixed in the f/w. | ||
98 | */ | ||
99 | typedef struct { | 94 | typedef struct { |
100 | u32 type; | 95 | u32 type; |
101 | u32 pad; | 96 | u32 pad; |
@@ -103,9 +98,6 @@ typedef struct { | |||
103 | u64 virt_addr; | 98 | u64 virt_addr; |
104 | u64 num_pages; | 99 | u64 num_pages; |
105 | u64 attribute; | 100 | u64 attribute; |
106 | #if defined (__i386__) | ||
107 | u64 pad1; | ||
108 | #endif | ||
109 | } efi_memory_desc_t; | 101 | } efi_memory_desc_t; |
110 | 102 | ||
111 | typedef int (*efi_freemem_callback_t) (unsigned long start, unsigned long end, void *arg); | 103 | typedef int (*efi_freemem_callback_t) (unsigned long start, unsigned long end, void *arg); |
@@ -240,10 +232,12 @@ typedef struct { | |||
240 | } efi_system_table_t; | 232 | } efi_system_table_t; |
241 | 233 | ||
242 | struct efi_memory_map { | 234 | struct efi_memory_map { |
243 | efi_memory_desc_t *phys_map; | 235 | void *phys_map; |
244 | efi_memory_desc_t *map; | 236 | void *map; |
237 | void *map_end; | ||
245 | int nr_map; | 238 | int nr_map; |
246 | unsigned long desc_version; | 239 | unsigned long desc_version; |
240 | unsigned long desc_size; | ||
247 | }; | 241 | }; |
248 | 242 | ||
249 | /* | 243 | /* |