1 /* 2 * Extensible Firmware Interface 3 * 4 * Based on Extensible Firmware Interface Specification version 2.4 5 * 6 * Copyright (C) 2013, 2014 Linaro Ltd. 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 * 12 */ 13 14 #include <linux/dmi.h> 15 #include <linux/efi.h> 16 #include <linux/io.h> 17 #include <linux/memblock.h> 18 #include <linux/mm_types.h> 19 #include <linux/preempt.h> 20 #include <linux/rbtree.h> 21 #include <linux/rwsem.h> 22 #include <linux/sched.h> 23 #include <linux/slab.h> 24 #include <linux/spinlock.h> 25 26 #include <asm/cacheflush.h> 27 #include <asm/efi.h> 28 #include <asm/mmu.h> 29 #include <asm/pgalloc.h> 30 #include <asm/pgtable.h> 31 32 extern u64 efi_system_table; 33 34 #ifdef CONFIG_ARM64_PTDUMP_DEBUGFS 35 #include <asm/ptdump.h> 36 37 static struct ptdump_info efi_ptdump_info = { 38 .mm = &efi_mm, 39 .markers = (struct addr_marker[]){ 40 { 0, "UEFI runtime start" }, 41 { TASK_SIZE_64, "UEFI runtime end" } 42 }, 43 .base_addr = 0, 44 }; 45 46 static int __init ptdump_init(void) 47 { 48 if (!efi_enabled(EFI_RUNTIME_SERVICES)) 49 return 0; 50 51 return ptdump_debugfs_register(&efi_ptdump_info, "efi_page_tables"); 52 } 53 device_initcall(ptdump_init); 54 55 #endif 56 57 static bool __init efi_virtmap_init(void) 58 { 59 efi_memory_desc_t *md; 60 bool systab_found; 61 62 efi_mm.pgd = pgd_alloc(&efi_mm); 63 mm_init_cpumask(&efi_mm); 64 init_new_context(NULL, &efi_mm); 65 66 systab_found = false; 67 for_each_efi_memory_desc(md) { 68 phys_addr_t phys = md->phys_addr; 69 int ret; 70 71 if (!(md->attribute & EFI_MEMORY_RUNTIME)) 72 continue; 73 if (md->virt_addr == 0) 74 return false; 75 76 ret = efi_create_mapping(&efi_mm, md); 77 if (ret) { 78 pr_warn(" EFI remap %pa: failed to create mapping (%d)\n", 79 &phys, ret); 80 return false; 81 } 82 /* 83 * If this entry covers the address of the UEFI system table, 84 * calculate and record its virtual address. 85 */ 86 if (efi_system_table >= phys && 87 efi_system_table < phys + (md->num_pages * EFI_PAGE_SIZE)) { 88 efi.systab = (void *)(unsigned long)(efi_system_table - 89 phys + md->virt_addr); 90 systab_found = true; 91 } 92 } 93 if (!systab_found) { 94 pr_err("No virtual mapping found for the UEFI System Table\n"); 95 return false; 96 } 97 98 if (efi_memattr_apply_permissions(&efi_mm, efi_set_mapping_permissions)) 99 return false; 100 101 return true; 102 } 103 104 /* 105 * Enable the UEFI Runtime Services if all prerequisites are in place, i.e., 106 * non-early mapping of the UEFI system table and virtual mappings for all 107 * EFI_MEMORY_RUNTIME regions. 108 */ 109 static int __init arm_enable_runtime_services(void) 110 { 111 u64 mapsize; 112 113 if (!efi_enabled(EFI_BOOT) || !efi_enabled(EFI_MEMMAP)) { 114 pr_info("EFI services will not be available.\n"); 115 return 0; 116 } 117 118 efi_memmap_unmap(); 119 120 mapsize = efi.memmap.desc_size * efi.memmap.nr_map; 121 122 if (efi_memmap_init_late(efi.memmap.phys_map, mapsize)) { 123 pr_err("Failed to remap EFI memory map\n"); 124 return 0; 125 } 126 127 if (efi_runtime_disabled()) { 128 pr_info("EFI runtime services will be disabled.\n"); 129 return 0; 130 } 131 132 if (efi_enabled(EFI_RUNTIME_SERVICES)) { 133 pr_info("EFI runtime services access via paravirt.\n"); 134 return 0; 135 } 136 137 pr_info("Remapping and enabling EFI services.\n"); 138 139 if (!efi_virtmap_init()) { 140 pr_err("UEFI virtual mapping missing or invalid -- runtime services will not be available\n"); 141 return -ENOMEM; 142 } 143 144 /* Set up runtime services function pointers */ 145 efi_native_runtime_setup(); 146 set_bit(EFI_RUNTIME_SERVICES, &efi.flags); 147 148 return 0; 149 } 150 early_initcall(arm_enable_runtime_services); 151 152 void efi_virtmap_load(void) 153 { 154 preempt_disable(); 155 efi_set_pgd(&efi_mm); 156 } 157 158 void efi_virtmap_unload(void) 159 { 160 efi_set_pgd(current->active_mm); 161 preempt_enable(); 162 } 163 164 165 static int __init arm_dmi_init(void) 166 { 167 /* 168 * On arm64/ARM, DMI depends on UEFI, and dmi_scan_machine() needs to 169 * be called early because dmi_id_init(), which is an arch_initcall 170 * itself, depends on dmi_scan_machine() having been called already. 171 */ 172 dmi_scan_machine(); 173 if (dmi_available) 174 dmi_set_dump_stack_arch_desc(); 175 return 0; 176 } 177 core_initcall(arm_dmi_init); 178