1 /* 2 * efi.c - EFI subsystem 3 * 4 * Copyright (C) 2001,2003,2004 Dell <Matt_Domsch@dell.com> 5 * Copyright (C) 2004 Intel Corporation <matthew.e.tolentino@intel.com> 6 * Copyright (C) 2013 Tom Gundersen <teg@jklm.no> 7 * 8 * This code registers /sys/firmware/efi{,/efivars} when EFI is supported, 9 * allowing the efivarfs to be mounted or the efivars module to be loaded. 10 * The existance of /sys/firmware/efi may also be used by userspace to 11 * determine that the system supports EFI. 12 * 13 * This file is released under the GPLv2. 14 */ 15 16 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 17 18 #include <linux/kobject.h> 19 #include <linux/module.h> 20 #include <linux/init.h> 21 #include <linux/device.h> 22 #include <linux/efi.h> 23 #include <linux/of.h> 24 #include <linux/of_fdt.h> 25 #include <linux/io.h> 26 27 struct efi __read_mostly efi = { 28 .mps = EFI_INVALID_TABLE_ADDR, 29 .acpi = EFI_INVALID_TABLE_ADDR, 30 .acpi20 = EFI_INVALID_TABLE_ADDR, 31 .smbios = EFI_INVALID_TABLE_ADDR, 32 .sal_systab = EFI_INVALID_TABLE_ADDR, 33 .boot_info = EFI_INVALID_TABLE_ADDR, 34 .hcdp = EFI_INVALID_TABLE_ADDR, 35 .uga = EFI_INVALID_TABLE_ADDR, 36 .uv_systab = EFI_INVALID_TABLE_ADDR, 37 .fw_vendor = EFI_INVALID_TABLE_ADDR, 38 .runtime = EFI_INVALID_TABLE_ADDR, 39 .config_table = EFI_INVALID_TABLE_ADDR, 40 }; 41 EXPORT_SYMBOL(efi); 42 43 static struct kobject *efi_kobj; 44 static struct kobject *efivars_kobj; 45 46 /* 47 * Let's not leave out systab information that snuck into 48 * the efivars driver 49 */ 50 static ssize_t systab_show(struct kobject *kobj, 51 struct kobj_attribute *attr, char *buf) 52 { 53 char *str = buf; 54 55 if (!kobj || !buf) 56 return -EINVAL; 57 58 if (efi.mps != EFI_INVALID_TABLE_ADDR) 59 str += sprintf(str, "MPS=0x%lx\n", efi.mps); 60 if (efi.acpi20 != EFI_INVALID_TABLE_ADDR) 61 str += sprintf(str, "ACPI20=0x%lx\n", efi.acpi20); 62 if (efi.acpi != EFI_INVALID_TABLE_ADDR) 63 str += sprintf(str, "ACPI=0x%lx\n", efi.acpi); 64 if (efi.smbios != EFI_INVALID_TABLE_ADDR) 65 str += sprintf(str, "SMBIOS=0x%lx\n", efi.smbios); 66 if (efi.hcdp != EFI_INVALID_TABLE_ADDR) 67 str += sprintf(str, "HCDP=0x%lx\n", efi.hcdp); 68 if (efi.boot_info != EFI_INVALID_TABLE_ADDR) 69 str += sprintf(str, "BOOTINFO=0x%lx\n", efi.boot_info); 70 if (efi.uga != EFI_INVALID_TABLE_ADDR) 71 str += sprintf(str, "UGA=0x%lx\n", efi.uga); 72 73 return str - buf; 74 } 75 76 static struct kobj_attribute efi_attr_systab = 77 __ATTR(systab, 0400, systab_show, NULL); 78 79 #define EFI_FIELD(var) efi.var 80 81 #define EFI_ATTR_SHOW(name) \ 82 static ssize_t name##_show(struct kobject *kobj, \ 83 struct kobj_attribute *attr, char *buf) \ 84 { \ 85 return sprintf(buf, "0x%lx\n", EFI_FIELD(name)); \ 86 } 87 88 EFI_ATTR_SHOW(fw_vendor); 89 EFI_ATTR_SHOW(runtime); 90 EFI_ATTR_SHOW(config_table); 91 92 static struct kobj_attribute efi_attr_fw_vendor = __ATTR_RO(fw_vendor); 93 static struct kobj_attribute efi_attr_runtime = __ATTR_RO(runtime); 94 static struct kobj_attribute efi_attr_config_table = __ATTR_RO(config_table); 95 96 static struct attribute *efi_subsys_attrs[] = { 97 &efi_attr_systab.attr, 98 &efi_attr_fw_vendor.attr, 99 &efi_attr_runtime.attr, 100 &efi_attr_config_table.attr, 101 NULL, 102 }; 103 104 static umode_t efi_attr_is_visible(struct kobject *kobj, 105 struct attribute *attr, int n) 106 { 107 umode_t mode = attr->mode; 108 109 if (attr == &efi_attr_fw_vendor.attr) 110 return (efi.fw_vendor == EFI_INVALID_TABLE_ADDR) ? 0 : mode; 111 else if (attr == &efi_attr_runtime.attr) 112 return (efi.runtime == EFI_INVALID_TABLE_ADDR) ? 0 : mode; 113 else if (attr == &efi_attr_config_table.attr) 114 return (efi.config_table == EFI_INVALID_TABLE_ADDR) ? 0 : mode; 115 116 return mode; 117 } 118 119 static struct attribute_group efi_subsys_attr_group = { 120 .attrs = efi_subsys_attrs, 121 .is_visible = efi_attr_is_visible, 122 }; 123 124 static struct efivars generic_efivars; 125 static struct efivar_operations generic_ops; 126 127 static int generic_ops_register(void) 128 { 129 generic_ops.get_variable = efi.get_variable; 130 generic_ops.set_variable = efi.set_variable; 131 generic_ops.get_next_variable = efi.get_next_variable; 132 generic_ops.query_variable_store = efi_query_variable_store; 133 134 return efivars_register(&generic_efivars, &generic_ops, efi_kobj); 135 } 136 137 static void generic_ops_unregister(void) 138 { 139 efivars_unregister(&generic_efivars); 140 } 141 142 /* 143 * We register the efi subsystem with the firmware subsystem and the 144 * efivars subsystem with the efi subsystem, if the system was booted with 145 * EFI. 146 */ 147 static int __init efisubsys_init(void) 148 { 149 int error; 150 151 if (!efi_enabled(EFI_BOOT)) 152 return 0; 153 154 /* We register the efi directory at /sys/firmware/efi */ 155 efi_kobj = kobject_create_and_add("efi", firmware_kobj); 156 if (!efi_kobj) { 157 pr_err("efi: Firmware registration failed.\n"); 158 return -ENOMEM; 159 } 160 161 error = generic_ops_register(); 162 if (error) 163 goto err_put; 164 165 error = sysfs_create_group(efi_kobj, &efi_subsys_attr_group); 166 if (error) { 167 pr_err("efi: Sysfs attribute export failed with error %d.\n", 168 error); 169 goto err_unregister; 170 } 171 172 error = efi_runtime_map_init(efi_kobj); 173 if (error) 174 goto err_remove_group; 175 176 /* and the standard mountpoint for efivarfs */ 177 efivars_kobj = kobject_create_and_add("efivars", efi_kobj); 178 if (!efivars_kobj) { 179 pr_err("efivars: Subsystem registration failed.\n"); 180 error = -ENOMEM; 181 goto err_remove_group; 182 } 183 184 return 0; 185 186 err_remove_group: 187 sysfs_remove_group(efi_kobj, &efi_subsys_attr_group); 188 err_unregister: 189 generic_ops_unregister(); 190 err_put: 191 kobject_put(efi_kobj); 192 return error; 193 } 194 195 subsys_initcall(efisubsys_init); 196 197 198 /* 199 * We can't ioremap data in EFI boot services RAM, because we've already mapped 200 * it as RAM. So, look it up in the existing EFI memory map instead. Only 201 * callable after efi_enter_virtual_mode and before efi_free_boot_services. 202 */ 203 void __iomem *efi_lookup_mapped_addr(u64 phys_addr) 204 { 205 struct efi_memory_map *map; 206 void *p; 207 map = efi.memmap; 208 if (!map) 209 return NULL; 210 if (WARN_ON(!map->map)) 211 return NULL; 212 for (p = map->map; p < map->map_end; p += map->desc_size) { 213 efi_memory_desc_t *md = p; 214 u64 size = md->num_pages << EFI_PAGE_SHIFT; 215 u64 end = md->phys_addr + size; 216 if (!(md->attribute & EFI_MEMORY_RUNTIME) && 217 md->type != EFI_BOOT_SERVICES_CODE && 218 md->type != EFI_BOOT_SERVICES_DATA) 219 continue; 220 if (!md->virt_addr) 221 continue; 222 if (phys_addr >= md->phys_addr && phys_addr < end) { 223 phys_addr += md->virt_addr - md->phys_addr; 224 return (__force void __iomem *)(unsigned long)phys_addr; 225 } 226 } 227 return NULL; 228 } 229 230 static __initdata efi_config_table_type_t common_tables[] = { 231 {ACPI_20_TABLE_GUID, "ACPI 2.0", &efi.acpi20}, 232 {ACPI_TABLE_GUID, "ACPI", &efi.acpi}, 233 {HCDP_TABLE_GUID, "HCDP", &efi.hcdp}, 234 {MPS_TABLE_GUID, "MPS", &efi.mps}, 235 {SAL_SYSTEM_TABLE_GUID, "SALsystab", &efi.sal_systab}, 236 {SMBIOS_TABLE_GUID, "SMBIOS", &efi.smbios}, 237 {UGA_IO_PROTOCOL_GUID, "UGA", &efi.uga}, 238 {NULL_GUID, NULL, NULL}, 239 }; 240 241 static __init int match_config_table(efi_guid_t *guid, 242 unsigned long table, 243 efi_config_table_type_t *table_types) 244 { 245 u8 str[EFI_VARIABLE_GUID_LEN + 1]; 246 int i; 247 248 if (table_types) { 249 efi_guid_unparse(guid, str); 250 251 for (i = 0; efi_guidcmp(table_types[i].guid, NULL_GUID); i++) { 252 efi_guid_unparse(&table_types[i].guid, str); 253 254 if (!efi_guidcmp(*guid, table_types[i].guid)) { 255 *(table_types[i].ptr) = table; 256 pr_cont(" %s=0x%lx ", 257 table_types[i].name, table); 258 return 1; 259 } 260 } 261 } 262 263 return 0; 264 } 265 266 int __init efi_config_init(efi_config_table_type_t *arch_tables) 267 { 268 void *config_tables, *tablep; 269 int i, sz; 270 271 if (efi_enabled(EFI_64BIT)) 272 sz = sizeof(efi_config_table_64_t); 273 else 274 sz = sizeof(efi_config_table_32_t); 275 276 /* 277 * Let's see what config tables the firmware passed to us. 278 */ 279 config_tables = early_memremap(efi.systab->tables, 280 efi.systab->nr_tables * sz); 281 if (config_tables == NULL) { 282 pr_err("Could not map Configuration table!\n"); 283 return -ENOMEM; 284 } 285 286 tablep = config_tables; 287 pr_info(""); 288 for (i = 0; i < efi.systab->nr_tables; i++) { 289 efi_guid_t guid; 290 unsigned long table; 291 292 if (efi_enabled(EFI_64BIT)) { 293 u64 table64; 294 guid = ((efi_config_table_64_t *)tablep)->guid; 295 table64 = ((efi_config_table_64_t *)tablep)->table; 296 table = table64; 297 #ifndef CONFIG_64BIT 298 if (table64 >> 32) { 299 pr_cont("\n"); 300 pr_err("Table located above 4GB, disabling EFI.\n"); 301 early_iounmap(config_tables, 302 efi.systab->nr_tables * sz); 303 return -EINVAL; 304 } 305 #endif 306 } else { 307 guid = ((efi_config_table_32_t *)tablep)->guid; 308 table = ((efi_config_table_32_t *)tablep)->table; 309 } 310 311 if (!match_config_table(&guid, table, common_tables)) 312 match_config_table(&guid, table, arch_tables); 313 314 tablep += sz; 315 } 316 pr_cont("\n"); 317 early_iounmap(config_tables, efi.systab->nr_tables * sz); 318 319 set_bit(EFI_CONFIG_TABLES, &efi.flags); 320 321 return 0; 322 } 323 324 #ifdef CONFIG_EFI_PARAMS_FROM_FDT 325 326 #define UEFI_PARAM(name, prop, field) \ 327 { \ 328 { name }, \ 329 { prop }, \ 330 offsetof(struct efi_fdt_params, field), \ 331 FIELD_SIZEOF(struct efi_fdt_params, field) \ 332 } 333 334 static __initdata struct { 335 const char name[32]; 336 const char propname[32]; 337 int offset; 338 int size; 339 } dt_params[] = { 340 UEFI_PARAM("System Table", "linux,uefi-system-table", system_table), 341 UEFI_PARAM("MemMap Address", "linux,uefi-mmap-start", mmap), 342 UEFI_PARAM("MemMap Size", "linux,uefi-mmap-size", mmap_size), 343 UEFI_PARAM("MemMap Desc. Size", "linux,uefi-mmap-desc-size", desc_size), 344 UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver) 345 }; 346 347 struct param_info { 348 int verbose; 349 void *params; 350 }; 351 352 static int __init fdt_find_uefi_params(unsigned long node, const char *uname, 353 int depth, void *data) 354 { 355 struct param_info *info = data; 356 const void *prop; 357 void *dest; 358 u64 val; 359 int i, len; 360 361 if (depth != 1 || 362 (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0)) 363 return 0; 364 365 pr_info("Getting parameters from FDT:\n"); 366 367 for (i = 0; i < ARRAY_SIZE(dt_params); i++) { 368 prop = of_get_flat_dt_prop(node, dt_params[i].propname, &len); 369 if (!prop) { 370 pr_err("Can't find %s in device tree!\n", 371 dt_params[i].name); 372 return 0; 373 } 374 dest = info->params + dt_params[i].offset; 375 376 val = of_read_number(prop, len / sizeof(u32)); 377 378 if (dt_params[i].size == sizeof(u32)) 379 *(u32 *)dest = val; 380 else 381 *(u64 *)dest = val; 382 383 if (info->verbose) 384 pr_info(" %s: 0x%0*llx\n", dt_params[i].name, 385 dt_params[i].size * 2, val); 386 } 387 return 1; 388 } 389 390 int __init efi_get_fdt_params(struct efi_fdt_params *params, int verbose) 391 { 392 struct param_info info; 393 394 info.verbose = verbose; 395 info.params = params; 396 397 return of_scan_flat_dt(fdt_find_uefi_params, &info); 398 } 399 #endif /* CONFIG_EFI_PARAMS_FROM_FDT */ 400