/* Taken from depthcharge: src/base/device_tree.c */
/* SPDX-License-Identifier: GPL-2.0-or-later */

#include <assert.h>
#include <commonlib/device_tree.h>
#include <ctype.h>
#include <endian.h>
#include <stdbool.h>
#include <stdint.h>
#ifdef __COREBOOT__
#include <console/console.h>
#else
#include <stdio.h>
#define printk(level, ...) printf(__VA_ARGS__)
#endif
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#include <stdlib.h>
#include <limits.h>

#define FDT_PATH_MAX_DEPTH 10 // should be a good enough upper bound
#define FDT_PATH_MAX_LEN 128 // should be a good enough upper bound
#define FDT_MAX_MEMORY_NODES 4 // should be a good enough upper bound
#define FDT_MAX_MEMORY_REGIONS 16 // should be a good enough upper bound

/*
 * Functions for picking apart flattened trees.
 */

static int fdt_skip_nops(const void *blob, uint32_t offset)
{
	uint32_t *ptr = (uint32_t *)(((uint8_t *)blob) + offset);

	int index = 0;
	while (be32toh(ptr[index]) == FDT_TOKEN_NOP)
		index++;

	return index * sizeof(uint32_t);
}

int fdt_next_property(const void *blob, uint32_t offset,
		      struct fdt_property *prop)
{
	struct fdt_header *header = (struct fdt_header *)blob;
	uint32_t *ptr = (uint32_t *)(((uint8_t *)blob) + offset);

	// skip NOP tokens
	offset += fdt_skip_nops(blob, offset);

	int index = 0;
	if (be32toh(ptr[index++]) != FDT_TOKEN_PROPERTY)
		return 0;

	uint32_t size = be32toh(ptr[index++]);
	uint32_t name_offset = be32toh(ptr[index++]);
	name_offset += be32toh(header->strings_offset);

	if (prop) {
		prop->name = (char *)((uint8_t *)blob + name_offset);
		prop->data = &ptr[index];
		prop->size = size;
	}

	index += DIV_ROUND_UP(size, sizeof(uint32_t));

	return index * sizeof(uint32_t);
}

/*
 * fdt_next_node_name  reads a node name
 *
 * @params blob    address of FDT
 * @params offset  offset to the node to read the name from
 * @params name    parameter to hold the name that has been read or NULL
 *
 * @returns  Either 0 on error or offset to the properties that come after the node name
 */
int fdt_next_node_name(const void *blob, uint32_t offset, const char **name)
{
	// skip NOP tokens
	offset += fdt_skip_nops(blob, offset);

	char *ptr = ((char *)blob) + offset;
	if (be32dec(ptr) != FDT_TOKEN_BEGIN_NODE)
		return 0;

	ptr += 4;
	if (name)
		*name = ptr;

	return ALIGN_UP(strlen(ptr) + 1, 4) + 4;
}

/*
 * A utility function to skip past nodes in flattened trees.
 */
int fdt_skip_node(const void *blob, uint32_t start_offset)
{
	uint32_t offset = start_offset;

	const char *name;
	int size = fdt_next_node_name(blob, offset, &name);
	if (!size)
		return 0;
	offset += size;

	while ((size = fdt_next_property(blob, offset, NULL)))
		offset += size;

	while ((size = fdt_skip_node(blob, offset)))
		offset += size;

	// skip NOP tokens
	offset += fdt_skip_nops(blob, offset);

	return offset - start_offset + sizeof(uint32_t);
}

/*
 * fdt_read_prop reads a property inside a node
 *
 * @params blob         address of FDT
 * @params node_offset  offset to the node to read the property from
 * @params prop_name    name of the property to read
 * @params fdt_prop     property is saved inside this parameter
 *
 * @returns  Either 0 if no property has been found or an offset that points to the location
 *           of the property
 */
u32 fdt_read_prop(const void *blob, u32 node_offset, const char *prop_name,
		  struct fdt_property *fdt_prop)
{
	u32 offset = node_offset;

	offset += fdt_next_node_name(blob, offset, NULL); // skip node name

	size_t size;
	while ((size = fdt_next_property(blob, offset, fdt_prop))) {
		if (strcmp(fdt_prop->name, prop_name) == 0)
			return offset;
		offset += size;
	}
	return 0; // property not found
}

/*
 * fdt_read_reg_prop reads the reg property inside a node
 *
 * @params blob           address of FDT
 * @params node_offset    offset to the node to read the reg property from
 * @params addr_cells     number of cells used for one address
 * @params size_cells     number of cells used for one size
 * @params regions        all regions that are read inside the reg property are saved inside
 *                        this array
 * @params regions_count  maximum number of entries that can be saved inside the regions array.
 *
 * Returns: Either 0 on error or returns the number of regions put into the regions array.
 */
u32 fdt_read_reg_prop(const void *blob, u32 node_offset, u32 addr_cells, u32 size_cells,
		      struct device_tree_region regions[], size_t regions_count)
{
	struct fdt_property prop;
	u32 offset = fdt_read_prop(blob, node_offset, "reg", &prop);

	if (!offset) {
		printk(BIOS_DEBUG, "no reg property found in node_offset: %x\n", node_offset);
		return 0;
	}

	// we found the reg property, now need to parse all regions in 'reg'
	size_t count = prop.size / (4 * addr_cells + 4 * size_cells);
	if (count > regions_count) {
		printk(BIOS_ERR, "reg property at node_offset: %x has more entries (%zd) than regions array can hold (%zd)\n", node_offset, count, regions_count);
		count = regions_count;
	}
	if (addr_cells > 2 || size_cells > 2) {
		printk(BIOS_ERR, "addr_cells (%d) or size_cells (%d) bigger than 2\n",
				  addr_cells, size_cells);
		return 0;
	}
	uint32_t *ptr = prop.data;
	for (int i = 0; i < count; i++) {
		if (addr_cells == 1)
			regions[i].addr = be32dec(ptr);
		else if (addr_cells == 2)
			regions[i].addr = be64dec(ptr);
		ptr += addr_cells;
		if (size_cells == 1)
			regions[i].size = be32dec(ptr);
		else if (size_cells == 2)
			regions[i].size = be64dec(ptr);
		ptr += size_cells;
	}

	return count; // return the number of regions found in the reg property
}

static u32 fdt_read_cell_props(const void *blob, u32 node_offset, u32 *addrcp, u32 *sizecp)
{
	struct fdt_property prop;
	u32 offset = node_offset;
	size_t size;
	while ((size = fdt_next_property(blob, offset, &prop))) {
		if (addrcp && !strcmp(prop.name, "#address-cells"))
			*addrcp = be32dec(prop.data);
		if (sizecp && !strcmp(prop.name, "#size-cells"))
			*sizecp = be32dec(prop.data);
		offset += size;
	}
	return offset;
}

/*
 * fdt_find_node searches for a node relative to another node
 *
 * @params blob  address of FDT
 *
 * @params parent_node_offset  offset to node from which to traverse the tree
 *
 * @params path  null terminated array of node names specifying a
 *               relative path (e.g: { "cpus", "cpu0", NULL })
 *
 * @params addrcp/sizecp  If any address-cells and size-cells properties are found that are
 *                        part of the parent node of the node we are looking, addrcp and sizecp
 *                        are set to these respectively.
 *
 * @returns: Either 0 if no node has been found or the offset to the node found
 */
static u32 fdt_find_node(const void *blob, u32 parent_node_offset, char **path,
			 u32 *addrcp, u32 *sizecp)
{
	if (*path == NULL)
		return parent_node_offset; // node found

	size_t size = fdt_next_node_name(blob, parent_node_offset, NULL); // skip node name

	/*
	 * get address-cells and size-cells properties while skipping the others.
	 * According to spec address-cells and size-cells are not inherited, but we
	 * intentionally follow the Linux implementation here and treat them as inheritable.
	 */
	u32 node_offset = fdt_read_cell_props(blob, parent_node_offset + size, addrcp, sizecp);

	const char *node_name;
	// walk all children nodes
	while ((size = fdt_next_node_name(blob, node_offset, &node_name))) {
		if (!strcmp(*path, node_name)) {
			// traverse one level deeper into the path
			return fdt_find_node(blob, node_offset, path + 1, addrcp, sizecp);
		}
		// node is not the correct one. skip current node
		node_offset += fdt_skip_node(blob, node_offset);
	}

	// we have searched everything and could not find a fitting node
	return 0;
}

