]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/firmware/efi/efi.c
Merge tag 'master-2014-12-08' of git://git.kernel.org/pub/scm/linux/kernel/git/linvil...
[karo-tx-linux.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         .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,
38         .fw_vendor  = EFI_INVALID_TABLE_ADDR,
39         .runtime    = EFI_INVALID_TABLE_ADDR,
40         .config_table  = EFI_INVALID_TABLE_ADDR,
41 };
42 EXPORT_SYMBOL(efi);
43
44 static bool disable_runtime;
45 static int __init setup_noefi(char *arg)
46 {
47         disable_runtime = true;
48         return 0;
49 }
50 early_param("noefi", setup_noefi);
51
52 bool efi_runtime_disabled(void)
53 {
54         return disable_runtime;
55 }
56
57 static int __init parse_efi_cmdline(char *str)
58 {
59         if (parse_option_str(str, "noruntime"))
60                 disable_runtime = true;
61
62         return 0;
63 }
64 early_param("efi", parse_efi_cmdline);
65
66 static struct kobject *efi_kobj;
67 static struct kobject *efivars_kobj;
68
69 /*
70  * Let's not leave out systab information that snuck into
71  * the efivars driver
72  */
73 static 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
99 static struct kobj_attribute efi_attr_systab =
100                         __ATTR(systab, 0400, systab_show, NULL);
101
102 #define EFI_FIELD(var) efi.var
103
104 #define EFI_ATTR_SHOW(name) \
105 static 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
111 EFI_ATTR_SHOW(fw_vendor);
112 EFI_ATTR_SHOW(runtime);
113 EFI_ATTR_SHOW(config_table);
114
115 static struct kobj_attribute efi_attr_fw_vendor = __ATTR_RO(fw_vendor);
116 static struct kobj_attribute efi_attr_runtime = __ATTR_RO(runtime);
117 static struct kobj_attribute efi_attr_config_table = __ATTR_RO(config_table);
118
119 static struct attribute *efi_subsys_attrs[] = {
120         &efi_attr_systab.attr,
121         &efi_attr_fw_vendor.attr,
122         &efi_attr_runtime.attr,
123         &efi_attr_config_table.attr,
124         NULL,
125 };
126
127 static umode_t efi_attr_is_visible(struct kobject *kobj,
128                                    struct attribute *attr, int n)
129 {
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         }
141
142         return attr->mode;
143 }
144
145 static struct attribute_group efi_subsys_attr_group = {
146         .attrs = efi_subsys_attrs,
147         .is_visible = efi_attr_is_visible,
148 };
149
150 static struct efivars generic_efivars;
151 static struct efivar_operations generic_ops;
152
153 static 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;
158         generic_ops.query_variable_store = efi_query_variable_store;
159
160         return efivars_register(&generic_efivars, &generic_ops, efi_kobj);
161 }
162
163 static 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  */
173 static 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
198         error = efi_runtime_map_init(efi_kobj);
199         if (error)
200                 goto err_remove_group;
201
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
212 err_remove_group:
213         sysfs_remove_group(efi_kobj, &efi_subsys_attr_group);
214 err_unregister:
215         generic_ops_unregister();
216 err_put:
217         kobject_put(efi_kobj);
218         return error;
219 }
220
221 subsys_initcall(efisubsys_init);
222
223
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  */
229 void __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
256 static __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},
264         {NULL_GUID, NULL, NULL},
265 };
266
267 static __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
292 int __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");
327                                 early_memunmap(config_tables,
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");
343         early_memunmap(config_tables, efi.systab->nr_tables * sz);
344
345         set_bit(EFI_CONFIG_TABLES, &efi.flags);
346
347         return 0;
348 }
349
350 #ifdef CONFIG_EFI_VARS_MODULE
351 static 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 }
361 device_initcall(efi_load_efivars);
362 #endif
363
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
374 static __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
387 struct param_info {
388         int verbose;
389         int found;
390         void *params;
391 };
392
393 static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
394                                        int depth, void *data)
395 {
396         struct param_info *info = data;
397         const void *prop;
398         void *dest;
399         u64 val;
400         int i, len;
401
402         if (depth != 1 ||
403             (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0))
404                 return 0;
405
406         for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
407                 prop = of_get_flat_dt_prop(node, dt_params[i].propname, &len);
408                 if (!prop)
409                         return 0;
410                 dest = info->params + dt_params[i].offset;
411                 info->found++;
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
427 int __init efi_get_fdt_params(struct efi_fdt_params *params, int verbose)
428 {
429         struct param_info info;
430         int ret;
431
432         pr_info("Getting EFI parameters from FDT:\n");
433
434         info.verbose = verbose;
435         info.found = 0;
436         info.params = params;
437
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;
446 }
447 #endif /* CONFIG_EFI_PARAMS_FROM_FDT */
448
449 static __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
466 char * __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 }