File Index
Files and directories
Sign in
FILE

efi-init.c

File preview with syntax highlighting.

linux-6.19.14/drivers/firmware/efi/efi-init.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * Extensible Firmware Interface
  4 *
  5 * Based on Extensible Firmware Interface Specification version 2.4
  6 *
  7 * Copyright (C) 2013 - 2015 Linaro Ltd.
  8 */
  9
 10#define pr_fmt(fmt)	"efi: " fmt
 11
 12#include <linux/efi.h>
 13#include <linux/fwnode.h>
 14#include <linux/init.h>
 15#include <linux/kexec_handover.h>
 16#include <linux/memblock.h>
 17#include <linux/mm_types.h>
 18#include <linux/of.h>
 19#include <linux/of_address.h>
 20#include <linux/of_fdt.h>
 21#include <linux/platform_device.h>
 22#include <linux/screen_info.h>
 23
 24#include <asm/efi.h>
 25
 26unsigned long __initdata screen_info_table = EFI_INVALID_TABLE_ADDR;
 27
 28static int __init is_memory(efi_memory_desc_t *md)
 29{
 30	if (md->attribute & (EFI_MEMORY_WB|EFI_MEMORY_WT|EFI_MEMORY_WC))
 31		return 1;
 32	return 0;
 33}
 34
 35/*
 36 * Translate a EFI virtual address into a physical address: this is necessary,
 37 * as some data members of the EFI system table are virtually remapped after
 38 * SetVirtualAddressMap() has been called.
 39 */
 40static phys_addr_t __init efi_to_phys(unsigned long addr)
 41{
 42	efi_memory_desc_t *md;
 43
 44	for_each_efi_memory_desc(md) {
 45		if (!(md->attribute & EFI_MEMORY_RUNTIME))
 46			continue;
 47		if (md->virt_addr == 0)
 48			/* no virtual mapping has been installed by the stub */
 49			break;
 50		if (md->virt_addr <= addr &&
 51		    (addr - md->virt_addr) < (md->num_pages << EFI_PAGE_SHIFT))
 52			return md->phys_addr + addr - md->virt_addr;
 53	}
 54	return addr;
 55}
 56
 57extern __weak const efi_config_table_type_t efi_arch_tables[];
 58
 59/*
 60 * x86 defines its own screen_info and uses it even without EFI,
 61 * everything else can get it from here.
 62 */
 63#if !defined(CONFIG_X86) && (defined(CONFIG_SYSFB) || defined(CONFIG_EFI_EARLYCON))
 64struct screen_info screen_info __section(".data");
 65EXPORT_SYMBOL_GPL(screen_info);
 66#endif
 67
 68static void __init init_screen_info(void)
 69{
 70	struct screen_info *si;
 71
 72	if (screen_info_table != EFI_INVALID_TABLE_ADDR) {
 73		si = early_memremap(screen_info_table, sizeof(*si));
 74		if (!si) {
 75			pr_err("Could not map screen_info config table\n");
 76			return;
 77		}
 78		screen_info = *si;
 79		memset(si, 0, sizeof(*si));
 80		early_memunmap(si, sizeof(*si));
 81
 82		if (memblock_is_map_memory(screen_info.lfb_base))
 83			memblock_mark_nomap(screen_info.lfb_base,
 84					    screen_info.lfb_size);
 85
 86		if (IS_ENABLED(CONFIG_EFI_EARLYCON))
 87			efi_earlycon_reprobe();
 88	}
 89}
 90
 91static int __init uefi_init(u64 efi_system_table)
 92{
 93	efi_config_table_t *config_tables;
 94	efi_system_table_t *systab;
 95	size_t table_size;
 96	int retval;
 97
 98	systab = early_memremap_ro(efi_system_table, sizeof(efi_system_table_t));
 99	if (systab == NULL) {
100		pr_warn("Unable to map EFI system table.\n");
101		return -ENOMEM;
102	}
103
104	set_bit(EFI_BOOT, &efi.flags);
105	if (IS_ENABLED(CONFIG_64BIT))
106		set_bit(EFI_64BIT, &efi.flags);
107
108	retval = efi_systab_check_header(&systab->hdr);
109	if (retval)
110		goto out;
111
112	efi.runtime = systab->runtime;
113	efi.runtime_version = systab->hdr.revision;
114
115	efi_systab_report_header(&systab->hdr, efi_to_phys(systab->fw_vendor));
116
117	table_size = sizeof(efi_config_table_t) * systab->nr_tables;
118	config_tables = early_memremap_ro(efi_to_phys(systab->tables),
119					  table_size);
120	if (config_tables == NULL) {
121		pr_warn("Unable to map EFI config table array.\n");
122		retval = -ENOMEM;
123		goto out;
124	}
125	retval = efi_config_parse_tables(config_tables, systab->nr_tables,
126					 efi_arch_tables);
127
128	early_memunmap(config_tables, table_size);
129out:
130	early_memunmap(systab, sizeof(efi_system_table_t));
131	return retval;
132}
133
134/*
135 * Return true for regions that can be used as System RAM.
136 */
137static __init int is_usable_memory(efi_memory_desc_t *md)
138{
139	switch (md->type) {
140	case EFI_LOADER_CODE:
141	case EFI_LOADER_DATA:
142	case EFI_ACPI_RECLAIM_MEMORY:
143	case EFI_BOOT_SERVICES_CODE:
144	case EFI_BOOT_SERVICES_DATA:
145	case EFI_CONVENTIONAL_MEMORY:
146	case EFI_PERSISTENT_MEMORY:
147		/*
148		 * According to the spec, these regions are no longer reserved
149		 * after calling ExitBootServices(). However, we can only use
150		 * them as System RAM if they can be mapped writeback cacheable.
151		 */
152		return (md->attribute & EFI_MEMORY_WB);
153	default:
154		break;
155	}
156	return false;
157}
158
159static __init void reserve_regions(void)
160{
161	efi_memory_desc_t *md;
162	u64 paddr, npages, size;
163
164	if (efi_enabled(EFI_DBG))
165		pr_info("Processing EFI memory map:\n");
166
167	/*
168	 * Discard memblocks discovered so far except for KHO scratch
169	 * regions. Most memblocks at this point originate from memory nodes
170	 * in the DT and UEFI uses its own memory map instead. However, if
171	 * KHO is enabled, scratch regions, which are good known memory
172	 * must be preserved.
173	 */
174	memblock_dump_all();
175
176	if (is_kho_boot()) {
177		struct memblock_region *r;
178
179		/* Remove all non-KHO regions */
180		for_each_mem_region(r) {
181			if (!memblock_is_kho_scratch(r)) {
182				memblock_remove(r->base, r->size);
183				r--;
184			}
185		}
186	} else {
187		/*
188		 * KHO is disabled. Discard memblocks discovered so far:
189		 * if there are any at this point, they originate from memory
190		 * nodes in the DT, and UEFI uses its own memory map instead.
191		 */
192		memblock_remove(0, PHYS_ADDR_MAX);
193	}
194
195	for_each_efi_memory_desc(md) {
196		paddr = md->phys_addr;
197		npages = md->num_pages;
198
199		if (efi_enabled(EFI_DBG)) {
200			char buf[64];
201
202			pr_info("  0x%012llx-0x%012llx %s\n",
203				paddr, paddr + (npages << EFI_PAGE_SHIFT) - 1,
204				efi_md_typeattr_format(buf, sizeof(buf), md));
205		}
206
207		memrange_efi_to_native(&paddr, &npages);
208		size = npages << PAGE_SHIFT;
209
210		if (is_memory(md)) {
211			/*
212			 * Special purpose memory is 'soft reserved', which
213			 * means it is set aside initially. Don't add a memblock
214			 * for it now so that it can be hotplugged back in or
215			 * be assigned to the dax driver after boot.
216			 */
217			if (efi_soft_reserve_enabled() &&
218			    (md->attribute & EFI_MEMORY_SP))
219				continue;
220
221			early_init_dt_add_memory_arch(paddr, size);
222
223			if (!is_usable_memory(md))
224				memblock_mark_nomap(paddr, size);
225
226			/* keep ACPI reclaim memory intact for kexec etc. */
227			if (md->type == EFI_ACPI_RECLAIM_MEMORY)
228				memblock_reserve(paddr, size);
229		}
230	}
231}
232
233void __init efi_init(void)
234{
235	struct efi_memory_map_data data;
236	u64 efi_system_table;
237
238	/* Grab UEFI information placed in FDT by stub */
239	efi_system_table = efi_get_fdt_params(&data);
240	if (!efi_system_table)
241		return;
242
243	if (efi_memmap_init_early(&data) < 0) {
244		/*
245		* If we are booting via UEFI, the UEFI memory map is the only
246		* description of memory we have, so there is little point in
247		* proceeding if we cannot access it.
248		*/
249		panic("Unable to map EFI memory map.\n");
250	}
251
252	WARN(efi.memmap.desc_version != 1,
253	     "Unexpected EFI_MEMORY_DESCRIPTOR version %ld",
254	      efi.memmap.desc_version);
255
256	if (uefi_init(efi_system_table) < 0) {
257		efi_memmap_unmap();
258		return;
259	}
260
261	reserve_regions();
262	/*
263	 * For memblock manipulation, the cap should come after the memblock_add().
264	 * And now, memblock is fully populated, it is time to do capping.
265	 */
266	early_init_dt_check_for_usable_mem_range();
267	efi_find_mirror();
268	efi_esrt_init();
269	efi_mokvar_table_init();
270
271	memblock_reserve(data.phys_map & PAGE_MASK,
272			 PAGE_ALIGN(data.size + (data.phys_map & ~PAGE_MASK)));
273
274	if (IS_ENABLED(CONFIG_X86) ||
275	    IS_ENABLED(CONFIG_SYSFB) ||
276	    IS_ENABLED(CONFIG_EFI_EARLYCON))
277		init_screen_info();
278}
~/ Read-only file preview.