/*
 * fdt_find_node_by_path finds a node behind a given node path
 *
 * @params blob  address of FDT
 * @params path  absolute path to the node that should be searched for
 *
 * @params addrcp/sizecp  Pointer that will be updated with any #address-cells and #size-cells
 *                        value found in the node of the node specified by node_offset. Either
 *                        may be NULL to ignore. If no #address-cells and #size-cells is found
 *                        default values of #address-cells=2 and #size-cells=1 are returned.
 *
 * @returns Either 0 on error or the offset to the node found behind the path
 */
u32 fdt_find_node_by_path(const void *blob, const char *path, u32 *addrcp, u32 *sizecp)
{
	// sanity check
	if (path[0] != '/') {
		printk(BIOS_ERR, "devicetree path must start with a /\n");
		return 0;
	}
	if (!blob) {
		printk(BIOS_ERR, "devicetree blob is NULL\n");
		return 0;
	}

	if (addrcp)
		*addrcp = 2;
	if (sizecp)
		*sizecp = 1;

	struct fdt_header *fdt_hdr = (struct fdt_header *)blob;

	/*
	 * split path into separate nodes
	 * e.g: "/cpus/cpu0" -> { "cpus", "cpu0" }
	 */
	char *path_array[FDT_PATH_MAX_DEPTH];
	size_t path_size = strlen(path);
	assert(path_size < FDT_PATH_MAX_LEN);
	char path_copy[FDT_PATH_MAX_LEN];
	memcpy(path_copy, path, path_size + 1);
	char *cur = path_copy;
	int i;
	for (i = 0; i < FDT_PATH_MAX_DEPTH; i++) {
		path_array[i] = strtok_r(NULL, "/", &cur);
		if (!path_array[i])
			break;
	}
	assert(i < FDT_PATH_MAX_DEPTH);

	return fdt_find_node(blob, be32toh(fdt_hdr->structure_offset), path_array, addrcp, sizecp);
}

/*
 * fdt_find_subnodes_by_prefix finds a node with a given prefix relative to a parent node
 *
 * @params blob  The FDT to search.
 *
 * @params node_offset  offset to the node of which the children should be searched
 *
 * @params prefix  A string to search for a node with a given prefix. This can for example
 *                 be 'cpu' to look for all nodes matching this prefix. Only children of
 *                 node_offset are searched. Therefore in order to search all nodes matching
 *                 the 'cpu' prefix, node_offset should probably point to the 'cpus' node.
 *                 An empty prefix ("") searches for all children nodes of node_offset.
 *
 * @params addrcp/sizecp  Pointer that will be updated with any #address-cells and #size-cells
 *                        value found in the node of the node specified by node_offset. Either
 *                        may be NULL to ignore. If no #address-cells and #size-cells is found
 *                        addrcp and sizecp are left untouched.
 *
 * @params results      Array of offsets pointing to each node matching the given prefix.
 * @params results_len  Number of entries allocated for the 'results' array
 *
 * @returns  offset to last node found behind path or 0 if no node has been found
 */
size_t fdt_find_subnodes_by_prefix(const void *blob, u32 node_offset, const char *prefix,
				   u32 *addrcp, u32 *sizecp, u32 *results, size_t results_len)
{
	// sanity checks
	if (!blob || !results || !prefix) {
		printk(BIOS_ERR, "%s: input parameter cannot be null/\n", __func__);
		return 0;
	}

	u32 offset = node_offset;

	// we don't care about the name of the current node
	u32 size = fdt_next_node_name(blob, offset, NULL);
	if (!size) {
		printk(BIOS_ERR, "%s: node_offset: %x does not point to a node\n",
		       __func__, node_offset);
		return 0;
	}
	offset += size;

	/*
	 * update addrcp and sizecp if the node contains an address-cells and size-cells
	 * property. Otherwise use addrcp and sizecp provided by caller.
	 */
	offset = fdt_read_cell_props(blob, offset, addrcp, sizecp);

	size_t count_results = 0;
	int prefix_len = strlen(prefix);
	const char *node_name;
	// walk all children nodes of offset
	while ((size = fdt_next_node_name(blob, offset, &node_name))) {

		if (count_results >= results_len) {
			printk(BIOS_WARNING,
				"%s: results_len (%zd) smaller than count_results (%zd)\n",
				__func__, results_len, count_results);
			break;
		}

		if (!strncmp(prefix, node_name, prefix_len)) {
			// we found a node that matches the prefix
			results[count_results++] = offset;
		}

		// node does not match the prefix. skip current node
		offset += fdt_skip_node(blob, offset);
	}

	// return last occurrence
	return count_results;
}

static const char *fdt_read_alias_prop(const void *blob, const char *alias_name)
{
	u32 node_offset =  fdt_find_node_by_path(blob, "/aliases", NULL, NULL);
	if (!node_offset) {
		printk(BIOS_DEBUG, "no /aliases node found\n");
		return NULL;
	}
	struct fdt_property alias_prop;
	if (!fdt_read_prop(blob, node_offset, alias_name, &alias_prop)) {
		printk(BIOS_DEBUG, "property %s in /aliases node not found\n", alias_name);
		return NULL;
	}
	return (const char *)alias_prop.data;
}

/*
 * Find a node in the tree from a string device tree path.
 *
 * @params blob           Address to the FDT
 * @params alias_name     node name alias that should be searched for.
 * @params addrcp/sizecp  Pointer that will be updated with any #address-cells and #size-cells
 *                        value found in the node of the node specified by node_offset. Either
 *                        may be NULL to ignore. If no #address-cells and #size-cells is found
 *                        default values of #address-cells=2 and #size-cells=1 are returned.
 *
 * @returns  offset to last node found behind path or 0 if no node has been found
 */
u32 fdt_find_node_by_alias(const void *blob, const char *alias_name, u32 *addrcp, u32 *sizecp)
{
	const char *node_name = fdt_read_alias_prop(blob, alias_name);
	if (!node_name)  {
		printk(BIOS_DEBUG, "alias %s not found\n", alias_name);
		return 0;
	}

	u32 node_offset = fdt_find_node_by_path(blob, node_name, addrcp, sizecp);
	if (!node_offset) {
		// This should not happen (invalid devicetree)
		printk(BIOS_WARNING,
		       "Could not find node '%s', which alias was referring to '%s'\n",
		       node_name, alias_name);
		return 0;
	}
	return node_offset;
}


/*
 * Functions for printing flattened trees.
 */

static void print_indent(int depth)
{
	printk(BIOS_DEBUG, "%*s", depth * 8, "");
}

static void print_property(const struct fdt_property *prop, int depth)
{
	int is_string = prop->size > 0 &&
			((char *)prop->data)[prop->size - 1] == '\0';

	if (is_string) {
		for (int i = 0; i < prop->size - 1; i++) {
			if (!isprint(((char *)prop->data)[i])) {
				is_string = 0;
				break;
			}
		}
	}

	print_indent(depth);
	if (is_string) {
		printk(BIOS_DEBUG, "%s = \"%s\";\n",
		       prop->name, (const char *)prop->data);
	} else {
		printk(BIOS_DEBUG, "%s = < ", prop->name);
		for (int i = 0; i < MIN(128, prop->size); i += 4) {
			uint32_t val = 0;
			for (int j = 0; j < MIN(4, prop->size - i); j++)
				val |= ((uint8_t *)prop->data)[i + j] <<
					(24 - j * 8);
			printk(BIOS_DEBUG, "%#.2x ", val);
		}
		if (prop->size > 128)
			printk(BIOS_DEBUG, "...");
		printk(BIOS_DEBUG, ">;\n");
	}
}

