]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - drivers/firmware/efi/efi.c
Merge tag 'efi-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mfleming/efi...
[mirror_ubuntu-bionic-kernel.git] / drivers / firmware / efi / efi.c
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 #include <linux/platform_device.h>
27
28 struct efi __read_mostly efi = {
29 .mps = EFI_INVALID_TABLE_ADDR,
30 .acpi = EFI_INVALID_TABLE_ADDR,
31 .acpi20 = EFI_INVALID_TABLE_ADDR,
32 .smbios = EFI_INVALID_TABLE_ADDR,
33 .smbios3 = EFI_INVALID_TABLE_ADDR,
34 .sal_systab = EFI_INVALID_TABLE_ADDR,
35 .boot_info = EFI_INVALID_TABLE_ADDR,
36 .hcdp = EFI_INVALID_TABLE_ADDR,
37 .uga = EFI_INVALID_TABLE_ADDR,
38 .uv_systab = EFI_INVALID_TABLE_ADDR,
39 .fw_vendor = EFI_INVALID_TABLE_ADDR,
40 .runtime = EFI_INVALID_TABLE_ADDR,
41 .config_table = EFI_INVALID_TABLE_ADDR,
42 };
43 EXPORT_SYMBOL(efi);
44
45 static bool disable_runtime;
46 static int __init setup_noefi(char *arg)
47 {
48 disable_runtime = true;
49 return 0;
50 }
51 early_param("noefi", setup_noefi);
52
53 bool efi_runtime_disabled(void)
54 {
55 return disable_runtime;
56 }
57
58 static int __init parse_efi_cmdline(char *str)
59 {
60 if (parse_option_str(str, "noruntime"))
61 disable_runtime = true;
62
63 return 0;
64 }
65 early_param("efi", parse_efi_cmdline);
66
67 static struct kobject *efi_kobj;
68 static struct kobject *efivars_kobj;
69
70 /*
71 * Let's not leave out systab information that snuck into
72 * the efivars driver
73 */
74 static ssize_t systab_show(struct kobject *kobj,
75 struct kobj_attribute *attr, char *buf)
76 {
77 char *str = buf;
78
79 if (!kobj || !buf)
80 return -EINVAL;
81
82 if (efi.mps != EFI_INVALID_TABLE_ADDR)
83 str += sprintf(str, "MPS=0x%lx\n", efi.mps);
84 if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
85 str += sprintf(str, "ACPI20=0x%lx\n", efi.acpi20);
86 if (efi.acpi != EFI_INVALID_TABLE_ADDR)
87 str += sprintf(str, "ACPI=0x%lx\n", efi.acpi);
88 if (efi.smbios != EFI_INVALID_TABLE_ADDR)
89 str += sprintf(str, "SMBIOS=0x%lx\n", efi.smbios);
90 if (efi.smbios3 != EFI_INVALID_TABLE_ADDR)
91 str += sprintf(str, "SMBIOS3=0x%lx\n", efi.smbios3);
92 if (efi.hcdp != EFI_INVALID_TABLE_ADDR)
93 str += sprintf(str, "HCDP=0x%lx\n", efi.hcdp);
94 if (efi.boot_info != EFI_INVALID_TABLE_ADDR)
95 str += sprintf(str, "BOOTINFO=0x%lx\n", efi.boot_info);
96 if (efi.uga != EFI_INVALID_TABLE_ADDR)
97 str += sprintf(str, "UGA=0x%lx\n", efi.uga);
98
99 return str - buf;
100 }
101
102 static struct kobj_attribute efi_attr_systab =
103 __ATTR(systab, 0400, systab_show, NULL);
104
105 #define EFI_FIELD(var) efi.var
106
107 #define EFI_ATTR_SHOW(name) \
108 static ssize_t name##_show(struct kobject *kobj, \
109 struct kobj_attribute *attr, char *buf) \
110 { \
111 return sprintf(buf, "0x%lx\n", EFI_FIELD(name)); \
112 }
113
114 EFI_ATTR_SHOW(fw_vendor);
115 EFI_ATTR_SHOW(runtime);
116 EFI_ATTR_SHOW(config_table);
117
118 static ssize_t fw_platform_size_show(struct kobject *kobj,
119 struct kobj_attribute *attr, char *buf)
120 {
121 return sprintf(buf, "%d\n", efi_enabled(EFI_64BIT) ? 64 : 32);
122 }
123
124 static struct kobj_attribute efi_attr_fw_vendor = __ATTR_RO(fw_vendor);
125 static struct kobj_attribute efi_attr_runtime = __ATTR_RO(runtime);
126 static struct kobj_attribute efi_attr_config_table = __ATTR_RO(config_table);
127 static struct kobj_attribute efi_attr_fw_platform_size =
128 __ATTR_RO(fw_platform_size);
129
130 static struct attribute *efi_subsys_attrs[] = {
131 &efi_attr_systab.attr,
132 &efi_attr_fw_vendor.attr,
133 &efi_attr_runtime.attr,
134 &efi_attr_config_table.attr,
135 &efi_attr_fw_platform_size.attr,
136 NULL,
137 };
138
139 static umode_t efi_attr_is_visible(struct kobject *kobj,
140 struct attribute *attr, int n)
141 {
142 if (attr == &efi_attr_fw_vendor.attr) {
143 if (efi_enabled(EFI_PARAVIRT) ||
144 efi.fw_vendor == EFI_INVALID_TABLE_ADDR)
145 return 0;
146 } else if (attr == &efi_attr_runtime.attr) {
147 if (efi.runtime == EFI_INVALID_TABLE_ADDR)
148 return 0;
149 } else if (attr == &efi_attr_config_table.attr) {
150 if (efi.config_table == EFI_INVALID_TABLE_ADDR)
151 return 0;
152 }
153
154 return attr->mode;
155 }
156
157 static struct attribute_group efi_subsys_attr_group = {
158 .attrs = efi_subsys_attrs,
159 .is_visible = efi_attr_is_visible,
160 };
161
162 static struct efivars generic_efivars;
163 static struct efivar_operations generic_ops;
164
165 static int generic_ops_register(void)
166 {
167 generic_ops.get_variable = efi.get_variable;
168 generic_ops.set_variable = efi.set_variable;
169 generic_ops.get_next_variable = efi.get_next_variable;
170 generic_ops.query_variable_store = efi_query_variable_store;
171
172 return efivars_register(&generic_efivars, &generic_ops, efi_kobj);
173 }
174
175 static void generic_ops_unregister(void)
176 {
177 efivars_unregister(&generic_efivars);
178 }
179
180 /*
181 * We register the efi subsystem with the firmware subsystem and the
182 * efivars subsystem with the efi subsystem, if the system was booted with
183 * EFI.
184 */
185 static int __init efisubsys_init(void)
186 {
187 int error;
188
189 if (!efi_enabled(EFI_BOOT))
190 return 0;
191
192 /* We register the efi directory at /sys/firmware/efi */
193 efi_kobj = kobject_create_and_add("efi", firmware_kobj);
194 if (!efi_kobj) {
195 pr_err("efi: Firmware registration failed.\n");
196 return -ENOMEM;
197 }
198
199 error = generic_ops_register();
200 if (error)
201 goto err_put;
202
203 error = sysfs_create_group(efi_kobj, &efi_subsys_attr_group);
204 if (error) {
205 pr_err("efi: Sysfs attribute export failed with error %d.\n",
206 error);
207 goto err_unregister;
208 }
209
210 error = efi_runtime_map_init(efi_kobj);
211 if (error)
212 goto err_remove_group;
213
214 /* and the standard mountpoint for efivarfs */
215 efivars_kobj = kobject_create_and_add("efivars", efi_kobj);
216 if (!efivars_kobj) {
217 pr_err("efivars: Subsystem registration failed.\n");
218 error = -ENOMEM;
219 goto err_remove_group;
220 }
221
222 return 0;
223
224 err_remove_group:
225 sysfs_remove_group(efi_kobj, &efi_subsys_attr_group);
226 err_unregister:
227 generic_ops_unregister();
228 err_put:
229 kobject_put(efi_kobj);
230 return error;
231 }
232
233 subsys_initcall(efisubsys_init);
234
235
236 /*
237 * We can't ioremap data in EFI boot services RAM, because we've already mapped
238 * it as RAM. So, look it up in the existing EFI memory map instead. Only
239 * callable after efi_enter_virtual_mode and before efi_free_boot_services.
240 */
241 void __iomem *efi_lookup_mapped_addr(u64 phys_addr)
242 {
243 struct efi_memory_map *map;
244 void *p;
245 map = efi.memmap;
246 if (!map)
247 return NULL;
248 if (WARN_ON(!map->map))
249 return NULL;
250 for (p = map->map; p < map->map_end; p += map->desc_size) {
251 efi_memory_desc_t *md = p;
252 u64 size = md->num_pages << EFI_PAGE_SHIFT;
253 u64 end = md->phys_addr + size;
254 if (!(md->attribute & EFI_MEMORY_RUNTIME) &&
255 md->type != EFI_BOOT_SERVICES_CODE &&
256 md->type != EFI_BOOT_SERVICES_DATA)
257 continue;
258 if (!md->virt_addr)
259 continue;
260 if (phys_addr >= md->phys_addr && phys_addr < end) {
261 phys_addr += md->virt_addr - md->phys_addr;
262 return (__force void __iomem *)(unsigned long)phys_addr;
263 }
264 }
265 return NULL;
266 }
267
268 static __initdata efi_config_table_type_t common_tables[] = {
269 {ACPI_20_TABLE_GUID, "ACPI 2.0", &efi.acpi20},
270 {ACPI_TABLE_GUID, "ACPI", &efi.acpi},
271 {HCDP_TABLE_GUID, "HCDP", &efi.hcdp},
272 {MPS_TABLE_GUID, "MPS", &efi.mps},
273 {SAL_SYSTEM_TABLE_GUID, "SALsystab", &efi.sal_systab},
274 {SMBIOS_TABLE_GUID, "SMBIOS", &efi.smbios},
275 {SMBIOS3_TABLE_GUID, "SMBIOS 3.0", &efi.smbios3},
276 {UGA_IO_PROTOCOL_GUID, "UGA", &efi.uga},
277 {NULL_GUID, NULL, NULL},
278 };
279
280 static __init int match_config_table(efi_guid_t *guid,
281 unsigned long table,
282 efi_config_table_type_t *table_types)
283 {
284 int i;
285
286 if (table_types) {
287 for (i = 0; efi_guidcmp(table_types[i].guid, NULL_GUID); i++) {
288 if (!efi_guidcmp(*guid, table_types[i].guid)) {
289 *(table_types[i].ptr) = table;
290 pr_cont(" %s=0x%lx ",
291 table_types[i].name, table);
292 return 1;
293 }
294 }
295 }
296
297 return 0;
298 }
299
300 int __init efi_config_init(efi_config_table_type_t *arch_tables)
301 {
302 void *config_tables, *tablep;
303 int i, sz;
304
305 if (efi_enabled(EFI_64BIT))
306 sz = sizeof(efi_config_table_64_t);
307 else
308 sz = sizeof(efi_config_table_32_t);
309
310 /*
311 * Let's see what config tables the firmware passed to us.
312 */
313 config_tables = early_memremap(efi.systab->tables,
314 efi.systab->nr_tables * sz);
315 if (config_tables == NULL) {
316 pr_err("Could not map Configuration table!\n");
317 return -ENOMEM;
318 }
319
320 tablep = config_tables;
321 pr_info("");
322 for (i = 0; i < efi.systab->nr_tables; i++) {
323 efi_guid_t guid;
324 unsigned long table;
325
326 if (efi_enabled(EFI_64BIT)) {
327 u64 table64;
328 guid = ((efi_config_table_64_t *)tablep)->guid;
329 table64 = ((efi_config_table_64_t *)tablep)->table;
330 table = table64;
331 #ifndef CONFIG_64BIT
332 if (table64 >> 32) {
333 pr_cont("\n");
334 pr_err("Table located above 4GB, disabling EFI.\n");
335 early_memunmap(config_tables,
336 efi.systab->nr_tables * sz);
337 return -EINVAL;
338 }
339 #endif
340 } else {
341 guid = ((efi_config_table_32_t *)tablep)->guid;
342 table = ((efi_config_table_32_t *)tablep)->table;
343 }
344
345 if (!match_config_table(&guid, table, common_tables))
346 match_config_table(&guid, table, arch_tables);
347
348 tablep += sz;
349 }
350 pr_cont("\n");
351 early_memunmap(config_tables, efi.systab->nr_tables * sz);
352
353 set_bit(EFI_CONFIG_TABLES, &efi.flags);
354
355 return 0;
356 }
357
358 #ifdef CONFIG_EFI_VARS_MODULE
359 static int __init efi_load_efivars(void)
360 {
361 struct platform_device *pdev;
362
363 if (!efi_enabled(EFI_RUNTIME_SERVICES))
364 return 0;
365
366 pdev = platform_device_register_simple("efivars", 0, NULL, 0);
367 return IS_ERR(pdev) ? PTR_ERR(pdev) : 0;
368 }
369 device_initcall(efi_load_efivars);
370 #endif
371
372 #ifdef CONFIG_EFI_PARAMS_FROM_FDT
373
374 #define UEFI_PARAM(name, prop, field) \
375 { \
376 { name }, \
377 { prop }, \
378 offsetof(struct efi_fdt_params, field), \
379 FIELD_SIZEOF(struct efi_fdt_params, field) \
380 }
381
382 static __initdata struct {
383 const char name[32];
384 const char propname[32];
385 int offset;
386 int size;
387 } dt_params[] = {
388 UEFI_PARAM("System Table", "linux,uefi-system-table", system_table),
389 UEFI_PARAM("MemMap Address", "linux,uefi-mmap-start", mmap),
390 UEFI_PARAM("MemMap Size", "linux,uefi-mmap-size", mmap_size),
391 UEFI_PARAM("MemMap Desc. Size", "linux,uefi-mmap-desc-size", desc_size),
392 UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver)
393 };
394
395 struct param_info {
396 int verbose;
397 int found;
398 void *params;
399 };
400
401 static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
402 int depth, void *data)
403 {
404 struct param_info *info = data;
405 const void *prop;
406 void *dest;
407 u64 val;
408 int i, len;
409
410 if (depth != 1 || strcmp(uname, "chosen") != 0)
411 return 0;
412
413 for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
414 prop = of_get_flat_dt_prop(node, dt_params[i].propname, &len);
415 if (!prop)
416 return 0;
417 dest = info->params + dt_params[i].offset;
418 info->found++;
419
420 val = of_read_number(prop, len / sizeof(u32));
421
422 if (dt_params[i].size == sizeof(u32))
423 *(u32 *)dest = val;
424 else
425 *(u64 *)dest = val;
426
427 if (info->verbose)
428 pr_info(" %s: 0x%0*llx\n", dt_params[i].name,
429 dt_params[i].size * 2, val);
430 }
431 return 1;
432 }
433
434 int __init efi_get_fdt_params(struct efi_fdt_params *params, int verbose)
435 {
436 struct param_info info;
437 int ret;
438
439 pr_info("Getting EFI parameters from FDT:\n");
440
441 info.verbose = verbose;
442 info.found = 0;
443 info.params = params;
444
445 ret = of_scan_flat_dt(fdt_find_uefi_params, &info);
446 if (!info.found)
447 pr_info("UEFI not found.\n");
448 else if (!ret)
449 pr_err("Can't find '%s' in device tree!\n",
450 dt_params[info.found].name);
451
452 return ret;
453 }
454 #endif /* CONFIG_EFI_PARAMS_FROM_FDT */
455
456 static __initdata char memory_type_name[][20] = {
457 "Reserved",
458 "Loader Code",
459 "Loader Data",
460 "Boot Code",
461 "Boot Data",
462 "Runtime Code",
463 "Runtime Data",
464 "Conventional Memory",
465 "Unusable Memory",
466 "ACPI Reclaim Memory",
467 "ACPI Memory NVS",
468 "Memory Mapped I/O",
469 "MMIO Port Space",
470 "PAL Code"
471 };
472
473 char * __init efi_md_typeattr_format(char *buf, size_t size,
474 const efi_memory_desc_t *md)
475 {
476 char *pos;
477 int type_len;
478 u64 attr;
479
480 pos = buf;
481 if (md->type >= ARRAY_SIZE(memory_type_name))
482 type_len = snprintf(pos, size, "[type=%u", md->type);
483 else
484 type_len = snprintf(pos, size, "[%-*s",
485 (int)(sizeof(memory_type_name[0]) - 1),
486 memory_type_name[md->type]);
487 if (type_len >= size)
488 return buf;
489
490 pos += type_len;
491 size -= type_len;
492
493 attr = md->attribute;
494 if (attr & ~(EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT |
495 EFI_MEMORY_WB | EFI_MEMORY_UCE | EFI_MEMORY_WP |
496 EFI_MEMORY_RP | EFI_MEMORY_XP | EFI_MEMORY_RUNTIME))
497 snprintf(pos, size, "|attr=0x%016llx]",
498 (unsigned long long)attr);
499 else
500 snprintf(pos, size, "|%3s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]",
501 attr & EFI_MEMORY_RUNTIME ? "RUN" : "",
502 attr & EFI_MEMORY_XP ? "XP" : "",
503 attr & EFI_MEMORY_RP ? "RP" : "",
504 attr & EFI_MEMORY_WP ? "WP" : "",
505 attr & EFI_MEMORY_UCE ? "UCE" : "",
506 attr & EFI_MEMORY_WB ? "WB" : "",
507 attr & EFI_MEMORY_WT ? "WT" : "",
508 attr & EFI_MEMORY_WC ? "WC" : "",
509 attr & EFI_MEMORY_UC ? "UC" : "");
510 return buf;
511 }