/*
 * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

/* Helper functions to offer easier navigation of Device Tree Blob */

#include <assert.h>
#include <errno.h>
#include <inttypes.h>
#include <stdint.h>
#include <string.h>

#include <libfdt.h>

#include <common/debug.h>
#include <common/fdt_wrappers.h>
#include <common/uuid.h>

/*
 * Read cells from a given property of the given node. Any number of 32-bit
 * cells of the property can be read. Returns 0 on success, or a negative
 * FDT error value otherwise.
 */
int fdt_read_uint32_array(const void *dtb, int node, const char *prop_name,
			  unsigned int cells, uint32_t *value)
{
	const fdt32_t *prop;
	int value_len;

	assert(dtb != NULL);
	assert(prop_name != NULL);
	assert(value != NULL);
	assert(node >= 0);

	/* Access property and obtain its length (in bytes) */
	prop = fdt_getprop(dtb, node, prop_name, &value_len);
	if (prop == NULL) {
		VERBOSE("Couldn't find property %s in dtb\n", prop_name);
		return -FDT_ERR_NOTFOUND;
	}

	/* Verify that property length can fill the entire array. */
	if (NCELLS((unsigned int)value_len) < cells) {
		WARN("Property length mismatch\n");
		return -FDT_ERR_BADVALUE;
	}

	for (unsigned int i = 0U; i < cells; i++) {
		value[i] = fdt32_to_cpu(prop[i]);
	}

	return 0;
}

int fdt_read_uint32(const void *dtb, int node, const char *prop_name,
		    uint32_t *value)
{
	return fdt_read_uint32_array(dtb, node, prop_name, 1, value);
}

uint32_t fdt_read_uint32_default(const void *dtb, int node,
				 const char *prop_name, uint32_t dflt_value)
{
	uint32_t ret = dflt_value;
	int err = fdt_read_uint32(dtb, node, prop_name, &ret);

	if (err < 0) {
		return dflt_value;
	}

	return ret;
}

int fdt_read_uint64(const void *dtb, int node, const char *prop_name,
		    uint64_t *value)
{
	uint32_t array[2] = {0, 0};
	int ret;

	ret = fdt_read_uint32_array(dtb, node, prop_name, 2, array);
	if (ret < 0) {
		return ret;
	}

	*value = ((uint64_t)array[0] << 32) | array[1];
	return 0;
}

uint64_t fdt_read_uint64_default(const void *dtb, int node,
				 const char *prop_name, uint64_t dflt_value)
{
	uint64_t ret = dflt_value;
	int err = fdt_read_uint64(dtb, node, prop_name, &ret);

	if (err < 0) {
		return dflt_value;
	}

	return ret;
}

/*
 * Read bytes from a given property of the given node. Any number of
 * bytes of the property can be read. The fdt pointer is updated.
 * Returns 0 on success, and -1 on error.
 */
int fdtw_read_bytes(const void *dtb, int node, const char *prop,
		    unsigned int length, void *value)
{
	const void *ptr;
	int value_len;

	assert(dtb != NULL);
	assert(prop != NULL);
	assert(value != NULL);
	assert(node >= 0);

	/* Access property and obtain its length (in bytes) */
	ptr = fdt_getprop_namelen(dtb, node, prop, (int)strlen(prop),
					&value_len);
	if (ptr == NULL) {
		WARN("Couldn't find property %s in dtb\n", prop);
		return -1;
	}

	/* Verify that property length is not less than number of bytes */
	if ((unsigned int)value_len < length) {
		WARN("Property length mismatch\n");
		return -1;
	}

	(void)memcpy(value, ptr, length);

	return 0;
}

/*
 * Read string from a given property of the given node. Up to 'size - 1'
 * characters are read, and a NUL terminator is added. Returns 0 on success,
 * and -1 upon error.
 */