static int print_flat_node(const void *blob, uint32_t start_offset, int depth)
{
	int offset = start_offset;
	const char *name;
	int size;

	size = fdt_next_node_name(blob, offset, &name);
	if (!size)
		return 0;
	offset += size;

	print_indent(depth);
	printk(BIOS_DEBUG, "%s {\n", name);

	struct fdt_property prop;
	while ((size = fdt_next_property(blob, offset, &prop))) {
		print_property(&prop, depth + 1);

		offset += size;
	}

	printk(BIOS_DEBUG, "\n");	/* empty line between props and nodes */

	while ((size = print_flat_node(blob, offset, depth + 1)))
		offset += size;

	print_indent(depth);
	printk(BIOS_DEBUG, "}\n");

	return offset - start_offset + sizeof(uint32_t);
}

void fdt_print_node(const void *blob, uint32_t offset)
{
	print_flat_node(blob, offset, 0);
}

/*
 * fdt_read_memory_regions finds memory ranges from a flat device-tree
 *
 * @params blob	          address of FDT
 * @params regions        all regions that are read inside the reg property of
 *                        memory nodes are saved inside this array
 * @params regions_count  maximum number of entries that can be saved inside
 *                        the regions array.
 *
 * Returns: Either 0 on error or returns the number of regions put into the regions array.
 */
size_t fdt_read_memory_regions(const void *blob,
			       struct device_tree_region regions[],
			       size_t regions_count)
{
	u32 node, root, addrcp, sizecp;
	u32 nodes[FDT_MAX_MEMORY_NODES] = {0};
	size_t region_idx = 0;
	size_t node_count = 0;

	if (!fdt_is_valid(blob))
		return 0;

	node = fdt_find_node_by_path(blob, "/memory",  &addrcp, &sizecp);
	if (node) {
		region_idx += fdt_read_reg_prop(blob, node, addrcp, sizecp,
						regions, regions_count);
		if (region_idx >= regions_count) {
			printk(BIOS_WARNING, "FDT: Too many memory regions\n");
			goto out;
		}
	}

	root = fdt_find_node_by_path(blob, "/",  &addrcp, &sizecp);
	node_count = fdt_find_subnodes_by_prefix(blob, root, "memory@",
						 &addrcp, &sizecp, nodes,
						 FDT_MAX_MEMORY_NODES);
	if (node_count >= FDT_MAX_MEMORY_NODES) {
		printk(BIOS_WARNING, "FDT: Too many memory nodes\n");
		/* Can still reading the regions for those we got */
	}

	for (size_t i = 0; i < MIN(node_count, FDT_MAX_MEMORY_NODES); i++) {
		region_idx += fdt_read_reg_prop(blob, nodes[i], addrcp, sizecp,
						&regions[region_idx],
						regions_count - region_idx);
		if (region_idx >= regions_count) {
			printk(BIOS_WARNING, "FDT: Too many memory regions\n");
			goto out;
		}
	}

out:
	for (size_t i = 0; i < MIN(region_idx, regions_count); i++) {
		printk(BIOS_DEBUG, "FDT: Memory region [%#llx - %#llx]\n",
		       regions[i].addr, regions[i].addr + regions[i].size);
	}

	return region_idx;
}

/*
 * fdt_get_memory_top finds top of memory from a flat device-tree
 *
 * @params blob	          address of FDT
 *
 * Returns: Either 0 on error or returns the maximum memory address
 */
uint64_t fdt_get_memory_top(const void *blob)
{
	struct device_tree_region regions[FDT_MAX_MEMORY_REGIONS] = {0};
	uint64_t top = 0;
	uint64_t total = 0;
	size_t count;

	if (!fdt_is_valid(blob))
		return 0;

	count = fdt_read_memory_regions(blob, regions, FDT_MAX_MEMORY_REGIONS);
	for (size_t i = 0; i < MIN(count, FDT_MAX_MEMORY_REGIONS); i++) {
		top = MAX(top, regions[i].addr + regions[i].size);
		total += regions[i].size;
	}

	printk(BIOS_DEBUG, "FDT: Found %u MiB of RAM\n",
	       (uint32_t)(total / MiB));

	return top;
}

/*
 * Functions to turn a flattened tree into an unflattened one.
 */

static int dt_prop_is_phandle(struct device_tree_property *prop)
{
	return !(strcmp("phandle", prop->prop.name) &&
		 strcmp("linux,phandle", prop->prop.name));
}

static int fdt_unflatten_node(const void *blob, uint32_t start_offset,
			      struct device_tree *tree,
			      struct device_tree_node **new_node)
{
	struct list_node *last;
	int offset = start_offset;
	const char *name;
	int size;

	size = fdt_next_node_name(blob, offset, &name);
	if (!size)
		return 0;
	offset += size;

	struct device_tree_node *node = xzalloc(sizeof(*node));
	*new_node = node;
	node->name = name;

	struct fdt_property fprop;
	last = &node->properties;
	while ((size = fdt_next_property(blob, offset, &fprop))) {
		struct device_tree_property *prop = xzalloc(sizeof(*prop));
		prop->prop = fprop;

		if (dt_prop_is_phandle(prop)) {
			node->phandle = be32dec(prop->prop.data);
			if (node->phandle > tree->max_phandle)
				tree->max_phandle = node->phandle;
		}

		list_insert_after(&prop->list_node, last);
		last = &prop->list_node;

		offset += size;
	}

	struct device_tree_node *child;
	last = &node->children;
	while ((size = fdt_unflatten_node(blob, offset, tree, &child))) {
		list_insert_after(&child->list_node, last);
		last = &child->list_node;

		offset += size;
	}

	return offset - start_offset + sizeof(uint32_t);
}

static int fdt_unflatten_map_entry(const void *blob, uint32_t offset,
				   struct device_tree_reserve_map_entry **new)
{
	const uint64_t *ptr = (const uint64_t *)(((uint8_t *)blob) + offset);
	const uint64_t start = be64toh(ptr[0]);
	const uint64_t size = be64toh(ptr[1]);

	if (!size)
		return 0;

	struct device_tree_reserve_map_entry *entry = xzalloc(sizeof(*entry));
	*new = entry;
	entry->start = start;
	entry->size = size;

	return sizeof(uint64_t) * 2;
}

bool fdt_is_valid(const void *blob)
{
	const struct fdt_header *header = (const struct fdt_header *)blob;

	uint32_t magic = be32toh(header->magic);
	uint32_t version = be32toh(header->version);
	uint32_t last_comp_version = be32toh(header->last_comp_version);

	if (magic != FDT_HEADER_MAGIC) {
		printk(BIOS_ERR, "Invalid device tree magic %#.8x!\n", magic);
		return false;
	}
	if (last_comp_version > FDT_SUPPORTED_VERSION) {
		printk(BIOS_ERR, "Unsupported device tree version %u(>=%u)\n",
		       version, last_comp_version);
		return false;
	}
	if (version > FDT_SUPPORTED_VERSION)
		printk(BIOS_NOTICE, "FDT version %u too new, should add support!\n",
		       version);
	return true;
}

struct device_tree *fdt_unflatten(const void *blob)
{
	struct device_tree *tree = xzalloc(sizeof(*tree));
	const struct fdt_header *header = (const struct fdt_header *)blob;
	tree->header = header;

	if (!fdt_is_valid(blob))
		return NULL;

	uint32_t struct_offset = be32toh(header->structure_offset);
	uint32_t strings_offset = be32toh(header->strings_offset);
	uint32_t reserve_offset = be32toh(header->reserve_map_offset);
	uint32_t min_offset = 0;
	min_offset = MIN(struct_offset, strings_offset);
	min_offset = MIN(min_offset, reserve_offset);
	/* Assume everything up to the first non-header component is part of
	   the header and needs to be preserved. This will protect us against
	   new elements being added in the future. */
	tree->header_size = min_offset;

	struct device_tree_reserve_map_entry *entry;
	uint32_t offset = reserve_offset;
	int size;
	struct list_node *last = &tree->reserve_map;
	while ((size = fdt_unflatten_map_entry(blob, offset, &entry))) {
		list_insert_after(&entry->list_node, last);
		last = &entry->list_node;

		offset += size;
	}

