xref: /linux/drivers/firmware/efi/efi.c (revision fbc872c38c8fed31948c85683b5326ee5ab9fccc)
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 #include <asm/early_ioremap.h>
29 
30 struct efi __read_mostly efi = {
31 	.mps			= EFI_INVALID_TABLE_ADDR,
32 	.acpi			= EFI_INVALID_TABLE_ADDR,
33 	.acpi20			= EFI_INVALID_TABLE_ADDR,
34 	.smbios			= EFI_INVALID_TABLE_ADDR,
35 	.smbios3		= EFI_INVALID_TABLE_ADDR,
36 	.sal_systab		= EFI_INVALID_TABLE_ADDR,
37 	.boot_info		= EFI_INVALID_TABLE_ADDR,
38 	.hcdp			= EFI_INVALID_TABLE_ADDR,
39 	.uga			= EFI_INVALID_TABLE_ADDR,
40 	.uv_systab		= EFI_INVALID_TABLE_ADDR,
41 	.fw_vendor		= EFI_INVALID_TABLE_ADDR,
42 	.runtime		= EFI_INVALID_TABLE_ADDR,
43 	.config_table		= EFI_INVALID_TABLE_ADDR,
44 	.esrt			= EFI_INVALID_TABLE_ADDR,
45 	.properties_table	= EFI_INVALID_TABLE_ADDR,
46 	.mem_attr_table		= EFI_INVALID_TABLE_ADDR,
47 };
48 EXPORT_SYMBOL(efi);
49 
50 static bool disable_runtime;
51 static int __init setup_noefi(char *arg)
52 {
53 	disable_runtime = true;
54 	return 0;
55 }
56 early_param("noefi", setup_noefi);
57 
58 bool efi_runtime_disabled(void)
59 {
60 	return disable_runtime;
61 }
62 
63 static int __init parse_efi_cmdline(char *str)
64 {
65 	if (!str) {
66 		pr_warn("need at least one option\n");
67 		return -EINVAL;
68 	}
69 
70 	if (parse_option_str(str, "debug"))
71 		set_bit(EFI_DBG, &efi.flags);
72 
73 	if (parse_option_str(str, "noruntime"))
74 		disable_runtime = true;
75 
76 	return 0;
77 }
78 early_param("efi", parse_efi_cmdline);
79 
80 struct kobject *efi_kobj;
81 
82 /*
83  * Let's not leave out systab information that snuck into
84  * the efivars driver
85  */
86 static ssize_t systab_show(struct kobject *kobj,
87 			   struct kobj_attribute *attr, char *buf)
88 {
89 	char *str = buf;
90 
91 	if (!kobj || !buf)
92 		return -EINVAL;
93 
94 	if (efi.mps != EFI_INVALID_TABLE_ADDR)
95 		str += sprintf(str, "MPS=0x%lx\n", efi.mps);
96 	if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
97 		str += sprintf(str, "ACPI20=0x%lx\n", efi.acpi20);
98 	if (efi.acpi != EFI_INVALID_TABLE_ADDR)
99 		str += sprintf(str, "ACPI=0x%lx\n", efi.acpi);
100 	/*
101 	 * If both SMBIOS and SMBIOS3 entry points are implemented, the
102 	 * SMBIOS3 entry point shall be preferred, so we list it first to
103 	 * let applications stop parsing after the first match.
104 	 */
105 	if (efi.smbios3 != EFI_INVALID_TABLE_ADDR)
106 		str += sprintf(str, "SMBIOS3=0x%lx\n", efi.smbios3);
107 	if (efi.smbios != EFI_INVALID_TABLE_ADDR)
108 		str += sprintf(str, "SMBIOS=0x%lx\n", efi.smbios);
109 	if (efi.hcdp != EFI_INVALID_TABLE_ADDR)
110 		str += sprintf(str, "HCDP=0x%lx\n", efi.hcdp);
111 	if (efi.boot_info != EFI_INVALID_TABLE_ADDR)
112 		str += sprintf(str, "BOOTINFO=0x%lx\n", efi.boot_info);
113 	if (efi.uga != EFI_INVALID_TABLE_ADDR)
114 		str += sprintf(str, "UGA=0x%lx\n", efi.uga);
115 
116 	return str - buf;
117 }
118 
119 static struct kobj_attribute efi_attr_systab =
120 			__ATTR(systab, 0400, systab_show, NULL);
121 
122 #define EFI_FIELD(var) efi.var
123 
124 #define EFI_ATTR_SHOW(name) \
125 static ssize_t name##_show(struct kobject *kobj, \
126 				struct kobj_attribute *attr, char *buf) \
127 { \
128 	return sprintf(buf, "0x%lx\n", EFI_FIELD(name)); \
129 }
130 
131 EFI_ATTR_SHOW(fw_vendor);
132 EFI_ATTR_SHOW(runtime);
133 EFI_ATTR_SHOW(config_table);
134 
135 static ssize_t fw_platform_size_show(struct kobject *kobj,
136 				     struct kobj_attribute *attr, char *buf)
137 {
138 	return sprintf(buf, "%d\n", efi_enabled(EFI_64BIT) ? 64 : 32);
139 }
140 
141 static struct kobj_attribute efi_attr_fw_vendor = __ATTR_RO(fw_vendor);
142 static struct kobj_attribute efi_attr_runtime = __ATTR_RO(runtime);
143 static struct kobj_attribute efi_attr_config_table = __ATTR_RO(config_table);
144 static struct kobj_attribute efi_attr_fw_platform_size =
145 	__ATTR_RO(fw_platform_size);
146 
147 static struct attribute *efi_subsys_attrs[] = {
148 	&efi_attr_systab.attr,
149 	&efi_attr_fw_vendor.attr,
150 	&efi_attr_runtime.attr,
151 	&efi_attr_config_table.attr,
152 	&efi_attr_fw_platform_size.attr,
153 	NULL,
154 };
155 
156 static umode_t efi_attr_is_visible(struct kobject *kobj,
157 				   struct attribute *attr, int n)
158 {
159 	if (attr == &efi_attr_fw_vendor.attr) {
160 		if (efi_enabled(EFI_PARAVIRT) ||
161 				efi.fw_vendor == EFI_INVALID_TABLE_ADDR)
162 			return 0;
163 	} else if (attr == &efi_attr_runtime.attr) {
164 		if (efi.runtime == EFI_INVALID_TABLE_ADDR)
165 			return 0;
166 	} else if (attr == &efi_attr_config_table.attr) {
167 		if (efi.config_table == EFI_INVALID_TABLE_ADDR)
168 			return 0;
169 	}
170 
171 	return attr->mode;
172 }
173 
174 static struct attribute_group efi_subsys_attr_group = {
175 	.attrs = efi_subsys_attrs,
176 	.is_visible = efi_attr_is_visible,
177 };
178 
179 static struct efivars generic_efivars;
180 static struct efivar_operations generic_ops;
181 
182 static int generic_ops_register(void)
183 {
184 	generic_ops.get_variable = efi.get_variable;
185 	generic_ops.set_variable = efi.set_variable;
186 	generic_ops.set_variable_nonblocking = efi.set_variable_nonblocking;
187 	generic_ops.get_next_variable = efi.get_next_variable;
188 	generic_ops.query_variable_store = efi_query_variable_store;
189 
190 	return efivars_register(&generic_efivars, &generic_ops, efi_kobj);
191 }
192 
193 static void generic_ops_unregister(void)
194 {
195 	efivars_unregister(&generic_efivars);
196 }
197 
198 /*
199  * We register the efi subsystem with the firmware subsystem and the
200  * efivars subsystem with the efi subsystem, if the system was booted with
201  * EFI.
202  */
203 static int __init efisubsys_init(void)
204 {
205 	int error;
206 
207 	if (!efi_enabled(EFI_BOOT))
208 		return 0;
209 
210 	/* We register the efi directory at /sys/firmware/efi */
211 	efi_kobj = kobject_create_and_add("efi", firmware_kobj);
212 	if (!efi_kobj) {
213 		pr_err("efi: Firmware registration failed.\n");
214 		return -ENOMEM;
215 	}
216 
217 	error = generic_ops_register();
218 	if (error)
219 		goto err_put;
220 
221 	error = sysfs_create_group(efi_kobj, &efi_subsys_attr_group);
222 	if (error) {
223 		pr_err("efi: Sysfs attribute export failed with error %d.\n",
224 		       error);
225 		goto err_unregister;
226 	}
227 
228 	error = efi_runtime_map_init(efi_kobj);
229 	if (error)
230 		goto err_remove_group;
231 
232 	/* and the standard mountpoint for efivarfs */
233 	error = sysfs_create_mount_point(efi_kobj, "efivars");
234 	if (error) {
235 		pr_err("efivars: Subsystem registration failed.\n");
236 		goto err_remove_group;
237 	}
238 
239 	return 0;
240 
241 err_remove_group:
242 	sysfs_remove_group(efi_kobj, &efi_subsys_attr_group);
243 err_unregister:
244 	generic_ops_unregister();
245 err_put:
246 	kobject_put(efi_kobj);
247 	return error;
248 }
249 
250 subsys_initcall(efisubsys_init);
251 
252 /*
253  * Find the efi memory descriptor for a given physical address.  Given a
254  * physicall address, determine if it exists within an EFI Memory Map entry,
255  * and if so, populate the supplied memory descriptor with the appropriate
256  * data.
257  */
258 int __init efi_mem_desc_lookup(u64 phys_addr, efi_memory_desc_t *out_md)
259 {
260 	struct efi_memory_map *map = &efi.memmap;
261 	phys_addr_t p, e;
262 
263 	if (!efi_enabled(EFI_MEMMAP)) {
264 		pr_err_once("EFI_MEMMAP is not enabled.\n");
265 		return -EINVAL;
266 	}
267 
268 	if (!map) {
269 		pr_err_once("efi.memmap is not set.\n");
270 		return -EINVAL;
271 	}
272 	if (!out_md) {
273 		pr_err_once("out_md is null.\n");
274 		return -EINVAL;
275         }
276 	if (WARN_ON_ONCE(!map->phys_map))
277 		return -EINVAL;
278 	if (WARN_ON_ONCE(map->nr_map == 0) || WARN_ON_ONCE(map->desc_size == 0))
279 		return -EINVAL;
280 
281 	e = map->phys_map + map->nr_map * map->desc_size;
282 	for (p = map->phys_map; p < e; p += map->desc_size) {
283 		efi_memory_desc_t *md;
284 		u64 size;
285 		u64 end;
286 
287 		/*
288 		 * If a driver calls this after efi_free_boot_services,
289 		 * ->map will be NULL, and the target may also not be mapped.
290 		 * So just always get our own virtual map on the CPU.
291 		 *
292 		 */
293 		md = early_memremap(p, sizeof (*md));
294 		if (!md) {
295 			pr_err_once("early_memremap(%pa, %zu) failed.\n",
296 				    &p, sizeof (*md));
297 			return -ENOMEM;
298 		}
299 
300 		if (!(md->attribute & EFI_MEMORY_RUNTIME) &&
301 		    md->type != EFI_BOOT_SERVICES_DATA &&
302 		    md->type != EFI_RUNTIME_SERVICES_DATA) {
303 			early_memunmap(md, sizeof (*md));
304 			continue;
305 		}
306 
307 		size = md->num_pages << EFI_PAGE_SHIFT;
308 		end = md->phys_addr + size;
309 		if (phys_addr >= md->phys_addr && phys_addr < end) {
310 			memcpy(out_md, md, sizeof(*out_md));
311 			early_memunmap(md, sizeof (*md));
312 			return 0;
313 		}
314 
315 		early_memunmap(md, sizeof (*md));
316 	}
317 	pr_err_once("requested map not found.\n");
318 	return -ENOENT;
319 }
320 
321 /*
322  * Calculate the highest address of an efi memory descriptor.
323  */
324 u64 __init efi_mem_desc_end(efi_memory_desc_t *md)
325 {
326 	u64 size = md->num_pages << EFI_PAGE_SHIFT;
327 	u64 end = md->phys_addr + size;
328 	return end;
329 }
330 
331 static __initdata efi_config_table_type_t common_tables[] = {
332 	{ACPI_20_TABLE_GUID, "ACPI 2.0", &efi.acpi20},
333 	{ACPI_TABLE_GUID, "ACPI", &efi.acpi},
334 	{HCDP_TABLE_GUID, "HCDP", &efi.hcdp},
335 	{MPS_TABLE_GUID, "MPS", &efi.mps},
336 	{SAL_SYSTEM_TABLE_GUID, "SALsystab", &efi.sal_systab},
337 	{SMBIOS_TABLE_GUID, "SMBIOS", &efi.smbios},
338 	{SMBIOS3_TABLE_GUID, "SMBIOS 3.0", &efi.smbios3},
339 	{UGA_IO_PROTOCOL_GUID, "UGA", &efi.uga},
340 	{EFI_SYSTEM_RESOURCE_TABLE_GUID, "ESRT", &efi.esrt},
341 	{EFI_PROPERTIES_TABLE_GUID, "PROP", &efi.properties_table},
342 	{EFI_MEMORY_ATTRIBUTES_TABLE_GUID, "MEMATTR", &efi.mem_attr_table},
343 	{NULL_GUID, NULL, NULL},
344 };
345 
346 static __init int match_config_table(efi_guid_t *guid,
347 				     unsigned long table,
348 				     efi_config_table_type_t *table_types)
349 {
350 	int i;
351 
352 	if (table_types) {
353 		for (i = 0; efi_guidcmp(table_types[i].guid, NULL_GUID); i++) {
354 			if (!efi_guidcmp(*guid, table_types[i].guid)) {
355 				*(table_types[i].ptr) = table;
356 				if (table_types[i].name)
357 					pr_cont(" %s=0x%lx ",
358 						table_types[i].name, table);
359 				return 1;
360 			}
361 		}
362 	}
363 
364 	return 0;
365 }
366 
367 int __init efi_config_parse_tables(void *config_tables, int count, int sz,
368 				   efi_config_table_type_t *arch_tables)
369 {
370 	void *tablep;
371 	int i;
372 
373 	tablep = config_tables;
374 	pr_info("");
375 	for (i = 0; i < count; i++) {
376 		efi_guid_t guid;
377 		unsigned long table;
378 
379 		if (efi_enabled(EFI_64BIT)) {
380 			u64 table64;
381 			guid = ((efi_config_table_64_t *)tablep)->guid;
382 			table64 = ((efi_config_table_64_t *)tablep)->table;
383 			table = table64;
384 #ifndef CONFIG_64BIT
385 			if (table64 >> 32) {
386 				pr_cont("\n");
387 				pr_err("Table located above 4GB, disabling EFI.\n");
388 				return -EINVAL;
389 			}
390 #endif
391 		} else {
392 			guid = ((efi_config_table_32_t *)tablep)->guid;
393 			table = ((efi_config_table_32_t *)tablep)->table;
394 		}
395 
396 		if (!match_config_table(&guid, table, common_tables))
397 			match_config_table(&guid, table, arch_tables);
398 
399 		tablep += sz;
400 	}
401 	pr_cont("\n");
402 	set_bit(EFI_CONFIG_TABLES, &efi.flags);
403 
404 	/* Parse the EFI Properties table if it exists */
405 	if (efi.properties_table != EFI_INVALID_TABLE_ADDR) {
406 		efi_properties_table_t *tbl;
407 
408 		tbl = early_memremap(efi.properties_table, sizeof(*tbl));
409 		if (tbl == NULL) {
410 			pr_err("Could not map Properties table!\n");
411 			return -ENOMEM;
412 		}
413 
414 		if (tbl->memory_protection_attribute &
415 		    EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA)
416 			set_bit(EFI_NX_PE_DATA, &efi.flags);
417 
418 		early_memunmap(tbl, sizeof(*tbl));
419 	}
420 
421 	return 0;
422 }
423 
424 int __init efi_config_init(efi_config_table_type_t *arch_tables)
425 {
426 	void *config_tables;
427 	int sz, ret;
428 
429 	if (efi_enabled(EFI_64BIT))
430 		sz = sizeof(efi_config_table_64_t);
431 	else
432 		sz = sizeof(efi_config_table_32_t);
433 
434 	/*
435 	 * Let's see what config tables the firmware passed to us.
436 	 */
437 	config_tables = early_memremap(efi.systab->tables,
438 				       efi.systab->nr_tables * sz);
439 	if (config_tables == NULL) {
440 		pr_err("Could not map Configuration table!\n");
441 		return -ENOMEM;
442 	}
443 
444 	ret = efi_config_parse_tables(config_tables, efi.systab->nr_tables, sz,
445 				      arch_tables);
446 
447 	early_memunmap(config_tables, efi.systab->nr_tables * sz);
448 	return ret;
449 }
450 
451 #ifdef CONFIG_EFI_VARS_MODULE
452 static int __init efi_load_efivars(void)
453 {
454 	struct platform_device *pdev;
455 
456 	if (!efi_enabled(EFI_RUNTIME_SERVICES))
457 		return 0;
458 
459 	pdev = platform_device_register_simple("efivars", 0, NULL, 0);
460 	return IS_ERR(pdev) ? PTR_ERR(pdev) : 0;
461 }
462 device_initcall(efi_load_efivars);
463 #endif
464 
465 #ifdef CONFIG_EFI_PARAMS_FROM_FDT
466 
467 #define UEFI_PARAM(name, prop, field)			   \
468 	{						   \
469 		{ name },				   \
470 		{ prop },				   \
471 		offsetof(struct efi_fdt_params, field),    \
472 		FIELD_SIZEOF(struct efi_fdt_params, field) \
473 	}
474 
475 struct params {
476 	const char name[32];
477 	const char propname[32];
478 	int offset;
479 	int size;
480 };
481 
482 static __initdata struct params fdt_params[] = {
483 	UEFI_PARAM("System Table", "linux,uefi-system-table", system_table),
484 	UEFI_PARAM("MemMap Address", "linux,uefi-mmap-start", mmap),
485 	UEFI_PARAM("MemMap Size", "linux,uefi-mmap-size", mmap_size),
486 	UEFI_PARAM("MemMap Desc. Size", "linux,uefi-mmap-desc-size", desc_size),
487 	UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver)
488 };
489 
490 static __initdata struct params xen_fdt_params[] = {
491 	UEFI_PARAM("System Table", "xen,uefi-system-table", system_table),
492 	UEFI_PARAM("MemMap Address", "xen,uefi-mmap-start", mmap),
493 	UEFI_PARAM("MemMap Size", "xen,uefi-mmap-size", mmap_size),
494 	UEFI_PARAM("MemMap Desc. Size", "xen,uefi-mmap-desc-size", desc_size),
495 	UEFI_PARAM("MemMap Desc. Version", "xen,uefi-mmap-desc-ver", desc_ver)
496 };
497 
498 #define EFI_FDT_PARAMS_SIZE	ARRAY_SIZE(fdt_params)
499 
500 static __initdata struct {
501 	const char *uname;
502 	const char *subnode;
503 	struct params *params;
504 } dt_params[] = {
505 	{ "hypervisor", "uefi", xen_fdt_params },
506 	{ "chosen", NULL, fdt_params },
507 };
508 
509 struct param_info {
510 	int found;
511 	void *params;
512 	const char *missing;
513 };
514 
515 static int __init __find_uefi_params(unsigned long node,
516 				     struct param_info *info,
517 				     struct params *params)
518 {
519 	const void *prop;
520 	void *dest;
521 	u64 val;
522 	int i, len;
523 
524 	for (i = 0; i < EFI_FDT_PARAMS_SIZE; i++) {
525 		prop = of_get_flat_dt_prop(node, params[i].propname, &len);
526 		if (!prop) {
527 			info->missing = params[i].name;
528 			return 0;
529 		}
530 
531 		dest = info->params + params[i].offset;
532 		info->found++;
533 
534 		val = of_read_number(prop, len / sizeof(u32));
535 
536 		if (params[i].size == sizeof(u32))
537 			*(u32 *)dest = val;
538 		else
539 			*(u64 *)dest = val;
540 
541 		if (efi_enabled(EFI_DBG))
542 			pr_info("  %s: 0x%0*llx\n", params[i].name,
543 				params[i].size * 2, val);
544 	}
545 
546 	return 1;
547 }
548 
549 static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
550 				       int depth, void *data)
551 {
552 	struct param_info *info = data;
553 	int i;
554 
555 	for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
556 		const char *subnode = dt_params[i].subnode;
557 
558 		if (depth != 1 || strcmp(uname, dt_params[i].uname) != 0) {
559 			info->missing = dt_params[i].params[0].name;
560 			continue;
561 		}
562 
563 		if (subnode) {
564 			node = of_get_flat_dt_subnode_by_name(node, subnode);
565 			if (node < 0)
566 				return 0;
567 		}
568 
569 		return __find_uefi_params(node, info, dt_params[i].params);
570 	}
571 
572 	return 0;
573 }
574 
575 int __init efi_get_fdt_params(struct efi_fdt_params *params)
576 {
577 	struct param_info info;
578 	int ret;
579 
580 	pr_info("Getting EFI parameters from FDT:\n");
581 
582 	info.found = 0;
583 	info.params = params;
584 
585 	ret = of_scan_flat_dt(fdt_find_uefi_params, &info);
586 	if (!info.found)
587 		pr_info("UEFI not found.\n");
588 	else if (!ret)
589 		pr_err("Can't find '%s' in device tree!\n",
590 		       info.missing);
591 
592 	return ret;
593 }
594 #endif /* CONFIG_EFI_PARAMS_FROM_FDT */
595 
596 static __initdata char memory_type_name[][20] = {
597 	"Reserved",
598 	"Loader Code",
599 	"Loader Data",
600 	"Boot Code",
601 	"Boot Data",
602 	"Runtime Code",
603 	"Runtime Data",
604 	"Conventional Memory",
605 	"Unusable Memory",
606 	"ACPI Reclaim Memory",
607 	"ACPI Memory NVS",
608 	"Memory Mapped I/O",
609 	"MMIO Port Space",
610 	"PAL Code",
611 	"Persistent Memory",
612 };
613 
614 char * __init efi_md_typeattr_format(char *buf, size_t size,
615 				     const efi_memory_desc_t *md)
616 {
617 	char *pos;
618 	int type_len;
619 	u64 attr;
620 
621 	pos = buf;
622 	if (md->type >= ARRAY_SIZE(memory_type_name))
623 		type_len = snprintf(pos, size, "[type=%u", md->type);
624 	else
625 		type_len = snprintf(pos, size, "[%-*s",
626 				    (int)(sizeof(memory_type_name[0]) - 1),
627 				    memory_type_name[md->type]);
628 	if (type_len >= size)
629 		return buf;
630 
631 	pos += type_len;
632 	size -= type_len;
633 
634 	attr = md->attribute;
635 	if (attr & ~(EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT |
636 		     EFI_MEMORY_WB | EFI_MEMORY_UCE | EFI_MEMORY_RO |
637 		     EFI_MEMORY_WP | EFI_MEMORY_RP | EFI_MEMORY_XP |
638 		     EFI_MEMORY_NV |
639 		     EFI_MEMORY_RUNTIME | EFI_MEMORY_MORE_RELIABLE))
640 		snprintf(pos, size, "|attr=0x%016llx]",
641 			 (unsigned long long)attr);
642 	else
643 		snprintf(pos, size,
644 			 "|%3s|%2s|%2s|%2s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]",
645 			 attr & EFI_MEMORY_RUNTIME ? "RUN" : "",
646 			 attr & EFI_MEMORY_MORE_RELIABLE ? "MR" : "",
647 			 attr & EFI_MEMORY_NV      ? "NV"  : "",
648 			 attr & EFI_MEMORY_XP      ? "XP"  : "",
649 			 attr & EFI_MEMORY_RP      ? "RP"  : "",
650 			 attr & EFI_MEMORY_WP      ? "WP"  : "",
651 			 attr & EFI_MEMORY_RO      ? "RO"  : "",
652 			 attr & EFI_MEMORY_UCE     ? "UCE" : "",
653 			 attr & EFI_MEMORY_WB      ? "WB"  : "",
654 			 attr & EFI_MEMORY_WT      ? "WT"  : "",
655 			 attr & EFI_MEMORY_WC      ? "WC"  : "",
656 			 attr & EFI_MEMORY_UC      ? "UC"  : "");
657 	return buf;
658 }
659 
660 /*
661  * efi_mem_attributes - lookup memmap attributes for physical address
662  * @phys_addr: the physical address to lookup
663  *
664  * Search in the EFI memory map for the region covering
665  * @phys_addr. Returns the EFI memory attributes if the region
666  * was found in the memory map, 0 otherwise.
667  *
668  * Despite being marked __weak, most architectures should *not*
669  * override this function. It is __weak solely for the benefit
670  * of ia64 which has a funky EFI memory map that doesn't work
671  * the same way as other architectures.
672  */
673 u64 __weak efi_mem_attributes(unsigned long phys_addr)
674 {
675 	efi_memory_desc_t *md;
676 
677 	if (!efi_enabled(EFI_MEMMAP))
678 		return 0;
679 
680 	for_each_efi_memory_desc(md) {
681 		if ((md->phys_addr <= phys_addr) &&
682 		    (phys_addr < (md->phys_addr +
683 		    (md->num_pages << EFI_PAGE_SHIFT))))
684 			return md->attribute;
685 	}
686 	return 0;
687 }
688 
689 int efi_status_to_err(efi_status_t status)
690 {
691 	int err;
692 
693 	switch (status) {
694 	case EFI_SUCCESS:
695 		err = 0;
696 		break;
697 	case EFI_INVALID_PARAMETER:
698 		err = -EINVAL;
699 		break;
700 	case EFI_OUT_OF_RESOURCES:
701 		err = -ENOSPC;
702 		break;
703 	case EFI_DEVICE_ERROR:
704 		err = -EIO;
705 		break;
706 	case EFI_WRITE_PROTECTED:
707 		err = -EROFS;
708 		break;
709 	case EFI_SECURITY_VIOLATION:
710 		err = -EACCES;
711 		break;
712 	case EFI_NOT_FOUND:
713 		err = -ENOENT;
714 		break;
715 	default:
716 		err = -EINVAL;
717 	}
718 
719 	return err;
720 }
721