int fdtw_read_string(const void *dtb, int node, const char *prop,
		char *str, size_t size)
{
	const char *ptr;
	size_t len;

	assert(dtb != NULL);
	assert(node >= 0);
	assert(prop != NULL);
	assert(str != NULL);
	assert(size > 0U);

	ptr = fdt_getprop_namelen(dtb, node, prop, (int)strlen(prop), NULL);
	if (ptr == NULL) {
		WARN("Couldn't find property %s in dtb\n", prop);
		return -1;
	}

	len = strlcpy(str, ptr, size);
	if (len >= size) {
		WARN("String of property %s in dtb has been truncated\n", prop);
		return -1;
	}

	return 0;
}

/*
 * Read UUID from a given property of the given node. Returns 0 on success,
 * and a negative value upon error.
 */
int fdtw_read_uuid(const void *dtb, int node, const char *prop,
		   unsigned int length, uint8_t *uuid)
{
	/* Buffer for UUID string (plus NUL terminator) */
	char uuid_string[UUID_STRING_LENGTH + 1U];
	int err;

	assert(dtb != NULL);
	assert(prop != NULL);
	assert(uuid != NULL);
	assert(node >= 0);

	if (length < UUID_BYTES_LENGTH) {
		return -EINVAL;
	}

	err = fdtw_read_string(dtb, node, prop, uuid_string,
			       UUID_STRING_LENGTH + 1U);
	if (err != 0) {
		return err;
	}

	if (read_uuid(uuid, uuid_string) != 0) {
		return -FDT_ERR_BADVALUE;
	}

	return 0;
}

/*
 * Write cells in place to a given property of the given node. At most 2 cells
 * of the property are written. Returns 0 on success, and -1 upon error.
 */
int fdtw_write_inplace_cells(void *dtb, int node, const char *prop,
		unsigned int cells, void *value)
{
	int err, len;

	assert(dtb != NULL);
	assert(prop != NULL);
	assert(value != NULL);
	assert(node >= 0);

	/* We expect either 1 or 2 cell property */
	assert(cells <= 2U);

	if (cells == 2U)
		*(fdt64_t *)value = cpu_to_fdt64(*(uint64_t *)value);
	else
		*(fdt32_t *)value = cpu_to_fdt32(*(uint32_t *)value);

	len = (int)cells * 4;

	/* Set property value in place */
	err = fdt_setprop_inplace(dtb, node, prop, value, len);
	if (err != 0) {
		WARN("Modify property %s failed with error %d\n", prop, err);
		return -1;
	}

	return 0;
}

/*
 * Write bytes in place to a given property of the given node.
 * Any number of bytes of the property can be written.
 * Returns 0 on success, and < 0 on error.
 */
int fdtw_write_inplace_bytes(void *dtb, int node, const char *prop,
			     unsigned int length, const void *data)
{
	const void *ptr;
	int namelen, value_len, err;

	assert(dtb != NULL);
	assert(prop != NULL);
	assert(data != NULL);
	assert(node >= 0);

	namelen = (int)strlen(prop);

	/* Access property and obtain its length in bytes */
	ptr = fdt_getprop_namelen(dtb, node, prop, namelen, &value_len);
	if (ptr == NULL) {
		WARN("Couldn't find property %s in dtb\n", prop);
		return -1;
	}

	/* Verify that property length is not less than number of bytes */
	if ((unsigned int)value_len < length) {
		WARN("Property length mismatch\n");
		return -1;
	}

	/* Set property value in place */
	err = fdt_setprop_inplace_namelen_partial(dtb, node, prop,
						  namelen, 0,
						  data, (int)length);
	if (err != 0) {
		WARN("Set property %s failed with error %d\n", prop, err);
	}

	return err;
}

static uint64_t fdt_read_prop_cells(const fdt32_t *prop, int nr_cells)
{
	uint64_t reg = fdt32_to_cpu(prop[0]);

	if (nr_cells > 1) {
		reg = (reg << 32) | fdt32_to_cpu(prop[1]);
	}

	return reg;
}

