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