target: Fix kref->refcount underflow in transport_cmd_finish_abort
[linux/fpc-iii.git] / drivers / firmware / efi / efi.c
bloba4944e22f294b321fba70d572dc4996fcbb838f7
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 ret = -ENOMEM;
264 goto free_entry;
267 ret = efivar_entry_get(entry, NULL, &size, data);
268 if (ret) {
269 pr_err("failed to get var data\n");
270 goto free_data;
273 ret = acpi_load_table(data);
274 if (ret) {
275 pr_err("failed to load table: %d\n", ret);
276 goto free_data;
279 goto free_entry;
281 free_data:
282 kfree(data);
284 free_entry:
285 kfree(entry);
288 return ret;
290 #else
291 static inline int efivar_ssdt_load(void) { return 0; }
292 #endif
295 * We register the efi subsystem with the firmware subsystem and the
296 * efivars subsystem with the efi subsystem, if the system was booted with
297 * EFI.
299 static int __init efisubsys_init(void)
301 int error;
303 if (!efi_enabled(EFI_BOOT))
304 return 0;
306 /* We register the efi directory at /sys/firmware/efi */
307 efi_kobj = kobject_create_and_add("efi", firmware_kobj);
308 if (!efi_kobj) {
309 pr_err("efi: Firmware registration failed.\n");
310 return -ENOMEM;
313 error = generic_ops_register();
314 if (error)
315 goto err_put;
317 if (efi_enabled(EFI_RUNTIME_SERVICES))
318 efivar_ssdt_load();
320 error = sysfs_create_group(efi_kobj, &efi_subsys_attr_group);
321 if (error) {
322 pr_err("efi: Sysfs attribute export failed with error %d.\n",
323 error);
324 goto err_unregister;
327 error = efi_runtime_map_init(efi_kobj);
328 if (error)
329 goto err_remove_group;
331 /* and the standard mountpoint for efivarfs */
332 error = sysfs_create_mount_point(efi_kobj, "efivars");
333 if (error) {
334 pr_err("efivars: Subsystem registration failed.\n");
335 goto err_remove_group;
338 return 0;
340 err_remove_group:
341 sysfs_remove_group(efi_kobj, &efi_subsys_attr_group);
342 err_unregister:
343 generic_ops_unregister();
344 err_put:
345 kobject_put(efi_kobj);
346 return error;
349 subsys_initcall(efisubsys_init);
352 * Find the efi memory descriptor for a given physical address. Given a
353 * physical address, determine if it exists within an EFI Memory Map entry,
354 * and if so, populate the supplied memory descriptor with the appropriate
355 * data.
357 int __init efi_mem_desc_lookup(u64 phys_addr, efi_memory_desc_t *out_md)
359 efi_memory_desc_t *md;
361 if (!efi_enabled(EFI_MEMMAP)) {
362 pr_err_once("EFI_MEMMAP is not enabled.\n");
363 return -EINVAL;
366 if (!out_md) {
367 pr_err_once("out_md is null.\n");
368 return -EINVAL;
371 for_each_efi_memory_desc(md) {
372 u64 size;
373 u64 end;
375 if (!(md->attribute & EFI_MEMORY_RUNTIME) &&
376 md->type != EFI_BOOT_SERVICES_DATA &&
377 md->type != EFI_RUNTIME_SERVICES_DATA) {
378 continue;
381 size = md->num_pages << EFI_PAGE_SHIFT;
382 end = md->phys_addr + size;
383 if (phys_addr >= md->phys_addr && phys_addr < end) {
384 memcpy(out_md, md, sizeof(*out_md));
385 return 0;
388 pr_err_once("requested map not found.\n");
389 return -ENOENT;
393 * Calculate the highest address of an efi memory descriptor.
395 u64 __init efi_mem_desc_end(efi_memory_desc_t *md)
397 u64 size = md->num_pages << EFI_PAGE_SHIFT;
398 u64 end = md->phys_addr + size;
399 return end;
402 void __init __weak efi_arch_mem_reserve(phys_addr_t addr, u64 size) {}
405 * efi_mem_reserve - Reserve an EFI memory region
406 * @addr: Physical address to reserve
407 * @size: Size of reservation
409 * Mark a region as reserved from general kernel allocation and
410 * prevent it being released by efi_free_boot_services().
412 * This function should be called drivers once they've parsed EFI
413 * configuration tables to figure out where their data lives, e.g.
414 * efi_esrt_init().
416 void __init efi_mem_reserve(phys_addr_t addr, u64 size)
418 if (!memblock_is_region_reserved(addr, size))
419 memblock_reserve(addr, size);
422 * Some architectures (x86) reserve all boot services ranges
423 * until efi_free_boot_services() because of buggy firmware
424 * implementations. This means the above memblock_reserve() is
425 * superfluous on x86 and instead what it needs to do is
426 * ensure the @start, @size is not freed.
428 efi_arch_mem_reserve(addr, size);
431 static __initdata efi_config_table_type_t common_tables[] = {
432 {ACPI_20_TABLE_GUID, "ACPI 2.0", &efi.acpi20},
433 {ACPI_TABLE_GUID, "ACPI", &efi.acpi},
434 {HCDP_TABLE_GUID, "HCDP", &efi.hcdp},
435 {MPS_TABLE_GUID, "MPS", &efi.mps},
436 {SAL_SYSTEM_TABLE_GUID, "SALsystab", &efi.sal_systab},
437 {SMBIOS_TABLE_GUID, "SMBIOS", &efi.smbios},
438 {SMBIOS3_TABLE_GUID, "SMBIOS 3.0", &efi.smbios3},
439 {UGA_IO_PROTOCOL_GUID, "UGA", &efi.uga},
440 {EFI_SYSTEM_RESOURCE_TABLE_GUID, "ESRT", &efi.esrt},
441 {EFI_PROPERTIES_TABLE_GUID, "PROP", &efi.properties_table},
442 {EFI_MEMORY_ATTRIBUTES_TABLE_GUID, "MEMATTR", &efi.mem_attr_table},
443 {NULL_GUID, NULL, NULL},
446 static __init int match_config_table(efi_guid_t *guid,
447 unsigned long table,
448 efi_config_table_type_t *table_types)
450 int i;
452 if (table_types) {
453 for (i = 0; efi_guidcmp(table_types[i].guid, NULL_GUID); i++) {
454 if (!efi_guidcmp(*guid, table_types[i].guid)) {
455 *(table_types[i].ptr) = table;
456 if (table_types[i].name)
457 pr_cont(" %s=0x%lx ",
458 table_types[i].name, table);
459 return 1;
464 return 0;
467 int __init efi_config_parse_tables(void *config_tables, int count, int sz,
468 efi_config_table_type_t *arch_tables)
470 void *tablep;
471 int i;
473 tablep = config_tables;
474 pr_info("");
475 for (i = 0; i < count; i++) {
476 efi_guid_t guid;
477 unsigned long table;
479 if (efi_enabled(EFI_64BIT)) {
480 u64 table64;
481 guid = ((efi_config_table_64_t *)tablep)->guid;
482 table64 = ((efi_config_table_64_t *)tablep)->table;
483 table = table64;
484 #ifndef CONFIG_64BIT
485 if (table64 >> 32) {
486 pr_cont("\n");
487 pr_err("Table located above 4GB, disabling EFI.\n");
488 return -EINVAL;
490 #endif
491 } else {
492 guid = ((efi_config_table_32_t *)tablep)->guid;
493 table = ((efi_config_table_32_t *)tablep)->table;
496 if (!match_config_table(&guid, table, common_tables))
497 match_config_table(&guid, table, arch_tables);
499 tablep += sz;
501 pr_cont("\n");
502 set_bit(EFI_CONFIG_TABLES, &efi.flags);
504 /* Parse the EFI Properties table if it exists */
505 if (efi.properties_table != EFI_INVALID_TABLE_ADDR) {
506 efi_properties_table_t *tbl;
508 tbl = early_memremap(efi.properties_table, sizeof(*tbl));
509 if (tbl == NULL) {
510 pr_err("Could not map Properties table!\n");
511 return -ENOMEM;
514 if (tbl->memory_protection_attribute &
515 EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA)
516 set_bit(EFI_NX_PE_DATA, &efi.flags);
518 early_memunmap(tbl, sizeof(*tbl));
521 return 0;
524 int __init efi_config_init(efi_config_table_type_t *arch_tables)
526 void *config_tables;
527 int sz, ret;
529 if (efi_enabled(EFI_64BIT))
530 sz = sizeof(efi_config_table_64_t);
531 else
532 sz = sizeof(efi_config_table_32_t);
535 * Let's see what config tables the firmware passed to us.
537 config_tables = early_memremap(efi.systab->tables,
538 efi.systab->nr_tables * sz);
539 if (config_tables == NULL) {
540 pr_err("Could not map Configuration table!\n");
541 return -ENOMEM;
544 ret = efi_config_parse_tables(config_tables, efi.systab->nr_tables, sz,
545 arch_tables);
547 early_memunmap(config_tables, efi.systab->nr_tables * sz);
548 return ret;
551 #ifdef CONFIG_EFI_VARS_MODULE
552 static int __init efi_load_efivars(void)
554 struct platform_device *pdev;
556 if (!efi_enabled(EFI_RUNTIME_SERVICES))
557 return 0;
559 pdev = platform_device_register_simple("efivars", 0, NULL, 0);
560 return IS_ERR(pdev) ? PTR_ERR(pdev) : 0;
562 device_initcall(efi_load_efivars);
563 #endif
565 #ifdef CONFIG_EFI_PARAMS_FROM_FDT
567 #define UEFI_PARAM(name, prop, field) \
569 { name }, \
570 { prop }, \
571 offsetof(struct efi_fdt_params, field), \
572 FIELD_SIZEOF(struct efi_fdt_params, field) \
575 struct params {
576 const char name[32];
577 const char propname[32];
578 int offset;
579 int size;
582 static __initdata struct params fdt_params[] = {
583 UEFI_PARAM("System Table", "linux,uefi-system-table", system_table),
584 UEFI_PARAM("MemMap Address", "linux,uefi-mmap-start", mmap),
585 UEFI_PARAM("MemMap Size", "linux,uefi-mmap-size", mmap_size),
586 UEFI_PARAM("MemMap Desc. Size", "linux,uefi-mmap-desc-size", desc_size),
587 UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver)
590 static __initdata struct params xen_fdt_params[] = {
591 UEFI_PARAM("System Table", "xen,uefi-system-table", system_table),
592 UEFI_PARAM("MemMap Address", "xen,uefi-mmap-start", mmap),
593 UEFI_PARAM("MemMap Size", "xen,uefi-mmap-size", mmap_size),
594 UEFI_PARAM("MemMap Desc. Size", "xen,uefi-mmap-desc-size", desc_size),
595 UEFI_PARAM("MemMap Desc. Version", "xen,uefi-mmap-desc-ver", desc_ver)
598 #define EFI_FDT_PARAMS_SIZE ARRAY_SIZE(fdt_params)
600 static __initdata struct {
601 const char *uname;
602 const char *subnode;
603 struct params *params;
604 } dt_params[] = {
605 { "hypervisor", "uefi", xen_fdt_params },
606 { "chosen", NULL, fdt_params },
609 struct param_info {
610 int found;
611 void *params;
612 const char *missing;
615 static int __init __find_uefi_params(unsigned long node,
616 struct param_info *info,
617 struct params *params)
619 const void *prop;
620 void *dest;
621 u64 val;
622 int i, len;
624 for (i = 0; i < EFI_FDT_PARAMS_SIZE; i++) {
625 prop = of_get_flat_dt_prop(node, params[i].propname, &len);
626 if (!prop) {
627 info->missing = params[i].name;
628 return 0;
631 dest = info->params + params[i].offset;
632 info->found++;
634 val = of_read_number(prop, len / sizeof(u32));
636 if (params[i].size == sizeof(u32))
637 *(u32 *)dest = val;
638 else
639 *(u64 *)dest = val;
641 if (efi_enabled(EFI_DBG))
642 pr_info(" %s: 0x%0*llx\n", params[i].name,
643 params[i].size * 2, val);
646 return 1;
649 static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
650 int depth, void *data)
652 struct param_info *info = data;
653 int i;
655 for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
656 const char *subnode = dt_params[i].subnode;
658 if (depth != 1 || strcmp(uname, dt_params[i].uname) != 0) {
659 info->missing = dt_params[i].params[0].name;
660 continue;
663 if (subnode) {
664 int err = of_get_flat_dt_subnode_by_name(node, subnode);
666 if (err < 0)
667 return 0;
669 node = err;
672 return __find_uefi_params(node, info, dt_params[i].params);
675 return 0;
678 int __init efi_get_fdt_params(struct efi_fdt_params *params)
680 struct param_info info;
681 int ret;
683 pr_info("Getting EFI parameters from FDT:\n");
685 info.found = 0;
686 info.params = params;
688 ret = of_scan_flat_dt(fdt_find_uefi_params, &info);
689 if (!info.found)
690 pr_info("UEFI not found.\n");
691 else if (!ret)
692 pr_err("Can't find '%s' in device tree!\n",
693 info.missing);
695 return ret;
697 #endif /* CONFIG_EFI_PARAMS_FROM_FDT */
699 static __initdata char memory_type_name[][20] = {
700 "Reserved",
701 "Loader Code",
702 "Loader Data",
703 "Boot Code",
704 "Boot Data",
705 "Runtime Code",
706 "Runtime Data",
707 "Conventional Memory",
708 "Unusable Memory",
709 "ACPI Reclaim Memory",
710 "ACPI Memory NVS",
711 "Memory Mapped I/O",
712 "MMIO Port Space",
713 "PAL Code",
714 "Persistent Memory",
717 char * __init efi_md_typeattr_format(char *buf, size_t size,
718 const efi_memory_desc_t *md)
720 char *pos;
721 int type_len;
722 u64 attr;
724 pos = buf;
725 if (md->type >= ARRAY_SIZE(memory_type_name))
726 type_len = snprintf(pos, size, "[type=%u", md->type);
727 else
728 type_len = snprintf(pos, size, "[%-*s",
729 (int)(sizeof(memory_type_name[0]) - 1),
730 memory_type_name[md->type]);
731 if (type_len >= size)
732 return buf;
734 pos += type_len;
735 size -= type_len;
737 attr = md->attribute;
738 if (attr & ~(EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT |
739 EFI_MEMORY_WB | EFI_MEMORY_UCE | EFI_MEMORY_RO |
740 EFI_MEMORY_WP | EFI_MEMORY_RP | EFI_MEMORY_XP |
741 EFI_MEMORY_NV |
742 EFI_MEMORY_RUNTIME | EFI_MEMORY_MORE_RELIABLE))
743 snprintf(pos, size, "|attr=0x%016llx]",
744 (unsigned long long)attr);
745 else
746 snprintf(pos, size,
747 "|%3s|%2s|%2s|%2s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]",
748 attr & EFI_MEMORY_RUNTIME ? "RUN" : "",
749 attr & EFI_MEMORY_MORE_RELIABLE ? "MR" : "",
750 attr & EFI_MEMORY_NV ? "NV" : "",
751 attr & EFI_MEMORY_XP ? "XP" : "",
752 attr & EFI_MEMORY_RP ? "RP" : "",
753 attr & EFI_MEMORY_WP ? "WP" : "",
754 attr & EFI_MEMORY_RO ? "RO" : "",
755 attr & EFI_MEMORY_UCE ? "UCE" : "",
756 attr & EFI_MEMORY_WB ? "WB" : "",
757 attr & EFI_MEMORY_WT ? "WT" : "",
758 attr & EFI_MEMORY_WC ? "WC" : "",
759 attr & EFI_MEMORY_UC ? "UC" : "");
760 return buf;
764 * efi_mem_attributes - lookup memmap attributes for physical address
765 * @phys_addr: the physical address to lookup
767 * Search in the EFI memory map for the region covering
768 * @phys_addr. Returns the EFI memory attributes if the region
769 * was found in the memory map, 0 otherwise.
771 * Despite being marked __weak, most architectures should *not*
772 * override this function. It is __weak solely for the benefit
773 * of ia64 which has a funky EFI memory map that doesn't work
774 * the same way as other architectures.
776 u64 __weak efi_mem_attributes(unsigned long phys_addr)
778 efi_memory_desc_t *md;
780 if (!efi_enabled(EFI_MEMMAP))
781 return 0;
783 for_each_efi_memory_desc(md) {
784 if ((md->phys_addr <= phys_addr) &&
785 (phys_addr < (md->phys_addr +
786 (md->num_pages << EFI_PAGE_SHIFT))))
787 return md->attribute;
789 return 0;
792 int efi_status_to_err(efi_status_t status)
794 int err;
796 switch (status) {
797 case EFI_SUCCESS:
798 err = 0;
799 break;
800 case EFI_INVALID_PARAMETER:
801 err = -EINVAL;
802 break;
803 case EFI_OUT_OF_RESOURCES:
804 err = -ENOSPC;
805 break;
806 case EFI_DEVICE_ERROR:
807 err = -EIO;
808 break;
809 case EFI_WRITE_PROTECTED:
810 err = -EROFS;
811 break;
812 case EFI_SECURITY_VIOLATION:
813 err = -EACCES;
814 break;
815 case EFI_NOT_FOUND:
816 err = -ENOENT;
817 break;
818 case EFI_ABORTED:
819 err = -EINTR;
820 break;
821 default:
822 err = -EINVAL;
825 return err;