	fdt_unflatten_node(blob, struct_offset, tree, &tree->root);

	return tree;
}



/*
 * Functions to find the size of the device tree if it was flattened.
 */

static void dt_flat_prop_size(struct device_tree_property *prop,
			      uint32_t *struct_size, uint32_t *strings_size)
{
	/* Starting token. */
	*struct_size += sizeof(uint32_t);
	/* Size. */
	*struct_size += sizeof(uint32_t);
	/* Name offset. */
	*struct_size += sizeof(uint32_t);
	/* Property value. */
	*struct_size += ALIGN_UP(prop->prop.size, sizeof(uint32_t));

	/* Property name. */
	*strings_size += strlen(prop->prop.name) + 1;
}

static void dt_flat_node_size(struct device_tree_node *node,
			      uint32_t *struct_size, uint32_t *strings_size)
{
	/* Starting token. */
	*struct_size += sizeof(uint32_t);
	/* Node name. */
	*struct_size += ALIGN_UP(strlen(node->name) + 1, sizeof(uint32_t));

	struct device_tree_property *prop;
	list_for_each(prop, node->properties, list_node)
		dt_flat_prop_size(prop, struct_size, strings_size);

	struct device_tree_node *child;
	list_for_each(child, node->children, list_node)
		dt_flat_node_size(child, struct_size, strings_size);

	/* End token. */
	*struct_size += sizeof(uint32_t);
}

uint32_t dt_flat_size(const struct device_tree *tree)
{
	uint32_t size = tree->header_size;
	struct device_tree_reserve_map_entry *entry;
	list_for_each(entry, tree->reserve_map, list_node)
		size += sizeof(uint64_t) * 2;
	size += sizeof(uint64_t) * 2;

	uint32_t struct_size = 0;
	uint32_t strings_size = 0;
	dt_flat_node_size(tree->root, &struct_size, &strings_size);

	size += struct_size;
	/* End token. */
	size += sizeof(uint32_t);

	size += strings_size;

	return size;
}



/*
 * Functions to flatten a device tree.
 */

static void dt_flatten_map_entry(struct device_tree_reserve_map_entry *entry,
				 void **map_start)
{
	((uint64_t *)*map_start)[0] = htobe64(entry->start);
	((uint64_t *)*map_start)[1] = htobe64(entry->size);
	*map_start = ((uint8_t *)*map_start) + sizeof(uint64_t) * 2;
}

static void dt_flatten_prop(struct device_tree_property *prop,
			    void **struct_start, void *strings_base,
			    void **strings_start)
{
	uint8_t *dstruct = (uint8_t *)*struct_start;
	uint8_t *dstrings = (uint8_t *)*strings_start;

	be32enc(dstruct, FDT_TOKEN_PROPERTY);
	dstruct += sizeof(uint32_t);

	be32enc(dstruct, prop->prop.size);
	dstruct += sizeof(uint32_t);

	uint32_t name_offset = (uintptr_t)dstrings - (uintptr_t)strings_base;
	be32enc(dstruct, name_offset);
	dstruct += sizeof(uint32_t);

	strcpy((char *)dstrings, prop->prop.name);
	dstrings += strlen(prop->prop.name) + 1;

	memcpy(dstruct, prop->prop.data, prop->prop.size);
	dstruct += ALIGN_UP(prop->prop.size, sizeof(uint32_t));

	*struct_start = dstruct;
	*strings_start = dstrings;
}

static void dt_flatten_node(const struct device_tree_node *node,
			    void **struct_start, void *strings_base,
			    void **strings_start)
{
	uint8_t *dstruct = (uint8_t *)*struct_start;
	uint8_t *dstrings = (uint8_t *)*strings_start;

	be32enc(dstruct, FDT_TOKEN_BEGIN_NODE);
	dstruct += sizeof(uint32_t);

	strcpy((char *)dstruct, node->name);
	dstruct += ALIGN_UP(strlen(node->name) + 1, sizeof(uint32_t));

	struct device_tree_property *prop;
	list_for_each(prop, node->properties, list_node)
		dt_flatten_prop(prop, (void **)&dstruct, strings_base,
				(void **)&dstrings);

	struct device_tree_node *child;
	list_for_each(child, node->children, list_node)
		dt_flatten_node(child, (void **)&dstruct, strings_base,
				(void **)&dstrings);

	be32enc(dstruct, FDT_TOKEN_END_NODE);
	dstruct += sizeof(uint32_t);

	*struct_start = dstruct;
	*strings_start = dstrings;
}

void dt_flatten(const struct device_tree *tree, void *start_dest)
{
	uint8_t *dest = (uint8_t *)start_dest;

	memcpy(dest, tree->header, tree->header_size);
	struct fdt_header *header = (struct fdt_header *)dest;
	dest += tree->header_size;

	struct device_tree_reserve_map_entry *entry;
	list_for_each(entry, tree->reserve_map, list_node)
		dt_flatten_map_entry(entry, (void **)&dest);
	((uint64_t *)dest)[0] = ((uint64_t *)dest)[1] = 0;
	dest += sizeof(uint64_t) * 2;

	uint32_t struct_size = 0;
	uint32_t strings_size = 0;
	dt_flat_node_size(tree->root, &struct_size, &strings_size);

	uint8_t *struct_start = dest;
	header->structure_offset = htobe32(dest - (uint8_t *)start_dest);
	header->structure_size = htobe32(struct_size);
	dest += struct_size;

	*((uint32_t *)dest) = htobe32(FDT_TOKEN_END);
	dest += sizeof(uint32_t);

	uint8_t *strings_start = dest;
	header->strings_offset = htobe32(dest - (uint8_t *)start_dest);
	header->strings_size = htobe32(strings_size);
	dest += strings_size;

	dt_flatten_node(tree->root, (void **)&struct_start, strings_start,
			(void **)&strings_start);

	header->totalsize = htobe32(dest - (uint8_t *)start_dest);
}



/*
 * Functions for printing a non-flattened device tree.
 */

static void print_node(const struct device_tree_node *node, int depth)
{
	print_indent(depth);
	if (depth == 0)	/* root node has no name, print a starting slash */
		printk(BIOS_DEBUG, "/");
	printk(BIOS_DEBUG, "%s {\n", node->name);

	struct device_tree_property *prop;
	list_for_each(prop, node->properties, list_node)
		print_property(&prop->prop, depth + 1);

	printk(BIOS_DEBUG, "\n");	/* empty line between props and nodes */

	struct device_tree_node *child;
	list_for_each(child, node->children, list_node)
		print_node(child, depth + 1);

	print_indent(depth);
	printk(BIOS_DEBUG, "};\n");
}

void dt_print_node(const struct device_tree_node *node)
{
	print_node(node, 0);
}



/*
 * Functions for reading and manipulating an unflattened device tree.
 */

/*
 * Read #address-cells and #size-cells properties from a node.
 *
 * @param node		The device tree node to read from.
 * @param addrcp	Pointer to store #address-cells in, skipped if NULL.
 * @param sizecp	Pointer to store #size-cells in, skipped if NULL.
 */
void dt_read_cell_props(const struct device_tree_node *node, u32 *addrcp,
			u32 *sizecp)
{
	struct device_tree_property *prop;
	list_for_each(prop, node->properties, list_node) {
		if (addrcp && !strcmp("#address-cells", prop->prop.name))
			*addrcp = be32dec(prop->prop.data);
		if (sizecp && !strcmp("#size-cells", prop->prop.name))
			*sizecp = be32dec(prop->prop.data);
	}
}

/*
 * Find a node from a device tree path, relative to a parent node.
 *
 * @param parent	The node from which to start the relative path lookup.
 * @param path		An array of path component strings that will be looked
 *			up in order to find the node. Must be terminated with
 *			a NULL pointer. Example: {'firmware', 'coreboot', NULL}
 * @param addrcp	Pointer that will be updated with any #address-cells
 *			value found in the path. May be NULL to ignore.
 * @param sizecp	Pointer that will be updated with any #size-cells
 *			value found in the path. May be NULL to ignore.
 * @param create	1: Create node(s) if not found. 0: Return NULL instead.
 * @return		The found/created node, or NULL.
 */