int fdt_get_reg_props_by_index(const void *dtb, int node, int index,
			       uintptr_t *base, size_t *size)
{
	const fdt32_t *prop;
	int parent, len;
	int ac, sc;
	int cell;

	parent = fdt_parent_offset(dtb, node);
	if (parent < 0) {
		return -FDT_ERR_BADOFFSET;
	}

	ac = fdt_address_cells(dtb, parent);
	sc = fdt_size_cells(dtb, parent);

	cell = index * (ac + sc);

	prop = fdt_getprop(dtb, node, "reg", &len);
	if (prop == NULL) {
		WARN("Couldn't find \"reg\" property in dtb\n");
		return -FDT_ERR_NOTFOUND;
	}

	if (((cell + ac + sc) * (int)sizeof(uint32_t)) > len) {
		return -FDT_ERR_BADVALUE;
	}

	if (base != NULL) {
		*base = (uintptr_t)fdt_read_prop_cells(&prop[cell], ac);
	}

	if (size != NULL) {
		*size = (size_t)fdt_read_prop_cells(&prop[cell + ac], sc);
	}

	return 0;
}

/*******************************************************************************
 * This function fills reg node info (base & size) with an index found by
 * checking the reg-names node.
 * Returns 0 on success and a negative FDT error code on failure.
 ******************************************************************************/
int fdt_get_reg_props_by_name(const void *dtb, int node, const char *name,
			      uintptr_t *base, size_t *size)
{
	int index;

	index = fdt_stringlist_search(dtb, node, "reg-names", name);
	if (index < 0) {
		return index;
	}

	return fdt_get_reg_props_by_index(dtb, node, index, base, size);
}

/*******************************************************************************
 * This function gets the stdout path node.
 * It reads the value indicated inside the device tree.
 * Returns node offset on success and a negative FDT error code on failure.
 ******************************************************************************/
int fdt_get_stdout_node_offset(const void *dtb)
{
	int node;
	const char *prop, *path;
	int len;

	/* The /secure-chosen node takes precedence over the standard one. */
	node = fdt_path_offset(dtb, "/secure-chosen");
	if (node < 0) {
		node = fdt_path_offset(dtb, "/chosen");
		if (node < 0) {
			return -FDT_ERR_NOTFOUND;
		}
	}

	prop = fdt_getprop(dtb, node, "stdout-path", NULL);
	if (prop == NULL) {
		return -FDT_ERR_NOTFOUND;
	}

	/* Determine the actual path length, as a colon terminates the path. */
	path = strchr(prop, ':');
	if (path == NULL) {
		len = strlen(prop);
	} else {
		len = path - prop;
	}

	/* Aliases cannot start with a '/', so it must be the actual path. */
	if (prop[0] == '/') {
		return fdt_path_offset_namelen(dtb, prop, len);
	}

	/* Lookup the alias, as this contains the actual path. */
	path = fdt_get_alias_namelen(dtb, prop, len);
	if (path == NULL) {
		return -FDT_ERR_NOTFOUND;
	}

	return fdt_path_offset(dtb, path);
}


/*******************************************************************************
 * Only devices which are direct children of root node use CPU address domain.
 * All other devices use addresses that are local to the device node and cannot
 * directly used by CPU. Device tree provides an address translation mechanism
 * through "ranges" property which provides mappings from local address space to
 * parent address space. Since a device could be a child of a child node to the
 * root node, there can be more than one level of address translation needed to
 * map the device local address space to CPU address space.
 * fdtw_translate_address() API performs address translation of a local address
 * to a global address with help of various helper functions.
 ******************************************************************************/

