blob: 9bdbc0533627d5e9a3a01b81b2b083ac06a3fda5 [file] [log] [blame]
Tom Gundersena9499fa2013-02-08 15:37:06 +00001/*
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
Leif Lindholm272686b2013-09-05 11:34:54 +010016#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
17
Tom Gundersena9499fa2013-02-08 15:37:06 +000018#include <linux/kobject.h>
19#include <linux/module.h>
20#include <linux/init.h>
21#include <linux/device.h>
22#include <linux/efi.h>
Mark Salter0302f712013-12-30 12:12:12 -050023#include <linux/of.h>
24#include <linux/of_fdt.h>
Leif Lindholm272686b2013-09-05 11:34:54 +010025#include <linux/io.h>
Lee, Chun-Yi28d54022014-07-09 18:39:29 +080026#include <linux/platform_device.h>
Leif Lindholm272686b2013-09-05 11:34:54 +010027
28struct 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 .sal_systab = EFI_INVALID_TABLE_ADDR,
34 .boot_info = EFI_INVALID_TABLE_ADDR,
35 .hcdp = EFI_INVALID_TABLE_ADDR,
36 .uga = EFI_INVALID_TABLE_ADDR,
37 .uv_systab = EFI_INVALID_TABLE_ADDR,
Dave Younga0998eb2013-12-20 18:02:17 +080038 .fw_vendor = EFI_INVALID_TABLE_ADDR,
39 .runtime = EFI_INVALID_TABLE_ADDR,
40 .config_table = EFI_INVALID_TABLE_ADDR,
Leif Lindholm272686b2013-09-05 11:34:54 +010041};
42EXPORT_SYMBOL(efi);
Tom Gundersena9499fa2013-02-08 15:37:06 +000043
Dave Youngb2e0a542014-08-14 17:15:26 +080044static bool disable_runtime;
45static int __init setup_noefi(char *arg)
46{
47 disable_runtime = true;
48 return 0;
49}
50early_param("noefi", setup_noefi);
51
52bool efi_runtime_disabled(void)
53{
54 return disable_runtime;
55}
56
Dave Young5ae36832014-08-14 17:15:28 +080057static int __init parse_efi_cmdline(char *str)
58{
59 if (parse_option_str(str, "noruntime"))
60 disable_runtime = true;
61
62 return 0;
63}
64early_param("efi", parse_efi_cmdline);
65
Tom Gundersena9499fa2013-02-08 15:37:06 +000066static struct kobject *efi_kobj;
67static struct kobject *efivars_kobj;
68
69/*
70 * Let's not leave out systab information that snuck into
71 * the efivars driver
72 */
73static ssize_t systab_show(struct kobject *kobj,
74 struct kobj_attribute *attr, char *buf)
75{
76 char *str = buf;
77
78 if (!kobj || !buf)
79 return -EINVAL;
80
81 if (efi.mps != EFI_INVALID_TABLE_ADDR)
82 str += sprintf(str, "MPS=0x%lx\n", efi.mps);
83 if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
84 str += sprintf(str, "ACPI20=0x%lx\n", efi.acpi20);
85 if (efi.acpi != EFI_INVALID_TABLE_ADDR)
86 str += sprintf(str, "ACPI=0x%lx\n", efi.acpi);
87 if (efi.smbios != EFI_INVALID_TABLE_ADDR)
88 str += sprintf(str, "SMBIOS=0x%lx\n", efi.smbios);
89 if (efi.hcdp != EFI_INVALID_TABLE_ADDR)
90 str += sprintf(str, "HCDP=0x%lx\n", efi.hcdp);
91 if (efi.boot_info != EFI_INVALID_TABLE_ADDR)
92 str += sprintf(str, "BOOTINFO=0x%lx\n", efi.boot_info);
93 if (efi.uga != EFI_INVALID_TABLE_ADDR)
94 str += sprintf(str, "UGA=0x%lx\n", efi.uga);
95
96 return str - buf;
97}
98
99static struct kobj_attribute efi_attr_systab =
100 __ATTR(systab, 0400, systab_show, NULL);
101
Dave Younga0998eb2013-12-20 18:02:17 +0800102#define EFI_FIELD(var) efi.var
103
104#define EFI_ATTR_SHOW(name) \
105static ssize_t name##_show(struct kobject *kobj, \
106 struct kobj_attribute *attr, char *buf) \
107{ \
108 return sprintf(buf, "0x%lx\n", EFI_FIELD(name)); \
109}
110
111EFI_ATTR_SHOW(fw_vendor);
112EFI_ATTR_SHOW(runtime);
113EFI_ATTR_SHOW(config_table);
114
Steve McIntyre2859dff2015-01-09 15:29:53 +0000115static ssize_t fw_platform_size_show(struct kobject *kobj,
116 struct kobj_attribute *attr, char *buf)
117{
118 return sprintf(buf, "%d\n", efi_enabled(EFI_64BIT) ? 64 : 32);
119}
120
Dave Younga0998eb2013-12-20 18:02:17 +0800121static struct kobj_attribute efi_attr_fw_vendor = __ATTR_RO(fw_vendor);
122static struct kobj_attribute efi_attr_runtime = __ATTR_RO(runtime);
123static struct kobj_attribute efi_attr_config_table = __ATTR_RO(config_table);
Steve McIntyre2859dff2015-01-09 15:29:53 +0000124static struct kobj_attribute efi_attr_fw_platform_size =
125 __ATTR_RO(fw_platform_size);
Dave Younga0998eb2013-12-20 18:02:17 +0800126
Tom Gundersena9499fa2013-02-08 15:37:06 +0000127static struct attribute *efi_subsys_attrs[] = {
128 &efi_attr_systab.attr,
Dave Younga0998eb2013-12-20 18:02:17 +0800129 &efi_attr_fw_vendor.attr,
130 &efi_attr_runtime.attr,
131 &efi_attr_config_table.attr,
Steve McIntyre2859dff2015-01-09 15:29:53 +0000132 &efi_attr_fw_platform_size.attr,
Dave Younga0998eb2013-12-20 18:02:17 +0800133 NULL,
Tom Gundersena9499fa2013-02-08 15:37:06 +0000134};
135
Dave Younga0998eb2013-12-20 18:02:17 +0800136static umode_t efi_attr_is_visible(struct kobject *kobj,
137 struct attribute *attr, int n)
138{
Daniel Kiper9f27bc52014-06-30 19:52:58 +0200139 if (attr == &efi_attr_fw_vendor.attr) {
140 if (efi_enabled(EFI_PARAVIRT) ||
141 efi.fw_vendor == EFI_INVALID_TABLE_ADDR)
142 return 0;
143 } else if (attr == &efi_attr_runtime.attr) {
144 if (efi.runtime == EFI_INVALID_TABLE_ADDR)
145 return 0;
146 } else if (attr == &efi_attr_config_table.attr) {
147 if (efi.config_table == EFI_INVALID_TABLE_ADDR)
148 return 0;
149 }
Dave Younga0998eb2013-12-20 18:02:17 +0800150
Daniel Kiper9f27bc52014-06-30 19:52:58 +0200151 return attr->mode;
Dave Younga0998eb2013-12-20 18:02:17 +0800152}
153
Tom Gundersena9499fa2013-02-08 15:37:06 +0000154static struct attribute_group efi_subsys_attr_group = {
155 .attrs = efi_subsys_attrs,
Dave Younga0998eb2013-12-20 18:02:17 +0800156 .is_visible = efi_attr_is_visible,
Tom Gundersena9499fa2013-02-08 15:37:06 +0000157};
158
159static struct efivars generic_efivars;
160static struct efivar_operations generic_ops;
161
162static int generic_ops_register(void)
163{
164 generic_ops.get_variable = efi.get_variable;
165 generic_ops.set_variable = efi.set_variable;
166 generic_ops.get_next_variable = efi.get_next_variable;
Matt Fleminga614e192013-04-30 11:30:24 +0100167 generic_ops.query_variable_store = efi_query_variable_store;
Tom Gundersena9499fa2013-02-08 15:37:06 +0000168
169 return efivars_register(&generic_efivars, &generic_ops, efi_kobj);
170}
171
172static void generic_ops_unregister(void)
173{
174 efivars_unregister(&generic_efivars);
175}
176
177/*
178 * We register the efi subsystem with the firmware subsystem and the
179 * efivars subsystem with the efi subsystem, if the system was booted with
180 * EFI.
181 */
182static int __init efisubsys_init(void)
183{
184 int error;
185
186 if (!efi_enabled(EFI_BOOT))
187 return 0;
188
189 /* We register the efi directory at /sys/firmware/efi */
190 efi_kobj = kobject_create_and_add("efi", firmware_kobj);
191 if (!efi_kobj) {
192 pr_err("efi: Firmware registration failed.\n");
193 return -ENOMEM;
194 }
195
196 error = generic_ops_register();
197 if (error)
198 goto err_put;
199
200 error = sysfs_create_group(efi_kobj, &efi_subsys_attr_group);
201 if (error) {
202 pr_err("efi: Sysfs attribute export failed with error %d.\n",
203 error);
204 goto err_unregister;
205 }
206
Dave Young926172d2013-12-20 18:02:18 +0800207 error = efi_runtime_map_init(efi_kobj);
208 if (error)
209 goto err_remove_group;
210
Tom Gundersena9499fa2013-02-08 15:37:06 +0000211 /* and the standard mountpoint for efivarfs */
212 efivars_kobj = kobject_create_and_add("efivars", efi_kobj);
213 if (!efivars_kobj) {
214 pr_err("efivars: Subsystem registration failed.\n");
215 error = -ENOMEM;
216 goto err_remove_group;
217 }
218
219 return 0;
220
221err_remove_group:
222 sysfs_remove_group(efi_kobj, &efi_subsys_attr_group);
223err_unregister:
224 generic_ops_unregister();
225err_put:
226 kobject_put(efi_kobj);
227 return error;
228}
229
230subsys_initcall(efisubsys_init);
Leif Lindholm272686b2013-09-05 11:34:54 +0100231
232
Leif Lindholm258f6fd2013-09-05 11:34:55 +0100233/*
234 * We can't ioremap data in EFI boot services RAM, because we've already mapped
235 * it as RAM. So, look it up in the existing EFI memory map instead. Only
236 * callable after efi_enter_virtual_mode and before efi_free_boot_services.
237 */
238void __iomem *efi_lookup_mapped_addr(u64 phys_addr)
239{
240 struct efi_memory_map *map;
241 void *p;
242 map = efi.memmap;
243 if (!map)
244 return NULL;
245 if (WARN_ON(!map->map))
246 return NULL;
247 for (p = map->map; p < map->map_end; p += map->desc_size) {
248 efi_memory_desc_t *md = p;
249 u64 size = md->num_pages << EFI_PAGE_SHIFT;
250 u64 end = md->phys_addr + size;
251 if (!(md->attribute & EFI_MEMORY_RUNTIME) &&
252 md->type != EFI_BOOT_SERVICES_CODE &&
253 md->type != EFI_BOOT_SERVICES_DATA)
254 continue;
255 if (!md->virt_addr)
256 continue;
257 if (phys_addr >= md->phys_addr && phys_addr < end) {
258 phys_addr += md->virt_addr - md->phys_addr;
259 return (__force void __iomem *)(unsigned long)phys_addr;
260 }
261 }
262 return NULL;
263}
264
Leif Lindholm272686b2013-09-05 11:34:54 +0100265static __initdata efi_config_table_type_t common_tables[] = {
266 {ACPI_20_TABLE_GUID, "ACPI 2.0", &efi.acpi20},
267 {ACPI_TABLE_GUID, "ACPI", &efi.acpi},
268 {HCDP_TABLE_GUID, "HCDP", &efi.hcdp},
269 {MPS_TABLE_GUID, "MPS", &efi.mps},
270 {SAL_SYSTEM_TABLE_GUID, "SALsystab", &efi.sal_systab},
271 {SMBIOS_TABLE_GUID, "SMBIOS", &efi.smbios},
272 {UGA_IO_PROTOCOL_GUID, "UGA", &efi.uga},
Daeseok Youn69e60842014-02-13 17:16:36 +0900273 {NULL_GUID, NULL, NULL},
Leif Lindholm272686b2013-09-05 11:34:54 +0100274};
275
276static __init int match_config_table(efi_guid_t *guid,
277 unsigned long table,
278 efi_config_table_type_t *table_types)
279{
280 u8 str[EFI_VARIABLE_GUID_LEN + 1];
281 int i;
282
283 if (table_types) {
Borislav Petkov26e02272014-12-18 16:02:17 +0100284 efi_guid_to_str(guid, str);
Leif Lindholm272686b2013-09-05 11:34:54 +0100285
286 for (i = 0; efi_guidcmp(table_types[i].guid, NULL_GUID); i++) {
Borislav Petkov26e02272014-12-18 16:02:17 +0100287 efi_guid_to_str(&table_types[i].guid, str);
Leif Lindholm272686b2013-09-05 11:34:54 +0100288
289 if (!efi_guidcmp(*guid, table_types[i].guid)) {
290 *(table_types[i].ptr) = table;
291 pr_cont(" %s=0x%lx ",
292 table_types[i].name, table);
293 return 1;
294 }
295 }
296 }
297
298 return 0;
299}
300
301int __init efi_config_init(efi_config_table_type_t *arch_tables)
302{
303 void *config_tables, *tablep;
304 int i, sz;
305
306 if (efi_enabled(EFI_64BIT))
307 sz = sizeof(efi_config_table_64_t);
308 else
309 sz = sizeof(efi_config_table_32_t);
310
311 /*
312 * Let's see what config tables the firmware passed to us.
313 */
314 config_tables = early_memremap(efi.systab->tables,
315 efi.systab->nr_tables * sz);
316 if (config_tables == NULL) {
317 pr_err("Could not map Configuration table!\n");
318 return -ENOMEM;
319 }
320
321 tablep = config_tables;
322 pr_info("");
323 for (i = 0; i < efi.systab->nr_tables; i++) {
324 efi_guid_t guid;
325 unsigned long table;
326
327 if (efi_enabled(EFI_64BIT)) {
328 u64 table64;
329 guid = ((efi_config_table_64_t *)tablep)->guid;
330 table64 = ((efi_config_table_64_t *)tablep)->table;
331 table = table64;
332#ifndef CONFIG_64BIT
333 if (table64 >> 32) {
334 pr_cont("\n");
335 pr_err("Table located above 4GB, disabling EFI.\n");
Daniel Kiperabc93f82014-06-30 19:52:56 +0200336 early_memunmap(config_tables,
Leif Lindholm272686b2013-09-05 11:34:54 +0100337 efi.systab->nr_tables * sz);
338 return -EINVAL;
339 }
340#endif
341 } else {
342 guid = ((efi_config_table_32_t *)tablep)->guid;
343 table = ((efi_config_table_32_t *)tablep)->table;
344 }
345
346 if (!match_config_table(&guid, table, common_tables))
347 match_config_table(&guid, table, arch_tables);
348
349 tablep += sz;
350 }
351 pr_cont("\n");
Daniel Kiperabc93f82014-06-30 19:52:56 +0200352 early_memunmap(config_tables, efi.systab->nr_tables * sz);
Matt Fleming0f8093a2014-01-15 13:36:33 +0000353
354 set_bit(EFI_CONFIG_TABLES, &efi.flags);
355
Leif Lindholm272686b2013-09-05 11:34:54 +0100356 return 0;
357}
Mark Salter0302f712013-12-30 12:12:12 -0500358
Lee, Chun-Yi28d54022014-07-09 18:39:29 +0800359#ifdef CONFIG_EFI_VARS_MODULE
360static int __init efi_load_efivars(void)
361{
362 struct platform_device *pdev;
363
364 if (!efi_enabled(EFI_RUNTIME_SERVICES))
365 return 0;
366
367 pdev = platform_device_register_simple("efivars", 0, NULL, 0);
368 return IS_ERR(pdev) ? PTR_ERR(pdev) : 0;
369}
370device_initcall(efi_load_efivars);
371#endif
372
Mark Salter0302f712013-12-30 12:12:12 -0500373#ifdef CONFIG_EFI_PARAMS_FROM_FDT
374
375#define UEFI_PARAM(name, prop, field) \
376 { \
377 { name }, \
378 { prop }, \
379 offsetof(struct efi_fdt_params, field), \
380 FIELD_SIZEOF(struct efi_fdt_params, field) \
381 }
382
383static __initdata struct {
384 const char name[32];
385 const char propname[32];
386 int offset;
387 int size;
388} dt_params[] = {
389 UEFI_PARAM("System Table", "linux,uefi-system-table", system_table),
390 UEFI_PARAM("MemMap Address", "linux,uefi-mmap-start", mmap),
391 UEFI_PARAM("MemMap Size", "linux,uefi-mmap-size", mmap_size),
392 UEFI_PARAM("MemMap Desc. Size", "linux,uefi-mmap-desc-size", desc_size),
393 UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver)
394};
395
396struct param_info {
397 int verbose;
Catalin Marinas29e24352014-07-08 16:54:18 +0100398 int found;
Mark Salter0302f712013-12-30 12:12:12 -0500399 void *params;
400};
401
402static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
403 int depth, void *data)
404{
405 struct param_info *info = data;
Catalin Marinas6fb8cc82014-06-02 11:31:06 +0100406 const void *prop;
407 void *dest;
Mark Salter0302f712013-12-30 12:12:12 -0500408 u64 val;
Catalin Marinas6fb8cc82014-06-02 11:31:06 +0100409 int i, len;
Mark Salter0302f712013-12-30 12:12:12 -0500410
411 if (depth != 1 ||
412 (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0))
413 return 0;
414
Mark Salter0302f712013-12-30 12:12:12 -0500415 for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
416 prop = of_get_flat_dt_prop(node, dt_params[i].propname, &len);
Catalin Marinas29e24352014-07-08 16:54:18 +0100417 if (!prop)
Mark Salter0302f712013-12-30 12:12:12 -0500418 return 0;
Mark Salter0302f712013-12-30 12:12:12 -0500419 dest = info->params + dt_params[i].offset;
Catalin Marinas29e24352014-07-08 16:54:18 +0100420 info->found++;
Mark Salter0302f712013-12-30 12:12:12 -0500421
422 val = of_read_number(prop, len / sizeof(u32));
423
424 if (dt_params[i].size == sizeof(u32))
425 *(u32 *)dest = val;
426 else
427 *(u64 *)dest = val;
428
429 if (info->verbose)
430 pr_info(" %s: 0x%0*llx\n", dt_params[i].name,
431 dt_params[i].size * 2, val);
432 }
433 return 1;
434}
435
436int __init efi_get_fdt_params(struct efi_fdt_params *params, int verbose)
437{
438 struct param_info info;
Catalin Marinas29e24352014-07-08 16:54:18 +0100439 int ret;
440
441 pr_info("Getting EFI parameters from FDT:\n");
Mark Salter0302f712013-12-30 12:12:12 -0500442
443 info.verbose = verbose;
Catalin Marinas29e24352014-07-08 16:54:18 +0100444 info.found = 0;
Mark Salter0302f712013-12-30 12:12:12 -0500445 info.params = params;
446
Catalin Marinas29e24352014-07-08 16:54:18 +0100447 ret = of_scan_flat_dt(fdt_find_uefi_params, &info);
448 if (!info.found)
449 pr_info("UEFI not found.\n");
450 else if (!ret)
451 pr_err("Can't find '%s' in device tree!\n",
452 dt_params[info.found].name);
453
454 return ret;
Mark Salter0302f712013-12-30 12:12:12 -0500455}
456#endif /* CONFIG_EFI_PARAMS_FROM_FDT */
Laszlo Ersek98d2a6c2014-09-03 13:32:20 +0200457
458static __initdata char memory_type_name[][20] = {
459 "Reserved",
460 "Loader Code",
461 "Loader Data",
462 "Boot Code",
463 "Boot Data",
464 "Runtime Code",
465 "Runtime Data",
466 "Conventional Memory",
467 "Unusable Memory",
468 "ACPI Reclaim Memory",
469 "ACPI Memory NVS",
470 "Memory Mapped I/O",
471 "MMIO Port Space",
472 "PAL Code"
473};
474
475char * __init efi_md_typeattr_format(char *buf, size_t size,
476 const efi_memory_desc_t *md)
477{
478 char *pos;
479 int type_len;
480 u64 attr;
481
482 pos = buf;
483 if (md->type >= ARRAY_SIZE(memory_type_name))
484 type_len = snprintf(pos, size, "[type=%u", md->type);
485 else
486 type_len = snprintf(pos, size, "[%-*s",
487 (int)(sizeof(memory_type_name[0]) - 1),
488 memory_type_name[md->type]);
489 if (type_len >= size)
490 return buf;
491
492 pos += type_len;
493 size -= type_len;
494
495 attr = md->attribute;
496 if (attr & ~(EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT |
497 EFI_MEMORY_WB | EFI_MEMORY_UCE | EFI_MEMORY_WP |
498 EFI_MEMORY_RP | EFI_MEMORY_XP | EFI_MEMORY_RUNTIME))
499 snprintf(pos, size, "|attr=0x%016llx]",
500 (unsigned long long)attr);
501 else
502 snprintf(pos, size, "|%3s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]",
503 attr & EFI_MEMORY_RUNTIME ? "RUN" : "",
504 attr & EFI_MEMORY_XP ? "XP" : "",
505 attr & EFI_MEMORY_RP ? "RP" : "",
506 attr & EFI_MEMORY_WP ? "WP" : "",
507 attr & EFI_MEMORY_UCE ? "UCE" : "",
508 attr & EFI_MEMORY_WB ? "WB" : "",
509 attr & EFI_MEMORY_WT ? "WT" : "",
510 attr & EFI_MEMORY_WC ? "WC" : "",
511 attr & EFI_MEMORY_UC ? "UC" : "");
512 return buf;
513}