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

fdt_addresses.c (2182B)


      1// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
      2/*
      3 * libfdt - Flat Device Tree manipulation
      4 * Copyright (C) 2014 David Gibson <david@gibson.dropbear.id.au>
      5 * Copyright (C) 2018 embedded brains GmbH
      6 */
      7#include "libfdt_env.h"
      8
      9#include <fdt.h>
     10#include <libfdt.h>
     11
     12#include "libfdt_internal.h"
     13
     14static int fdt_cells(const void *fdt, int nodeoffset, const char *name)
     15{
     16	const fdt32_t *c;
     17	uint32_t val;
     18	int len;
     19
     20	c = fdt_getprop(fdt, nodeoffset, name, &len);
     21	if (!c)
     22		return len;
     23
     24	if (len != sizeof(*c))
     25		return -FDT_ERR_BADNCELLS;
     26
     27	val = fdt32_to_cpu(*c);
     28	if (val > FDT_MAX_NCELLS)
     29		return -FDT_ERR_BADNCELLS;
     30
     31	return (int)val;
     32}
     33
     34int fdt_address_cells(const void *fdt, int nodeoffset)
     35{
     36	int val;
     37
     38	val = fdt_cells(fdt, nodeoffset, "#address-cells");
     39	if (val == 0)
     40		return -FDT_ERR_BADNCELLS;
     41	if (val == -FDT_ERR_NOTFOUND)
     42		return 2;
     43	return val;
     44}
     45
     46int fdt_size_cells(const void *fdt, int nodeoffset)
     47{
     48	int val;
     49
     50	val = fdt_cells(fdt, nodeoffset, "#size-cells");
     51	if (val == -FDT_ERR_NOTFOUND)
     52		return 1;
     53	return val;
     54}
     55
     56/* This function assumes that [address|size]_cells is 1 or 2 */
     57int fdt_appendprop_addrrange(void *fdt, int parent, int nodeoffset,
     58			     const char *name, uint64_t addr, uint64_t size)
     59{
     60	int addr_cells, size_cells, ret;
     61	uint8_t data[sizeof(fdt64_t) * 2], *prop;
     62
     63	ret = fdt_address_cells(fdt, parent);
     64	if (ret < 0)
     65		return ret;
     66	addr_cells = ret;
     67
     68	ret = fdt_size_cells(fdt, parent);
     69	if (ret < 0)
     70		return ret;
     71	size_cells = ret;
     72
     73	/* check validity of address */
     74	prop = data;
     75	if (addr_cells == 1) {
     76		if ((addr > UINT32_MAX) || ((UINT32_MAX + 1 - addr) < size))
     77			return -FDT_ERR_BADVALUE;
     78
     79		fdt32_st(prop, (uint32_t)addr);
     80	} else if (addr_cells == 2) {
     81		fdt64_st(prop, addr);
     82	} else {
     83		return -FDT_ERR_BADNCELLS;
     84	}
     85
     86	/* check validity of size */
     87	prop += addr_cells * sizeof(fdt32_t);
     88	if (size_cells == 1) {
     89		if (size > UINT32_MAX)
     90			return -FDT_ERR_BADVALUE;
     91
     92		fdt32_st(prop, (uint32_t)size);
     93	} else if (size_cells == 2) {
     94		fdt64_st(prop, size);
     95	} else {
     96		return -FDT_ERR_BADNCELLS;
     97	}
     98
     99	return fdt_appendprop(fdt, nodeoffset, name, data,
    100			      (addr_cells + size_cells) * sizeof(fdt32_t));
    101}