brintos

brintos / linux-shallow public Read only

0
0
Text · 3.0 KiB · b815d2a Raw
134 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2 3#define pr_fmt(fmt) "efi: " fmt4 5#include <linux/module.h>6#include <linux/init.h>7#include <linux/efi.h>8#include <linux/libfdt.h>9#include <linux/of_fdt.h>10 11#include <linux/unaligned.h>12 13enum {14	SYSTAB,15	MMBASE,16	MMSIZE,17	DCSIZE,18	DCVERS,19 20	PARAMCOUNT21};22 23static __initconst const char name[][22] = {24	[SYSTAB] = "System Table         ",25	[MMBASE] = "MemMap Address       ",26	[MMSIZE] = "MemMap Size          ",27	[DCSIZE] = "MemMap Desc. Size    ",28	[DCVERS] = "MemMap Desc. Version ",29};30 31static __initconst const struct {32	const char	path[17];33	u8		paravirt;34	const char	params[PARAMCOUNT][26];35} dt_params[] = {36	{37#ifdef CONFIG_XEN    //  <-------17------>38		.path = "/hypervisor/uefi",39		.paravirt = 1,40		.params = {41			[SYSTAB] = "xen,uefi-system-table",42			[MMBASE] = "xen,uefi-mmap-start",43			[MMSIZE] = "xen,uefi-mmap-size",44			[DCSIZE] = "xen,uefi-mmap-desc-size",45			[DCVERS] = "xen,uefi-mmap-desc-ver",46		}47	}, {48#endif49		.path = "/chosen",50		.params = {	//  <-----------26----------->51			[SYSTAB] = "linux,uefi-system-table",52			[MMBASE] = "linux,uefi-mmap-start",53			[MMSIZE] = "linux,uefi-mmap-size",54			[DCSIZE] = "linux,uefi-mmap-desc-size",55			[DCVERS] = "linux,uefi-mmap-desc-ver",56		}57	}58};59 60static int __init efi_get_fdt_prop(const void *fdt, int node, const char *pname,61				   const char *rname, void *var, int size)62{63	const void *prop;64	int len;65	u64 val;66 67	prop = fdt_getprop(fdt, node, pname, &len);68	if (!prop)69		return 1;70 71	val = (len == 4) ? (u64)be32_to_cpup(prop) : get_unaligned_be64(prop);72 73	if (size == 8)74		*(u64 *)var = val;75	else76		*(u32 *)var = (val < U32_MAX) ? val : U32_MAX; // saturate77 78	if (efi_enabled(EFI_DBG))79		pr_info("  %s: 0x%0*llx\n", rname, size * 2, val);80 81	return 0;82}83 84u64 __init efi_get_fdt_params(struct efi_memory_map_data *mm)85{86	const void *fdt = initial_boot_params;87	unsigned long systab;88	int i, j, node;89	struct {90		void	*var;91		int	size;92	} target[] = {93		[SYSTAB] = { &systab,		sizeof(systab) },94		[MMBASE] = { &mm->phys_map,	sizeof(mm->phys_map) },95		[MMSIZE] = { &mm->size,		sizeof(mm->size) },96		[DCSIZE] = { &mm->desc_size,	sizeof(mm->desc_size) },97		[DCVERS] = { &mm->desc_version,	sizeof(mm->desc_version) },98	};99 100	BUILD_BUG_ON(ARRAY_SIZE(target) != ARRAY_SIZE(name));101	BUILD_BUG_ON(ARRAY_SIZE(target) != ARRAY_SIZE(dt_params[0].params));102 103	if (!fdt)104		return 0;105 106	for (i = 0; i < ARRAY_SIZE(dt_params); i++) {107		node = fdt_path_offset(fdt, dt_params[i].path);108		if (node < 0)109			continue;110 111		if (efi_enabled(EFI_DBG))112			pr_info("Getting UEFI parameters from %s in DT:\n",113				dt_params[i].path);114 115		for (j = 0; j < ARRAY_SIZE(target); j++) {116			const char *pname = dt_params[i].params[j];117 118			if (!efi_get_fdt_prop(fdt, node, pname, name[j],119					      target[j].var, target[j].size))120				continue;121			if (!j)122				goto notfound;123			pr_err("Can't find property '%s' in DT!\n", pname);124			return 0;125		}126		if (dt_params[i].paravirt)127			set_bit(EFI_PARAVIRT, &efi.flags);128		return systab;129	}130notfound:131	pr_info("UEFI not found.\n");132	return 0;133}134