struct device_tree_node *dt_find_node(struct device_tree_node *parent,
				      const char **path, u32 *addrcp,
				      u32 *sizecp, int create)
{
	struct device_tree_node *node, *found = NULL;

	/* Update #address-cells and #size-cells for this level. */
	dt_read_cell_props(parent, addrcp, sizecp);

	if (!*path)
		return parent;

	/* Find the next node in the path, if it exists. */
	list_for_each(node, parent->children, list_node) {
		if (!strcmp(node->name, *path)) {
			found = node;
			break;
		}
	}

	/* Otherwise create it or return NULL. */
	if (!found) {
		if (!create)
			return NULL;

		found = calloc(1, sizeof(*found));
		if (!found)
			return NULL;
		found->name = strdup(*path);
		if (!found->name)
			return NULL;

		list_insert_after(&found->list_node, &parent->children);
	}

	return dt_find_node(found, path + 1, addrcp, sizecp, create);
}

/*
 * Find a node in the tree from a string device tree path.
 *
 * @param tree		The device tree to search.
 * @param path          A string representing a path in the device tree, with
 *			nodes separated by '/'. Example: "/firmware/coreboot"
 * @param addrcp	Pointer that will be updated with any #address-cells
 *			value found in the path. May be NULL to ignore.
 * @param sizecp	Pointer that will be updated with any #size-cells
 *			value found in the path. May be NULL to ignore.
 * @param create	1: Create node(s) if not found. 0: Return NULL instead.
 * @return		The found/created node, or NULL.
 *
 * It is the caller responsibility to provide a path string that doesn't end
 * with a '/' and doesn't contain any "//". If the path does not start with a
 * '/', the first segment is interpreted as an alias. */
struct device_tree_node *dt_find_node_by_path(struct device_tree *tree,
					      const char *path, u32 *addrcp,
					      u32 *sizecp, int create)
{
	char *sub_path;
	char *duped_str;
	struct device_tree_node *parent;
	char *next_slash;
	/* Hopefully enough depth for any node. */
	const char *path_array[15];
	int i;
	struct device_tree_node *node = NULL;

	if (path[0] == '/') { /* regular path */
		if (path[1] == '\0') {	/* special case: "/" is root node */
			dt_read_cell_props(tree->root, addrcp, sizecp);
			return tree->root;
		}

		sub_path = duped_str = strdup(&path[1]);
		if (!sub_path)
			return NULL;

		parent = tree->root;
	} else { /* alias */
		char *alias;

		alias = duped_str = strdup(path);
		if (!alias)
			return NULL;

		sub_path = strchr(alias, '/');
		if (sub_path)
			*sub_path = '\0';

		parent = dt_find_node_by_alias(tree, alias);
		if (!parent) {
			printk(BIOS_DEBUG,
			       "Could not find node '%s', alias '%s' does not exist\n",
			       path, alias);
			free(duped_str);
			return NULL;
		}

		if (!sub_path) {
			/* it's just the alias, no sub-path */
			free(duped_str);
			return parent;
		}

		sub_path++;
	}

	next_slash = sub_path;
	path_array[0] = sub_path;
	for (i = 1; i < (ARRAY_SIZE(path_array) - 1); i++) {
		next_slash = strchr(next_slash, '/');
		if (!next_slash)
			break;

		*next_slash++ = '\0';
		path_array[i] = next_slash;
	}

	if (!next_slash) {
		path_array[i] = NULL;
		node = dt_find_node(parent, path_array,
				    addrcp, sizecp, create);
	}

	free(duped_str);
	return node;
}

/*
 * Find a node from an alias
 *
 * @param tree		The device tree.
 * @param alias		The alias name.
 * @return		The found node, or NULL.
 */
struct device_tree_node *dt_find_node_by_alias(struct device_tree *tree,
					       const char *alias)
{
	struct device_tree_node *node;
	const char *alias_path;

	node = dt_find_node_by_path(tree, "/aliases", NULL, NULL, 0);
	if (!node)
		return NULL;

	alias_path = dt_find_string_prop(node, alias);
	if (!alias_path)
		return NULL;

	return dt_find_node_by_path(tree, alias_path, NULL, NULL, 0);
}

struct device_tree_node *dt_find_node_by_phandle(struct device_tree_node *root,
						 uint32_t phandle)
{
	if (!root)
		return NULL;

	if (root->phandle == phandle)
		return root;

	struct device_tree_node *node;
	struct device_tree_node *result;
	list_for_each(node, root->children, list_node) {
		result = dt_find_node_by_phandle(node, phandle);
		if (result)
			return result;
	}

	return NULL;
}

/*
 * Check if given node is compatible.
 *
 * @param node		The node which is to be checked for compatible property.
 * @param compat	The compatible string to match.
 * @return		1 = compatible, 0 = not compatible.
 */
static int dt_check_compat_match(struct device_tree_node *node,
				 const char *compat)
{
	struct device_tree_property *prop;

	list_for_each(prop, node->properties, list_node) {
		if (!strcmp("compatible", prop->prop.name)) {
			size_t bytes = prop->prop.size;
			const char *str = prop->prop.data;
			while (bytes > 0) {
				if (!strncmp(compat, str, bytes))
					return 1;
				size_t len = strnlen(str, bytes) + 1;
				if (bytes <= len)
					break;
				str += len;
				bytes -= len;
			}
			break;
		}
	}

	return 0;
}

/*
 * Find a node from a compatible string, in the subtree of a parent node.
 *
 * @param parent	The parent node under which to look.
 * @param compat	The compatible string to find.
 * @return		The found node, or NULL.
 */
struct device_tree_node *dt_find_compat(struct device_tree_node *parent,
					const char *compat)
{
	/* Check if the parent node itself is compatible. */
	if (dt_check_compat_match(parent, compat))
		return parent;

	struct device_tree_node *child;
	list_for_each(child, parent->children, list_node) {
		struct device_tree_node *found = dt_find_compat(child, compat);
		if (found)
			return found;
	}

	return NULL;
}

/*
 * Find the next compatible child of a given parent. All children up to the
 * child passed in by caller are ignored. If child is NULL, it considers all the
 * children to find the first child which is compatible.
 *
 * @param parent	The parent node under which to look.
 * @param child	The child node to start search from (exclusive). If NULL
 *                      consider all children.
 * @param compat	The compatible string to find.
 * @return		The found node, or NULL.
 */
struct device_tree_node *
dt_find_next_compat_child(struct device_tree_node *parent,
			  struct device_tree_node *child,
			  const char *compat)
{
	struct device_tree_node *next;
	int ignore = 0;

	if (child)
		ignore = 1;

	list_for_each(next, parent->children, list_node) {
		if (ignore) {
			if (child == next)
				ignore = 0;
			continue;
		}

		if (dt_check_compat_match(next, compat))
			return next;
	}

	return NULL;
}

/*
 * Find a node with matching property value, in the subtree of a parent node.
 *
 * @param parent	The parent node under which to look.
 * @param name		The property name to look for.
 * @param data		The property value to look for.
 * @param size		The property size.
 */
struct device_tree_node *dt_find_prop_value(struct device_tree_node *parent,
					    const char *name, void *data,
					    size_t size)
{
	struct device_tree_property *prop;

	/* Check if parent itself has the required property value. */
	list_for_each(prop, parent->properties, list_node) {
		if (!strcmp(name, prop->prop.name)) {
			size_t bytes = prop->prop.size;
			const void *prop_data = prop->prop.data;
			if (size != bytes)
				break;
			if (!memcmp(data, prop_data, size))
				return parent;
			break;
		}
	}

	struct device_tree_node *child;
	list_for_each(child, parent->children, list_node) {
		struct device_tree_node *found = dt_find_prop_value(child, name,
								    data, size);
		if (found)
			return found;
	}
	return NULL;
}

/*
 * Write an arbitrary sized big-endian integer into a pointer.
 *
 * @param dest		Pointer to the DT property data buffer to write.
 * @param src		The integer to write (in CPU endianness).
 * @param length	the length of the destination integer in bytes.
 */
