blob: 04c7bc8595417dcbb181694b10cd9ac9ebf3143d [file] [log] [blame]
SzuWei Lin6ad4caa2017-04-06 17:12:27 +08001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Li Chenf6c209b2016-11-28 12:15:33 +080016
17#ifndef LIBUFDT_H
18#define LIBUFDT_H
19
20#include "libufdt_sysdeps.h"
21#include "ufdt_types.h"
22
23/*
Li Chenf6c209b2016-11-28 12:15:33 +080024 * BEGIN of ufdt_node methods
25 */
26
27/*
28 * Allocates spaces for new ufdt_node who represents a fdt node at fdt_tag_ptr.
SzuWei Lin8a7039c2017-04-14 15:38:15 +080029 * In order to get name pointer, it's necessary to give the pointer to the
Li Chenf6c209b2016-11-28 12:15:33 +080030 * entire fdt it belongs to.
31 *
32 *
33 * @return: a pointer to the newly created ufdt_node or
34 * NULL if dto_malloc failed
35 */
SzuWei Lind62a8492017-04-24 10:17:15 +080036struct ufdt_node *ufdt_node_construct(void *fdtp, fdt32_t *fdt_tag_ptr,
37 struct ufdt_node_pool *pool);
Li Chenf6c209b2016-11-28 12:15:33 +080038
39/*
40 * Frees all nodes in the subtree rooted at *node.
Li Chenf6c209b2016-11-28 12:15:33 +080041 */
SzuWei Lind62a8492017-04-24 10:17:15 +080042void ufdt_node_destruct(struct ufdt_node *node, struct ufdt_node_pool *pool);
Li Chenf6c209b2016-11-28 12:15:33 +080043
44/*
45 * Adds the child as a subnode of the parent.
46 * It's been done by add entries in parent->prop_list or node_list depending on
47 * the tag type of child.
48 *
49 * @return: 0 if success
50 * < 0 otherwise
51 *
52 * @Time: O(1) w.h.p.
53 */
54int ufdt_node_add_child(struct ufdt_node *parent, struct ufdt_node *child);
55
56/* BEGIN of FDT_PROP related functions .*/
57
58/*
59 * Gets pointer to FDT_PROP subnode of node with name equals to name[0..len-1]
60 *
61 * @return: a pointer to the subnode or
62 * NULL if no such subnode.
63 *
64 * @Time: O(len = length of name) w.h.p.
65 */
66struct ufdt_node *ufdt_node_get_property_by_name_len(
67 const struct ufdt_node *node, const char *name, int len);
68struct ufdt_node *ufdt_node_get_property_by_name(const struct ufdt_node *node,
69 const char *name);
70
71/*
72 * Gets the pointer to the FDT_PROP node's data in the corresponding fdt.
73 * Also writes the length of such data to *out_len if out_len is not NULL.
74 *
75 * @return: a pointer to some data located in fdt or
76 * NULL if *node is not a FDT_PROP
77 */
78char *ufdt_node_get_fdt_prop_data(const struct ufdt_node *node, int *out_len);
79
80/*
81 * Gets pointer to FDT_PROP node's data in fdt with name equals to
82 * name[0..len-1], which is a subnode of *node.
83 * It's actually a composition of ufdt_node_get_property_by_name and
84 * ufdt_node_get_fdt_prop_data
85 *
86 * @return: a pointer to some data located in fdt or
87 * NULL if no such subnode.
88 *
89 * @Time: O(len = length of name) w.h.p.
90 */
91char *ufdt_node_get_fdt_prop_data_by_name_len(const struct ufdt_node *node,
92 const char *name, int len,
93 int *out_len);
94char *ufdt_node_get_fdt_prop_data_by_name(const struct ufdt_node *node,
95 const char *name, int *out_len);
96
97/* END of FDT_PROP related functions .*/
98
99/*
100 * Gets pointer to FDT_BEGIN_NODE subnode of node with name equals to
101 * name[0..len-1].
102 *
103 * @return: a pointer to the subnode or
104 * NULL if no such subnode.
105 *
106 * @Time: O(len = length of name) w.h.p.
107 */
108
109struct ufdt_node *ufdt_node_get_subnode_by_name_len(const struct ufdt_node *node,
110 const char *name, int len);
111struct ufdt_node *ufdt_node_get_subnode_by_name(const struct ufdt_node *node,
112 const char *name);
113
114/*
115 * Gets the pointer to FDT_NODE node whose relative path to *node is
116 * path[0..len-1].
117 * Note that the relative path doesn't support parent node like:
118 * "../path/to/node".
119 *
120 * @return: a pointer to the node or
121 * NULL if no such node.
122 *
123 * @Time: O(len = length of path) w.h.p.
124 */
125struct ufdt_node *ufdt_node_get_node_by_path_len(const struct ufdt_node *node,
126 const char *path, int len);
127struct ufdt_node *ufdt_node_get_node_by_path(const struct ufdt_node *node,
128 const char *path);
129
130/*
131 * Gets the phandle value of the node if it has.
132 *
133 * @return: phandle value of that node or
134 * 0 if *node is not FDT_NODE or there's no "phandle"/"linux,phandle"
135 * property.
136 *
137 * @Time: O(1) w.h.p.
138 */
139uint32_t ufdt_node_get_phandle(const struct ufdt_node *node);
140
141/*
142 * END of ufdt_node methods
143 */
144
145/*
146 * BEGIN of ufdt methods.
147 */
148
149/*
150 * Constructs a ufdt whose base fdt is fdtp.
151 * Note that this function doesn't construct the entire tree.
SzuWei Lin8a7039c2017-04-14 15:38:15 +0800152 * To get the whole tree please call `ufdt_from_fdt(fdtp, fdt_size)`
Li Chenf6c209b2016-11-28 12:15:33 +0800153 *
154 * @return: an empty ufdt with base fdtp = fdtp
155 */
SzuWei Lind62a8492017-04-24 10:17:15 +0800156struct ufdt *ufdt_construct(void *fdtp, struct ufdt_node_pool *pool);
Li Chenf6c209b2016-11-28 12:15:33 +0800157
158/*
SzuWei Lin1be68ae2017-03-30 11:44:54 +0800159 * Frees the space occupied by the ufdt, including all ufdt_nodes
SzuWei Lin8a7039c2017-04-14 15:38:15 +0800160 * with ufdt_static_phandle_table.
Li Chenf6c209b2016-11-28 12:15:33 +0800161 */
SzuWei Lind62a8492017-04-24 10:17:15 +0800162void ufdt_destruct(struct ufdt *tree, struct ufdt_node_pool *pool);
Li Chenf6c209b2016-11-28 12:15:33 +0800163
164/*
SzuWei Lin1be68ae2017-03-30 11:44:54 +0800165 * Add a fdt into this ufdt.
166 * Note that this function just add the given fdtp into this ufdt,
167 * and doesn't create any node.
168 *
169 * @return: 0 if success.
170 */
171int ufdt_add_fdt(struct ufdt *tree, void *fdtp);
172
173/*
174 * Calculate the offset in the string tables of the given string.
175 * All string tables will be concatenated in reversed order.
176 *
177 * @return: The offset is a negative number, base on the end position of
178 * all concatenated string tables
179 * Return 0 if not in any string table.
180 */
181int ufdt_get_string_off(const struct ufdt *tree, const char *s);
182
183/*
Li Chenf6c209b2016-11-28 12:15:33 +0800184 * Gets the pointer to the ufdt_node in tree with phandle = phandle.
185 * The function do a binary search in tree->phandle_table.
186 *
187 * @return: a pointer to the target ufdt_node
188 * NULL if no ufdt_node has phandle = phandle
189 *
190 * @Time: O(log(# of nodes in tree)) = O(log(size of underlying fdt))
191 */
192struct ufdt_node *ufdt_get_node_by_phandle(struct ufdt *tree, uint32_t phandle);
193
194/*
SzuWei Lin8a7039c2017-04-14 15:38:15 +0800195 * Gets the pointer to the ufdt_node in tree with absolute path =
Li Chenf6c209b2016-11-28 12:15:33 +0800196 * path[0..len-1].
197 * Absolute path has form "/path/to/node" or "some_alias/to/node".
198 * In later example, some_alias is a property in "/aliases" with data is a path
199 * to some node X. Then the funcion will return node with relative
200 * path = "to/node" w.r.t. X.
201 *
202 * @return: a pointer to the target ufdt_node or
203 * NULL if such dnt doesn't exist.
204 *
205 * @Time: O(len = length of path) w.h.p.
206 */
207struct ufdt_node *ufdt_get_node_by_path_len(struct ufdt *tree, const char *path,
208 int len);
209struct ufdt_node *ufdt_get_node_by_path(struct ufdt *tree, const char *path);
210
211/*
Li Chenf6c209b2016-11-28 12:15:33 +0800212 * Determines whether node->name equals to name[0..len-1]
213 *
214 * @return: true if they're equal.
215 * false otherwise
216 */
SzuWei Lin8a7039c2017-04-14 15:38:15 +0800217bool ufdt_node_name_eq(const struct ufdt_node *node, const char *name, int len);
Li Chenf6c209b2016-11-28 12:15:33 +0800218
219/*
SzuWei Line78aa562017-04-17 10:24:45 +0800220 * Merges tree_b into tree_a with tree_b has all nodes except root disappeared.
221 * Overwrite property in tree_a if there's one with same name in tree_b.
222 * Otherwise add the property to tree_a.
223 * For subnodes with the same name, recursively run this function.
224 *
225 * Ex:
226 * tree_a : ta {
227 * b = "b";
228 * c = "c";
229 * d {
230 * e = "g";
231 * };
232 * };
233 *
234 * tree_b : tb {
235 * c = "C";
236 * g = "G";
237 * d {
238 * da = "dad";
239 * };
240 * h {
241 * hh = "HH";
242 * };
243 * };
244 *
245 * The resulting trees will be:
246 *
247 * tree_a : ta {
248 * b = "b";
249 * c = "C";
250 * g = "G";
251 * d {
252 * da = "dad";
253 * e = "g";
254 * };
255 * h {
256 * hh = "HH";
257 * };
258 * };
259 *
260 * tree_b : tb {
261 * };
262 *
263 *
264 * @return: 0 if merge success
265 * < 0 otherwise
266 *
267 * @Time: O(# of nodes in tree_b + total length of all names in tree_b) w.h.p.
268 */
SzuWei Lind62a8492017-04-24 10:17:15 +0800269int ufdt_node_merge_into(struct ufdt_node *node_a, struct ufdt_node *node_b,
270 struct ufdt_node_pool *pool);
SzuWei Line78aa562017-04-17 10:24:45 +0800271
272/*
SzuWei Lin8a7039c2017-04-14 15:38:15 +0800273 * END of ufdt methods.
Li Chenf6c209b2016-11-28 12:15:33 +0800274 */
Li Chenf6c209b2016-11-28 12:15:33 +0800275
276/*
277 * BEGIN of ufdt output functions
278 */
279
280/*
281 * Builds the ufdt for FDT pointed by fdtp.
Li Chenf6c209b2016-11-28 12:15:33 +0800282 *
283 * @return: the ufdt T representing fdtp or
284 * T with T.fdtp == NULL if fdtp is unvalid.
285 *
286 * @Time: O(fdt_size + nlogn) where n = # of nodes in fdt.
287 */
SzuWei Lind62a8492017-04-24 10:17:15 +0800288struct ufdt *ufdt_from_fdt(void *fdtp, size_t fdt_size,
289 struct ufdt_node_pool *pool);
Li Chenf6c209b2016-11-28 12:15:33 +0800290
291/*
Li Chenf6c209b2016-11-28 12:15:33 +0800292 * Sequentially dumps the whole ufdt to FDT buffer fdtp with buffer size
293 * buf_size.
Li Chenf6c209b2016-11-28 12:15:33 +0800294 *
SzuWei Lin1be68ae2017-03-30 11:44:54 +0800295 * Basically using functions provided by libfdt/fdt_sw.c.
Li Chenf6c209b2016-11-28 12:15:33 +0800296 *
297 * @return: 0 if successfully dump or
298 * < 0 otherwise
299 *
300 * @Time: O(total length of all names + # of nodes in tree)
301 */
SzuWei Lin1be68ae2017-03-30 11:44:54 +0800302int ufdt_to_fdt(const struct ufdt *tree, void *buf, int buf_size);
Li Chenf6c209b2016-11-28 12:15:33 +0800303
304/*
305 * prints the entire subtree rooted at *node in form:
306 * NODE :[node name]:
307 * PROP :[prop name]:
308 * ...
309 * NODE :[subnode1 name]:
310 * ...
311 * NODE :[subnode1 name]:
312 * ...
313 * ...
314 * There're (depth * TAB_SIZE) spaces in front of each line.
315 */
316void ufdt_node_print(const struct ufdt_node *node, int depth);
317
318/*
319 * It's just ufdt_node_print(tree->root, 0).
320 */
321void ufdt_print(struct ufdt *tree);
322
323/*
324 * END of ufdt output functions
325 */
326
Li Chenf6c209b2016-11-28 12:15:33 +0800327#endif /* LIBUFDT_H */