xref: /openbmc/linux/arch/arm64/kernel/efi.c (revision 56a0eccd)
1 /*
2  * Extensible Firmware Interface
3  *
4  * Based on Extensible Firmware Interface Specification version 2.4
5  *
6  * Copyright (C) 2013, 2014 Linaro Ltd.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  *
12  */
13 
14 #include <linux/dmi.h>
15 #include <linux/efi.h>
16 #include <linux/init.h>
17 
18 #include <asm/efi.h>
19 
20 int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md)
21 {
22 	pteval_t prot_val;
23 
24 	/*
25 	 * Only regions of type EFI_RUNTIME_SERVICES_CODE need to be
26 	 * executable, everything else can be mapped with the XN bits
27 	 * set.
28 	 */
29 	if ((md->attribute & EFI_MEMORY_WB) == 0)
30 		prot_val = PROT_DEVICE_nGnRE;
31 	else if (md->type == EFI_RUNTIME_SERVICES_CODE ||
32 		 !PAGE_ALIGNED(md->phys_addr))
33 		prot_val = pgprot_val(PAGE_KERNEL_EXEC);
34 	else
35 		prot_val = pgprot_val(PAGE_KERNEL);
36 
37 	create_pgd_mapping(mm, md->phys_addr, md->virt_addr,
38 			   md->num_pages << EFI_PAGE_SHIFT,
39 			   __pgprot(prot_val | PTE_NG));
40 	return 0;
41 }
42 
43 static int __init arm64_dmi_init(void)
44 {
45 	/*
46 	 * On arm64, DMI depends on UEFI, and dmi_scan_machine() needs to
47 	 * be called early because dmi_id_init(), which is an arch_initcall
48 	 * itself, depends on dmi_scan_machine() having been called already.
49 	 */
50 	dmi_scan_machine();
51 	if (dmi_available)
52 		dmi_set_dump_stack_arch_desc();
53 	return 0;
54 }
55 core_initcall(arm64_dmi_init);
56 
57 /*
58  * UpdateCapsule() depends on the system being shutdown via
59  * ResetSystem().
60  */
61 bool efi_poweroff_required(void)
62 {
63 	return efi_enabled(EFI_RUNTIME_SERVICES);
64 }
65