void dt_write_int(u8 *dest, u64 src, size_t length)
{
	while (length--) {
		dest[length] = (u8)src;
		src >>= 8;
	}
}

/*
 * Delete a property by name in a given node if it exists.
 *
 * @param node		The device tree node to operate on.
 * @param name		The name of the property to delete.
 */
void dt_delete_prop(struct device_tree_node *node, const char *name)
{
	struct device_tree_property *prop;

	list_for_each(prop, node->properties, list_node) {
		if (!strcmp(prop->prop.name, name)) {
			list_remove(&prop->list_node);
			return;
		}
	}
}

/*
 * Add an arbitrary property to a node, or update it if it already exists.
 *
 * @param node		The device tree node to add to.
 * @param name		The name of the new property.
 * @param data		The raw data blob to be stored in the property.
 * @param size		The size of data in bytes.
 */
void dt_add_bin_prop(struct device_tree_node *node, const char *name,
		     void *data, size_t size)
{
	struct device_tree_property *prop;

	list_for_each(prop, node->properties, list_node) {
		if (!strcmp(prop->prop.name, name)) {
			prop->prop.data = data;
			prop->prop.size = size;
			return;
		}
	}

	prop = xzalloc(sizeof(*prop));
	list_insert_after(&prop->list_node, &node->properties);
	prop->prop.name = name;
	prop->prop.data = data;
	prop->prop.size = size;
}

/*
 * Find given string property in a node and return its content.
 *
 * @param node		The device tree node to search.
 * @param name		The name of the property.
 * @return		The found string, or NULL.
 */
const char *dt_find_string_prop(const struct device_tree_node *node,
				const char *name)
{
	const void *content;
	size_t size;

	dt_find_bin_prop(node, name, &content, &size);

	return content;
}

/*
 * Find given property in a node.
 *
 * @param node		The device tree node to search.
 * @param name		The name of the property.
 * @param data		Pointer to return raw data blob in the property.
 * @param size		Pointer to return the size of data in bytes.
 */
void dt_find_bin_prop(const struct device_tree_node *node, const char *name,
		      const void **data, size_t *size)
{
	struct device_tree_property *prop;

	*data = NULL;
	*size = 0;

	list_for_each(prop, node->properties, list_node) {
		if (!strcmp(prop->prop.name, name)) {
			*data = prop->prop.data;
			*size = prop->prop.size;
			return;
		}
	}
}

/*
 * Add a string property to a node, or update it if it already exists.
 *
 * @param node		The device tree node to add to.
 * @param name		The name of the new property.
 * @param str		The zero-terminated string to be stored in the property.
 */
void dt_add_string_prop(struct device_tree_node *node, const char *name,
			const char *str)
{
	dt_add_bin_prop(node, name, (char *)str, strlen(str) + 1);
}

/*
 * Add a 32-bit integer property to a node, or update it if it already exists.
 *
 * @param node		The device tree node to add to.
 * @param name		The name of the new property.
 * @param val		The integer to be stored in the property.
 */
void dt_add_u32_prop(struct device_tree_node *node, const char *name, u32 val)
{
	u32 *val_ptr = xmalloc(sizeof(val));
	*val_ptr = htobe32(val);
	dt_add_bin_prop(node, name, val_ptr, sizeof(*val_ptr));
}

/*
 * Add a 64-bit integer property to a node, or update it if it already exists.
 *
 * @param node		The device tree node to add to.
 * @param name		The name of the new property.
 * @param val		The integer to be stored in the property.
 */
void dt_add_u64_prop(struct device_tree_node *node, const char *name, u64 val)
{
	u64 *val_ptr = xmalloc(sizeof(val));
	*val_ptr = htobe64(val);
	dt_add_bin_prop(node, name, val_ptr, sizeof(*val_ptr));
}

/*
 * Add a 'reg' address list property to a node, or update it if it exists.
 *
 * @param node		The device tree node to add to.
 * @param regions       Array of address values to be stored in the property.
 * @param sizes		Array of corresponding size values to 'addrs'.
 * @param count		Number of values in 'addrs' and 'sizes' (must be equal).
 * @param addr_cells	Value of #address-cells property valid for this node.
 * @param size_cells	Value of #size-cells property valid for this node.
 */
void dt_add_reg_prop(struct device_tree_node *node, u64 *addrs, u64 *sizes,
		     int count, u32 addr_cells, u32 size_cells)
{
	int i;
	size_t length = (addr_cells + size_cells) * sizeof(u32) * count;
	u8 *data = xmalloc(length);
	u8 *cur = data;

	for (i = 0; i < count; i++) {
		dt_write_int(cur, addrs[i], addr_cells * sizeof(u32));
		cur += addr_cells * sizeof(u32);
		dt_write_int(cur, sizes[i], size_cells * sizeof(u32));
		cur += size_cells * sizeof(u32);
	}

	dt_add_bin_prop(node, "reg", data, length);
}

/*
 * Fixups to apply to a kernel's device tree before booting it.
 */

struct list_node device_tree_fixups;

int dt_apply_fixups(struct device_tree *tree)
{
	struct device_tree_fixup *fixup;
	list_for_each(fixup, device_tree_fixups, list_node) {
		assert(fixup->fixup);
		if (fixup->fixup(fixup, tree))
			return 1;
	}
	return 0;
}

int dt_set_bin_prop_by_path(struct device_tree *tree, const char *path,
			    void *data, size_t data_size, int create)
{
	char *path_copy, *prop_name;
	struct device_tree_node *dt_node;

	path_copy = strdup(path);

	if (!path_copy) {
		printk(BIOS_ERR, "Failed to allocate a copy of path %s\n",
		       path);
		return 1;
	}

	prop_name = strrchr(path_copy, '/');
	if (!prop_name) {
		free(path_copy);
		printk(BIOS_ERR, "Path %s does not include '/'\n", path);
		return 1;
	}

	*prop_name++ = '\0'; /* Separate path from the property name. */

	dt_node = dt_find_node_by_path(tree, path_copy, NULL,
				       NULL, create);

	if (!dt_node) {
		printk(BIOS_ERR, "Failed to %s %s in the device tree\n",
		       create ? "create" : "find", path_copy);
		free(path_copy);
		return 1;
	}

	dt_add_bin_prop(dt_node, prop_name, data, data_size);
	free(path_copy);

	return 0;
}

/*
 * Prepare the /reserved-memory/ node.
 *
 * Technically, this can be called more than one time, to init and/or retrieve
 * the node. But dt_add_u32_prop() may leak a bit of memory if you do.
 *
 * @tree: Device tree to add/retrieve from.
 * @return: The /reserved-memory/ node (or NULL, if error).
 */
struct device_tree_node *dt_init_reserved_memory_node(struct device_tree *tree)
{
	struct device_tree_node *reserved;
	u32 addr = 0, size = 0;

	reserved = dt_find_node_by_path(tree, "/reserved-memory", &addr,
					&size, 1);
	if (!reserved)
		return NULL;

	/* Binding doc says this should have the same #{address,size}-cells as
	   the root. */
	dt_add_u32_prop(reserved, "#address-cells", addr);
	dt_add_u32_prop(reserved, "#size-cells", size);
	/* Binding doc says this should be empty (1:1 mapping from root). */
	dt_add_bin_prop(reserved, "ranges", NULL, 0);

	return reserved;
}

/*
 * Increment a single phandle in prop at a given offset by a given adjustment.
 *
 * @param prop		Property whose phandle should be adjusted.
 * @param adjustment	Value that should be added to the existing phandle.
 * @param offset	Byte offset of the phandle in the property data.
 *
 * @return		New phandle value, or 0 on error.
 */
static uint32_t dt_adjust_phandle(struct device_tree_property *prop,
				  uint32_t adjustment, uint32_t offset)
{
	if (offset + 4 > prop->prop.size)
		return 0;

	uint32_t phandle = be32dec(prop->prop.data + offset);
	if (phandle == 0 ||
	    phandle == FDT_PHANDLE_ILLEGAL ||
	    phandle == 0xffffffff)
		return 0;

	phandle += adjustment;
	if (phandle >= FDT_PHANDLE_ILLEGAL)
		return 0;

	be32enc(prop->prop.data + offset, phandle);
	return phandle;
}

