lib/devicetree: Integrate flattened devicetree support
* Adapt to coreboot coding style. * Use coreboot's endian conversion functions. * Fix header and header guards. * Get rid of unused functions. * Add Kconfig to build it on ramstage. * Replace size32 with ALIGN_UP and DIV_ROUND_UP. * Add NULL pointer checks * Convert constants to defines Required for Cavium's BDK and uImage FIT support. Change-Id: I6e6cd9f78fb402bd54d684097326d26eb78d552a Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com> Reviewed-on: https://review.coreboot.org/25523 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Julius Werner <jwerner@chromium.org>
This commit is contained in:
		
				
					committed by
					
						 Patrick Georgi
						Patrick Georgi
					
				
			
			
				
	
			
			
			
						parent
						
							67aca3e7dc
						
					
				
				
					commit
					666c172d38
				
			| @@ -1,8 +1,8 @@ | ||||
| /* | ||||
|  * Copyright 2013 Google Inc. | ||||
|  * Copyright 2018-present Facebook, Inc. | ||||
|  * | ||||
|  * See file CREDITS for list of people who contributed to this | ||||
|  * project. | ||||
|  * Taken from depthcharge: src/base/device_tree.h | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
| @@ -15,18 +15,17 @@ | ||||
|  * GNU General Public License for more details. | ||||
|  */ | ||||
|  | ||||
| #ifndef __BASE_DEVICE_TREE_H__ | ||||
| #define __BASE_DEVICE_TREE_H__ | ||||
| #ifndef __DEVICE_TREE_H__ | ||||
| #define __DEVICE_TREE_H__ | ||||
|  | ||||
| #include <stdint.h> | ||||
|  | ||||
| #include "base/list.h" | ||||
| #include <list.h> | ||||
|  | ||||
| /* | ||||
|  * Flattened device tree structures/constants. | ||||
|  */ | ||||
|  | ||||
| typedef struct FdtHeader { | ||||
| struct fdt_header { | ||||
| 	uint32_t magic; | ||||
| 	uint32_t totalsize; | ||||
| 	uint32_t structure_offset; | ||||
| @@ -40,21 +39,20 @@ typedef struct FdtHeader { | ||||
|  | ||||
| 	uint32_t strings_size; | ||||
| 	uint32_t structure_size; | ||||
| } FdtHeader; | ||||
| }; | ||||
|  | ||||
| static const uint32_t FdtMagic = 0xd00dfeed; | ||||
| #define FDT_HEADER_MAGIC	0xd00dfeed | ||||
| #define FDT_TOKEN_BEGIN_NODE	1 | ||||
| #define FDT_TOKEN_END_NODE	2 | ||||
| #define FDT_TOKEN_PROPERTY	3 | ||||
| #define FDT_TOKEN_END		9 | ||||
|  | ||||
| static const uint32_t TokenBeginNode = 1; | ||||
| static const uint32_t TokenEndNode = 2; | ||||
| static const uint32_t TokenProperty = 3; | ||||
| static const uint32_t TokenEnd = 9; | ||||
|  | ||||
| typedef struct FdtProperty | ||||
| struct fdt_property | ||||
| { | ||||
| 	const char *name; | ||||
| 	void *data; | ||||
| 	uint32_t size; | ||||
| } FdtProperty; | ||||
| }; | ||||
|  | ||||
|  | ||||
|  | ||||
| @@ -62,41 +60,41 @@ typedef struct FdtProperty | ||||
|  * Unflattened device tree structures. | ||||
|  */ | ||||
|  | ||||
| typedef struct DeviceTreeProperty | ||||
| struct device_tree_property | ||||
| { | ||||
| 	FdtProperty prop; | ||||
| 	struct fdt_property prop; | ||||
|  | ||||
| 	ListNode list_node; | ||||
| } DeviceTreeProperty; | ||||
| 	struct list_node list_node; | ||||
| }; | ||||
|  | ||||
| typedef struct DeviceTreeNode | ||||
| struct device_tree_node | ||||
| { | ||||
| 	const char *name; | ||||
| 	// List of DeviceTreeProperty-s. | ||||
| 	ListNode properties; | ||||
| 	// List of DeviceTreeNodes. | ||||
| 	ListNode children; | ||||
| 	// List of struct device_tree_property-s. | ||||
| 	struct list_node properties; | ||||
| 	// List of struct device_tree_nodes. | ||||
| 	struct list_node children; | ||||
|  | ||||
| 	ListNode list_node; | ||||
| } DeviceTreeNode; | ||||
| 	struct list_node list_node; | ||||
| }; | ||||
|  | ||||
| typedef struct DeviceTreeReserveMapEntry | ||||
| struct device_tree_reserve_map_entry | ||||
| { | ||||
| 	uint64_t start; | ||||
| 	uint64_t size; | ||||
|  | ||||
| 	ListNode list_node; | ||||
| } DeviceTreeReserveMapEntry; | ||||
| 	struct list_node list_node; | ||||
| }; | ||||
|  | ||||
| typedef struct DeviceTree | ||||
| struct device_tree | ||||
| { | ||||
| 	void *header; | ||||
| 	uint32_t header_size; | ||||
|  | ||||
| 	ListNode reserve_map; | ||||
| 	struct list_node reserve_map; | ||||
|  | ||||
| 	DeviceTreeNode *root; | ||||
| } DeviceTree; | ||||
| 	struct device_tree_node *root; | ||||
| }; | ||||
|  | ||||
|  | ||||
|  | ||||
| @@ -106,7 +104,7 @@ typedef struct DeviceTree | ||||
|  */ | ||||
|  | ||||
| // Read the property, if any, at offset offset. | ||||
| int fdt_next_property(void *blob, uint32_t offset, FdtProperty *prop); | ||||
| int fdt_next_property(void *blob, uint32_t offset, struct fdt_property *prop); | ||||
| // Read the name of the node, if any, at offset offset. | ||||
| int fdt_node_name(void *blob, uint32_t offset, const char **name); | ||||
|  | ||||
| @@ -116,7 +114,7 @@ int fdt_skip_node(void *blob, uint32_t offset); | ||||
| // Read a flattened device tree into a heirarchical structure which refers to | ||||
| // the contents of the flattened tree in place. Modifying the flat tree | ||||
| // invalidates the unflattened one. | ||||
| DeviceTree *fdt_unflatten(void *blob); | ||||
| struct device_tree *fdt_unflatten(void *blob); | ||||
|  | ||||
|  | ||||
|  | ||||
| @@ -125,95 +123,73 @@ DeviceTree *fdt_unflatten(void *blob); | ||||
|  */ | ||||
|  | ||||
| // Figure out how big a device tree would be if it were flattened. | ||||
| uint32_t dt_flat_size(DeviceTree *tree); | ||||
| uint32_t dt_flat_size(struct device_tree *tree); | ||||
| // Flatten a device tree into the buffer pointed to by dest. | ||||
| void dt_flatten(DeviceTree *tree, void *dest); | ||||
| void dt_print_node(DeviceTreeNode *node); | ||||
| void dt_flatten(struct device_tree *tree, void *dest); | ||||
| void dt_print_node(struct device_tree_node *node); | ||||
| // Read #address-cells and #size-cells properties from a node. | ||||
| void dt_read_cell_props(DeviceTreeNode *node, u32 *addrcp, u32 *sizecp); | ||||
| void dt_read_cell_props(struct device_tree_node *node, u32 *addrcp, u32 *sizecp); | ||||
| // Look up or create a node relative to a parent node, through its path | ||||
| // represented as an array of strings. | ||||
| DeviceTreeNode *dt_find_node(DeviceTreeNode *parent, const char **path, | ||||
| struct device_tree_node *dt_find_node(struct device_tree_node *parent, const char **path, | ||||
| 			     u32 *addrcp, u32 *sizecp, int create); | ||||
| // Look up or create a node relative to a parent node, through its path | ||||
| // represented as a string of '/' separated node names. | ||||
| DeviceTreeNode *dt_find_node_by_path(DeviceTreeNode *parent, const char *path, | ||||
| struct device_tree_node *dt_find_node_by_path(struct device_tree_node *parent, const char *path, | ||||
| 				     u32 *addrcp, u32 *sizecp, int create); | ||||
| // Look up a node relative to a parent node, through its compatible string. | ||||
| DeviceTreeNode *dt_find_compat(DeviceTreeNode *parent, const char *compatible); | ||||
| struct device_tree_node *dt_find_compat(struct device_tree_node *parent, const char *compatible); | ||||
| // Look up the next child of a parent node, through its compatible string. It | ||||
| // uses child pointer as the marker to find next. | ||||
| DeviceTreeNode *dt_find_next_compat_child(DeviceTreeNode *parent, | ||||
| 					  DeviceTreeNode *child, | ||||
| struct device_tree_node *dt_find_next_compat_child(struct device_tree_node *parent, | ||||
| 					  struct device_tree_node *child, | ||||
| 					  const char *compat); | ||||
| // Look up a node relative to a parent node, through its property value. | ||||
| DeviceTreeNode *dt_find_prop_value(DeviceTreeNode *parent, const char *name, | ||||
| struct device_tree_node *dt_find_prop_value(struct device_tree_node *parent, const char *name, | ||||
| 				   void *data, size_t size); | ||||
| // Write src into *dest as a 'length'-byte big-endian integer. | ||||
| void dt_write_int(u8 *dest, u64 src, size_t length); | ||||
| // Add different kinds of properties to a node, or update existing ones. | ||||
| void dt_add_bin_prop(DeviceTreeNode *node, char *name, void *data, size_t size); | ||||
| void dt_add_string_prop(DeviceTreeNode *node, char *name, char *str); | ||||
| void dt_add_u32_prop(DeviceTreeNode *node, char *name, u32 val); | ||||
| void dt_add_reg_prop(DeviceTreeNode *node, u64 *addrs, u64 *sizes, | ||||
| void dt_add_bin_prop(struct device_tree_node *node, const char *name, void *data, | ||||
| 		     size_t size); | ||||
| void dt_add_string_prop(struct device_tree_node *node, const char *name, char *str); | ||||
| void dt_add_u32_prop(struct device_tree_node *node, const char *name, u32 val); | ||||
| void dt_add_reg_prop(struct device_tree_node *node, u64 *addrs, u64 *sizes, | ||||
| 		     int count, u32 addr_cells, u32 size_cells); | ||||
| int dt_set_bin_prop_by_path(DeviceTree *tree, const char *path, | ||||
| int dt_set_bin_prop_by_path(struct device_tree *tree, const char *path, | ||||
| 			    void *data, size_t size, int create); | ||||
|  | ||||
| void dt_find_bin_prop(DeviceTreeNode *node, const char *name, void **data, | ||||
| void dt_find_bin_prop(struct device_tree_node *node, const char *name, void **data, | ||||
| 		      size_t *size); | ||||
| const char *dt_find_string_prop(DeviceTreeNode *node, const char *name); | ||||
| const char *dt_find_string_prop(struct device_tree_node *node, const char *name); | ||||
|  | ||||
| /* | ||||
|  * Fixups to apply to a kernel's device tree before booting it. | ||||
|  */ | ||||
|  | ||||
| typedef struct DeviceTreeFixup | ||||
| struct device_tree_fixup | ||||
| { | ||||
| 	// The function which does the fixing. | ||||
| 	int (*fixup)(struct DeviceTreeFixup *fixup, DeviceTree *tree); | ||||
| 	/** | ||||
| 	 * The function which does the fixing. | ||||
| 	 * 0 on success, non-zero on error. | ||||
| 	 */ | ||||
| 	int (*fixup)(struct device_tree_fixup *fixup, | ||||
| 		struct device_tree *tree); | ||||
|  | ||||
| 	ListNode list_node; | ||||
| } DeviceTreeFixup; | ||||
| 	struct list_node list_node; | ||||
| }; | ||||
|  | ||||
| extern ListNode device_tree_fixups; | ||||
| extern struct list_node device_tree_fixups; | ||||
|  | ||||
| int dt_apply_fixups(DeviceTree *tree); | ||||
|  | ||||
| /* | ||||
|  * Structure defining mapping between arbitrary objects and the device tree | ||||
|  * path to the property corresponding to the object. | ||||
| /** | ||||
|  * Function to apply fixups. | ||||
|  * 0 on success, non-zero on error. | ||||
|  */ | ||||
| typedef struct { | ||||
| 	int force_create; /* If false - do not create a new node. */ | ||||
| 	const char *dt_path; | ||||
| 	const char *key; | ||||
| } DtPathMap; | ||||
|  | ||||
| /* | ||||
|  * Copy mac addresses from sysinfo table into the device tree. The mapping | ||||
|  * between the dt_maps entries and sysinfo mac address table elements is | ||||
|  * implicit, i.e. the device tree node found in the maps entry, gets assinged | ||||
|  * the mac address found in the sysinfo table, in the same order. | ||||
|   */ | ||||
| int dt_set_mac_addresses(DeviceTree *tree, const DtPathMap *dt_maps); | ||||
|  | ||||
| /* | ||||
|  * Copy WIFI calibration data from sysinfo table into the device tree. Each | ||||
|  * WIFI calibration blob stored the sysinfo table contains key and data. The | ||||
|  * key is used for mapping into the device tree path. The data becomes the | ||||
|  * contents of the device tree property at that path. | ||||
|  */ | ||||
| int dt_set_wifi_calibration(DeviceTree *tree, const DtPathMap *maps); | ||||
|  | ||||
| /* | ||||
|  * Retrieve Country Code data from VPD and add it into the device tree. | ||||
|  */ | ||||
| int dt_set_wifi_country_code(DeviceTree *tree, const DtPathMap *maps); | ||||
| int dt_apply_fixups(struct device_tree *tree); | ||||
|  | ||||
| /* | ||||
|  * Init/retrieve the /reserved-memory/ node. | ||||
|  */ | ||||
| DeviceTreeNode *dt_init_reserved_memory_node(DeviceTree *tree); | ||||
| struct device_tree_node *dt_init_reserved_memory_node(struct device_tree *tree); | ||||
|  | ||||
| #endif /* __BASE_DEVICE_TREE_H__ */ | ||||
| #endif /* __DEVICE_TREE_H__ */ | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| /* | ||||
|  * Copyright 2012 Google Inc. | ||||
|  * Copyright 2018-present Facebook, Inc. | ||||
|  * | ||||
|  * See file CREDITS for list of people who contributed to this | ||||
|  * project. | ||||
|  * Taken from depthcharge: src/base/list.h | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
| @@ -15,25 +15,23 @@ | ||||
|  * GNU General Public License for more details. | ||||
|  */ | ||||
|  | ||||
| #ifndef __BASE_LIST_H__ | ||||
| #define __BASE_LIST_H__ | ||||
| #ifndef __LIST_H__ | ||||
| #define __LIST_H__ | ||||
|  | ||||
| #include <stddef.h> | ||||
| #include <stdint.h> | ||||
|  | ||||
| #include "base/container_of.h" | ||||
| struct list_node { | ||||
| 	struct list_node *next; | ||||
| 	struct list_node *prev; | ||||
| }; | ||||
|  | ||||
| typedef struct ListNode { | ||||
| 	struct ListNode *next; | ||||
| 	struct ListNode *prev; | ||||
| } ListNode; | ||||
|  | ||||
| // Remove ListNode node from the doubly linked list it's a part of. | ||||
| void list_remove(ListNode *node); | ||||
| // Insert ListNode node after ListNode after in a doubly linked list. | ||||
| void list_insert_after(ListNode *node, ListNode *after); | ||||
| // Insert ListNode node before ListNode before in a doubly linked list. | ||||
| void list_insert_before(ListNode *node, ListNode *before); | ||||
| // Remove list_node node from the doubly linked list it's a part of. | ||||
| void list_remove(struct list_node *node); | ||||
| // Insert list_node node after list_node after in a doubly linked list. | ||||
| void list_insert_after(struct list_node *node, struct list_node *after); | ||||
| // Insert list_node node before list_node before in a doubly linked list. | ||||
| void list_insert_before(struct list_node *node, struct list_node *before); | ||||
|  | ||||
| #define list_for_each(ptr, head, member)                                \ | ||||
| 	for ((ptr) = container_of((head).next, typeof(*(ptr)), member); \ | ||||
| @@ -41,4 +39,4 @@ void list_insert_before(ListNode *node, ListNode *before); | ||||
| 		(ptr) = container_of((ptr)->member.next,                \ | ||||
| 			typeof(*(ptr)), member)) | ||||
|  | ||||
| #endif /* __BASE_LIST_H__ */ | ||||
| #endif /* __LIST_H__ */ | ||||
|   | ||||
| @@ -17,6 +17,12 @@ config RAMSTAGE_LIBHWBASE | ||||
| 	help | ||||
| 	  Selected by features that require `libhwbase` in ramstage. | ||||
|  | ||||
| config FLATTENED_DEVICE_TREE | ||||
| 	bool | ||||
| 	help | ||||
| 	  Selected by features that require to parse and manipulate a flattened | ||||
| 	  devicetree in ramstage. | ||||
|  | ||||
| if RAMSTAGE_LIBHWBASE | ||||
|  | ||||
| config HWBASE_DYNAMIC_MMIO | ||||
|   | ||||
| @@ -135,6 +135,8 @@ ramstage-$(CONFIG_GENERIC_GPIO_LIB) += gpio.c | ||||
| ramstage-$(CONFIG_GENERIC_UDELAY) += timer.c | ||||
| ramstage-y += b64_decode.c | ||||
| ramstage-$(CONFIG_ACPI_NHLT) += nhlt.c | ||||
| ramstage-y += list.c | ||||
| ramstage-$(CONFIG_FLATTENED_DEVICE_TREE) += device_tree.c | ||||
|  | ||||
| romstage-y += cbmem_common.c | ||||
| romstage-y += imd_cbmem.c | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| /* | ||||
|  * Copyright 2013 Google Inc. | ||||
|  * Copyright 2018-present Facebook, Inc. | ||||
|  * | ||||
|  * See file CREDITS for list of people who contributed to this | ||||
|  * project. | ||||
|  * Taken from depthcharge: src/base/device_tree.c | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
| @@ -16,33 +16,30 @@ | ||||
|  */ | ||||
|  | ||||
| #include <assert.h> | ||||
| #include <console/console.h> | ||||
| #include <device_tree.h> | ||||
| #include <endian.h> | ||||
| #include <libpayload.h> | ||||
| #include <stdint.h> | ||||
|  | ||||
| #include "base/device_tree.h" | ||||
| #include <string.h> | ||||
| #include <stddef.h> | ||||
| #include <stdlib.h> | ||||
|  | ||||
| /* | ||||
|  * Functions for picking apart flattened trees. | ||||
|  */ | ||||
|  | ||||
| static uint32_t size32(uint32_t val) | ||||
| int fdt_next_property(void *blob, uint32_t offset, struct fdt_property *prop) | ||||
| { | ||||
| 	return (val + sizeof(uint32_t) - 1) / sizeof(uint32_t); | ||||
| } | ||||
|  | ||||
| int fdt_next_property(void *blob, uint32_t offset, FdtProperty *prop) | ||||
| { | ||||
| 	FdtHeader *header = (FdtHeader *)blob; | ||||
| 	struct fdt_header *header = (struct fdt_header *)blob; | ||||
| 	uint32_t *ptr = (uint32_t *)(((uint8_t *)blob) + offset); | ||||
|  | ||||
| 	int index = 0; | ||||
| 	if (betohl(ptr[index++]) != TokenProperty) | ||||
| 	if (be32toh(ptr[index++]) != FDT_TOKEN_PROPERTY) | ||||
| 		return 0; | ||||
|  | ||||
| 	uint32_t size = betohl(ptr[index++]); | ||||
| 	uint32_t name_offset = betohl(ptr[index++]); | ||||
| 	name_offset += betohl(header->strings_offset); | ||||
| 	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); | ||||
| @@ -50,22 +47,21 @@ int fdt_next_property(void *blob, uint32_t offset, FdtProperty *prop) | ||||
| 		prop->size = size; | ||||
| 	} | ||||
|  | ||||
| 	index += size32(size); | ||||
| 	index += DIV_ROUND_UP(size, sizeof(uint32_t)); | ||||
|  | ||||
| 	return index * 4; | ||||
| 	return index * sizeof(uint32_t); | ||||
| } | ||||
|  | ||||
| int fdt_node_name(void *blob, uint32_t offset, const char **name) | ||||
| { | ||||
| 	uint8_t *ptr = ((uint8_t *)blob) + offset; | ||||
|  | ||||
| 	if (betohl(*(uint32_t *)ptr) != TokenBeginNode) | ||||
| 	if (be32toh(*(uint32_t *)ptr) != FDT_TOKEN_BEGIN_NODE) | ||||
| 		return 0; | ||||
|  | ||||
| 	ptr += 4; | ||||
| 	if (name) | ||||
| 		*name = (char *)ptr; | ||||
| 	return size32(strlen((char *)ptr) + 1) * sizeof(uint32_t) + 4; | ||||
| 	return ALIGN_UP(strlen((char *)ptr) + 1, sizeof(uint32_t)) + 4; | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -77,20 +73,20 @@ int fdt_node_name(void *blob, uint32_t offset, const char **name) | ||||
| static void print_indent(int depth) | ||||
| { | ||||
| 	while (depth--) | ||||
| 		printf("  "); | ||||
| 		printk(BIOS_DEBUG, "  "); | ||||
| } | ||||
|  | ||||
| static void print_property(FdtProperty *prop, int depth) | ||||
| static void print_property(struct fdt_property *prop, int depth) | ||||
| { | ||||
| 	print_indent(depth); | ||||
| 	printf("prop \"%s\" (%d bytes).\n", prop->name, prop->size); | ||||
| 	printk(BIOS_DEBUG, "prop \"%s\" (%d bytes).\n", prop->name, prop->size); | ||||
| 	print_indent(depth + 1); | ||||
| 	for (int i = 0; i < MIN(25, prop->size); i++) { | ||||
| 		printf("%02x ", ((uint8_t *)prop->data)[i]); | ||||
| 		printk(BIOS_DEBUG, "%02x ", ((uint8_t *)prop->data)[i]); | ||||
| 	} | ||||
| 	if (prop->size > 25) | ||||
| 		printf("..."); | ||||
| 	printf("\n"); | ||||
| 		printk(BIOS_DEBUG, "..."); | ||||
| 	printk(BIOS_DEBUG, "\n"); | ||||
| } | ||||
|  | ||||
| static int print_flat_node(void *blob, uint32_t start_offset, int depth) | ||||
| @@ -105,9 +101,9 @@ static int print_flat_node(void *blob, uint32_t start_offset, int depth) | ||||
| 	offset += size; | ||||
|  | ||||
| 	print_indent(depth); | ||||
| 	printf("name = %s\n", name); | ||||
| 	printk(BIOS_DEBUG, "name = %s\n", name); | ||||
|  | ||||
| 	FdtProperty prop; | ||||
| 	struct fdt_property prop; | ||||
| 	while ((size = fdt_next_property(blob, offset, &prop))) { | ||||
| 		print_property(&prop, depth + 1); | ||||
|  | ||||
| @@ -156,34 +152,29 @@ int fdt_skip_node(void *blob, uint32_t start_offset) | ||||
| /* | ||||
|  * Functions to turn a flattened tree into an unflattened one. | ||||
|  */ | ||||
|  | ||||
| static DeviceTreeNode node_cache[1000]; | ||||
| static int node_counter = 0; | ||||
| static DeviceTreeProperty prop_cache[5000]; | ||||
| static int prop_counter = 0; | ||||
|  | ||||
| /* | ||||
|  * Libpayload's malloc() has linear allocation complexity and goes completely | ||||
|  * mental after a few thousand small requests. This little hack will absorb | ||||
|  * the worst of it to avoid increasing boot time for no reason. | ||||
|  */ | ||||
| static DeviceTreeNode *alloc_node(void) | ||||
| static struct device_tree_node *alloc_node(void) | ||||
| { | ||||
| 	if (node_counter >= ARRAY_SIZE(node_cache)) | ||||
| 		return xzalloc(sizeof(DeviceTreeNode)); | ||||
| 	return &node_cache[node_counter++]; | ||||
| 	struct device_tree_node *buf = malloc(sizeof(struct device_tree_node)); | ||||
| 	if (!buf) | ||||
| 		return NULL; | ||||
| 	memset(buf, 0, sizeof(*buf)); | ||||
| 	return buf; | ||||
| } | ||||
| static DeviceTreeProperty *alloc_prop(void) | ||||
|  | ||||
| static struct device_tree_property *alloc_prop(void) | ||||
| { | ||||
| 	if (prop_counter >= ARRAY_SIZE(prop_cache)) | ||||
| 		return xzalloc(sizeof(DeviceTreeProperty)); | ||||
| 	return &prop_cache[prop_counter++]; | ||||
| 	struct device_tree_property *buf = | ||||
| 		malloc(sizeof(struct device_tree_property)); | ||||
| 	if (!buf) | ||||
| 		return NULL; | ||||
| 	memset(buf, 0, sizeof(*buf)); | ||||
| 	return buf; | ||||
| } | ||||
|  | ||||
| static int fdt_unflatten_node(void *blob, uint32_t start_offset, | ||||
| 			      DeviceTreeNode **new_node) | ||||
| 			      struct device_tree_node **new_node) | ||||
| { | ||||
| 	ListNode *last; | ||||
| 	struct list_node *last; | ||||
| 	int offset = start_offset; | ||||
| 	const char *name; | ||||
| 	int size; | ||||
| @@ -193,14 +184,18 @@ static int fdt_unflatten_node(void *blob, uint32_t start_offset, | ||||
| 		return 0; | ||||
| 	offset += size; | ||||
|  | ||||
| 	DeviceTreeNode *node = alloc_node(); | ||||
| 	struct device_tree_node *node = alloc_node(); | ||||
| 	*new_node = node; | ||||
| 	if (!node) | ||||
| 		return 0; | ||||
| 	node->name = name; | ||||
|  | ||||
| 	FdtProperty fprop; | ||||
| 	struct fdt_property fprop; | ||||
| 	last = &node->properties; | ||||
| 	while ((size = fdt_next_property(blob, offset, &fprop))) { | ||||
| 		DeviceTreeProperty *prop = alloc_prop(); | ||||
| 		struct device_tree_property *prop = alloc_prop(); | ||||
| 		if (!prop) | ||||
| 			return 0; | ||||
| 		prop->prop = fprop; | ||||
|  | ||||
| 		list_insert_after(&prop->list_node, last); | ||||
| @@ -209,7 +204,7 @@ static int fdt_unflatten_node(void *blob, uint32_t start_offset, | ||||
| 		offset += size; | ||||
| 	} | ||||
|  | ||||
| 	DeviceTreeNode *child; | ||||
| 	struct device_tree_node *child; | ||||
| 	last = &node->children; | ||||
| 	while ((size = fdt_unflatten_node(blob, offset, &child))) { | ||||
| 		list_insert_after(&child->list_node, last); | ||||
| @@ -222,32 +217,38 @@ static int fdt_unflatten_node(void *blob, uint32_t start_offset, | ||||
| } | ||||
|  | ||||
| static int fdt_unflatten_map_entry(void *blob, uint32_t offset, | ||||
| 				   DeviceTreeReserveMapEntry **new_entry) | ||||
| 				   struct device_tree_reserve_map_entry **new) | ||||
| { | ||||
| 	uint64_t *ptr = (uint64_t *)(((uint8_t *)blob) + offset); | ||||
| 	uint64_t start = betohll(ptr[0]); | ||||
| 	uint64_t size = betohll(ptr[1]); | ||||
| 	uint64_t start = be64toh(ptr[0]); | ||||
| 	uint64_t size = be64toh(ptr[1]); | ||||
|  | ||||
| 	if (!size) | ||||
| 		return 0; | ||||
|  | ||||
| 	DeviceTreeReserveMapEntry *entry = xzalloc(sizeof(*entry)); | ||||
| 	*new_entry = entry; | ||||
| 	struct device_tree_reserve_map_entry *entry = malloc(sizeof(*entry)); | ||||
| 	if (!entry) | ||||
| 		return 0; | ||||
| 	memset(entry, 0, sizeof(*entry)); | ||||
| 	*new = entry; | ||||
| 	entry->start = start; | ||||
| 	entry->size = size; | ||||
|  | ||||
| 	return sizeof(uint64_t) * 2; | ||||
| } | ||||
|  | ||||
| DeviceTree *fdt_unflatten(void *blob) | ||||
| struct device_tree *fdt_unflatten(void *blob) | ||||
| { | ||||
| 	DeviceTree *tree = xzalloc(sizeof(*tree)); | ||||
| 	FdtHeader *header = (FdtHeader *)blob; | ||||
| 	struct device_tree *tree = malloc(sizeof(*tree)); | ||||
| 	struct fdt_header *header = (struct fdt_header *)blob; | ||||
| 	if (!tree) | ||||
| 		return NULL; | ||||
| 	memset(tree, 0, sizeof(*tree)); | ||||
| 	tree->header = header; | ||||
|  | ||||
| 	uint32_t struct_offset = betohl(header->structure_offset); | ||||
| 	uint32_t strings_offset = betohl(header->strings_offset); | ||||
| 	uint32_t reserve_offset = betohl(header->reserve_map_offset); | ||||
| 	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); | ||||
| @@ -256,10 +257,10 @@ DeviceTree *fdt_unflatten(void *blob) | ||||
| 	// new elements being added in the future. | ||||
| 	tree->header_size = min_offset; | ||||
|  | ||||
| 	DeviceTreeReserveMapEntry *entry; | ||||
| 	struct device_tree_reserve_map_entry *entry; | ||||
| 	uint32_t offset = reserve_offset; | ||||
| 	int size; | ||||
| 	ListNode *last = &tree->reserve_map; | ||||
| 	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; | ||||
| @@ -275,11 +276,11 @@ DeviceTree *fdt_unflatten(void *blob) | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Functions to find the size of device tree would take if it was flattened. | ||||
|  * Functions to find the size of the device tree if it was flattened. | ||||
|  */ | ||||
|  | ||||
| static void dt_flat_prop_size(DeviceTreeProperty *prop, uint32_t *struct_size, | ||||
| 			      uint32_t *strings_size) | ||||
| 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); | ||||
| @@ -288,25 +289,25 @@ static void dt_flat_prop_size(DeviceTreeProperty *prop, uint32_t *struct_size, | ||||
| 	// Name offset. | ||||
| 	*struct_size += sizeof(uint32_t); | ||||
| 	// Property value. | ||||
| 	*struct_size += size32(prop->prop.size) * sizeof(uint32_t); | ||||
| 	*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(DeviceTreeNode *node, uint32_t *struct_size, | ||||
| 			      uint32_t *strings_size) | ||||
| 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 += size32(strlen(node->name) + 1) * sizeof(uint32_t); | ||||
| 	*struct_size += ALIGN_UP(strlen(node->name) + 1, sizeof(uint32_t)); | ||||
|  | ||||
| 	DeviceTreeProperty *prop; | ||||
| 	struct device_tree_property *prop; | ||||
| 	list_for_each(prop, node->properties, list_node) | ||||
| 		dt_flat_prop_size(prop, struct_size, strings_size); | ||||
|  | ||||
| 	DeviceTreeNode *child; | ||||
| 	struct device_tree_node *child; | ||||
| 	list_for_each(child, node->children, list_node) | ||||
| 		dt_flat_node_size(child, struct_size, strings_size); | ||||
|  | ||||
| @@ -314,10 +315,10 @@ static void dt_flat_node_size(DeviceTreeNode *node, uint32_t *struct_size, | ||||
| 	*struct_size += sizeof(uint32_t); | ||||
| } | ||||
|  | ||||
| uint32_t dt_flat_size(DeviceTree *tree) | ||||
| uint32_t dt_flat_size(struct device_tree *tree) | ||||
| { | ||||
| 	uint32_t size = tree->header_size; | ||||
| 	DeviceTreeReserveMapEntry *entry; | ||||
| 	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; | ||||
| @@ -341,78 +342,79 @@ uint32_t dt_flat_size(DeviceTree *tree) | ||||
|  * Functions to flatten a device tree. | ||||
|  */ | ||||
|  | ||||
| static void dt_flatten_map_entry(DeviceTreeReserveMapEntry *entry, | ||||
| static void dt_flatten_map_entry(struct device_tree_reserve_map_entry *entry, | ||||
| 				 void **map_start) | ||||
| { | ||||
| 	((uint64_t *)*map_start)[0] = htobell(entry->start); | ||||
| 	((uint64_t *)*map_start)[1] = htobell(entry->size); | ||||
| 	((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(DeviceTreeProperty *prop, void **struct_start, | ||||
| 			    void *strings_base, void **strings_start) | ||||
| 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; | ||||
|  | ||||
| 	*((uint32_t *)dstruct) = htobel(TokenProperty); | ||||
| 	*((uint32_t *)dstruct) = htobe32(FDT_TOKEN_PROPERTY); | ||||
| 	dstruct += sizeof(uint32_t); | ||||
|  | ||||
| 	*((uint32_t *)dstruct) = htobel(prop->prop.size); | ||||
| 	*((uint32_t *)dstruct) = htobe32(prop->prop.size); | ||||
| 	dstruct += sizeof(uint32_t); | ||||
|  | ||||
| 	uint32_t name_offset = (uintptr_t)dstrings - (uintptr_t)strings_base; | ||||
| 	*((uint32_t *)dstruct) = htobel(name_offset); | ||||
| 	*((uint32_t *)dstruct) = htobe32(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 += size32(prop->prop.size) * 4; | ||||
| 	dstruct += ALIGN_UP(prop->prop.size, sizeof(uint32_t)); | ||||
|  | ||||
| 	*struct_start = dstruct; | ||||
| 	*strings_start = dstrings; | ||||
| } | ||||
|  | ||||
| static void dt_flatten_node(DeviceTreeNode *node, void **struct_start, | ||||
| static void dt_flatten_node(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; | ||||
|  | ||||
| 	*((uint32_t *)dstruct) = htobel(TokenBeginNode); | ||||
| 	*((uint32_t *)dstruct) = htobe32(FDT_TOKEN_BEGIN_NODE); | ||||
| 	dstruct += sizeof(uint32_t); | ||||
|  | ||||
| 	strcpy((char *)dstruct, node->name); | ||||
| 	dstruct += size32(strlen(node->name) + 1) * 4; | ||||
| 	dstruct += ALIGN_UP(strlen(node->name) + 1, sizeof(uint32_t)); | ||||
|  | ||||
| 	DeviceTreeProperty *prop; | ||||
| 	struct device_tree_property *prop; | ||||
| 	list_for_each(prop, node->properties, list_node) | ||||
| 		dt_flatten_prop(prop, (void **)&dstruct, strings_base, | ||||
| 				(void **)&dstrings); | ||||
|  | ||||
| 	DeviceTreeNode *child; | ||||
| 	struct device_tree_node *child; | ||||
| 	list_for_each(child, node->children, list_node) | ||||
| 		dt_flatten_node(child, (void **)&dstruct, strings_base, | ||||
| 				(void **)&dstrings); | ||||
|  | ||||
| 	*((uint32_t *)dstruct) = htobel(TokenEndNode); | ||||
| 	*((uint32_t *)dstruct) = htobe32(FDT_TOKEN_END_NODE); | ||||
| 	dstruct += sizeof(uint32_t); | ||||
|  | ||||
| 	*struct_start = dstruct; | ||||
| 	*strings_start = dstrings; | ||||
| } | ||||
|  | ||||
| void dt_flatten(DeviceTree *tree, void *start_dest) | ||||
| void dt_flatten(struct device_tree *tree, void *start_dest) | ||||
| { | ||||
| 	uint8_t *dest = (uint8_t *)start_dest; | ||||
|  | ||||
| 	memcpy(dest, tree->header, tree->header_size); | ||||
| 	FdtHeader *header = (FdtHeader *)dest; | ||||
| 	struct fdt_header *header = (struct fdt_header *)dest; | ||||
| 	dest += tree->header_size; | ||||
|  | ||||
| 	DeviceTreeReserveMapEntry *entry; | ||||
| 	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; | ||||
| @@ -423,22 +425,22 @@ void dt_flatten(DeviceTree *tree, void *start_dest) | ||||
| 	dt_flat_node_size(tree->root, &struct_size, &strings_size); | ||||
|  | ||||
| 	uint8_t *struct_start = dest; | ||||
| 	header->structure_offset = htobel(dest - (uint8_t *)start_dest); | ||||
| 	header->structure_size = htobel(struct_size); | ||||
| 	header->structure_offset = htobe32(dest - (uint8_t *)start_dest); | ||||
| 	header->structure_size = htobe32(struct_size); | ||||
| 	dest += struct_size; | ||||
|  | ||||
| 	*((uint32_t *)dest) = htobel(TokenEnd); | ||||
| 	*((uint32_t *)dest) = htobe32(FDT_TOKEN_END); | ||||
| 	dest += sizeof(uint32_t); | ||||
|  | ||||
| 	uint8_t *strings_start = dest; | ||||
| 	header->strings_offset = htobel(dest - (uint8_t *)start_dest); | ||||
| 	header->strings_size = htobel(strings_size); | ||||
| 	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 = htobel(dest - (uint8_t *)start_dest); | ||||
| 	header->totalsize = htobe32(dest - (uint8_t *)start_dest); | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -447,21 +449,21 @@ void dt_flatten(DeviceTree *tree, void *start_dest) | ||||
|  * Functions for printing a non-flattened device tree. | ||||
|  */ | ||||
|  | ||||
| static void print_node(DeviceTreeNode *node, int depth) | ||||
| static void print_node(struct device_tree_node *node, int depth) | ||||
| { | ||||
| 	print_indent(depth); | ||||
| 	printf("name = %s\n", node->name); | ||||
| 	printk(BIOS_DEBUG, "name = %s\n", node->name); | ||||
|  | ||||
| 	DeviceTreeProperty *prop; | ||||
| 	struct device_tree_property *prop; | ||||
| 	list_for_each(prop, node->properties, list_node) | ||||
| 		print_property(&prop->prop, depth + 1); | ||||
|  | ||||
| 	DeviceTreeNode *child; | ||||
| 	struct device_tree_node *child; | ||||
| 	list_for_each(child, node->children, list_node) | ||||
| 		print_node(child, depth + 1); | ||||
| } | ||||
|  | ||||
| void dt_print_node(DeviceTreeNode *node) | ||||
| void dt_print_node(struct device_tree_node *node) | ||||
| { | ||||
| 	print_node(node, 0); | ||||
| } | ||||
| @@ -479,14 +481,14 @@ void dt_print_node(DeviceTreeNode *node) | ||||
|  * @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(DeviceTreeNode *node, u32 *addrcp, u32 *sizecp) | ||||
| void dt_read_cell_props(struct device_tree_node *node, u32 *addrcp, u32 *sizecp) | ||||
| { | ||||
| 	DeviceTreeProperty *prop; | ||||
| 	struct device_tree_property *prop; | ||||
| 	list_for_each(prop, node->properties, list_node) { | ||||
| 		if (addrcp && !strcmp("#address-cells", prop->prop.name)) | ||||
| 			*addrcp = betohl(*(u32 *)prop->prop.data); | ||||
| 			*addrcp = be32toh(*(u32 *)prop->prop.data); | ||||
| 		if (sizecp && !strcmp("#size-cells", prop->prop.name)) | ||||
| 			*sizecp = betohl(*(u32 *)prop->prop.data); | ||||
| 			*sizecp = be32toh(*(u32 *)prop->prop.data); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -504,10 +506,11 @@ void dt_read_cell_props(DeviceTreeNode *node, u32 *addrcp, u32 *sizecp) | ||||
|  * @param create	1: Create node(s) if not found. 0: Return NULL instead. | ||||
|  * @return		The found/created node, or NULL. | ||||
|  */ | ||||
| DeviceTreeNode *dt_find_node(DeviceTreeNode *parent, const char **path, | ||||
| 			     u32 *addrcp, u32 *sizecp, int create) | ||||
| struct device_tree_node *dt_find_node(struct device_tree_node *parent, | ||||
| 				      const char **path, u32 *addrcp, | ||||
| 				      u32 *sizecp, int create) | ||||
| { | ||||
| 	DeviceTreeNode *node, *found = NULL; | ||||
| 	struct device_tree_node *node, *found = NULL; | ||||
|  | ||||
| 	// Update #address-cells and #size-cells for this level. | ||||
| 	dt_read_cell_props(parent, addrcp, sizecp); | ||||
| @@ -529,6 +532,8 @@ DeviceTreeNode *dt_find_node(DeviceTreeNode *parent, const char **path, | ||||
| 			return NULL; | ||||
|  | ||||
| 		found = alloc_node(); | ||||
| 		if (!found) | ||||
| 			return NULL; | ||||
| 		found->name = strdup(*path); | ||||
| 		if (!found->name) | ||||
| 			return NULL; | ||||
| @@ -555,15 +560,16 @@ DeviceTreeNode *dt_find_node(DeviceTreeNode *parent, const char **path, | ||||
|  * It is the caller responsibility to provide the correct path string, namely | ||||
|  * not starting or ending with a '/', and not having "//" anywhere in it. | ||||
|  */ | ||||
| DeviceTreeNode *dt_find_node_by_path(DeviceTreeNode *parent, const char *path, | ||||
| 				     u32 *addrcp, u32 *sizecp, int create) | ||||
| struct device_tree_node *dt_find_node_by_path(struct device_tree_node *parent, | ||||
| 					      const char *path, u32 *addrcp, | ||||
| 					      u32 *sizecp, int create) | ||||
| { | ||||
| 	char *dup_path = strdup(path); | ||||
| 	/* Hopefully enough depth for any node. */ | ||||
| 	const char *path_array[15]; | ||||
| 	int i; | ||||
| 	char *next_slash; | ||||
| 	DeviceTreeNode *node = NULL; | ||||
| 	struct device_tree_node *node = NULL; | ||||
|  | ||||
| 	if (!dup_path) | ||||
| 		return NULL; | ||||
| @@ -597,9 +603,10 @@ DeviceTreeNode *dt_find_node_by_path(DeviceTreeNode *parent, const char *path, | ||||
|  * @param compat	The compatible string to match. | ||||
|  * @return		1 = compatible, 0 = not compatible. | ||||
|  */ | ||||
| static int dt_check_compat_match(DeviceTreeNode *node, const char *compat) | ||||
| static int dt_check_compat_match(struct device_tree_node *node, | ||||
| 				 const char *compat) | ||||
| { | ||||
| 	DeviceTreeProperty *prop; | ||||
| 	struct device_tree_property *prop; | ||||
|  | ||||
| 	list_for_each(prop, node->properties, list_node) { | ||||
| 		if (!strcmp("compatible", prop->prop.name)) { | ||||
| @@ -628,15 +635,16 @@ static int dt_check_compat_match(DeviceTreeNode *node, const char *compat) | ||||
|  * @param compat	The compatible string to find. | ||||
|  * @return		The found node, or NULL. | ||||
|  */ | ||||
| DeviceTreeNode *dt_find_compat(DeviceTreeNode *parent, const char *compat) | ||||
| 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; | ||||
|  | ||||
| 	DeviceTreeNode *child; | ||||
| 	struct device_tree_node *child; | ||||
| 	list_for_each(child, parent->children, list_node) { | ||||
| 		DeviceTreeNode *found = dt_find_compat(child, compat); | ||||
| 		struct device_tree_node *found = dt_find_compat(child, compat); | ||||
| 		if (found) | ||||
| 			return found; | ||||
| 	} | ||||
| @@ -655,11 +663,12 @@ DeviceTreeNode *dt_find_compat(DeviceTreeNode *parent, const char *compat) | ||||
|  * @param compat	The compatible string to find. | ||||
|  * @return		The found node, or NULL. | ||||
|  */ | ||||
| DeviceTreeNode *dt_find_next_compat_child(DeviceTreeNode *parent, | ||||
| 					  DeviceTreeNode *child, | ||||
| 					  const char *compat) | ||||
| struct device_tree_node * | ||||
| dt_find_next_compat_child(struct device_tree_node *parent, | ||||
| 			  struct device_tree_node *child, | ||||
| 			  const char *compat) | ||||
| { | ||||
| 	DeviceTreeNode *next; | ||||
| 	struct device_tree_node *next; | ||||
| 	int ignore = 0; | ||||
|  | ||||
| 	if (child) | ||||
| @@ -687,10 +696,11 @@ DeviceTreeNode *dt_find_next_compat_child(DeviceTreeNode *parent, | ||||
|  * @param data		The property value to look for. | ||||
|  * @param size		The property size. | ||||
|  */ | ||||
| DeviceTreeNode *dt_find_prop_value(DeviceTreeNode *parent, const char *name, | ||||
| 				   void *data, size_t size) | ||||
| struct device_tree_node *dt_find_prop_value(struct device_tree_node *parent, | ||||
| 					    const char *name, void *data, | ||||
| 					    size_t size) | ||||
| { | ||||
| 	DeviceTreeProperty *prop; | ||||
| 	struct device_tree_property *prop; | ||||
|  | ||||
| 	/* Check if parent itself has the required property value. */ | ||||
| 	list_for_each(prop, parent->properties, list_node) { | ||||
| @@ -705,10 +715,10 @@ DeviceTreeNode *dt_find_prop_value(DeviceTreeNode *parent, const char *name, | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	DeviceTreeNode *child; | ||||
| 	struct device_tree_node *child; | ||||
| 	list_for_each(child, parent->children, list_node) { | ||||
| 		DeviceTreeNode *found = dt_find_prop_value(child, name, data, | ||||
| 							   size); | ||||
| 		struct device_tree_node *found = dt_find_prop_value(child, name, | ||||
| 								    data, size); | ||||
| 		if (found) | ||||
| 			return found; | ||||
| 	} | ||||
| @@ -738,9 +748,10 @@ void dt_write_int(u8 *dest, u64 src, size_t length) | ||||
|  * @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(DeviceTreeNode *node, char *name, void *data, size_t size) | ||||
| void dt_add_bin_prop(struct device_tree_node *node, const char *name, | ||||
| 		     void *data, size_t size) | ||||
| { | ||||
| 	DeviceTreeProperty *prop; | ||||
| 	struct device_tree_property *prop; | ||||
|  | ||||
| 	list_for_each(prop, node->properties, list_node) { | ||||
| 		if (!strcmp(prop->prop.name, name)) { | ||||
| @@ -751,6 +762,8 @@ void dt_add_bin_prop(DeviceTreeNode *node, char *name, void *data, size_t size) | ||||
| 	} | ||||
|  | ||||
| 	prop = alloc_prop(); | ||||
| 	if (!prop) | ||||
| 		return; | ||||
| 	list_insert_after(&prop->list_node, &node->properties); | ||||
| 	prop->prop.name = name; | ||||
| 	prop->prop.data = data; | ||||
| @@ -764,7 +777,7 @@ void dt_add_bin_prop(DeviceTreeNode *node, char *name, void *data, size_t size) | ||||
|  * @param name		The name of the property. | ||||
|  * @return		The found string, or NULL. | ||||
|  */ | ||||
| const char *dt_find_string_prop(DeviceTreeNode *node, const char *name) | ||||
| const char *dt_find_string_prop(struct device_tree_node *node, const char *name) | ||||
| { | ||||
| 	void *content; | ||||
| 	size_t size; | ||||
| @@ -782,10 +795,10 @@ const char *dt_find_string_prop(DeviceTreeNode *node, const char *name) | ||||
|  * @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(DeviceTreeNode *node, const char *name, void **data, | ||||
| 		      size_t *size) | ||||
| void dt_find_bin_prop(struct device_tree_node *node, const char *name, | ||||
| 		      void **data, size_t *size) | ||||
| { | ||||
| 	DeviceTreeProperty *prop; | ||||
| 	struct device_tree_property *prop; | ||||
|  | ||||
| 	*data = NULL; | ||||
| 	*size = 0; | ||||
| @@ -806,7 +819,8 @@ void dt_find_bin_prop(DeviceTreeNode *node, const char *name, void **data, | ||||
|  * @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(DeviceTreeNode *node, char *name, char *str) | ||||
| void dt_add_string_prop(struct device_tree_node *node, const char *name, | ||||
| 			char *str) | ||||
| { | ||||
| 	dt_add_bin_prop(node, name, str, strlen(str) + 1); | ||||
| } | ||||
| @@ -818,10 +832,12 @@ void dt_add_string_prop(DeviceTreeNode *node, char *name, char *str) | ||||
|  * @param name		The name of the new property. | ||||
|  * @param val		The integer to be stored in the property. | ||||
|  */ | ||||
| void dt_add_u32_prop(DeviceTreeNode *node, char *name, u32 val) | ||||
| void dt_add_u32_prop(struct device_tree_node *node, const char *name, u32 val) | ||||
| { | ||||
| 	u32 *val_ptr = xmalloc(sizeof(val)); | ||||
| 	*val_ptr = htobel(val); | ||||
| 	u32 *val_ptr = malloc(sizeof(val)); | ||||
| 	if (!val_ptr) | ||||
| 		return; | ||||
| 	*val_ptr = htobe32(val); | ||||
| 	dt_add_bin_prop(node, name, val_ptr, sizeof(*val_ptr)); | ||||
| } | ||||
|  | ||||
| @@ -835,12 +851,14 @@ void dt_add_u32_prop(DeviceTreeNode *node, char *name, u32 val) | ||||
|  * @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(DeviceTreeNode *node, u64 *addrs, u64 *sizes, | ||||
| 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 *data = malloc(length); | ||||
| 	if (!data) | ||||
| 		return; | ||||
| 	u8 *cur = data; | ||||
|  | ||||
| 	for (i = 0; i < count; i++) { | ||||
| @@ -857,11 +875,11 @@ void dt_add_reg_prop(DeviceTreeNode *node, u64 *addrs, u64 *sizes, | ||||
|  * Fixups to apply to a kernel's device tree before booting it. | ||||
|  */ | ||||
|  | ||||
| ListNode device_tree_fixups; | ||||
| struct list_node device_tree_fixups; | ||||
|  | ||||
| int dt_apply_fixups(DeviceTree *tree) | ||||
| int dt_apply_fixups(struct device_tree *tree) | ||||
| { | ||||
| 	DeviceTreeFixup *fixup; | ||||
| 	struct device_tree_fixup *fixup; | ||||
| 	list_for_each(fixup, device_tree_fixups, list_node) { | ||||
| 		assert(fixup->fixup); | ||||
| 		if (fixup->fixup(fixup, tree)) | ||||
| @@ -870,23 +888,23 @@ int dt_apply_fixups(DeviceTree *tree) | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| int dt_set_bin_prop_by_path(DeviceTree *tree, const char *path, | ||||
| 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; | ||||
| 	DeviceTreeNode *dt_node; | ||||
| 	struct device_tree_node *dt_node; | ||||
|  | ||||
| 	path_copy = strdup(path); | ||||
|  | ||||
| 	if (!path_copy) { | ||||
| 		printf("Failed to allocate a copy of path %s\n", path); | ||||
| 		printk(BIOS_ERR, "Failed to allocate a copy of path %s\n", | ||||
| 		       path); | ||||
| 		return 1; | ||||
| 	} | ||||
|  | ||||
| 	prop_name = strrchr(path_copy, '/'); | ||||
| 	if (!prop_name) { | ||||
| 		printf("Path %s does not include '/'\n", path); | ||||
| 		free(path_copy); | ||||
| 		printk(BIOS_ERR, "Path %s does not include '/'\n", path); | ||||
| 		return 1; | ||||
| 	} | ||||
|  | ||||
| @@ -896,9 +914,8 @@ int dt_set_bin_prop_by_path(DeviceTree *tree, const char *path, | ||||
| 				       NULL, create); | ||||
|  | ||||
| 	if (!dt_node) { | ||||
| 		printf("Failed to %s %s in the device tree\n", | ||||
| 		printk(BIOS_ERR, "Failed to %s %s in the device tree\n", | ||||
| 		       create ? "create" : "find", path_copy); | ||||
| 		free(path_copy); | ||||
| 		return 1; | ||||
| 	} | ||||
|  | ||||
| @@ -916,9 +933,9 @@ int dt_set_bin_prop_by_path(DeviceTree *tree, const char *path, | ||||
|  * @tree: Device tree to add/retrieve from. | ||||
|  * @return: The /reserved-memory/ node (or NULL, if error). | ||||
|  */ | ||||
| DeviceTreeNode *dt_init_reserved_memory_node(DeviceTree *tree) | ||||
| struct device_tree_node *dt_init_reserved_memory_node(struct device_tree *tree) | ||||
| { | ||||
| 	DeviceTreeNode *reserved; | ||||
| 	struct device_tree_node *reserved; | ||||
| 	u32 addr = 0, size = 0; | ||||
|  | ||||
| 	reserved = dt_find_node_by_path(tree->root, "reserved-memory", &addr, | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| /* | ||||
|  * Copyright 2012 Google Inc. | ||||
|  * Copyright 2018-present Facebook, Inc. | ||||
|  * | ||||
|  * See file CREDITS for list of people who contributed to this | ||||
|  * project. | ||||
|  * Taken from depthcharge: src/base/list.c | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
| @@ -15,9 +15,9 @@ | ||||
|  * GNU General Public License for more details. | ||||
|  */ | ||||
|  | ||||
| #include "base/list.h" | ||||
| #include <list.h> | ||||
|  | ||||
| void list_remove(ListNode *node) | ||||
| void list_remove(struct list_node *node) | ||||
| { | ||||
| 	if (node->prev) | ||||
| 		node->prev->next = node->next; | ||||
| @@ -25,7 +25,7 @@ void list_remove(ListNode *node) | ||||
| 		node->next->prev = node->prev; | ||||
| } | ||||
|  | ||||
| void list_insert_after(ListNode *node, ListNode *after) | ||||
| void list_insert_after(struct list_node *node, struct list_node *after) | ||||
| { | ||||
| 	node->next = after->next; | ||||
| 	node->prev = after; | ||||
| @@ -34,7 +34,7 @@ void list_insert_after(ListNode *node, ListNode *after) | ||||
| 		node->next->prev = node; | ||||
| } | ||||
|  | ||||
| void list_insert_before(ListNode *node, ListNode *before) | ||||
| void list_insert_before(struct list_node *node, struct list_node *before) | ||||
| { | ||||
| 	node->prev = before->prev; | ||||
| 	node->next = before; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user