1 /* Taken from depthcharge: src/base/device_tree.h */ 2 /* SPDX-License-Identifier: GPL-2.0-or-later */ 3 4 #ifndef __COMMONLIB_DEVICE_TREE_H__ 5 #define __COMMONLIB_DEVICE_TREE_H__ 6 7 #include <stdbool.h> 8 #include <stddef.h> 9 #include <stdint.h> 10 #include <commonlib/list.h> 11 12 /* 13 * Flattened device tree structures/constants. 14 */ 15 16 struct fdt_header { 17 uint32_t magic; 18 uint32_t totalsize; 19 uint32_t structure_offset; 20 uint32_t strings_offset; 21 uint32_t reserve_map_offset; 22 23 uint32_t version; 24 uint32_t last_comp_version; 25 26 uint32_t boot_cpuid_phys; 27 28 uint32_t strings_size; 29 uint32_t structure_size; 30 }; 31 32 #define FDT_HEADER_MAGIC 0xd00dfeed 33 #define FDT_SUPPORTED_VERSION 17 34 #define FDT_TOKEN_BEGIN_NODE 1 35 #define FDT_TOKEN_END_NODE 2 36 #define FDT_TOKEN_PROPERTY 3 37 #define FDT_TOKEN_NOP 4 38 #define FDT_TOKEN_END 9 39 #define FDT_PHANDLE_ILLEGAL 0xdeadbeef 40 41 struct fdt_property 42 { 43 const char *name; 44 void *data; 45 uint32_t size; 46 }; 47 48 /* 49 * Unflattened device tree structures. 50 */ 51 52 struct device_tree_region { 53 u64 addr; 54 u64 size; 55 }; 56 57 struct device_tree_property 58 { 59 struct fdt_property prop; 60 61 struct list_node list_node; 62 }; 63 64 struct device_tree_node 65 { 66 const char *name; 67 uint32_t phandle; 68 69 /* List of struct device_tree_property-s. */ 70 struct list_node properties; 71 /* List of struct device_tree_nodes. */ 72 struct list_node children; 73 74 struct list_node list_node; 75 }; 76 77 struct device_tree_reserve_map_entry 78 { 79 uint64_t start; 80 uint64_t size; 81 82 struct list_node list_node; 83 }; 84 85 struct device_tree 86 { 87 const void *header; 88 uint32_t header_size; 89 uint32_t max_phandle; 90 91 struct list_node reserve_map; 92 93 struct device_tree_node *root; 94 }; 95 96 /* 97 * Flattened device tree functions. These generally return the number of bytes 98 * which were consumed reading the requested value. 99 */ 100 101 /* Checks if blob points to a valid FDT */ 102 bool fdt_is_valid(const void *blob); 103 /* Read the property at offset, if any exists. */ 104 int fdt_next_property(const void *blob, uint32_t offset, 105 struct fdt_property *prop); 106 /* 107 * Read the node name into 'name' of the node behind 'node_offset' 108 * and return total bytes used for name 109 */ 110 int fdt_next_node_name(const void *blob, uint32_t node_offset, const char **name); 111 112 void fdt_print_node(const void *blob, uint32_t offset); 113 int fdt_skip_node(const void *blob, uint32_t offset); 114 115 /* Read property and put into fdt_prop. Returns offset to property */ 116 u32 fdt_read_prop(const void *blob, u32 node_offset, const char *prop_name, 117 struct fdt_property *fdt_prop); 118 /* Read reg property and save regions inside 'regions'. Returns number of regions read */ 119 u32 fdt_read_reg_prop(const void *blob, u32 node_offset, u32 addr_cells, u32 size_cells, 120 struct device_tree_region regions[], size_t regions_count); 121 /* Find a node by a given path and return the offset */ 122 u32 fdt_find_node_by_path(const void *blob, const char *path, u32 *addrcp, u32 *sizecp); 123 /* Find multiple nodes matching a given pattern. Returns number of nodes found */ 124 size_t fdt_find_subnodes_by_prefix(const void *blob, u32 node_offset, const char *prefix, 125 u32 *addrcp, u32 *sizecp, u32 results[], size_t results_len); 126 /* Find a node by a given alias and return its offset */ 127 u32 fdt_find_node_by_alias(const void *blob, const char *alias_name, 128 u32 *addr_cells, u32 *size_cells); 129 130 /* Read memory regions from a flat device-tree. */ 131 size_t fdt_read_memory_regions(const void *blob, struct device_tree_region regions[], 132 size_t regions_count); 133 /* Find top of memory from a flat device-tree. */ 134 uint64_t fdt_get_memory_top(const void *blob); 135 136 /* Read a flattened device tree into a hierarchical structure which refers to 137 the contents of the flattened tree in place. Modifying the flat tree 138 invalidates the unflattened one. */ 139 struct device_tree *fdt_unflatten(const void *blob); 140 141 /* 142 * Unflattened device tree functions. 143 */ 144 145 /* Figure out how big a device tree would be if it were flattened. */ 146 uint32_t dt_flat_size(const struct device_tree *tree); 147 /* Flatten a device tree into the buffer pointed to by dest. */ 148 void dt_flatten(const struct device_tree *tree, void *dest); 149 void dt_print_node(const struct device_tree_node *node); 150 /* Read #address-cells and #size-cells properties from a node. */ 151 void dt_read_cell_props(const struct device_tree_node *node, u32 *addrcp, 152 u32 *sizecp); 153 /* Look up or create a node relative to a parent node, through its path 154 represented as an array of strings. */ 155 struct device_tree_node *dt_find_node(struct device_tree_node *parent, const char **path, 156 u32 *addrcp, u32 *sizecp, int create); 157 struct device_tree_node *dt_find_node_by_phandle(struct device_tree_node *root, 158 uint32_t phandle); 159 /* Look up or create a node in the tree, through its path 160 represented as a string of '/' separated node names. */ 161 struct device_tree_node *dt_find_node_by_path(struct device_tree *tree, 162 const char *path, u32 *addrcp, u32 *sizecp, int create); 163 /* Look up a node through an alias. */ 164 struct device_tree_node *dt_find_node_by_alias(struct device_tree *tree, 165 const char *alias); 166 /* Look up a node relative to a parent node, through its compatible string. */ 167 struct device_tree_node *dt_find_compat(struct device_tree_node *parent, const char *compatible); 168 /* Look up the next child of a parent node, through its compatible string. It 169 uses child pointer as the marker to find next. */ 170 struct device_tree_node *dt_find_next_compat_child(struct device_tree_node *parent, 171 struct device_tree_node *child, 172 const char *compat); 173 /* Look up a node relative to a parent node, through its property value. */ 174 struct device_tree_node *dt_find_prop_value(struct device_tree_node *parent, const char *name, 175 void *data, size_t size); 176 /* Write src into *dest as a 'length'-byte big-endian integer. */ 177 void dt_write_int(u8 *dest, u64 src, size_t length); 178 /* Delete a property */ 179 void dt_delete_prop(struct device_tree_node *node, const char *name); 180 /* Add different kinds of properties to a node, or update existing ones. */ 181 void dt_add_bin_prop(struct device_tree_node *node, const char *name, 182 void *data, size_t size); 183 void dt_add_string_prop(struct device_tree_node *node, const char *name, 184 const char *str); 185 void dt_add_u32_prop(struct device_tree_node *node, const char *name, u32 val); 186 void dt_add_u64_prop(struct device_tree_node *node, const char *name, u64 val); 187 void dt_add_reg_prop(struct device_tree_node *node, u64 *addrs, u64 *sizes, 188 int count, u32 addr_cells, u32 size_cells); 189 int dt_set_bin_prop_by_path(struct device_tree *tree, const char *path, 190 void *data, size_t size, int create); 191 192 void dt_find_bin_prop(const struct device_tree_node *node, const char *name, 193 const void **data, size_t *size); 194 const char *dt_find_string_prop(const struct device_tree_node *node, 195 const char *name); 196 197 /* Apply an overlay to a base device tree. Ownership of the overlay data passes 198 to the newly combined base tree -- do not free() or access it afterwards! */ 199 int dt_apply_overlay(struct device_tree *tree, struct device_tree *overlay); 200 201 /* 202 * Fixups to apply to a kernel's device tree before booting it. 203 */ 204 205 struct device_tree_fixup 206 { 207 /** 208 * The function which does the fixing. 209 * 0 on success, non-zero on error. 210 */ 211 int (*fixup)(struct device_tree_fixup *fixup, 212 struct device_tree *tree); 213 214 struct list_node list_node; 215 }; 216 217 extern struct list_node device_tree_fixups; 218 219 /** 220 * Function to apply fixups. 221 * 0 on success, non-zero on error. 222 */ 223 int dt_apply_fixups(struct device_tree *tree); 224 225 /* 226 * Init/retrieve the /reserved-memory/ node. 227 */ 228 struct device_tree_node *dt_init_reserved_memory_node(struct device_tree *tree); 229 230 #endif /* __COMMONLIB_DEVICE_TREE_H__ */ 231