/*
 * Adjust all phandles in subtree by adding a new base offset.
 *
 * @param node		Root node of the subtree to work on.
 * @param base		New phandle base to be added to all phandles.
 *
 * @return		New highest phandle in the subtree, or 0 on error.
 */
static uint32_t dt_adjust_all_phandles(struct device_tree_node *node,
				       uint32_t base)
{
	uint32_t new_max = MAX(base, 1);  /* make sure we don't return 0 */
	struct device_tree_property *prop;
	struct device_tree_node *child;

	if (!node)
		return new_max;

	list_for_each(prop, node->properties, list_node)
		if (dt_prop_is_phandle(prop)) {
			node->phandle = dt_adjust_phandle(prop, base, 0);
			if (!node->phandle)
				return 0;
			new_max = MAX(new_max, node->phandle);
		}  /* no break -- can have more than one phandle prop */

	list_for_each(child, node->children, list_node)
		new_max = MAX(new_max, dt_adjust_all_phandles(child, base));

	return new_max;
}

/*
 * Apply a /__local_fixup__ subtree to the corresponding overlay subtree.
 *
 * @param node		Root node of the overlay subtree to fix up.
 * @param node		Root node of the /__local_fixup__ subtree.
 * @param base		Adjustment that was added to phandles in the overlay.
 *
 * @return		0 on success, -1 on error.
 */
static int dt_fixup_locals(struct device_tree_node *node,
		    struct device_tree_node *fixup, uint32_t base)
{
	struct device_tree_property *prop;
	struct device_tree_property *fixup_prop;
	struct device_tree_node *child;
	struct device_tree_node *fixup_child;
	int i;

	/*
	 * For local fixups the /__local_fixup__ subtree contains the same node
	 * hierarchy as the main tree we're fixing up. Each property contains
	 * the fixup offsets for the respective property in the main tree. For
	 * each property in the fixup node, find the corresponding property in
	 * the base node and apply fixups to all offsets it specifies.
	 */
	list_for_each(fixup_prop, fixup->properties, list_node) {
		struct device_tree_property *base_prop = NULL;
		list_for_each(prop, node->properties, list_node)
			if (!strcmp(prop->prop.name, fixup_prop->prop.name)) {
				base_prop = prop;
				break;
			}

		/* We should always find a corresponding base prop for a fixup,
		   and fixup props contain a list of 32-bit fixup offsets. */
		if (!base_prop || fixup_prop->prop.size % sizeof(uint32_t))
			return -1;

		for (i = 0; i < fixup_prop->prop.size; i += sizeof(uint32_t))
			if (!dt_adjust_phandle(base_prop, base, be32dec(
					fixup_prop->prop.data + i)))
				return -1;
	}

	/* Now recursively descend both the base tree and the /__local_fixups__
	   subtree in sync to apply all fixups. */
	list_for_each(fixup_child, fixup->children, list_node) {
		struct device_tree_node *base_child = NULL;
		list_for_each(child, node->children, list_node)
			if (!strcmp(child->name, fixup_child->name)) {
				base_child = child;
				break;
			}

		/* All fixup nodes should have a corresponding base node. */
		if (!base_child)
			return -1;

		if (dt_fixup_locals(base_child, fixup_child, base) < 0)
			return -1;
	}

	return 0;
}

/*
 * Update all /__symbols__ properties in an overlay that start with
 * "/fragment@X/__overlay__" with corresponding path prefix in the base tree.
 *
 * @param symbols	/__symbols__ done to update.
 * @param fragment	/fragment@X node that references to should be updated.
 * @param base_path	Path of base tree node that the fragment overlaid.
 */
static void dt_fix_symbols(struct device_tree_node *symbols,
			   struct device_tree_node *fragment,
			   const char *base_path)
{
	struct device_tree_property *prop;
	char buf[512]; /* Should be enough for maximum DT path length? */
	char node_path[64]; /* easily enough for /fragment@XXXX/__overlay__ */

	if (!symbols) /* If the overlay has no /__symbols__ node, we're done! */
		return;

	int len = snprintf(node_path, sizeof(node_path), "/%s/__overlay__",
			   fragment->name);

	list_for_each(prop, symbols->properties, list_node)
		if (!strncmp(prop->prop.data, node_path, len)) {
			prop->prop.size = snprintf(buf, sizeof(buf), "%s%s",
				base_path, (char *)prop->prop.data + len) + 1;
			free(prop->prop.data);
			prop->prop.data = strdup(buf);
		}
}

/*
 * Fix up overlay according to a property in /__fixup__. If the fixed property
 * is a /fragment@X:target, also update /__symbols__ references to fragment.
 *
 * @params overlay	Overlay to fix up.
 * @params fixup	/__fixup__ property.
 * @params phandle	phandle value to insert where the fixup points to.
 * @params base_path	Path to the base DT node that the fixup points to.
 * @params overlay_symbols /__symbols__ node of the overlay.
 *
 * @return		0 on success, -1 on error.
 */
static int dt_fixup_external(struct device_tree *overlay,
			     struct device_tree_property *fixup,
			     uint32_t phandle, const char *base_path,
			     struct device_tree_node *overlay_symbols)
{
	struct device_tree_property *prop;

	/* External fixup properties are encoded as "<path>:<prop>:<offset>". */
	char *entry = fixup->prop.data;
	while ((void *)entry < fixup->prop.data + fixup->prop.size) {
		/* okay to destroy fixup property value, won't need it again */
		char *node_path = entry;
		entry = strchr(node_path, ':');
		if (!entry)
			return -1;
		*entry++ = '\0';

		char *prop_name = entry;
		entry = strchr(prop_name, ':');
		if (!entry)
			return -1;
		*entry++ = '\0';

		struct device_tree_node *ovl_node = dt_find_node_by_path(
			overlay, node_path, NULL, NULL, 0);
		if (!ovl_node || !isdigit(*entry))
			return -1;

		struct device_tree_property *ovl_prop = NULL;
		list_for_each(prop, ovl_node->properties, list_node)
			if (!strcmp(prop->prop.name, prop_name)) {
				ovl_prop = prop;
				break;
			}

		/* Move entry to first char after number, must be a '\0'. */
		uint32_t offset = skip_atoi(&entry);
		if (!ovl_prop || offset + 4 > ovl_prop->prop.size || entry[0])
			return -1;
		entry++;  /* jump over '\0' to potential next fixup */

		be32enc(ovl_prop->prop.data + offset, phandle);

		/* If this is a /fragment@X:target property, update references
		   to this fragment in the overlay __symbols__ now. */
		if (offset == 0 && !strcmp(prop_name, "target") &&
		    !strchr(node_path + 1, '/')) /* only toplevel nodes */
			dt_fix_symbols(overlay_symbols, ovl_node, base_path);
	}

	return 0;
}

/*
 * Apply all /__fixup__ properties in the overlay. This will destroy the
 * property data in /__fixup__ and it should not be accessed again.
 *
 * @params tree		Base device tree that the overlay updates.
 * @params symbols	/__symbols__ node of the base device tree.
 * @params overlay	Overlay to fix up.
 * @params fixups	/__fixup__ node in the overlay.
 * @params overlay_symbols /__symbols__ node of the overlay.
 *
 * @return		0 on success, -1 on error.
 */
static int dt_fixup_all_externals(struct device_tree *tree,
				  struct device_tree_node *symbols,
				  struct device_tree *overlay,
				  struct device_tree_node *fixups,
				  struct device_tree_node *overlay_symbols)
{
	struct device_tree_property *fix;

	/* If we have any external fixups, base tree must have /__symbols__. */
	if (!symbols)
		return -1;

