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 |