diff options
author | Patrick Rudolph <patrick.rudolph@9elements.com> | 2018-04-03 09:57:33 +0200 |
---|---|---|
committer | Patrick Georgi <pgeorgi@google.com> | 2018-04-30 09:33:32 +0000 |
commit | 666c172d385823eefdfeb99ae3a4c20fd1b711f9 (patch) | |
tree | 8d21e2083f19171688181d20baea09a6b78b6bd8 /src | |
parent | 67aca3e7dc05f0f982a50c7e8edb91a03d573687 (diff) |
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>
Diffstat (limited to 'src')
-rw-r--r-- | src/include/device_tree.h | 160 | ||||
-rw-r--r-- | src/include/list.h | 32 | ||||
-rw-r--r-- | src/lib/Kconfig | 6 | ||||
-rw-r--r-- | src/lib/Makefile.inc | 2 | ||||
-rw-r--r-- | src/lib/device_tree.c | 329 | ||||
-rw-r--r-- | src/lib/list.c | 12 |
6 files changed, 270 insertions, 271 deletions
diff --git a/src/include/device_tree.h b/src/include/device_tree.h index 7a2cfb20be..107fcf6a48 100644 --- a/src/include/device_tree.h +++ b/src/include/device_tree.h @@ -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; +}; -static const uint32_t TokenBeginNode = 1; -static const uint32_t TokenEndNode = 2; -static const uint32_t TokenProperty = 3; -static const uint32_t TokenEnd = 9; +#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 -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); - - ListNode list_node; -} DeviceTreeFixup; - -extern ListNode 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. - */ -typedef struct { - int force_create; /* If false - do not create a new node. */ - const char *dt_path; - const char *key; -} DtPathMap; + /** + * The function which does the fixing. + * 0 on success, non-zero on error. + */ + int (*fixup)(struct device_tree_fixup *fixup, + struct device_tree *tree); -/* - * 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); + struct list_node list_node; +}; -/* - * 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); +extern struct list_node device_tree_fixups; -/* - * Retrieve Country Code data from VPD and add it into the device tree. +/** + * Function to apply fixups. + * 0 on success, non-zero on error. */ -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__ */ diff --git a/src/include/list.h b/src/include/list.h index 084c8f015f..201a8d39a8 100644 --- a/src/include/list.h +++ b/src/include/list.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__ */ diff --git a/src/lib/Kconfig b/src/lib/Kconfig index bce0291b9b..eb4c16eb51 100644 --- a/src/lib/Kconfig +++ b/src/lib/Kconfig @@ -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 diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc index 99322dcc76..a902e0cd6a 100644 --- a/src/lib/Makefile.inc +++ b/src/lib/Makefile.inc @@ -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 diff --git a/src/lib/device_tree.c b/src/lib/device_tree.c index 5f77870e4d..0a88c1f886 100644 --- a/src/lib/device_tree.c +++ b/src/lib/device_tree.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, diff --git a/src/lib/list.c b/src/lib/list.c index ea7eff44f7..06d422d30e 100644 --- a/src/lib/list.c +++ b/src/lib/list.c @@ -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; |