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

#include <assert.h>
#include <console/console.h>
#include <ctype.h>
#include <device_tree.h>
#include <endian.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#include <stdlib.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

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

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