|
@@ -150,6 +150,38 @@ err_put:
|
|
|
subsys_initcall(efisubsys_init);
|
|
|
|
|
|
|
|
|
+/*
|
|
|
+ * We can't ioremap data in EFI boot services RAM, because we've already mapped
|
|
|
+ * it as RAM. So, look it up in the existing EFI memory map instead. Only
|
|
|
+ * callable after efi_enter_virtual_mode and before efi_free_boot_services.
|
|
|
+ */
|
|
|
+void __iomem *efi_lookup_mapped_addr(u64 phys_addr)
|
|
|
+{
|
|
|
+ struct efi_memory_map *map;
|
|
|
+ void *p;
|
|
|
+ map = efi.memmap;
|
|
|
+ if (!map)
|
|
|
+ return NULL;
|
|
|
+ if (WARN_ON(!map->map))
|
|
|
+ return NULL;
|
|
|
+ for (p = map->map; p < map->map_end; p += map->desc_size) {
|
|
|
+ efi_memory_desc_t *md = p;
|
|
|
+ u64 size = md->num_pages << EFI_PAGE_SHIFT;
|
|
|
+ u64 end = md->phys_addr + size;
|
|
|
+ if (!(md->attribute & EFI_MEMORY_RUNTIME) &&
|
|
|
+ md->type != EFI_BOOT_SERVICES_CODE &&
|
|
|
+ md->type != EFI_BOOT_SERVICES_DATA)
|
|
|
+ continue;
|
|
|
+ if (!md->virt_addr)
|
|
|
+ continue;
|
|
|
+ if (phys_addr >= md->phys_addr && phys_addr < end) {
|
|
|
+ phys_addr += md->virt_addr - md->phys_addr;
|
|
|
+ return (__force void __iomem *)(unsigned long)phys_addr;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return NULL;
|
|
|
+}
|
|
|
+
|
|
|
static __initdata efi_config_table_type_t common_tables[] = {
|
|
|
{ACPI_20_TABLE_GUID, "ACPI 2.0", &efi.acpi20},
|
|
|
{ACPI_TABLE_GUID, "ACPI", &efi.acpi},
|