Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v5.1-rc3 281 lines 7.1 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Extensible Firmware Interface 4 * 5 * Based on Extensible Firmware Interface Specification version 2.4 6 * 7 * Copyright (C) 2013 - 2015 Linaro Ltd. 8 */ 9 10#define pr_fmt(fmt) "efi: " fmt 11 12#include <linux/efi.h> 13#include <linux/init.h> 14#include <linux/memblock.h> 15#include <linux/mm_types.h> 16#include <linux/of.h> 17#include <linux/of_fdt.h> 18#include <linux/platform_device.h> 19#include <linux/screen_info.h> 20 21#include <asm/efi.h> 22 23u64 efi_system_table; 24 25static int __init is_memory(efi_memory_desc_t *md) 26{ 27 if (md->attribute & (EFI_MEMORY_WB|EFI_MEMORY_WT|EFI_MEMORY_WC)) 28 return 1; 29 return 0; 30} 31 32/* 33 * Translate a EFI virtual address into a physical address: this is necessary, 34 * as some data members of the EFI system table are virtually remapped after 35 * SetVirtualAddressMap() has been called. 36 */ 37static phys_addr_t efi_to_phys(unsigned long addr) 38{ 39 efi_memory_desc_t *md; 40 41 for_each_efi_memory_desc(md) { 42 if (!(md->attribute & EFI_MEMORY_RUNTIME)) 43 continue; 44 if (md->virt_addr == 0) 45 /* no virtual mapping has been installed by the stub */ 46 break; 47 if (md->virt_addr <= addr && 48 (addr - md->virt_addr) < (md->num_pages << EFI_PAGE_SHIFT)) 49 return md->phys_addr + addr - md->virt_addr; 50 } 51 return addr; 52} 53 54static __initdata unsigned long screen_info_table = EFI_INVALID_TABLE_ADDR; 55 56static __initdata efi_config_table_type_t arch_tables[] = { 57 {LINUX_EFI_ARM_SCREEN_INFO_TABLE_GUID, NULL, &screen_info_table}, 58 {NULL_GUID, NULL, NULL} 59}; 60 61static void __init init_screen_info(void) 62{ 63 struct screen_info *si; 64 65 if (screen_info_table != EFI_INVALID_TABLE_ADDR) { 66 si = early_memremap_ro(screen_info_table, sizeof(*si)); 67 if (!si) { 68 pr_err("Could not map screen_info config table\n"); 69 return; 70 } 71 screen_info = *si; 72 early_memunmap(si, sizeof(*si)); 73 74 /* dummycon on ARM needs non-zero values for columns/lines */ 75 screen_info.orig_video_cols = 80; 76 screen_info.orig_video_lines = 25; 77 } 78 79 if (screen_info.orig_video_isVGA == VIDEO_TYPE_EFI && 80 memblock_is_map_memory(screen_info.lfb_base)) 81 memblock_mark_nomap(screen_info.lfb_base, screen_info.lfb_size); 82} 83 84static int __init uefi_init(void) 85{ 86 efi_char16_t *c16; 87 void *config_tables; 88 size_t table_size; 89 char vendor[100] = "unknown"; 90 int i, retval; 91 92 efi.systab = early_memremap_ro(efi_system_table, 93 sizeof(efi_system_table_t)); 94 if (efi.systab == NULL) { 95 pr_warn("Unable to map EFI system table.\n"); 96 return -ENOMEM; 97 } 98 99 set_bit(EFI_BOOT, &efi.flags); 100 if (IS_ENABLED(CONFIG_64BIT)) 101 set_bit(EFI_64BIT, &efi.flags); 102 103 /* 104 * Verify the EFI Table 105 */ 106 if (efi.systab->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) { 107 pr_err("System table signature incorrect\n"); 108 retval = -EINVAL; 109 goto out; 110 } 111 if ((efi.systab->hdr.revision >> 16) < 2) 112 pr_warn("Warning: EFI system table version %d.%02d, expected 2.00 or greater\n", 113 efi.systab->hdr.revision >> 16, 114 efi.systab->hdr.revision & 0xffff); 115 116 efi.runtime_version = efi.systab->hdr.revision; 117 118 /* Show what we know for posterity */ 119 c16 = early_memremap_ro(efi_to_phys(efi.systab->fw_vendor), 120 sizeof(vendor) * sizeof(efi_char16_t)); 121 if (c16) { 122 for (i = 0; i < (int) sizeof(vendor) - 1 && *c16; ++i) 123 vendor[i] = c16[i]; 124 vendor[i] = '\0'; 125 early_memunmap(c16, sizeof(vendor) * sizeof(efi_char16_t)); 126 } 127 128 pr_info("EFI v%u.%.02u by %s\n", 129 efi.systab->hdr.revision >> 16, 130 efi.systab->hdr.revision & 0xffff, vendor); 131 132 table_size = sizeof(efi_config_table_64_t) * efi.systab->nr_tables; 133 config_tables = early_memremap_ro(efi_to_phys(efi.systab->tables), 134 table_size); 135 if (config_tables == NULL) { 136 pr_warn("Unable to map EFI config table array.\n"); 137 retval = -ENOMEM; 138 goto out; 139 } 140 retval = efi_config_parse_tables(config_tables, efi.systab->nr_tables, 141 sizeof(efi_config_table_t), 142 arch_tables); 143 144 if (!retval) 145 efi.config_table = (unsigned long)efi.systab->tables; 146 147 early_memunmap(config_tables, table_size); 148out: 149 early_memunmap(efi.systab, sizeof(efi_system_table_t)); 150 return retval; 151} 152 153/* 154 * Return true for regions that can be used as System RAM. 155 */ 156static __init int is_usable_memory(efi_memory_desc_t *md) 157{ 158 switch (md->type) { 159 case EFI_LOADER_CODE: 160 case EFI_LOADER_DATA: 161 case EFI_ACPI_RECLAIM_MEMORY: 162 case EFI_BOOT_SERVICES_CODE: 163 case EFI_BOOT_SERVICES_DATA: 164 case EFI_CONVENTIONAL_MEMORY: 165 case EFI_PERSISTENT_MEMORY: 166 /* 167 * According to the spec, these regions are no longer reserved 168 * after calling ExitBootServices(). However, we can only use 169 * them as System RAM if they can be mapped writeback cacheable. 170 */ 171 return (md->attribute & EFI_MEMORY_WB); 172 default: 173 break; 174 } 175 return false; 176} 177 178static __init void reserve_regions(void) 179{ 180 efi_memory_desc_t *md; 181 u64 paddr, npages, size; 182 183 if (efi_enabled(EFI_DBG)) 184 pr_info("Processing EFI memory map:\n"); 185 186 /* 187 * Discard memblocks discovered so far: if there are any at this 188 * point, they originate from memory nodes in the DT, and UEFI 189 * uses its own memory map instead. 190 */ 191 memblock_dump_all(); 192 memblock_remove(0, PHYS_ADDR_MAX); 193 194 for_each_efi_memory_desc(md) { 195 paddr = md->phys_addr; 196 npages = md->num_pages; 197 198 if (efi_enabled(EFI_DBG)) { 199 char buf[64]; 200 201 pr_info(" 0x%012llx-0x%012llx %s\n", 202 paddr, paddr + (npages << EFI_PAGE_SHIFT) - 1, 203 efi_md_typeattr_format(buf, sizeof(buf), md)); 204 } 205 206 memrange_efi_to_native(&paddr, &npages); 207 size = npages << PAGE_SHIFT; 208 209 if (is_memory(md)) { 210 early_init_dt_add_memory_arch(paddr, size); 211 212 if (!is_usable_memory(md)) 213 memblock_mark_nomap(paddr, size); 214 215 /* keep ACPI reclaim memory intact for kexec etc. */ 216 if (md->type == EFI_ACPI_RECLAIM_MEMORY) 217 memblock_reserve(paddr, size); 218 } 219 } 220} 221 222void __init efi_init(void) 223{ 224 struct efi_memory_map_data data; 225 struct efi_fdt_params params; 226 227 /* Grab UEFI information placed in FDT by stub */ 228 if (!efi_get_fdt_params(&params)) 229 return; 230 231 efi_system_table = params.system_table; 232 233 data.desc_version = params.desc_ver; 234 data.desc_size = params.desc_size; 235 data.size = params.mmap_size; 236 data.phys_map = params.mmap; 237 238 if (efi_memmap_init_early(&data) < 0) { 239 /* 240 * If we are booting via UEFI, the UEFI memory map is the only 241 * description of memory we have, so there is little point in 242 * proceeding if we cannot access it. 243 */ 244 panic("Unable to map EFI memory map.\n"); 245 } 246 247 WARN(efi.memmap.desc_version != 1, 248 "Unexpected EFI_MEMORY_DESCRIPTOR version %ld", 249 efi.memmap.desc_version); 250 251 if (uefi_init() < 0) { 252 efi_memmap_unmap(); 253 return; 254 } 255 256 reserve_regions(); 257 efi_esrt_init(); 258 259 memblock_reserve(params.mmap & PAGE_MASK, 260 PAGE_ALIGN(params.mmap_size + 261 (params.mmap & ~PAGE_MASK))); 262 263 init_screen_info(); 264 265 /* ARM does not permit early mappings to persist across paging_init() */ 266 if (IS_ENABLED(CONFIG_ARM)) 267 efi_memmap_unmap(); 268} 269 270static int __init register_gop_device(void) 271{ 272 void *pd; 273 274 if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI) 275 return 0; 276 277 pd = platform_device_register_data(NULL, "efi-framebuffer", 0, 278 &screen_info, sizeof(screen_info)); 279 return PTR_ERR_OR_ZERO(pd); 280} 281subsys_initcall(register_gop_device);