diff options
| author | Leif Lindholm <leif.lindholm@linaro.org> | 2013-09-05 06:34:55 -0400 |
|---|---|---|
| committer | Matt Fleming <matt.fleming@intel.com> | 2013-09-05 08:29:29 -0400 |
| commit | 258f6fd738221766b512cd8c7120563b78d62829 (patch) | |
| tree | f2796181d313ef0cb9f0d516fd6a63e910d8b9a7 | |
| parent | 272686bf46a34f86d270cf192f68769667792026 (diff) | |
efi: x86: make efi_lookup_mapped_addr() a common function
efi_lookup_mapped_addr() is a handy utility for other platforms than
x86. Move it from arch/x86 to drivers/firmware. Add memmap pointer
to global efi structure, and initialise it on x86.
Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
| -rw-r--r-- | arch/x86/platform/efi/efi.c | 30 | ||||
| -rw-r--r-- | drivers/firmware/efi/efi.c | 32 | ||||
| -rw-r--r-- | include/linux/efi.h | 1 |
3 files changed, 35 insertions, 28 deletions
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index ed2be58ea3f1..fbc1d70188f8 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c | |||
| @@ -393,6 +393,8 @@ int __init efi_memblock_x86_reserve_range(void) | |||
| 393 | 393 | ||
| 394 | memblock_reserve(pmap, memmap.nr_map * memmap.desc_size); | 394 | memblock_reserve(pmap, memmap.nr_map * memmap.desc_size); |
| 395 | 395 | ||
| 396 | efi.memmap = &memmap; | ||
| 397 | |||
| 396 | return 0; | 398 | return 0; |
| 397 | } | 399 | } |
| 398 | 400 | ||
| @@ -736,34 +738,6 @@ static void __init runtime_code_page_mkexec(void) | |||
| 736 | } | 738 | } |
| 737 | } | 739 | } |
| 738 | 740 | ||
| 739 | /* | ||
| 740 | * We can't ioremap data in EFI boot services RAM, because we've already mapped | ||
| 741 | * it as RAM. So, look it up in the existing EFI memory map instead. Only | ||
| 742 | * callable after efi_enter_virtual_mode and before efi_free_boot_services. | ||
| 743 | */ | ||
| 744 | void __iomem *efi_lookup_mapped_addr(u64 phys_addr) | ||
| 745 | { | ||
| 746 | void *p; | ||
| 747 | if (WARN_ON(!memmap.map)) | ||
| 748 | return NULL; | ||
| 749 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { | ||
| 750 | efi_memory_desc_t *md = p; | ||
| 751 | u64 size = md->num_pages << EFI_PAGE_SHIFT; | ||
| 752 | u64 end = md->phys_addr + size; | ||
| 753 | if (!(md->attribute & EFI_MEMORY_RUNTIME) && | ||
| 754 | md->type != EFI_BOOT_SERVICES_CODE && | ||
| 755 | md->type != EFI_BOOT_SERVICES_DATA) | ||
| 756 | continue; | ||
| 757 | if (!md->virt_addr) | ||
| 758 | continue; | ||
| 759 | if (phys_addr >= md->phys_addr && phys_addr < end) { | ||
| 760 | phys_addr += md->virt_addr - md->phys_addr; | ||
| 761 | return (__force void __iomem *)(unsigned long)phys_addr; | ||
| 762 | } | ||
| 763 | } | ||
| 764 | return NULL; | ||
| 765 | } | ||
| 766 | |||
| 767 | void efi_memory_uc(u64 addr, unsigned long size) | 741 | void efi_memory_uc(u64 addr, unsigned long size) |
| 768 | { | 742 | { |
| 769 | unsigned long page_shift = 1UL << EFI_PAGE_SHIFT; | 743 | unsigned long page_shift = 1UL << EFI_PAGE_SHIFT; |
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index e1010d450b65..2e2fbdec0845 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c | |||
| @@ -150,6 +150,38 @@ err_put: | |||
| 150 | subsys_initcall(efisubsys_init); | 150 | subsys_initcall(efisubsys_init); |
| 151 | 151 | ||
| 152 | 152 | ||
| 153 | /* | ||
| 154 | * We can't ioremap data in EFI boot services RAM, because we've already mapped | ||
| 155 | * it as RAM. So, look it up in the existing EFI memory map instead. Only | ||
| 156 | * callable after efi_enter_virtual_mode and before efi_free_boot_services. | ||
| 157 | */ | ||
| 158 | void __iomem *efi_lookup_mapped_addr(u64 phys_addr) | ||
| 159 | { | ||
| 160 | struct efi_memory_map *map; | ||
| 161 | void *p; | ||
| 162 | map = efi.memmap; | ||
| 163 | if (!map) | ||
| 164 | return NULL; | ||
| 165 | if (WARN_ON(!map->map)) | ||
| 166 | return NULL; | ||
| 167 | for (p = map->map; p < map->map_end; p += map->desc_size) { | ||
| 168 | efi_memory_desc_t *md = p; | ||
| 169 | u64 size = md->num_pages << EFI_PAGE_SHIFT; | ||
| 170 | u64 end = md->phys_addr + size; | ||
| 171 | if (!(md->attribute & EFI_MEMORY_RUNTIME) && | ||
| 172 | md->type != EFI_BOOT_SERVICES_CODE && | ||
| 173 | md->type != EFI_BOOT_SERVICES_DATA) | ||
| 174 | continue; | ||
| 175 | if (!md->virt_addr) | ||
| 176 | continue; | ||
| 177 | if (phys_addr >= md->phys_addr && phys_addr < end) { | ||
| 178 | phys_addr += md->virt_addr - md->phys_addr; | ||
| 179 | return (__force void __iomem *)(unsigned long)phys_addr; | ||
| 180 | } | ||
| 181 | } | ||
| 182 | return NULL; | ||
| 183 | } | ||
| 184 | |||
| 153 | static __initdata efi_config_table_type_t common_tables[] = { | 185 | static __initdata efi_config_table_type_t common_tables[] = { |
| 154 | {ACPI_20_TABLE_GUID, "ACPI 2.0", &efi.acpi20}, | 186 | {ACPI_20_TABLE_GUID, "ACPI 2.0", &efi.acpi20}, |
| 155 | {ACPI_TABLE_GUID, "ACPI", &efi.acpi}, | 187 | {ACPI_TABLE_GUID, "ACPI", &efi.acpi}, |
diff --git a/include/linux/efi.h b/include/linux/efi.h index 09d9e4212799..c084b6d942c3 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h | |||
| @@ -558,6 +558,7 @@ extern struct efi { | |||
| 558 | efi_get_next_high_mono_count_t *get_next_high_mono_count; | 558 | efi_get_next_high_mono_count_t *get_next_high_mono_count; |
| 559 | efi_reset_system_t *reset_system; | 559 | efi_reset_system_t *reset_system; |
| 560 | efi_set_virtual_address_map_t *set_virtual_address_map; | 560 | efi_set_virtual_address_map_t *set_virtual_address_map; |
| 561 | struct efi_memory_map *memmap; | ||
| 561 | } efi; | 562 | } efi; |
| 562 | 563 | ||
| 563 | static inline int | 564 | static inline int |
