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