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.8-rc7 271 lines 6.9 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_normal_ram(efi_memory_desc_t *md) 30{ 31 if (md->attribute & EFI_MEMORY_WB) 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 RAM regions we want to permanently reserve. 156 */ 157static __init int is_reserve_region(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 return 0; 167 default: 168 break; 169 } 170 return is_normal_ram(md); 171} 172 173static __init void reserve_regions(void) 174{ 175 efi_memory_desc_t *md; 176 u64 paddr, npages, size; 177 int resv; 178 179 if (efi_enabled(EFI_DBG)) 180 pr_info("Processing EFI memory map:\n"); 181 182 /* 183 * Discard memblocks discovered so far: if there are any at this 184 * point, they originate from memory nodes in the DT, and UEFI 185 * uses its own memory map instead. 186 */ 187 memblock_dump_all(); 188 memblock_remove(0, (phys_addr_t)ULLONG_MAX); 189 190 for_each_efi_memory_desc(md) { 191 paddr = md->phys_addr; 192 npages = md->num_pages; 193 194 resv = is_reserve_region(md); 195 if (efi_enabled(EFI_DBG)) { 196 char buf[64]; 197 198 pr_info(" 0x%012llx-0x%012llx %s%s\n", 199 paddr, paddr + (npages << EFI_PAGE_SHIFT) - 1, 200 efi_md_typeattr_format(buf, sizeof(buf), md), 201 resv ? "*" : ""); 202 } 203 204 memrange_efi_to_native(&paddr, &npages); 205 size = npages << PAGE_SHIFT; 206 207 if (is_normal_ram(md)) 208 early_init_dt_add_memory_arch(paddr, size); 209 210 if (resv) 211 memblock_mark_nomap(paddr, size); 212 213 } 214 215 set_bit(EFI_MEMMAP, &efi.flags); 216} 217 218void __init efi_init(void) 219{ 220 struct efi_fdt_params params; 221 222 /* Grab UEFI information placed in FDT by stub */ 223 if (!efi_get_fdt_params(&params)) 224 return; 225 226 efi_system_table = params.system_table; 227 228 efi.memmap.phys_map = params.mmap; 229 efi.memmap.map = early_memremap_ro(params.mmap, params.mmap_size); 230 if (efi.memmap.map == NULL) { 231 /* 232 * If we are booting via UEFI, the UEFI memory map is the only 233 * description of memory we have, so there is little point in 234 * proceeding if we cannot access it. 235 */ 236 panic("Unable to map EFI memory map.\n"); 237 } 238 efi.memmap.map_end = efi.memmap.map + params.mmap_size; 239 efi.memmap.desc_size = params.desc_size; 240 efi.memmap.desc_version = params.desc_ver; 241 242 WARN(efi.memmap.desc_version != 1, 243 "Unexpected EFI_MEMORY_DESCRIPTOR version %ld", 244 efi.memmap.desc_version); 245 246 if (uefi_init() < 0) 247 return; 248 249 reserve_regions(); 250 efi_memattr_init(); 251 early_memunmap(efi.memmap.map, params.mmap_size); 252 253 memblock_reserve(params.mmap & PAGE_MASK, 254 PAGE_ALIGN(params.mmap_size + 255 (params.mmap & ~PAGE_MASK))); 256 257 init_screen_info(); 258} 259 260static int __init register_gop_device(void) 261{ 262 void *pd; 263 264 if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI) 265 return 0; 266 267 pd = platform_device_register_data(NULL, "efi-framebuffer", 0, 268 &screen_info, sizeof(screen_info)); 269 return PTR_ERR_OR_ZERO(pd); 270} 271subsys_initcall(register_gop_device);