From: Al Stone ahs3@redhat.com
Make efi_remap_regions() visible. This allows ARM to gain access to objects passed in RAM from EFI very early on -- as needed by ACPI and FDT, for example -- by allowing the use of this function in setup_arch(). Note that in the process of making this visible, some portions of the function had to be corrected in order to operate well with ACPI and/or FDT.
Signed-off-by: Al Stone al.stone@linaro.org --- arch/arm/include/asm/efi.h | 1 + arch/arm/kernel/efi.c | 31 +++++++++++++++++++++++-------- 2 files changed, 24 insertions(+), 8 deletions(-)
diff --git a/arch/arm/include/asm/efi.h b/arch/arm/include/asm/efi.h index aead94c..93fa002 100644 --- a/arch/arm/include/asm/efi.h +++ b/arch/arm/include/asm/efi.h @@ -4,6 +4,7 @@ #include <asm/mach/map.h>
extern int efi_memblock_arm_reserve_range(void); +extern void efi_remap_regions(void);
typedef efi_status_t efi_phys_call_t(u32 memory_map_size, u32 descriptor_size, diff --git a/arch/arm/kernel/efi.c b/arch/arm/kernel/efi.c index 11892b1..36e52f1 100644 --- a/arch/arm/kernel/efi.c +++ b/arch/arm/kernel/efi.c @@ -7,6 +7,7 @@ * */
+#include <linux/bootmem.h> #include <linux/efi.h> #include <linux/export.h> #include <linux/memblock.h> @@ -362,20 +363,21 @@ static int __init remap_region(efi_memory_desc_t *md, efi_memory_desc_t *entry) return 1; }
-static int __init remap_regions(void) +void __init efi_remap_regions(void) { void *p, *next; efi_memory_desc_t *md;
- memmap.phys_map = get_runtime_mmap(); + memmap.phys_map = efi_remap(virt_to_phys(memmap.phys_map), + efi_boot_mmap_size); if (!memmap.phys_map) - return 0; + return; memmap.map_end = (void *)memmap.phys_map + efi_boot_mmap_size;
/* Allocate space for the physical region map */ - memmap.map = kzalloc(memmap.nr_map * memmap.desc_size, GFP_KERNEL); + memmap.map = alloc_bootmem_align(memmap.nr_map * memmap.desc_size, 8); if (!memmap.map) - return 0; + return;
next = memmap.map; for (p = memmap.phys_map; p < memmap.map_end; p += memmap.desc_size) { @@ -384,7 +386,7 @@ static int __init remap_regions(void) continue;
if (!remap_region(p, next)) - return 0; + return;
next += memmap.desc_size; } @@ -401,7 +403,10 @@ static int __init remap_regions(void) */ runtime = efi_lookup_mapped_addr((u32)efi.systab->runtime);
- return 1; + initial_boot_params = efi_lookup_mapped_addr( + __virt_to_phys((long unsigned int)initial_boot_params)); + + efi_unmap(memmap.phys_map); }
@@ -441,6 +446,7 @@ efi_status_t __init phys_set_virtual_address_map(u32 memory_map_size, void __init efi_enter_virtual_mode(void) { efi_status_t status; + void *mmap;
if (!efi_enabled(EFI_BOOT)) { pr_info("EFI services will not be available.\n"); @@ -451,11 +457,20 @@ void __init efi_enter_virtual_mode(void)
/* Map the regions we memblock_remove:d earlier into kernel address space */ - if (!remap_regions()) { + if (!efi_enabled(EFI_SYSTEM_TABLES)) { pr_info("Failed to remap EFI regions - runtime services will not be available.\n"); return; }
+ mmap = kzalloc(memmap.nr_map * memmap.desc_size, GFP_KERNEL); + if (!mmap) { + pr_info("Failed to allocate EFI memory map.\n"); + return; + } + memcpy(mmap, memmap.map, memmap.nr_map * memmap.desc_size); + memmap.map = mmap; + memmap.phys_map = get_runtime_mmap(); + /* Call SetVirtualAddressMap with the physical address of the map */ efi.set_virtual_address_map = (efi_set_virtual_address_map_t *)