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 v4.12-rc5 274 lines 7.0 kB view raw
1/* 2 * Extensible Firmware Interface 3 * 4 * Based on Extensible Firmware Interface Specification version 2.4 5 * 6 * Copyright (C) 2013 - 2015 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#define pr_fmt(fmt) "efi: " fmt 15 16#include <linux/efi.h> 17#include <linux/init.h> 18#include <linux/memblock.h> 19#include <linux/mm_types.h> 20#include <linux/of.h> 21#include <linux/of_fdt.h> 22#include <linux/platform_device.h> 23#include <linux/screen_info.h> 24 25#include <asm/efi.h> 26 27u64 efi_system_table; 28 29static int __init is_memory(efi_memory_desc_t *md) 30{ 31 if (md->attribute & (EFI_MEMORY_WB|EFI_MEMORY_WT|EFI_MEMORY_WC)) 32 return 1; 33 return 0; 34} 35 36/* 37 * Translate a EFI virtual address into a physical address: this is necessary, 38 * as some data members of the EFI system table are virtually remapped after 39 * SetVirtualAddressMap() has been called. 40 */ 41static phys_addr_t efi_to_phys(unsigned long addr) 42{ 43 efi_memory_desc_t *md; 44 45 for_each_efi_memory_desc(md) { 46 if (!(md->attribute & EFI_MEMORY_RUNTIME)) 47 continue; 48 if (md->virt_addr == 0) 49 /* no virtual mapping has been installed by the stub */ 50 break; 51 if (md->virt_addr <= addr && 52 (addr - md->virt_addr) < (md->num_pages << EFI_PAGE_SHIFT)) 53 return md->phys_addr + addr - md->virt_addr; 54 } 55 return addr; 56} 57 58static __initdata unsigned long screen_info_table = EFI_INVALID_TABLE_ADDR; 59 60static __initdata efi_config_table_type_t arch_tables[] = { 61 {LINUX_EFI_ARM_SCREEN_INFO_TABLE_GUID, NULL, &screen_info_table}, 62 {NULL_GUID, NULL, NULL} 63}; 64 65static void __init init_screen_info(void) 66{ 67 struct screen_info *si; 68 69 if (screen_info_table != EFI_INVALID_TABLE_ADDR) { 70 si = early_memremap_ro(screen_info_table, sizeof(*si)); 71 if (!si) { 72 pr_err("Could not map screen_info config table\n"); 73 return; 74 } 75 screen_info = *si; 76 early_memunmap(si, sizeof(*si)); 77 78 /* dummycon on ARM needs non-zero values for columns/lines */ 79 screen_info.orig_video_cols = 80; 80 screen_info.orig_video_lines = 25; 81 } 82 83 if (screen_info.orig_video_isVGA == VIDEO_TYPE_EFI && 84 memblock_is_map_memory(screen_info.lfb_base)) 85 memblock_mark_nomap(screen_info.lfb_base, screen_info.lfb_size); 86} 87 88static int __init uefi_init(void) 89{ 90 efi_char16_t *c16; 91 void *config_tables; 92 size_t table_size; 93 char vendor[100] = "unknown"; 94 int i, retval; 95 96 efi.systab = early_memremap_ro(efi_system_table, 97 sizeof(efi_system_table_t)); 98 if (efi.systab == NULL) { 99 pr_warn("Unable to map EFI system table.\n"); 100 return -ENOMEM; 101 } 102 103 set_bit(EFI_BOOT, &efi.flags); 104 if (IS_ENABLED(CONFIG_64BIT)) 105 set_bit(EFI_64BIT, &efi.flags); 106 107 /* 108 * Verify the EFI Table 109 */ 110 if (efi.systab->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) { 111 pr_err("System table signature incorrect\n"); 112 retval = -EINVAL; 113 goto out; 114 } 115 if ((efi.systab->hdr.revision >> 16) < 2) 116 pr_warn("Warning: EFI system table version %d.%02d, expected 2.00 or greater\n", 117 efi.systab->hdr.revision >> 16, 118 efi.systab->hdr.revision & 0xffff); 119 120 efi.runtime_version = efi.systab->hdr.revision; 121 122 /* Show what we know for posterity */ 123 c16 = early_memremap_ro(efi_to_phys(efi.systab->fw_vendor), 124 sizeof(vendor) * sizeof(efi_char16_t)); 125 if (c16) { 126 for (i = 0; i < (int) sizeof(vendor) - 1 && *c16; ++i) 127 vendor[i] = c16[i]; 128 vendor[i] = '\0'; 129 early_memunmap(c16, sizeof(vendor) * sizeof(efi_char16_t)); 130 } 131 132 pr_info("EFI v%u.%.02u by %s\n", 133 efi.systab->hdr.revision >> 16, 134 efi.systab->hdr.revision & 0xffff, vendor); 135 136 table_size = sizeof(efi_config_table_64_t) * efi.systab->nr_tables; 137 config_tables = early_memremap_ro(efi_to_phys(efi.systab->tables), 138 table_size); 139 if (config_tables == NULL) { 140 pr_warn("Unable to map EFI config table array.\n"); 141 retval = -ENOMEM; 142 goto out; 143 } 144 retval = efi_config_parse_tables(config_tables, efi.systab->nr_tables, 145 sizeof(efi_config_table_t), 146 arch_tables); 147 148 early_memunmap(config_tables, table_size); 149out: 150 early_memunmap(efi.systab, sizeof(efi_system_table_t)); 151 return retval; 152} 153 154/* 155 * Return true for regions that can be used as System RAM. 156 */ 157static __init int is_usable_memory(efi_memory_desc_t *md) 158{ 159 switch (md->type) { 160 case EFI_LOADER_CODE: 161 case EFI_LOADER_DATA: 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_t)ULLONG_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 } 216} 217 218void __init efi_init(void) 219{ 220 struct efi_memory_map_data data; 221 struct efi_fdt_params params; 222 223 /* Grab UEFI information placed in FDT by stub */ 224 if (!efi_get_fdt_params(&params)) 225 return; 226 227 efi_system_table = params.system_table; 228 229 data.desc_version = params.desc_ver; 230 data.desc_size = params.desc_size; 231 data.size = params.mmap_size; 232 data.phys_map = params.mmap; 233 234 if (efi_memmap_init_early(&data) < 0) { 235 /* 236 * If we are booting via UEFI, the UEFI memory map is the only 237 * description of memory we have, so there is little point in 238 * proceeding if we cannot access it. 239 */ 240 panic("Unable to map EFI memory map.\n"); 241 } 242 243 WARN(efi.memmap.desc_version != 1, 244 "Unexpected EFI_MEMORY_DESCRIPTOR version %ld", 245 efi.memmap.desc_version); 246 247 if (uefi_init() < 0) { 248 efi_memmap_unmap(); 249 return; 250 } 251 252 reserve_regions(); 253 efi_esrt_init(); 254 efi_memmap_unmap(); 255 256 memblock_reserve(params.mmap & PAGE_MASK, 257 PAGE_ALIGN(params.mmap_size + 258 (params.mmap & ~PAGE_MASK))); 259 260 init_screen_info(); 261} 262 263static int __init register_gop_device(void) 264{ 265 void *pd; 266 267 if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI) 268 return 0; 269 270 pd = platform_device_register_data(NULL, "efi-framebuffer", 0, 271 &screen_info, sizeof(screen_info)); 272 return PTR_ERR_OR_ZERO(pd); 273} 274subsys_initcall(register_gop_device);