cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

fdtparams.c (2960B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2
      3#define pr_fmt(fmt) "efi: " fmt
      4
      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 <asm/unaligned.h>
     12
     13enum {
     14	SYSTAB,
     15	MMBASE,
     16	MMSIZE,
     17	DCSIZE,
     18	DCVERS,
     19
     20	PARAMCOUNT
     21};
     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	const char	params[PARAMCOUNT][26];
     34} dt_params[] = {
     35	{
     36#ifdef CONFIG_XEN    //  <-------17------>
     37		.path = "/hypervisor/uefi",
     38		.params = {
     39			[SYSTAB] = "xen,uefi-system-table",
     40			[MMBASE] = "xen,uefi-mmap-start",
     41			[MMSIZE] = "xen,uefi-mmap-size",
     42			[DCSIZE] = "xen,uefi-mmap-desc-size",
     43			[DCVERS] = "xen,uefi-mmap-desc-ver",
     44		}
     45	}, {
     46#endif
     47		.path = "/chosen",
     48		.params = {	//  <-----------26----------->
     49			[SYSTAB] = "linux,uefi-system-table",
     50			[MMBASE] = "linux,uefi-mmap-start",
     51			[MMSIZE] = "linux,uefi-mmap-size",
     52			[DCSIZE] = "linux,uefi-mmap-desc-size",
     53			[DCVERS] = "linux,uefi-mmap-desc-ver",
     54		}
     55	}
     56};
     57
     58static int __init efi_get_fdt_prop(const void *fdt, int node, const char *pname,
     59				   const char *rname, void *var, int size)
     60{
     61	const void *prop;
     62	int len;
     63	u64 val;
     64
     65	prop = fdt_getprop(fdt, node, pname, &len);
     66	if (!prop)
     67		return 1;
     68
     69	val = (len == 4) ? (u64)be32_to_cpup(prop) : get_unaligned_be64(prop);
     70
     71	if (size == 8)
     72		*(u64 *)var = val;
     73	else
     74		*(u32 *)var = (val < U32_MAX) ? val : U32_MAX; // saturate
     75
     76	if (efi_enabled(EFI_DBG))
     77		pr_info("  %s: 0x%0*llx\n", rname, size * 2, val);
     78
     79	return 0;
     80}
     81
     82u64 __init efi_get_fdt_params(struct efi_memory_map_data *mm)
     83{
     84	const void *fdt = initial_boot_params;
     85	unsigned long systab;
     86	int i, j, node;
     87	struct {
     88		void	*var;
     89		int	size;
     90	} target[] = {
     91		[SYSTAB] = { &systab,		sizeof(systab) },
     92		[MMBASE] = { &mm->phys_map,	sizeof(mm->phys_map) },
     93		[MMSIZE] = { &mm->size,		sizeof(mm->size) },
     94		[DCSIZE] = { &mm->desc_size,	sizeof(mm->desc_size) },
     95		[DCVERS] = { &mm->desc_version,	sizeof(mm->desc_version) },
     96	};
     97
     98	BUILD_BUG_ON(ARRAY_SIZE(target) != ARRAY_SIZE(name));
     99	BUILD_BUG_ON(ARRAY_SIZE(target) != ARRAY_SIZE(dt_params[0].params));
    100
    101	if (!fdt)
    102		return 0;
    103
    104	for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
    105		node = fdt_path_offset(fdt, dt_params[i].path);
    106		if (node < 0)
    107			continue;
    108
    109		if (efi_enabled(EFI_DBG))
    110			pr_info("Getting UEFI parameters from %s in DT:\n",
    111				dt_params[i].path);
    112
    113		for (j = 0; j < ARRAY_SIZE(target); j++) {
    114			const char *pname = dt_params[i].params[j];
    115
    116			if (!efi_get_fdt_prop(fdt, node, pname, name[j],
    117					      target[j].var, target[j].size))
    118				continue;
    119			if (!j)
    120				goto notfound;
    121			pr_err("Can't find property '%s' in DT!\n", pname);
    122			return 0;
    123		}
    124		return systab;
    125	}
    126notfound:
    127	pr_info("UEFI not found.\n");
    128	return 0;
    129}