static bool fdtw_xlat_hit(const fdt32_t *value, int child_addr_size,
		int parent_addr_size, int range_size, uint64_t base_address,
		uint64_t *translated_addr)
{
	uint64_t local_address, parent_address, addr_range;

	local_address = fdt_read_prop_cells(value, child_addr_size);
	parent_address = fdt_read_prop_cells(value + child_addr_size,
				parent_addr_size);
	addr_range = fdt_read_prop_cells(value + child_addr_size +
				parent_addr_size,
				range_size);
	VERBOSE("DT: Address %" PRIx64 " mapped to %" PRIx64 " with range %" PRIx64 "\n",
		local_address, parent_address, addr_range);

	/* Perform range check */
	if ((base_address < local_address) ||
		(base_address >= local_address + addr_range)) {
		return false;
	}

	/* Found hit for the addr range that needs to be translated */
	*translated_addr = parent_address + (base_address - local_address);
	VERBOSE("DT: child address %" PRIx64 "mapped to %" PRIx64 " in parent bus\n",
		local_address, parent_address);
	return true;
}

#define ILLEGAL_ADDR	ULL(~0)

static uint64_t fdtw_search_all_xlat_entries(const void *dtb,
				const struct fdt_property *ranges_prop,
				int local_bus, uint64_t base_address)
{
	uint64_t translated_addr;
	const fdt32_t *next_entry;
	int parent_bus_node, nxlat_entries, length;
	int self_addr_cells, parent_addr_cells, self_size_cells, ncells_xlat;

	/*
	 * The number of cells in one translation entry in ranges is the sum of
	 * the following values:
	 * self#address-cells + parent#address-cells + self#size-cells
	 * Ex: the iofpga ranges property has one translation entry with 4 cells
	 * They represent iofpga#addr-cells + motherboard#addr-cells + iofpga#size-cells
	 *              = 1                 + 2                      + 1
	 */

	parent_bus_node = fdt_parent_offset(dtb, local_bus);
	self_addr_cells = fdt_address_cells(dtb, local_bus);
	self_size_cells = fdt_size_cells(dtb, local_bus);
	parent_addr_cells = fdt_address_cells(dtb, parent_bus_node);

	/* Number of cells per translation entry i.e., mapping */
	ncells_xlat = self_addr_cells + parent_addr_cells + self_size_cells;

	assert(ncells_xlat > 0);

	/*
	 * Find the number of translations(mappings) specified in the current
	 * `ranges` property. Note that length represents number of bytes and
	 * is stored in big endian mode.
	 */
	length = fdt32_to_cpu(ranges_prop->len);
	nxlat_entries = (length/sizeof(uint32_t))/ncells_xlat;

	assert(nxlat_entries > 0);

	next_entry = (const fdt32_t *)ranges_prop->data;

	/* Iterate over the entries in the "ranges" */
	for (int i = 0; i < nxlat_entries; i++) {
		if (fdtw_xlat_hit(next_entry, self_addr_cells,
				parent_addr_cells, self_size_cells, base_address,
				&translated_addr)){
			return translated_addr;
		}
		next_entry = next_entry + ncells_xlat;
	}

	INFO("DT: No translation found for address %" PRIx64 " in node %s\n",
	     base_address, fdt_get_name(dtb, local_bus, NULL));
	return ILLEGAL_ADDR;
}


/*******************************************************************************
 * address mapping needs to be done recursively starting from current node to
 * root node through all intermediate parent nodes.
 * Sample device tree is shown here:

smb@0,0 {
	compatible = "simple-bus";

	#address-cells = <2>;
	#size-cells = <1>;
	ranges = <0 0 0 0x08000000 0x04000000>,
		 <1 0 0 0x14000000 0x04000000>,
		 <2 0 0 0x18000000 0x04000000>,
		 <3 0 0 0x1c000000 0x04000000>,
		 <4 0 0 0x0c000000 0x04000000>,
		 <5 0 0 0x10000000 0x04000000>;

	motherboard {
		arm,v2m-memory-map = "rs1";
		compatible = "arm,vexpress,v2m-p1", "simple-bus";
		#address-cells = <2>;
		#size-cells = <1>;
		ranges;

		iofpga@3,00000000 {
			compatible = "arm,amba-bus", "simple-bus";
			#address-cells = <1>;
			#size-cells = <1>;
			ranges = <0 3 0 0x200000>;
			v2m_serial1: uart@a0000 {
				compatible = "arm,pl011", "arm,primecell";
				reg = <0x0a0000 0x1000>;
				interrupts = <0 6 4>;
				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
				clock-names = "uartclk", "apb_pclk";
		};
	};
};

 * As seen above, there are 3 levels of address translations needed. An empty
 * `ranges` property denotes identity mapping (as seen in `motherboard` node).
 * Each ranges property can map a set of child addresses to parent bus. Hence
 * there can be more than 1 (translation) entry in the ranges property as seen
 * in the `smb` node which has 6 translation entries.
 ******************************************************************************/