	/*
	 * Unlike /__local_fixups__, /__fixups__ is not a whole subtree that
	 * mirrors the node hierarchy. It's just a directory of fixup properties
	 * that each directly contain all information necessary to apply them.
	 */
	list_for_each(fix, fixups->properties, list_node) {
		/* The name of a fixup property is the label of the node we want
		   a property to phandle-reference. Look up in /__symbols__. */
		const char *path = dt_find_string_prop(symbols, fix->prop.name);
		if (!path)
			return -1;

		/* Find node the label pointed to figure out its phandle. */
		struct device_tree_node *node = dt_find_node_by_path(tree, path,
			NULL, NULL, 0);
		if (!node)
			return -1;

		/* Write into the overlay property(s) pointing to that node. */
		if (dt_fixup_external(overlay, fix, node->phandle,
				      path, overlay_symbols) < 0)
			return -1;
	}

	return 0;
}

/*
 * Copy all nodes and properties from one DT subtree into another. This is a
 * shallow copy so both trees will point to the same property data afterwards.
 *
 * @params dst		Destination subtree to copy into.
 * @params src		Source subtree to copy from.
 * @params upd		1 to overwrite same-name properties, 0 to discard them.
 */
static void dt_copy_subtree(struct device_tree_node *dst,
			    struct device_tree_node *src, int upd)
{
	struct device_tree_property *prop;
	struct device_tree_property *src_prop;
	list_for_each(src_prop, src->properties, list_node) {
		if (dt_prop_is_phandle(src_prop) ||
		    !strcmp(src_prop->prop.name, "name")) {
			printk(BIOS_DEBUG,
			       "WARNING: ignoring illegal overlay prop '%s'\n",
			       src_prop->prop.name);
			continue;
		}

		struct device_tree_property *dst_prop = NULL;
		list_for_each(prop, dst->properties, list_node)
			if (!strcmp(prop->prop.name, src_prop->prop.name)) {
				dst_prop = prop;
				break;
			}

		if (dst_prop) {
			if (!upd) {
				printk(BIOS_DEBUG,
				       "WARNING: ignoring prop update '%s'\n",
				       src_prop->prop.name);
				continue;
			}
		} else {
			dst_prop = xzalloc(sizeof(*dst_prop));
			list_insert_after(&dst_prop->list_node,
					  &dst->properties);
		}

		dst_prop->prop = src_prop->prop;
	}

	struct device_tree_node *node;
	struct device_tree_node *src_node;
	list_for_each(src_node, src->children, list_node) {
		struct device_tree_node *dst_node = NULL;
		list_for_each(node, dst->children, list_node)
			if (!strcmp(node->name, src_node->name)) {
				dst_node = node;
				break;
			}

		if (!dst_node) {
			dst_node = xzalloc(sizeof(*dst_node));
			*dst_node = *src_node;
			list_insert_after(&dst_node->list_node, &dst->children);
		} else {
			dt_copy_subtree(dst_node, src_node, upd);
		}
	}
}

/*
 * Apply an overlay /fragment@X node to a base device tree.
 *
 * @param tree		Base device tree.
 * @param fragment	/fragment@X node.
 * @params overlay_symbols /__symbols__ node of the overlay.
 *
 * @return		0 on success, -1 on error.
 */
static int dt_import_fragment(struct device_tree *tree,
			      struct device_tree_node *fragment,
			      struct device_tree_node *overlay_symbols)
{
	/* The actual overlaid nodes/props are in an __overlay__ child node. */
	static const char *overlay_path[] = { "__overlay__", NULL };
	struct device_tree_node *overlay = dt_find_node(fragment, overlay_path,
							NULL, NULL, 0);

	/* If it doesn't have an __overlay__ child, it's not a fragment. */
	if (!overlay)
		return 0;

	/* Target node of the fragment can be given by path or by phandle. */
	struct device_tree_property *prop;
	struct device_tree_property *phandle = NULL;
	struct device_tree_property *path = NULL;
	list_for_each(prop, fragment->properties, list_node) {
		if (!strcmp(prop->prop.name, "target")) {
			phandle = prop;
			break; /* phandle target has priority, stop looking */
		}
		if (!strcmp(prop->prop.name, "target-path"))
			path = prop;
	}

	struct device_tree_node *target = NULL;
	if (phandle) {
		if (phandle->prop.size != sizeof(uint32_t))
			return -1;
		target = dt_find_node_by_phandle(tree->root,
						 be32dec(phandle->prop.data));
		/* Symbols already updated as part of dt_fixup_external(). */
	} else if (path) {
		target = dt_find_node_by_path(tree, path->prop.data,
					      NULL, NULL, 0);
		dt_fix_symbols(overlay_symbols, fragment, path->prop.data);
	}
	if (!target)
		return -1;

	dt_copy_subtree(target, overlay, 1);
	return 0;
}

/*
 * Apply a device tree overlay to a base device tree. This will
 * destroy/incorporate the overlay data, so it should not be freed or reused.
 * See dtc.git/Documentation/dt-object-internal.txt for overlay format details.
 *
 * @param tree		Unflattened base device tree to add the overlay into.
 * @param overlay	Unflattened overlay device tree to apply to the base.
 *
 * @return		0 on success, -1 on error.
 */
int dt_apply_overlay(struct device_tree *tree, struct device_tree *overlay)
{
	/*
	 * First, we need to make sure phandles inside the overlay don't clash
	 * with those in the base tree. We just define the highest phandle value
	 * in the base tree as the "phandle offset" for this overlay and
	 * increment all phandles in it by that value.
	 */
	uint32_t phandle_base = tree->max_phandle;
	uint32_t new_max = dt_adjust_all_phandles(overlay->root, phandle_base);
	if (!new_max) {
		printk(BIOS_ERR, "invalid phandles in overlay\n");
		return -1;
	}
	tree->max_phandle = new_max;

	/* Now that we changed phandles in the overlay, we need to update any
	   nodes referring to them. Those are listed in /__local_fixups__. */
	struct device_tree_node *local_fixups = dt_find_node_by_path(overlay,
					"/__local_fixups__", NULL, NULL, 0);
	if (local_fixups && dt_fixup_locals(overlay->root, local_fixups,
					    phandle_base) < 0) {
		printk(BIOS_ERR, "invalid local fixups in overlay\n");
		return -1;
	}

	/*
	 * Besides local phandle references (from nodes within the overlay to
	 * other nodes within the overlay), the overlay may also contain phandle
	 * references to the base tree. These are stored with invalid values and
	 * must be updated now. /__symbols__ contains a list of all labels in
	 * the base tree, and /__fixups__ describes all nodes in the overlay
	 * that contain external phandle references.
	 * We also take this opportunity to update all /fragment@X/__overlay__/
	 * prefixes in the overlay's /__symbols__ node to the correct path that
	 * the fragment will be placed in later, since this is the only step
	 * where we have all necessary information for that easily available.
	 */
	struct device_tree_node *symbols = dt_find_node_by_path(tree,
		"/__symbols__", NULL, NULL, 0);
	struct device_tree_node *fixups = dt_find_node_by_path(overlay,
		"/__fixups__", NULL, NULL, 0);
	struct device_tree_node *overlay_symbols = dt_find_node_by_path(overlay,
		"/__symbols__", NULL, NULL, 0);
	if (fixups && dt_fixup_all_externals(tree, symbols, overlay,
					     fixups, overlay_symbols) < 0) {
		printk(BIOS_ERR, "cannot match external fixups from overlay\n");
		return -1;
	}

	/* After all this fixing up, we can finally merge overlay into the tree
	   (one fragment at a time, because for some reason it's split up). */
	struct device_tree_node *fragment;
	list_for_each(fragment, overlay->root->children, list_node)
		if (dt_import_fragment(tree, fragment, overlay_symbols) < 0) {
			printk(BIOS_ERR, "bad DT fragment '%s'\n",
			       fragment->name);
			return -1;
		}

	/*
	 * We need to also update /__symbols__ to include labels from this
	 * overlay, in case we want to load further overlays with external
	 * phandle references to it. If the base tree already has a /__symbols__
	 * we merge them together, otherwise we just insert the overlay's
	 * /__symbols__ node into the base tree root.
	 */
	if (overlay_symbols) {
		if (symbols)
			dt_copy_subtree(symbols, overlay_symbols, 0);
		else
			list_insert_after(&overlay_symbols->list_node,
					  &tree->root->children);
	}

	return 0;
}
