scsi: ufshcd: release resources if probe fails
[linux/fpc-iii.git] / drivers / firmware / efi / efi.c
blob1ac199cd75e7bdd56ce8d5b9ab91bc2ee9d15133
1 /*
2 * efi.c - EFI subsystem
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>
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.
13 * This file is released under the GPLv2.
16 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
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 #include <linux/slab.h>
28 #include <linux/acpi.h>
29 #include <linux/ucs2_string.h>
30 #include <linux/memblock.h>
32 #include <asm/early_ioremap.h>
34 struct efi __read_mostly efi = {
35 .mps = EFI_INVALID_TABLE_ADDR,
36 .acpi = EFI_INVALID_TABLE_ADDR,
37 .acpi20 = EFI_INVALID_TABLE_ADDR,
38 .smbios = EFI_INVALID_TABLE_ADDR,
39 .smbios3 = EFI_INVALID_TABLE_ADDR,
40 .sal_systab = EFI_INVALID_TABLE_ADDR,
41 .boot_info = EFI_INVALID_TABLE_ADDR,
42 .hcdp = EFI_INVALID_TABLE_ADDR,
43 .uga = EFI_INVALID_TABLE_ADDR,
44 .uv_systab = EFI_INVALID_TABLE_ADDR,
45 .fw_vendor = EFI_INVALID_TABLE_ADDR,
46 .runtime = EFI_INVALID_TABLE_ADDR,
47 .config_table = EFI_INVALID_TABLE_ADDR,
48 .esrt = EFI_INVALID_TABLE_ADDR,
49 .properties_table = EFI_INVALID_TABLE_ADDR,
50 .mem_attr_table = EFI_INVALID_TABLE_ADDR,
52 EXPORT_SYMBOL(efi);
54 static bool disable_runtime;
55 static int __init setup_noefi(char *arg)
57 disable_runtime = true;
58 return 0;
60 early_param("noefi", setup_noefi);
62 bool efi_runtime_disabled(void)
64 return disable_runtime;
67 static int __init parse_efi_cmdline(char *str)
69 if (!str) {
70 pr_warn("need at least one option\n");
71 return -EINVAL;
74 if (parse_option_str(str, "debug"))
75 set_bit(EFI_DBG, &efi.flags);
77 if (parse_option_str(str, "noruntime"))
78 disable_runtime = true;
80 return 0;
82 early_param("efi", parse_efi_cmdline);
84 struct kobject *efi_kobj;
87 * Let's not leave out systab information that snuck into
88 * the efivars driver
90 static ssize_t systab_show(struct kobject *kobj,
91 struct kobj_attribute *attr, char *buf)
93 char *str = buf;
95 if (!kobj || !buf)
96 return -EINVAL;
98 if (efi.mps != EFI_INVALID_TABLE_ADDR)
99 str += sprintf(str, "MPS=0x%lx\n", efi.mps);
100 if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
101 str += sprintf(str, "ACPI20=0x%lx\n", efi.acpi20);
102 if (efi.acpi != EFI_INVALID_TABLE_ADDR)
103 str += sprintf(str, "ACPI=0x%lx\n", efi.acpi);
105 * If both SMBIOS and SMBIOS3 entry points are implemented, the
106 * SMBIOS3 entry point shall be preferred, so we list it first to
107 * let applications stop parsing after the first match.
109 if (efi.smbios3 != EFI_INVALID_TABLE_ADDR)
110 str += sprintf(str, "SMBIOS3=0x%lx\n", efi.smbios3);
111 if (efi.smbios != EFI_INVALID_TABLE_ADDR)
112 str += sprintf(str, "SMBIOS=0x%lx\n", efi.smbios);
113 if (efi.hcdp != EFI_INVALID_TABLE_ADDR)
114 str += sprintf(str, "HCDP=0x%lx\n", efi.hcdp);
115 if (efi.boot_info != EFI_INVALID_TABLE_ADDR)
116 str += sprintf(str, "BOOTINFO=0x%lx\n", efi.boot_info);
117 if (efi.uga != EFI_INVALID_TABLE_ADDR)
118 str += sprintf(str, "UGA=0x%lx\n", efi.uga);
120 return str - buf;
123 static struct kobj_attribute efi_attr_systab =
124 __ATTR(systab, 0400, systab_show, NULL);
126 #define EFI_FIELD(var) efi.var
128 #define EFI_ATTR_SHOW(name) \
129 static ssize_t name##_show(struct kobject *kobj, \
130 struct kobj_attribute *attr, char *buf) \
132 return sprintf(buf, "0x%lx\n", EFI_FIELD(name)); \
135 EFI_ATTR_SHOW(fw_vendor);
136 EFI_ATTR_SHOW(runtime);
137 EFI_ATTR_SHOW(config_table);
139 static ssize_t fw_platform_size_show(struct kobject *kobj,
140 struct kobj_attribute *attr, char *buf)
142 return sprintf(buf, "%d\n", efi_enabled(EFI_64BIT) ? 64 : 32);
145 static struct kobj_attribute efi_attr_fw_vendor = __ATTR_RO(fw_vendor);
146 static struct kobj_attribute efi_attr_runtime = __ATTR_RO(runtime);
147 static struct kobj_attribute efi_attr_config_table = __ATTR_RO(config_table);
148 static struct kobj_attribute efi_attr_fw_platform_size =
149 __ATTR_RO(fw_platform_size);
151 static struct attribute *efi_subsys_attrs[] = {
152 &efi_attr_systab.attr,
153 &efi_attr_fw_vendor.attr,
154 &efi_attr_runtime.attr,
155 &efi_attr_config_table.attr,
156 &efi_attr_fw_platform_size.attr,
157 NULL,
160 static umode_t efi_attr_is_visible(struct kobject *kobj,
161 struct attribute *attr, int n)
163 if (attr == &efi_attr_fw_vendor.attr) {
164 if (efi_enabled(EFI_PARAVIRT) ||
165 efi.fw_vendor == EFI_INVALID_TABLE_ADDR)
166 return 0;
167 } else if (attr == &efi_attr_runtime.attr) {
168 if (efi.runtime == EFI_INVALID_TABLE_ADDR)
169 return 0;
170 } else if (attr == &efi_attr_config_table.attr) {
171 if (efi.config_table == EFI_INVALID_TABLE_ADDR)
172 return 0;
175 return attr->mode;
178 static struct attribute_group efi_subsys_attr_group = {
179 .attrs = efi_subsys_attrs,
180 .is_visible = efi_attr_is_visible,
183 static struct efivars generic_efivars;
184 static struct efivar_operations generic_ops;
186 static int generic_ops_register(void)
188 generic_ops.get_variable = efi.get_variable;
189 generic_ops.set_variable = efi.set_variable;
190 generic_ops.set_variable_nonblocking = efi.set_variable_nonblocking;
191 generic_ops.get_next_variable = efi.get_next_variable;
192 generic_ops.query_variable_store = efi_query_variable_store;
194 return efivars_register(&generic_efivars, &generic_ops, efi_kobj);
197 static void generic_ops_unregister(void)
199 efivars_unregister(&generic_efivars);
202 #if IS_ENABLED(CONFIG_ACPI)
203 #define EFIVAR_SSDT_NAME_MAX 16
204 static char efivar_ssdt[EFIVAR_SSDT_NAME_MAX] __initdata;
205 static int __init efivar_ssdt_setup(char *str)
207 if (strlen(str) < sizeof(efivar_ssdt))
208 memcpy(efivar_ssdt, str, strlen(str));
209 else
210 pr_warn("efivar_ssdt: name too long: %s\n", str);
211 return 0;
213 __setup("efivar_ssdt=", efivar_ssdt_setup);
215 static __init int efivar_ssdt_iter(efi_char16_t *name, efi_guid_t vendor,
216 unsigned long name_size, void *data)
218 struct efivar_entry *entry;
219 struct list_head *list = data;
220 char utf8_name[EFIVAR_SSDT_NAME_MAX];
221 int limit = min_t(unsigned long, EFIVAR_SSDT_NAME_MAX, name_size);
223 ucs2_as_utf8(utf8_name, name, limit - 1);
224 if (strncmp(utf8_name, efivar_ssdt, limit) != 0)
225 return 0;
227 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
228 if (!entry)
229 return 0;
231 memcpy(entry->var.VariableName, name, name_size);
232 memcpy(&entry->var.VendorGuid, &vendor, sizeof(efi_guid_t));
234 efivar_entry_add(entry, list);
236 return 0;
239 static __init int efivar_ssdt_load(void)
241 LIST_HEAD(entries);
242 struct efivar_entry *entry, *aux;
243 unsigned long size;
244 void *data;
245 int ret;
247 ret = efivar_init(efivar_ssdt_iter, &entries, true, &entries);
249 list_for_each_entry_safe(entry, aux, &entries, list) {
250 pr_info("loading SSDT from variable %s-%pUl\n", efivar_ssdt,
251 &entry->var.VendorGuid);
253 list_del(&entry->list);
255 ret = efivar_entry_size(entry, &size);
256 if (ret) {
257 pr_err("failed to get var size\n");
258 goto free_entry;
261 data = kmalloc(size, GFP_KERNEL);
262 if (!data)
263 goto free_entry;
265 ret = efivar_entry_get(entry, NULL, &size, data);
266 if (ret) {
267 pr_err("failed to get var data\n");
268 goto free_data;
271 ret = acpi_load_table(data);
272 if (ret) {
273 pr_err("failed to load table: %d\n", ret);
274 goto free_data;
277 goto free_entry;
279 free_data:
280 kfree(data);
282 free_entry:
283 kfree(entry);
286 return ret;
288 #else
289 static inline int efivar_ssdt_load(void) { return 0; }
290 #endif
293 * We register the efi subsystem with the firmware subsystem and the
294 * efivars subsystem with the efi subsystem, if the system was booted with
295 * EFI.
297 static int __init efisubsys_init(void)
299 int error;
301 if (!efi_enabled(EFI_BOOT))
302 return 0;
304 /* We register the efi directory at /sys/firmware/efi */
305 efi_kobj = kobject_create_and_add("efi", firmware_kobj);
306 if (!efi_kobj) {
307 pr_err("efi: Firmware registration failed.\n");
308 return -ENOMEM;
311 error = generic_ops_register();
312 if (error)
313 goto err_put;
315 if (efi_enabled(EFI_RUNTIME_SERVICES))
316 efivar_ssdt_load();
318 error = sysfs_create_group(efi_kobj, &efi_subsys_attr_group);
319 if (error) {
320 pr_err("efi: Sysfs attribute export failed with error %d.\n",
321 error);
322 goto err_unregister;
325 error = efi_runtime_map_init(efi_kobj);
326 if (error)
327 goto err_remove_group;
329 /* and the standard mountpoint for efivarfs */
330 error = sysfs_create_mount_point(efi_kobj, "efivars");
331 if (error) {
332 pr_err("efivars: Subsystem registration failed.\n");
333 goto err_remove_group;
336 return 0;
338 err_remove_group:
339 sysfs_remove_group(efi_kobj, &efi_subsys_attr_group);
340 err_unregister:
341 generic_ops_unregister();
342 err_put:
343 kobject_put(efi_kobj);
344 return error;
347 subsys_initcall(efisubsys_init);
350 * Find the efi memory descriptor for a given physical address. Given a
351 * physical address, determine if it exists within an EFI Memory Map entry,
352 * and if so, populate the supplied memory descriptor with the appropriate
353 * data.
355 int __init efi_mem_desc_lookup(u64 phys_addr, efi_memory_desc_t *out_md)
357 efi_memory_desc_t *md;
359 if (!efi_enabled(EFI_MEMMAP)) {
360 pr_err_once("EFI_MEMMAP is not enabled.\n");
361 return -EINVAL;
364 if (!out_md) {
365 pr_err_once("out_md is null.\n");
366 return -EINVAL;
369 for_each_efi_memory_desc(md) {
370 u64 size;
371 u64 end;
373 if (!(md->attribute & EFI_MEMORY_RUNTIME) &&
374 md->type != EFI_BOOT_SERVICES_DATA &&
375 md->type != EFI_RUNTIME_SERVICES_DATA) {
376 continue;
379 size = md->num_pages << EFI_PAGE_SHIFT;
380 end = md->phys_addr + size;
381 if (phys_addr >= md->phys_addr && phys_addr < end) {
382 memcpy(out_md, md, sizeof(*out_md));
383 return 0;
386 pr_err_once("requested map not found.\n");
387 return -ENOENT;
391 * Calculate the highest address of an efi memory descriptor.
393 u64 __init efi_mem_desc_end(efi_memory_desc_t *md)
395 u64 size = md->num_pages << EFI_PAGE_SHIFT;
396 u64 end = md->phys_addr + size;
397 return end;
400 void __init __weak efi_arch_mem_reserve(phys_addr_t addr, u64 size) {}
403 * efi_mem_reserve - Reserve an EFI memory region
404 * @addr: Physical address to reserve
405 * @size: Size of reservation
407 * Mark a region as reserved from general kernel allocation and
408 * prevent it being released by efi_free_boot_services().
410 * This function should be called drivers once they've parsed EFI
411 * configuration tables to figure out where their data lives, e.g.
412 * efi_esrt_init().
414 void __init efi_mem_reserve(phys_addr_t addr, u64 size)
416 if (!memblock_is_region_reserved(addr, size))
417 memblock_reserve(addr, size);
420 * Some architectures (x86) reserve all boot services ranges
421 * until efi_free_boot_services() because of buggy firmware
422 * implementations. This means the above memblock_reserve() is
423 * superfluous on x86 and instead what it needs to do is
424 * ensure the @start, @size is not freed.
426 efi_arch_mem_reserve(addr, size);
429 static __initdata efi_config_table_type_t common_tables[] = {
430 {ACPI_20_TABLE_GUID, "ACPI 2.0", &efi.acpi20},
431 {ACPI_TABLE_GUID, "ACPI", &efi.acpi},
432 {HCDP_TABLE_GUID, "HCDP", &efi.hcdp},
433 {MPS_TABLE_GUID, "MPS", &efi.mps},
434 {SAL_SYSTEM_TABLE_GUID, "SALsystab", &efi.sal_systab},
435 {SMBIOS_TABLE_GUID, "SMBIOS", &efi.smbios},
436 {SMBIOS3_TABLE_GUID, "SMBIOS 3.0", &efi.smbios3},
437 {UGA_IO_PROTOCOL_GUID, "UGA", &efi.uga},
438 {EFI_SYSTEM_RESOURCE_TABLE_GUID, "ESRT", &efi.esrt},
439 {EFI_PROPERTIES_TABLE_GUID, "PROP", &efi.properties_table},
440 {EFI_MEMORY_ATTRIBUTES_TABLE_GUID, "MEMATTR", &efi.mem_attr_table},
441 {NULL_GUID, NULL, NULL},
444 static __init int match_config_table(efi_guid_t *guid,
445 unsigned long table,
446 efi_config_table_type_t *table_types)
448 int i;
450 if (table_types) {
451 for (i = 0; efi_guidcmp(table_types[i].guid, NULL_GUID); i++) {
452 if (!efi_guidcmp(*guid, table_types[i].guid)) {
453 *(table_types[i].ptr) = table;
454 if (table_types[i].name)
455 pr_cont(" %s=0x%lx ",
456 table_types[i].name, table);
457 return 1;
462 return 0;
465 int __init efi_config_parse_tables(void *config_tables, int count, int sz,
466 efi_config_table_type_t *arch_tables)
468 void *tablep;
469 int i;
471 tablep = config_tables;
472 pr_info("");
473 for (i = 0; i < count; i++) {
474 efi_guid_t guid;
475 unsigned long table;
477 if (efi_enabled(EFI_64BIT)) {
478 u64 table64;
479 guid = ((efi_config_table_64_t *)tablep)->guid;
480 table64 = ((efi_config_table_64_t *)tablep)->table;
481 table = table64;
482 #ifndef CONFIG_64BIT
483 if (table64 >> 32) {
484 pr_cont("\n");
485 pr_err("Table located above 4GB, disabling EFI.\n");
486 return -EINVAL;
488 #endif
489 } else {
490 guid = ((efi_config_table_32_t *)tablep)->guid;
491 table = ((efi_config_table_32_t *)tablep)->table;
494 if (!match_config_table(&guid, table, common_tables))
495 match_config_table(&guid, table, arch_tables);
497 tablep += sz;
499 pr_cont("\n");
500 set_bit(EFI_CONFIG_TABLES, &efi.flags);
502 /* Parse the EFI Properties table if it exists */
503 if (efi.properties_table != EFI_INVALID_TABLE_ADDR) {
504 efi_properties_table_t *tbl;
506 tbl = early_memremap(efi.properties_table, sizeof(*tbl));
507 if (tbl == NULL) {
508 pr_err("Could not map Properties table!\n");
509 return -ENOMEM;
512 if (tbl->memory_protection_attribute &
513 EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA)
514 set_bit(EFI_NX_PE_DATA, &efi.flags);
516 early_memunmap(tbl, sizeof(*tbl));
519 return 0;
522 int __init efi_config_init(efi_config_table_type_t *arch_tables)
524 void *config_tables;
525 int sz, ret;
527 if (efi_enabled(EFI_64BIT))
528 sz = sizeof(efi_config_table_64_t);
529 else
530 sz = sizeof(efi_config_table_32_t);
533 * Let's see what config tables the firmware passed to us.
535 config_tables = early_memremap(efi.systab->tables,
536 efi.systab->nr_tables * sz);
537 if (config_tables == NULL) {
538 pr_err("Could not map Configuration table!\n");
539 return -ENOMEM;
542 ret = efi_config_parse_tables(config_tables, efi.systab->nr_tables, sz,
543 arch_tables);
545 early_memunmap(config_tables, efi.systab->nr_tables * sz);
546 return ret;
549 #ifdef CONFIG_EFI_VARS_MODULE
550 static int __init efi_load_efivars(void)
552 struct platform_device *pdev;
554 if (!efi_enabled(EFI_RUNTIME_SERVICES))
555 return 0;
557 pdev = platform_device_register_simple("efivars", 0, NULL, 0);
558 return IS_ERR(pdev) ? PTR_ERR(pdev) : 0;
560 device_initcall(efi_load_efivars);
561 #endif
563 #ifdef CONFIG_EFI_PARAMS_FROM_FDT
565 #define UEFI_PARAM(name, prop, field) \
567 { name }, \
568 { prop }, \
569 offsetof(struct efi_fdt_params, field), \
570 FIELD_SIZEOF(struct efi_fdt_params, field) \
573 struct params {
574 const char name[32];
575 const char propname[32];
576 int offset;
577 int size;
580 static __initdata struct params fdt_params[] = {
581 UEFI_PARAM("System Table", "linux,uefi-system-table", system_table),
582 UEFI_PARAM("MemMap Address", "linux,uefi-mmap-start", mmap),
583 UEFI_PARAM("MemMap Size", "linux,uefi-mmap-size", mmap_size),
584 UEFI_PARAM("MemMap Desc. Size", "linux,uefi-mmap-desc-size", desc_size),
585 UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver)
588 static __initdata struct params xen_fdt_params[] = {
589 UEFI_PARAM("System Table", "xen,uefi-system-table", system_table),
590 UEFI_PARAM("MemMap Address", "xen,uefi-mmap-start", mmap),
591 UEFI_PARAM("MemMap Size", "xen,uefi-mmap-size", mmap_size),
592 UEFI_PARAM("MemMap Desc. Size", "xen,uefi-mmap-desc-size", desc_size),
593 UEFI_PARAM("MemMap Desc. Version", "xen,uefi-mmap-desc-ver", desc_ver)
596 #define EFI_FDT_PARAMS_SIZE ARRAY_SIZE(fdt_params)
598 static __initdata struct {
599 const char *uname;
600 const char *subnode;
601 struct params *params;
602 } dt_params[] = {
603 { "hypervisor", "uefi", xen_fdt_params },
604 { "chosen", NULL, fdt_params },
607 struct param_info {
608 int found;
609 void *params;
610 const char *missing;
613 static int __init __find_uefi_params(unsigned long node,
614 struct param_info *info,
615 struct params *params)
617 const void *prop;
618 void *dest;
619 u64 val;
620 int i, len;
622 for (i = 0; i < EFI_FDT_PARAMS_SIZE; i++) {
623 prop = of_get_flat_dt_prop(node, params[i].propname, &len);
624 if (!prop) {
625 info->missing = params[i].name;
626 return 0;
629 dest = info->params + params[i].offset;
630 info->found++;
632 val = of_read_number(prop, len / sizeof(u32));
634 if (params[i].size == sizeof(u32))
635 *(u32 *)dest = val;
636 else
637 *(u64 *)dest = val;
639 if (efi_enabled(EFI_DBG))
640 pr_info(" %s: 0x%0*llx\n", params[i].name,
641 params[i].size * 2, val);
644 return 1;
647 static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
648 int depth, void *data)
650 struct param_info *info = data;
651 int i;
653 for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
654 const char *subnode = dt_params[i].subnode;
656 if (depth != 1 || strcmp(uname, dt_params[i].uname) != 0) {
657 info->missing = dt_params[i].params[0].name;
658 continue;
661 if (subnode) {
662 int err = of_get_flat_dt_subnode_by_name(node, subnode);
664 if (err < 0)
665 return 0;
667 node = err;
670 return __find_uefi_params(node, info, dt_params[i].params);
673 return 0;
676 int __init efi_get_fdt_params(struct efi_fdt_params *params)
678 struct param_info info;
679 int ret;
681 pr_info("Getting EFI parameters from FDT:\n");
683 info.found = 0;
684 info.params = params;
686 ret = of_scan_flat_dt(fdt_find_uefi_params, &info);
687 if (!info.found)
688 pr_info("UEFI not found.\n");
689 else if (!ret)
690 pr_err("Can't find '%s' in device tree!\n",
691 info.missing);
693 return ret;
695 #endif /* CONFIG_EFI_PARAMS_FROM_FDT */
697 static __initdata char memory_type_name[][20] = {
698 "Reserved",
699 "Loader Code",
700 "Loader Data",
701 "Boot Code",
702 "Boot Data",
703 "Runtime Code",
704 "Runtime Data",
705 "Conventional Memory",
706 "Unusable Memory",
707 "ACPI Reclaim Memory",
708 "ACPI Memory NVS",
709 "Memory Mapped I/O",
710 "MMIO Port Space",
711 "PAL Code",
712 "Persistent Memory",
715 char * __init efi_md_typeattr_format(char *buf, size_t size,
716 const efi_memory_desc_t *md)
718 char *pos;
719 int type_len;
720 u64 attr;
722 pos = buf;
723 if (md->type >= ARRAY_SIZE(memory_type_name))
724 type_len = snprintf(pos, size, "[type=%u", md->type);
725 else
726 type_len = snprintf(pos, size, "[%-*s",
727 (int)(sizeof(memory_type_name[0]) - 1),
728 memory_type_name[md->type]);
729 if (type_len >= size)
730 return buf;
732 pos += type_len;
733 size -= type_len;
735 attr = md->attribute;
736 if (attr & ~(EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT |
737 EFI_MEMORY_WB | EFI_MEMORY_UCE | EFI_MEMORY_RO |
738 EFI_MEMORY_WP | EFI_MEMORY_RP | EFI_MEMORY_XP |
739 EFI_MEMORY_NV |
740 EFI_MEMORY_RUNTIME | EFI_MEMORY_MORE_RELIABLE))
741 snprintf(pos, size, "|attr=0x%016llx]",
742 (unsigned long long)attr);
743 else
744 snprintf(pos, size,
745 "|%3s|%2s|%2s|%2s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]",
746 attr & EFI_MEMORY_RUNTIME ? "RUN" : "",
747 attr & EFI_MEMORY_MORE_RELIABLE ? "MR" : "",
748 attr & EFI_MEMORY_NV ? "NV" : "",
749 attr & EFI_MEMORY_XP ? "XP" : "",
750 attr & EFI_MEMORY_RP ? "RP" : "",
751 attr & EFI_MEMORY_WP ? "WP" : "",
752 attr & EFI_MEMORY_RO ? "RO" : "",
753 attr & EFI_MEMORY_UCE ? "UCE" : "",
754 attr & EFI_MEMORY_WB ? "WB" : "",
755 attr & EFI_MEMORY_WT ? "WT" : "",
756 attr & EFI_MEMORY_WC ? "WC" : "",
757 attr & EFI_MEMORY_UC ? "UC" : "");
758 return buf;
762 * efi_mem_attributes - lookup memmap attributes for physical address
763 * @phys_addr: the physical address to lookup
765 * Search in the EFI memory map for the region covering
766 * @phys_addr. Returns the EFI memory attributes if the region
767 * was found in the memory map, 0 otherwise.
769 * Despite being marked __weak, most architectures should *not*
770 * override this function. It is __weak solely for the benefit
771 * of ia64 which has a funky EFI memory map that doesn't work
772 * the same way as other architectures.
774 u64 __weak efi_mem_attributes(unsigned long phys_addr)
776 efi_memory_desc_t *md;
778 if (!efi_enabled(EFI_MEMMAP))
779 return 0;
781 for_each_efi_memory_desc(md) {
782 if ((md->phys_addr <= phys_addr) &&
783 (phys_addr < (md->phys_addr +
784 (md->num_pages << EFI_PAGE_SHIFT))))
785 return md->attribute;
787 return 0;
790 int efi_status_to_err(efi_status_t status)
792 int err;
794 switch (status) {
795 case EFI_SUCCESS:
796 err = 0;
797 break;
798 case EFI_INVALID_PARAMETER:
799 err = -EINVAL;
800 break;
801 case EFI_OUT_OF_RESOURCES:
802 err = -ENOSPC;
803 break;
804 case EFI_DEVICE_ERROR:
805 err = -EIO;
806 break;
807 case EFI_WRITE_PROTECTED:
808 err = -EROFS;
809 break;
810 case EFI_SECURITY_VIOLATION:
811 err = -EACCES;
812 break;
813 case EFI_NOT_FOUND:
814 err = -ENOENT;
815 break;
816 case EFI_ABORTED:
817 err = -EINTR;
818 break;
819 default:
820 err = -EINVAL;
823 return err;