/* Recursive implementation */
uint64_t fdtw_translate_address(const void *dtb, int node,
				uint64_t base_address)
{
	int length, local_bus_node;
	const char *node_name;
	uint64_t global_address;

	local_bus_node = fdt_parent_offset(dtb, node);
	node_name = fdt_get_name(dtb, local_bus_node, NULL);

	/*
	 * In the example given above, starting from the leaf node:
	 * uart@a000 represents the current node
	 * iofpga@3,00000000 represents the local bus
	 * motherboard represents the parent bus
	 */

	/* Read the ranges property */
	const struct fdt_property *property = fdt_get_property(dtb,
					local_bus_node, "ranges", &length);

	if (property == NULL) {
		if (local_bus_node == 0) {
			/*
			 * root node doesn't have range property as addresses
			 * are in CPU address space.
			 */
			return base_address;
		}
		INFO("DT: Couldn't find ranges property in node %s\n",
			node_name);
		return ILLEGAL_ADDR;
	} else if (length == 0) {
		/* empty ranges indicates identity map to parent bus */
		return fdtw_translate_address(dtb, local_bus_node, base_address);
	}

	VERBOSE("DT: Translation lookup in node %s at offset %d\n", node_name,
		local_bus_node);
	global_address = fdtw_search_all_xlat_entries(dtb, property,
				local_bus_node, base_address);

	if (global_address == ILLEGAL_ADDR) {
		return ILLEGAL_ADDR;
	}

	/* Translate the local device address recursively */
	return fdtw_translate_address(dtb, local_bus_node, global_address);
}

/*
 * For every CPU node (`/cpus/cpu@n`) in an FDT, execute a callback passing a
 * pointer to the FDT and the offset of the CPU node. If the return value of the
 * callback is negative, it is treated as an error and the loop is aborted. In
 * this situation, the value of the callback is returned from the function.
 *
 * Returns `0` on success, or a negative integer representing an error code.
 */
int fdtw_for_each_cpu(const void *dtb,
		      int (*callback)(const void *dtb, int node, uintptr_t mpidr))
{
	int ret = 0;
	int parent, node = 0;

	parent = fdt_path_offset(dtb, "/cpus");
	if (parent < 0) {
		return parent;
	}

	fdt_for_each_subnode(node, dtb, parent) {
		const char *name;
		int len;

		uintptr_t mpidr = 0U;

		name = fdt_get_name(dtb, node, &len);
		if (strncmp(name, "cpu@", 4) != 0) {
			continue;
		}

		ret = fdt_get_reg_props_by_index(dtb, node, 0, &mpidr, NULL);
		if (ret < 0) {
			break;
		}

		ret = callback(dtb, node, mpidr);
		if (ret < 0) {
			break;
		}
	}

	return ret;
}

/*
 * Find a given node in device tree. If not present, add it.
 * Returns offset of node found/added on success, and < 0 on error.
 */
int fdtw_find_or_add_subnode(void *fdt, int parentoffset, const char *name)
{
	int offset;

	offset = fdt_subnode_offset(fdt, parentoffset, name);

	if (offset == -FDT_ERR_NOTFOUND) {
		offset = fdt_add_subnode(fdt, parentoffset, name);
	}

	if (offset < 0) {
		ERROR("%s: %s: %s\n", __func__, name, fdt_strerror(offset));
	}

	return offset;
}
