xref: /openbmc/linux/drivers/firmware/efi/efi.c (revision ca460cc2)
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 }
505