• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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  */
16 
17 #ifndef LIBUFDT_H
18 #define LIBUFDT_H
19 
20 #include "libufdt_sysdeps.h"
21 #include "ufdt_types.h"
22 
23 /*
24  * BEGIN of ufdt_node methods
25  */
26 
27 /*
28  * Allocates spaces for new ufdt_node who represents a fdt node at fdt_tag_ptr.
29  * In order to get name pointer, it's necessary to give the pointer to the
30  * 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  */
36 struct ufdt_node *ufdt_node_construct(void *fdtp, fdt32_t *fdt_tag_ptr,
37                                       struct ufdt_node_pool *pool);
38 
39 /*
40  * Frees all nodes in the subtree rooted at *node.
41  */
42 void ufdt_node_destruct(struct ufdt_node *node, struct ufdt_node_pool *pool);
43 
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  */
54 int 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  */
66 struct ufdt_node *ufdt_node_get_property_by_name_len(
67     const struct ufdt_node *node, const char *name, int len);
68 struct 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  */
78 char *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  */
91 char *ufdt_node_get_fdt_prop_data_by_name_len(const struct ufdt_node *node,
92                                               const char *name, int len,
93                                               int *out_len);
94 char *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 
109 struct ufdt_node *ufdt_node_get_subnode_by_name_len(const struct ufdt_node *node,
110                                                     const char *name, int len);
111 struct 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  */
125 struct ufdt_node *ufdt_node_get_node_by_path_len(const struct ufdt_node *node,
126                                                  const char *path, int len);
127 struct 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  */
139 uint32_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.
152  * To get the whole tree please call `ufdt_from_fdt(fdtp, fdt_size)`
153  *
154  * @return: an empty ufdt with base fdtp = fdtp
155  */
156 struct ufdt *ufdt_construct(void *fdtp, struct ufdt_node_pool *pool);
157 
158 /*
159  * Frees the space occupied by the ufdt, including all ufdt_nodes
160  * with ufdt_static_phandle_table.
161  */
162 void ufdt_destruct(struct ufdt *tree, struct ufdt_node_pool *pool);
163 
164 /*
165  * 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  */
171 int 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  */
181 int ufdt_get_string_off(const struct ufdt *tree, const char *s);
182 
183 /*
184  * 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  */
192 struct ufdt_node *ufdt_get_node_by_phandle(struct ufdt *tree, uint32_t phandle);
193 
194 /*
195  * Gets the pointer to the ufdt_node in tree with absolute path =
196  * 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  */
207 struct ufdt_node *ufdt_get_node_by_path_len(struct ufdt *tree, const char *path,
208                                             int len);
209 struct ufdt_node *ufdt_get_node_by_path(struct ufdt *tree, const char *path);
210 
211 /*
212  * Determines whether node->name equals to name[0..len-1]
213  *
214  * @return: true if they're equal.
215  *          false otherwise
216  */
217 bool ufdt_node_name_eq(const struct ufdt_node *node, const char *name, int len);
218 
219 /*
220  * 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  */
269 int ufdt_node_merge_into(struct ufdt_node *node_a, struct ufdt_node *node_b,
270                          struct ufdt_node_pool *pool);
271 
272 /*
273  * END of ufdt methods.
274  */
275 
276 /*
277  * BEGIN of ufdt output functions
278  */
279 
280 /*
281  * Builds the ufdt for FDT pointed by fdtp.
282  *
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  */
288 struct ufdt *ufdt_from_fdt(void *fdtp, size_t fdt_size,
289                            struct ufdt_node_pool *pool);
290 
291 /*
292  * Sequentially dumps the whole ufdt to FDT buffer fdtp with buffer size
293  * buf_size.
294  *
295  * Basically using functions provided by libfdt/fdt_sw.c.
296  *
297  * @return: 0 if successfully dump or
298  *          < 0 otherwise
299  *
300  * @Time: O(total length of all names + # of nodes in tree)
301  */
302 int ufdt_to_fdt(const struct ufdt *tree, void *buf, int buf_size);
303 
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  */
316 void ufdt_node_print(const struct ufdt_node *node, int depth);
317 
318 /*
319  * It's just ufdt_node_print(tree->root, 0).
320  */
321 void ufdt_print(struct ufdt *tree);
322 
323 /*
324  * END of ufdt output functions
325  */
326 
327 #endif /* LIBUFDT_H */
328