xref: /aosp_15_r20/external/coreboot/src/commonlib/include/commonlib/device_tree.h (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
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