/*
 * 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;
}

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;
}
