1d18719a4STom Rini /*
2d18719a4STom Rini * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
3d18719a4STom Rini *
4d18719a4STom Rini *
5d18719a4STom Rini * This program is free software; you can redistribute it and/or
6d18719a4STom Rini * modify it under the terms of the GNU General Public License as
7d18719a4STom Rini * published by the Free Software Foundation; either version 2 of the
8d18719a4STom Rini * License, or (at your option) any later version.
9d18719a4STom Rini *
10d18719a4STom Rini * This program is distributed in the hope that it will be useful,
11d18719a4STom Rini * but WITHOUT ANY WARRANTY; without even the implied warranty of
12d18719a4STom Rini * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13d18719a4STom Rini * General Public License for more details.
14d18719a4STom Rini *
15d18719a4STom Rini * You should have received a copy of the GNU General Public License
16d18719a4STom Rini * along with this program; if not, write to the Free Software
17d18719a4STom Rini * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18d18719a4STom Rini * USA
19d18719a4STom Rini */
20d18719a4STom Rini
21d18719a4STom Rini #include "dtc.h"
22d18719a4STom Rini
23d18719a4STom Rini /*
24d18719a4STom Rini * Tree building functions
25d18719a4STom Rini */
26d18719a4STom Rini
add_label(struct label ** labels,char * label)27d18719a4STom Rini void add_label(struct label **labels, char *label)
28d18719a4STom Rini {
29d18719a4STom Rini struct label *new;
30d18719a4STom Rini
31d18719a4STom Rini /* Make sure the label isn't already there */
32d18719a4STom Rini for_each_label_withdel(*labels, new)
33d18719a4STom Rini if (streq(new->label, label)) {
34d18719a4STom Rini new->deleted = 0;
35d18719a4STom Rini return;
36d18719a4STom Rini }
37d18719a4STom Rini
38d18719a4STom Rini new = xmalloc(sizeof(*new));
39d18719a4STom Rini memset(new, 0, sizeof(*new));
40d18719a4STom Rini new->label = label;
41d18719a4STom Rini new->next = *labels;
42d18719a4STom Rini *labels = new;
43d18719a4STom Rini }
44d18719a4STom Rini
delete_labels(struct label ** labels)45d18719a4STom Rini void delete_labels(struct label **labels)
46d18719a4STom Rini {
47d18719a4STom Rini struct label *label;
48d18719a4STom Rini
49d18719a4STom Rini for_each_label(*labels, label)
50d18719a4STom Rini label->deleted = 1;
51d18719a4STom Rini }
52d18719a4STom Rini
build_property(char * name,struct data val)53d18719a4STom Rini struct property *build_property(char *name, struct data val)
54d18719a4STom Rini {
55d18719a4STom Rini struct property *new = xmalloc(sizeof(*new));
56d18719a4STom Rini
57d18719a4STom Rini memset(new, 0, sizeof(*new));
58d18719a4STom Rini
59d18719a4STom Rini new->name = name;
60d18719a4STom Rini new->val = val;
61d18719a4STom Rini
62d18719a4STom Rini return new;
63d18719a4STom Rini }
64d18719a4STom Rini
build_property_delete(char * name)65d18719a4STom Rini struct property *build_property_delete(char *name)
66d18719a4STom Rini {
67d18719a4STom Rini struct property *new = xmalloc(sizeof(*new));
68d18719a4STom Rini
69d18719a4STom Rini memset(new, 0, sizeof(*new));
70d18719a4STom Rini
71d18719a4STom Rini new->name = name;
72d18719a4STom Rini new->deleted = 1;
73d18719a4STom Rini
74d18719a4STom Rini return new;
75d18719a4STom Rini }
76d18719a4STom Rini
chain_property(struct property * first,struct property * list)77d18719a4STom Rini struct property *chain_property(struct property *first, struct property *list)
78d18719a4STom Rini {
79d18719a4STom Rini assert(first->next == NULL);
80d18719a4STom Rini
81d18719a4STom Rini first->next = list;
82d18719a4STom Rini return first;
83d18719a4STom Rini }
84d18719a4STom Rini
reverse_properties(struct property * first)85d18719a4STom Rini struct property *reverse_properties(struct property *first)
86d18719a4STom Rini {
87d18719a4STom Rini struct property *p = first;
88d18719a4STom Rini struct property *head = NULL;
89d18719a4STom Rini struct property *next;
90d18719a4STom Rini
91d18719a4STom Rini while (p) {
92d18719a4STom Rini next = p->next;
93d18719a4STom Rini p->next = head;
94d18719a4STom Rini head = p;
95d18719a4STom Rini p = next;
96d18719a4STom Rini }
97d18719a4STom Rini return head;
98d18719a4STom Rini }
99d18719a4STom Rini
build_node(struct property * proplist,struct node * children)100d18719a4STom Rini struct node *build_node(struct property *proplist, struct node *children)
101d18719a4STom Rini {
102d18719a4STom Rini struct node *new = xmalloc(sizeof(*new));
103d18719a4STom Rini struct node *child;
104d18719a4STom Rini
105d18719a4STom Rini memset(new, 0, sizeof(*new));
106d18719a4STom Rini
107d18719a4STom Rini new->proplist = reverse_properties(proplist);
108d18719a4STom Rini new->children = children;
109d18719a4STom Rini
110d18719a4STom Rini for_each_child(new, child) {
111d18719a4STom Rini child->parent = new;
112d18719a4STom Rini }
113d18719a4STom Rini
114d18719a4STom Rini return new;
115d18719a4STom Rini }
116d18719a4STom Rini
build_node_delete(void)117d18719a4STom Rini struct node *build_node_delete(void)
118d18719a4STom Rini {
119d18719a4STom Rini struct node *new = xmalloc(sizeof(*new));
120d18719a4STom Rini
121d18719a4STom Rini memset(new, 0, sizeof(*new));
122d18719a4STom Rini
123d18719a4STom Rini new->deleted = 1;
124d18719a4STom Rini
125d18719a4STom Rini return new;
126d18719a4STom Rini }
127d18719a4STom Rini
name_node(struct node * node,char * name)128d18719a4STom Rini struct node *name_node(struct node *node, char *name)
129d18719a4STom Rini {
130d18719a4STom Rini assert(node->name == NULL);
131d18719a4STom Rini
132d18719a4STom Rini node->name = name;
133d18719a4STom Rini
134d18719a4STom Rini return node;
135d18719a4STom Rini }
136d18719a4STom Rini
merge_nodes(struct node * old_node,struct node * new_node)137d18719a4STom Rini struct node *merge_nodes(struct node *old_node, struct node *new_node)
138d18719a4STom Rini {
139d18719a4STom Rini struct property *new_prop, *old_prop;
140d18719a4STom Rini struct node *new_child, *old_child;
141d18719a4STom Rini struct label *l;
142d18719a4STom Rini
143d18719a4STom Rini old_node->deleted = 0;
144d18719a4STom Rini
145d18719a4STom Rini /* Add new node labels to old node */
146d18719a4STom Rini for_each_label_withdel(new_node->labels, l)
147d18719a4STom Rini add_label(&old_node->labels, l->label);
148d18719a4STom Rini
149d18719a4STom Rini /* Move properties from the new node to the old node. If there
150d18719a4STom Rini * is a collision, replace the old value with the new */
151d18719a4STom Rini while (new_node->proplist) {
152d18719a4STom Rini /* Pop the property off the list */
153d18719a4STom Rini new_prop = new_node->proplist;
154d18719a4STom Rini new_node->proplist = new_prop->next;
155d18719a4STom Rini new_prop->next = NULL;
156d18719a4STom Rini
157d18719a4STom Rini if (new_prop->deleted) {
158d18719a4STom Rini delete_property_by_name(old_node, new_prop->name);
159d18719a4STom Rini free(new_prop);
160d18719a4STom Rini continue;
161d18719a4STom Rini }
162d18719a4STom Rini
163d18719a4STom Rini /* Look for a collision, set new value if there is */
164d18719a4STom Rini for_each_property_withdel(old_node, old_prop) {
165d18719a4STom Rini if (streq(old_prop->name, new_prop->name)) {
166d18719a4STom Rini /* Add new labels to old property */
167d18719a4STom Rini for_each_label_withdel(new_prop->labels, l)
168d18719a4STom Rini add_label(&old_prop->labels, l->label);
169d18719a4STom Rini
170d18719a4STom Rini old_prop->val = new_prop->val;
171d18719a4STom Rini old_prop->deleted = 0;
172d18719a4STom Rini free(new_prop);
173d18719a4STom Rini new_prop = NULL;
174d18719a4STom Rini break;
175d18719a4STom Rini }
176d18719a4STom Rini }
177d18719a4STom Rini
178d18719a4STom Rini /* if no collision occurred, add property to the old node. */
179d18719a4STom Rini if (new_prop)
180d18719a4STom Rini add_property(old_node, new_prop);
181d18719a4STom Rini }
182d18719a4STom Rini
183d18719a4STom Rini /* Move the override child nodes into the primary node. If
184d18719a4STom Rini * there is a collision, then merge the nodes. */
185d18719a4STom Rini while (new_node->children) {
186d18719a4STom Rini /* Pop the child node off the list */
187d18719a4STom Rini new_child = new_node->children;
188d18719a4STom Rini new_node->children = new_child->next_sibling;
189d18719a4STom Rini new_child->parent = NULL;
190d18719a4STom Rini new_child->next_sibling = NULL;
191d18719a4STom Rini
192d18719a4STom Rini if (new_child->deleted) {
193d18719a4STom Rini delete_node_by_name(old_node, new_child->name);
194d18719a4STom Rini free(new_child);
195d18719a4STom Rini continue;
196d18719a4STom Rini }
197d18719a4STom Rini
198d18719a4STom Rini /* Search for a collision. Merge if there is */
199d18719a4STom Rini for_each_child_withdel(old_node, old_child) {
200d18719a4STom Rini if (streq(old_child->name, new_child->name)) {
201d18719a4STom Rini merge_nodes(old_child, new_child);
202d18719a4STom Rini new_child = NULL;
203d18719a4STom Rini break;
204d18719a4STom Rini }
205d18719a4STom Rini }
206d18719a4STom Rini
207d18719a4STom Rini /* if no collision occurred, add child to the old node. */
208d18719a4STom Rini if (new_child)
209d18719a4STom Rini add_child(old_node, new_child);
210d18719a4STom Rini }
211d18719a4STom Rini
212d18719a4STom Rini /* The new node contents are now merged into the old node. Free
213d18719a4STom Rini * the new node. */
214d18719a4STom Rini free(new_node);
215d18719a4STom Rini
216d18719a4STom Rini return old_node;
217d18719a4STom Rini }
218d18719a4STom Rini
add_orphan_node(struct node * dt,struct node * new_node,char * ref)21914df9b24SMasahiro Yamada void add_orphan_node(struct node *dt, struct node *new_node, char *ref)
22014df9b24SMasahiro Yamada {
22114df9b24SMasahiro Yamada static unsigned int next_orphan_fragment = 0;
22214df9b24SMasahiro Yamada struct node *node;
22314df9b24SMasahiro Yamada struct property *p;
22414df9b24SMasahiro Yamada struct data d = empty_data;
22514df9b24SMasahiro Yamada char *name;
22614df9b24SMasahiro Yamada
22714df9b24SMasahiro Yamada d = data_add_marker(d, REF_PHANDLE, ref);
22814df9b24SMasahiro Yamada d = data_append_integer(d, 0xffffffff, 32);
22914df9b24SMasahiro Yamada
23014df9b24SMasahiro Yamada p = build_property("target", d);
23114df9b24SMasahiro Yamada
23214df9b24SMasahiro Yamada xasprintf(&name, "fragment@%u",
23314df9b24SMasahiro Yamada next_orphan_fragment++);
23414df9b24SMasahiro Yamada name_node(new_node, "__overlay__");
23514df9b24SMasahiro Yamada node = build_node(p, new_node);
23614df9b24SMasahiro Yamada name_node(node, name);
23714df9b24SMasahiro Yamada
23814df9b24SMasahiro Yamada add_child(dt, node);
23914df9b24SMasahiro Yamada }
24014df9b24SMasahiro Yamada
chain_node(struct node * first,struct node * list)241d18719a4STom Rini struct node *chain_node(struct node *first, struct node *list)
242d18719a4STom Rini {
243d18719a4STom Rini assert(first->next_sibling == NULL);
244d18719a4STom Rini
245d18719a4STom Rini first->next_sibling = list;
246d18719a4STom Rini return first;
247d18719a4STom Rini }
248d18719a4STom Rini
add_property(struct node * node,struct property * prop)249d18719a4STom Rini void add_property(struct node *node, struct property *prop)
250d18719a4STom Rini {
251d18719a4STom Rini struct property **p;
252d18719a4STom Rini
253d18719a4STom Rini prop->next = NULL;
254d18719a4STom Rini
255d18719a4STom Rini p = &node->proplist;
256d18719a4STom Rini while (*p)
257d18719a4STom Rini p = &((*p)->next);
258d18719a4STom Rini
259d18719a4STom Rini *p = prop;
260d18719a4STom Rini }
261d18719a4STom Rini
delete_property_by_name(struct node * node,char * name)262d18719a4STom Rini void delete_property_by_name(struct node *node, char *name)
263d18719a4STom Rini {
264d18719a4STom Rini struct property *prop = node->proplist;
265d18719a4STom Rini
266d18719a4STom Rini while (prop) {
267d18719a4STom Rini if (streq(prop->name, name)) {
268d18719a4STom Rini delete_property(prop);
269d18719a4STom Rini return;
270d18719a4STom Rini }
271d18719a4STom Rini prop = prop->next;
272d18719a4STom Rini }
273d18719a4STom Rini }
274d18719a4STom Rini
delete_property(struct property * prop)275d18719a4STom Rini void delete_property(struct property *prop)
276d18719a4STom Rini {
277d18719a4STom Rini prop->deleted = 1;
278d18719a4STom Rini delete_labels(&prop->labels);
279d18719a4STom Rini }
280d18719a4STom Rini
add_child(struct node * parent,struct node * child)281d18719a4STom Rini void add_child(struct node *parent, struct node *child)
282d18719a4STom Rini {
283d18719a4STom Rini struct node **p;
284d18719a4STom Rini
285d18719a4STom Rini child->next_sibling = NULL;
286d18719a4STom Rini child->parent = parent;
287d18719a4STom Rini
288d18719a4STom Rini p = &parent->children;
289d18719a4STom Rini while (*p)
290d18719a4STom Rini p = &((*p)->next_sibling);
291d18719a4STom Rini
292d18719a4STom Rini *p = child;
293d18719a4STom Rini }
294d18719a4STom Rini
delete_node_by_name(struct node * parent,char * name)295d18719a4STom Rini void delete_node_by_name(struct node *parent, char *name)
296d18719a4STom Rini {
297d18719a4STom Rini struct node *node = parent->children;
298d18719a4STom Rini
299d18719a4STom Rini while (node) {
300d18719a4STom Rini if (streq(node->name, name)) {
301d18719a4STom Rini delete_node(node);
302d18719a4STom Rini return;
303d18719a4STom Rini }
304d18719a4STom Rini node = node->next_sibling;
305d18719a4STom Rini }
306d18719a4STom Rini }
307d18719a4STom Rini
delete_node(struct node * node)308d18719a4STom Rini void delete_node(struct node *node)
309d18719a4STom Rini {
310d18719a4STom Rini struct property *prop;
311d18719a4STom Rini struct node *child;
312d18719a4STom Rini
313d18719a4STom Rini node->deleted = 1;
314d18719a4STom Rini for_each_child(node, child)
315d18719a4STom Rini delete_node(child);
316d18719a4STom Rini for_each_property(node, prop)
317d18719a4STom Rini delete_property(prop);
318d18719a4STom Rini delete_labels(&node->labels);
319d18719a4STom Rini }
320d18719a4STom Rini
append_to_property(struct node * node,char * name,const void * data,int len)321d18719a4STom Rini void append_to_property(struct node *node,
322d18719a4STom Rini char *name, const void *data, int len)
323d18719a4STom Rini {
324d18719a4STom Rini struct data d;
325d18719a4STom Rini struct property *p;
326d18719a4STom Rini
327d18719a4STom Rini p = get_property(node, name);
328d18719a4STom Rini if (p) {
329d18719a4STom Rini d = data_append_data(p->val, data, len);
330d18719a4STom Rini p->val = d;
331d18719a4STom Rini } else {
332d18719a4STom Rini d = data_append_data(empty_data, data, len);
333d18719a4STom Rini p = build_property(name, d);
334d18719a4STom Rini add_property(node, p);
335d18719a4STom Rini }
336d18719a4STom Rini }
337d18719a4STom Rini
build_reserve_entry(uint64_t address,uint64_t size)338d18719a4STom Rini struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size)
339d18719a4STom Rini {
340d18719a4STom Rini struct reserve_info *new = xmalloc(sizeof(*new));
341d18719a4STom Rini
342d18719a4STom Rini memset(new, 0, sizeof(*new));
343d18719a4STom Rini
344e23ffda2STom Rini new->address = address;
345e23ffda2STom Rini new->size = size;
346d18719a4STom Rini
347d18719a4STom Rini return new;
348d18719a4STom Rini }
349d18719a4STom Rini
chain_reserve_entry(struct reserve_info * first,struct reserve_info * list)350d18719a4STom Rini struct reserve_info *chain_reserve_entry(struct reserve_info *first,
351d18719a4STom Rini struct reserve_info *list)
352d18719a4STom Rini {
353d18719a4STom Rini assert(first->next == NULL);
354d18719a4STom Rini
355d18719a4STom Rini first->next = list;
356d18719a4STom Rini return first;
357d18719a4STom Rini }
358d18719a4STom Rini
add_reserve_entry(struct reserve_info * list,struct reserve_info * new)359d18719a4STom Rini struct reserve_info *add_reserve_entry(struct reserve_info *list,
360d18719a4STom Rini struct reserve_info *new)
361d18719a4STom Rini {
362d18719a4STom Rini struct reserve_info *last;
363d18719a4STom Rini
364d18719a4STom Rini new->next = NULL;
365d18719a4STom Rini
366d18719a4STom Rini if (! list)
367d18719a4STom Rini return new;
368d18719a4STom Rini
369d18719a4STom Rini for (last = list; last->next; last = last->next)
370d18719a4STom Rini ;
371d18719a4STom Rini
372d18719a4STom Rini last->next = new;
373d18719a4STom Rini
374d18719a4STom Rini return list;
375d18719a4STom Rini }
376d18719a4STom Rini
build_dt_info(unsigned int dtsflags,struct reserve_info * reservelist,struct node * tree,uint32_t boot_cpuid_phys)377d18719a4STom Rini struct dt_info *build_dt_info(unsigned int dtsflags,
378d18719a4STom Rini struct reserve_info *reservelist,
379d18719a4STom Rini struct node *tree, uint32_t boot_cpuid_phys)
380d18719a4STom Rini {
381d18719a4STom Rini struct dt_info *dti;
382d18719a4STom Rini
383d18719a4STom Rini dti = xmalloc(sizeof(*dti));
384d18719a4STom Rini dti->dtsflags = dtsflags;
385d18719a4STom Rini dti->reservelist = reservelist;
386d18719a4STom Rini dti->dt = tree;
387d18719a4STom Rini dti->boot_cpuid_phys = boot_cpuid_phys;
388d18719a4STom Rini
389d18719a4STom Rini return dti;
390d18719a4STom Rini }
391d18719a4STom Rini
392d18719a4STom Rini /*
393d18719a4STom Rini * Tree accessor functions
394d18719a4STom Rini */
395d18719a4STom Rini
get_unitname(struct node * node)396d18719a4STom Rini const char *get_unitname(struct node *node)
397d18719a4STom Rini {
398d18719a4STom Rini if (node->name[node->basenamelen] == '\0')
399d18719a4STom Rini return "";
400d18719a4STom Rini else
401d18719a4STom Rini return node->name + node->basenamelen + 1;
402d18719a4STom Rini }
403d18719a4STom Rini
get_property(struct node * node,const char * propname)404d18719a4STom Rini struct property *get_property(struct node *node, const char *propname)
405d18719a4STom Rini {
406d18719a4STom Rini struct property *prop;
407d18719a4STom Rini
408d18719a4STom Rini for_each_property(node, prop)
409d18719a4STom Rini if (streq(prop->name, propname))
410d18719a4STom Rini return prop;
411d18719a4STom Rini
412d18719a4STom Rini return NULL;
413d18719a4STom Rini }
414d18719a4STom Rini
propval_cell(struct property * prop)415d18719a4STom Rini cell_t propval_cell(struct property *prop)
416d18719a4STom Rini {
417d18719a4STom Rini assert(prop->val.len == sizeof(cell_t));
418e23ffda2STom Rini return fdt32_to_cpu(*((fdt32_t *)prop->val.val));
419d18719a4STom Rini }
420d18719a4STom Rini
propval_cell_n(struct property * prop,int n)42114df9b24SMasahiro Yamada cell_t propval_cell_n(struct property *prop, int n)
42214df9b24SMasahiro Yamada {
42314df9b24SMasahiro Yamada assert(prop->val.len / sizeof(cell_t) >= n);
42414df9b24SMasahiro Yamada return fdt32_to_cpu(*((fdt32_t *)prop->val.val + n));
42514df9b24SMasahiro Yamada }
42614df9b24SMasahiro Yamada
get_property_by_label(struct node * tree,const char * label,struct node ** node)427d18719a4STom Rini struct property *get_property_by_label(struct node *tree, const char *label,
428d18719a4STom Rini struct node **node)
429d18719a4STom Rini {
430d18719a4STom Rini struct property *prop;
431d18719a4STom Rini struct node *c;
432d18719a4STom Rini
433d18719a4STom Rini *node = tree;
434d18719a4STom Rini
435d18719a4STom Rini for_each_property(tree, prop) {
436d18719a4STom Rini struct label *l;
437d18719a4STom Rini
438d18719a4STom Rini for_each_label(prop->labels, l)
439d18719a4STom Rini if (streq(l->label, label))
440d18719a4STom Rini return prop;
441d18719a4STom Rini }
442d18719a4STom Rini
443d18719a4STom Rini for_each_child(tree, c) {
444d18719a4STom Rini prop = get_property_by_label(c, label, node);
445d18719a4STom Rini if (prop)
446d18719a4STom Rini return prop;
447d18719a4STom Rini }
448d18719a4STom Rini
449d18719a4STom Rini *node = NULL;
450d18719a4STom Rini return NULL;
451d18719a4STom Rini }
452d18719a4STom Rini
get_marker_label(struct node * tree,const char * label,struct node ** node,struct property ** prop)453d18719a4STom Rini struct marker *get_marker_label(struct node *tree, const char *label,
454d18719a4STom Rini struct node **node, struct property **prop)
455d18719a4STom Rini {
456d18719a4STom Rini struct marker *m;
457d18719a4STom Rini struct property *p;
458d18719a4STom Rini struct node *c;
459d18719a4STom Rini
460d18719a4STom Rini *node = tree;
461d18719a4STom Rini
462d18719a4STom Rini for_each_property(tree, p) {
463d18719a4STom Rini *prop = p;
464d18719a4STom Rini m = p->val.markers;
465d18719a4STom Rini for_each_marker_of_type(m, LABEL)
466d18719a4STom Rini if (streq(m->ref, label))
467d18719a4STom Rini return m;
468d18719a4STom Rini }
469d18719a4STom Rini
470d18719a4STom Rini for_each_child(tree, c) {
471d18719a4STom Rini m = get_marker_label(c, label, node, prop);
472d18719a4STom Rini if (m)
473d18719a4STom Rini return m;
474d18719a4STom Rini }
475d18719a4STom Rini
476d18719a4STom Rini *prop = NULL;
477d18719a4STom Rini *node = NULL;
478d18719a4STom Rini return NULL;
479d18719a4STom Rini }
480d18719a4STom Rini
get_subnode(struct node * node,const char * nodename)481d18719a4STom Rini struct node *get_subnode(struct node *node, const char *nodename)
482d18719a4STom Rini {
483d18719a4STom Rini struct node *child;
484d18719a4STom Rini
485d18719a4STom Rini for_each_child(node, child)
486d18719a4STom Rini if (streq(child->name, nodename))
487d18719a4STom Rini return child;
488d18719a4STom Rini
489d18719a4STom Rini return NULL;
490d18719a4STom Rini }
491d18719a4STom Rini
get_node_by_path(struct node * tree,const char * path)492d18719a4STom Rini struct node *get_node_by_path(struct node *tree, const char *path)
493d18719a4STom Rini {
494d18719a4STom Rini const char *p;
495d18719a4STom Rini struct node *child;
496d18719a4STom Rini
497d18719a4STom Rini if (!path || ! (*path)) {
498d18719a4STom Rini if (tree->deleted)
499d18719a4STom Rini return NULL;
500d18719a4STom Rini return tree;
501d18719a4STom Rini }
502d18719a4STom Rini
503d18719a4STom Rini while (path[0] == '/')
504d18719a4STom Rini path++;
505d18719a4STom Rini
506d18719a4STom Rini p = strchr(path, '/');
507d18719a4STom Rini
508d18719a4STom Rini for_each_child(tree, child) {
509d7857e40STom Rini if (p && (strlen(child->name) == p-path) &&
510d7857e40STom Rini strneq(path, child->name, p-path))
511d18719a4STom Rini return get_node_by_path(child, p+1);
512d18719a4STom Rini else if (!p && streq(path, child->name))
513d18719a4STom Rini return child;
514d18719a4STom Rini }
515d18719a4STom Rini
516d18719a4STom Rini return NULL;
517d18719a4STom Rini }
518d18719a4STom Rini
get_node_by_label(struct node * tree,const char * label)519d18719a4STom Rini struct node *get_node_by_label(struct node *tree, const char *label)
520d18719a4STom Rini {
521d18719a4STom Rini struct node *child, *node;
522d18719a4STom Rini struct label *l;
523d18719a4STom Rini
524d18719a4STom Rini assert(label && (strlen(label) > 0));
525d18719a4STom Rini
526d18719a4STom Rini for_each_label(tree->labels, l)
527d18719a4STom Rini if (streq(l->label, label))
528d18719a4STom Rini return tree;
529d18719a4STom Rini
530d18719a4STom Rini for_each_child(tree, child) {
531d18719a4STom Rini node = get_node_by_label(child, label);
532d18719a4STom Rini if (node)
533d18719a4STom Rini return node;
534d18719a4STom Rini }
535d18719a4STom Rini
536d18719a4STom Rini return NULL;
537d18719a4STom Rini }
538d18719a4STom Rini
get_node_by_phandle(struct node * tree,cell_t phandle)539d18719a4STom Rini struct node *get_node_by_phandle(struct node *tree, cell_t phandle)
540d18719a4STom Rini {
541d18719a4STom Rini struct node *child, *node;
542d18719a4STom Rini
543d18719a4STom Rini assert((phandle != 0) && (phandle != -1));
544d18719a4STom Rini
545d18719a4STom Rini if (tree->phandle == phandle) {
546d18719a4STom Rini if (tree->deleted)
547d18719a4STom Rini return NULL;
548d18719a4STom Rini return tree;
549d18719a4STom Rini }
550d18719a4STom Rini
551d18719a4STom Rini for_each_child(tree, child) {
552d18719a4STom Rini node = get_node_by_phandle(child, phandle);
553d18719a4STom Rini if (node)
554d18719a4STom Rini return node;
555d18719a4STom Rini }
556d18719a4STom Rini
557d18719a4STom Rini return NULL;
558d18719a4STom Rini }
559d18719a4STom Rini
get_node_by_ref(struct node * tree,const char * ref)560d18719a4STom Rini struct node *get_node_by_ref(struct node *tree, const char *ref)
561d18719a4STom Rini {
562d18719a4STom Rini if (streq(ref, "/"))
563d18719a4STom Rini return tree;
564d18719a4STom Rini else if (ref[0] == '/')
565d18719a4STom Rini return get_node_by_path(tree, ref);
566d18719a4STom Rini else
567d18719a4STom Rini return get_node_by_label(tree, ref);
568d18719a4STom Rini }
569d18719a4STom Rini
get_node_phandle(struct node * root,struct node * node)570d18719a4STom Rini cell_t get_node_phandle(struct node *root, struct node *node)
571d18719a4STom Rini {
572*bd3ad955SJianqun Xu static cell_t phandle = 0x10000000; /* FIXME: ick, static local */
573d18719a4STom Rini
574d18719a4STom Rini if ((node->phandle != 0) && (node->phandle != -1))
575d18719a4STom Rini return node->phandle;
576d18719a4STom Rini
577d18719a4STom Rini while (get_node_by_phandle(root, phandle))
578d18719a4STom Rini phandle++;
579d18719a4STom Rini
580d18719a4STom Rini node->phandle = phandle;
581d18719a4STom Rini
582d18719a4STom Rini if (!get_property(node, "linux,phandle")
583d18719a4STom Rini && (phandle_format & PHANDLE_LEGACY))
584d18719a4STom Rini add_property(node,
585d18719a4STom Rini build_property("linux,phandle",
586d18719a4STom Rini data_append_cell(empty_data, phandle)));
587d18719a4STom Rini
588d18719a4STom Rini if (!get_property(node, "phandle")
589d18719a4STom Rini && (phandle_format & PHANDLE_EPAPR))
590d18719a4STom Rini add_property(node,
591d18719a4STom Rini build_property("phandle",
592d18719a4STom Rini data_append_cell(empty_data, phandle)));
593d18719a4STom Rini
594d18719a4STom Rini /* If the node *does* have a phandle property, we must
595d18719a4STom Rini * be dealing with a self-referencing phandle, which will be
596d18719a4STom Rini * fixed up momentarily in the caller */
597d18719a4STom Rini
598d18719a4STom Rini return node->phandle;
599d18719a4STom Rini }
600d18719a4STom Rini
guess_boot_cpuid(struct node * tree)601d18719a4STom Rini uint32_t guess_boot_cpuid(struct node *tree)
602d18719a4STom Rini {
603d18719a4STom Rini struct node *cpus, *bootcpu;
604d18719a4STom Rini struct property *reg;
605d18719a4STom Rini
606d18719a4STom Rini cpus = get_node_by_path(tree, "/cpus");
607d18719a4STom Rini if (!cpus)
608d18719a4STom Rini return 0;
609d18719a4STom Rini
610d18719a4STom Rini
611d18719a4STom Rini bootcpu = cpus->children;
612d18719a4STom Rini if (!bootcpu)
613d18719a4STom Rini return 0;
614d18719a4STom Rini
615d18719a4STom Rini reg = get_property(bootcpu, "reg");
616d18719a4STom Rini if (!reg || (reg->val.len != sizeof(uint32_t)))
617d18719a4STom Rini return 0;
618d18719a4STom Rini
619d18719a4STom Rini /* FIXME: Sanity check node? */
620d18719a4STom Rini
621d18719a4STom Rini return propval_cell(reg);
622d18719a4STom Rini }
623d18719a4STom Rini
cmp_reserve_info(const void * ax,const void * bx)624d18719a4STom Rini static int cmp_reserve_info(const void *ax, const void *bx)
625d18719a4STom Rini {
626d18719a4STom Rini const struct reserve_info *a, *b;
627d18719a4STom Rini
628d18719a4STom Rini a = *((const struct reserve_info * const *)ax);
629d18719a4STom Rini b = *((const struct reserve_info * const *)bx);
630d18719a4STom Rini
631e23ffda2STom Rini if (a->address < b->address)
632d18719a4STom Rini return -1;
633e23ffda2STom Rini else if (a->address > b->address)
634d18719a4STom Rini return 1;
635e23ffda2STom Rini else if (a->size < b->size)
636d18719a4STom Rini return -1;
637e23ffda2STom Rini else if (a->size > b->size)
638d18719a4STom Rini return 1;
639d18719a4STom Rini else
640d18719a4STom Rini return 0;
641d18719a4STom Rini }
642d18719a4STom Rini
sort_reserve_entries(struct dt_info * dti)643d18719a4STom Rini static void sort_reserve_entries(struct dt_info *dti)
644d18719a4STom Rini {
645d18719a4STom Rini struct reserve_info *ri, **tbl;
646d18719a4STom Rini int n = 0, i = 0;
647d18719a4STom Rini
648d18719a4STom Rini for (ri = dti->reservelist;
649d18719a4STom Rini ri;
650d18719a4STom Rini ri = ri->next)
651d18719a4STom Rini n++;
652d18719a4STom Rini
653d18719a4STom Rini if (n == 0)
654d18719a4STom Rini return;
655d18719a4STom Rini
656d18719a4STom Rini tbl = xmalloc(n * sizeof(*tbl));
657d18719a4STom Rini
658d18719a4STom Rini for (ri = dti->reservelist;
659d18719a4STom Rini ri;
660d18719a4STom Rini ri = ri->next)
661d18719a4STom Rini tbl[i++] = ri;
662d18719a4STom Rini
663d18719a4STom Rini qsort(tbl, n, sizeof(*tbl), cmp_reserve_info);
664d18719a4STom Rini
665d18719a4STom Rini dti->reservelist = tbl[0];
666d18719a4STom Rini for (i = 0; i < (n-1); i++)
667d18719a4STom Rini tbl[i]->next = tbl[i+1];
668d18719a4STom Rini tbl[n-1]->next = NULL;
669d18719a4STom Rini
670d18719a4STom Rini free(tbl);
671d18719a4STom Rini }
672d18719a4STom Rini
cmp_prop(const void * ax,const void * bx)673d18719a4STom Rini static int cmp_prop(const void *ax, const void *bx)
674d18719a4STom Rini {
675d18719a4STom Rini const struct property *a, *b;
676d18719a4STom Rini
677d18719a4STom Rini a = *((const struct property * const *)ax);
678d18719a4STom Rini b = *((const struct property * const *)bx);
679d18719a4STom Rini
680d18719a4STom Rini return strcmp(a->name, b->name);
681d18719a4STom Rini }
682d18719a4STom Rini
sort_properties(struct node * node)683d18719a4STom Rini static void sort_properties(struct node *node)
684d18719a4STom Rini {
685d18719a4STom Rini int n = 0, i = 0;
686d18719a4STom Rini struct property *prop, **tbl;
687d18719a4STom Rini
688d18719a4STom Rini for_each_property_withdel(node, prop)
689d18719a4STom Rini n++;
690d18719a4STom Rini
691d18719a4STom Rini if (n == 0)
692d18719a4STom Rini return;
693d18719a4STom Rini
694d18719a4STom Rini tbl = xmalloc(n * sizeof(*tbl));
695d18719a4STom Rini
696d18719a4STom Rini for_each_property_withdel(node, prop)
697d18719a4STom Rini tbl[i++] = prop;
698d18719a4STom Rini
699d18719a4STom Rini qsort(tbl, n, sizeof(*tbl), cmp_prop);
700d18719a4STom Rini
701d18719a4STom Rini node->proplist = tbl[0];
702d18719a4STom Rini for (i = 0; i < (n-1); i++)
703d18719a4STom Rini tbl[i]->next = tbl[i+1];
704d18719a4STom Rini tbl[n-1]->next = NULL;
705d18719a4STom Rini
706d18719a4STom Rini free(tbl);
707d18719a4STom Rini }
708d18719a4STom Rini
cmp_subnode(const void * ax,const void * bx)709d18719a4STom Rini static int cmp_subnode(const void *ax, const void *bx)
710d18719a4STom Rini {
711d18719a4STom Rini const struct node *a, *b;
712d18719a4STom Rini
713d18719a4STom Rini a = *((const struct node * const *)ax);
714d18719a4STom Rini b = *((const struct node * const *)bx);
715d18719a4STom Rini
716d18719a4STom Rini return strcmp(a->name, b->name);
717d18719a4STom Rini }
718d18719a4STom Rini
sort_subnodes(struct node * node)719d18719a4STom Rini static void sort_subnodes(struct node *node)
720d18719a4STom Rini {
721d18719a4STom Rini int n = 0, i = 0;
722d18719a4STom Rini struct node *subnode, **tbl;
723d18719a4STom Rini
724d18719a4STom Rini for_each_child_withdel(node, subnode)
725d18719a4STom Rini n++;
726d18719a4STom Rini
727d18719a4STom Rini if (n == 0)
728d18719a4STom Rini return;
729d18719a4STom Rini
730d18719a4STom Rini tbl = xmalloc(n * sizeof(*tbl));
731d18719a4STom Rini
732d18719a4STom Rini for_each_child_withdel(node, subnode)
733d18719a4STom Rini tbl[i++] = subnode;
734d18719a4STom Rini
735d18719a4STom Rini qsort(tbl, n, sizeof(*tbl), cmp_subnode);
736d18719a4STom Rini
737d18719a4STom Rini node->children = tbl[0];
738d18719a4STom Rini for (i = 0; i < (n-1); i++)
739d18719a4STom Rini tbl[i]->next_sibling = tbl[i+1];
740d18719a4STom Rini tbl[n-1]->next_sibling = NULL;
741d18719a4STom Rini
742d18719a4STom Rini free(tbl);
743d18719a4STom Rini }
744d18719a4STom Rini
sort_node(struct node * node)745d18719a4STom Rini static void sort_node(struct node *node)
746d18719a4STom Rini {
747d18719a4STom Rini struct node *c;
748d18719a4STom Rini
749d18719a4STom Rini sort_properties(node);
750d18719a4STom Rini sort_subnodes(node);
751d18719a4STom Rini for_each_child_withdel(node, c)
752d18719a4STom Rini sort_node(c);
753d18719a4STom Rini }
754d18719a4STom Rini
sort_tree(struct dt_info * dti)755d18719a4STom Rini void sort_tree(struct dt_info *dti)
756d18719a4STom Rini {
757d18719a4STom Rini sort_reserve_entries(dti);
758d18719a4STom Rini sort_node(dti->dt);
759d18719a4STom Rini }
760d18719a4STom Rini
761d18719a4STom Rini /* utility helper to avoid code duplication */
build_and_name_child_node(struct node * parent,char * name)762d18719a4STom Rini static struct node *build_and_name_child_node(struct node *parent, char *name)
763d18719a4STom Rini {
764d18719a4STom Rini struct node *node;
765d18719a4STom Rini
766d18719a4STom Rini node = build_node(NULL, NULL);
767d18719a4STom Rini name_node(node, xstrdup(name));
768d18719a4STom Rini add_child(parent, node);
769d18719a4STom Rini
770d18719a4STom Rini return node;
771d18719a4STom Rini }
772d18719a4STom Rini
build_root_node(struct node * dt,char * name)773d18719a4STom Rini static struct node *build_root_node(struct node *dt, char *name)
774d18719a4STom Rini {
775d18719a4STom Rini struct node *an;
776d18719a4STom Rini
777d18719a4STom Rini an = get_subnode(dt, name);
778d18719a4STom Rini if (!an)
779d18719a4STom Rini an = build_and_name_child_node(dt, name);
780d18719a4STom Rini
781d18719a4STom Rini if (!an)
782d18719a4STom Rini die("Could not build root node /%s\n", name);
783d18719a4STom Rini
784d18719a4STom Rini return an;
785d18719a4STom Rini }
786d18719a4STom Rini
any_label_tree(struct dt_info * dti,struct node * node)787d18719a4STom Rini static bool any_label_tree(struct dt_info *dti, struct node *node)
788d18719a4STom Rini {
789d18719a4STom Rini struct node *c;
790d18719a4STom Rini
791d18719a4STom Rini if (node->labels)
792d18719a4STom Rini return true;
793d18719a4STom Rini
794d18719a4STom Rini for_each_child(node, c)
795d18719a4STom Rini if (any_label_tree(dti, c))
796d18719a4STom Rini return true;
797d18719a4STom Rini
798d18719a4STom Rini return false;
799d18719a4STom Rini }
800d18719a4STom Rini
generate_label_tree_internal(struct dt_info * dti,struct node * an,struct node * node,bool allocph)801d18719a4STom Rini static void generate_label_tree_internal(struct dt_info *dti,
802d18719a4STom Rini struct node *an, struct node *node,
803d18719a4STom Rini bool allocph)
804d18719a4STom Rini {
805d18719a4STom Rini struct node *dt = dti->dt;
806d18719a4STom Rini struct node *c;
807d18719a4STom Rini struct property *p;
808d18719a4STom Rini struct label *l;
809d18719a4STom Rini
810d18719a4STom Rini /* if there are labels */
811d18719a4STom Rini if (node->labels) {
812d18719a4STom Rini
813d18719a4STom Rini /* now add the label in the node */
814d18719a4STom Rini for_each_label(node->labels, l) {
815d18719a4STom Rini
816d18719a4STom Rini /* check whether the label already exists */
817d18719a4STom Rini p = get_property(an, l->label);
818d18719a4STom Rini if (p) {
819d18719a4STom Rini fprintf(stderr, "WARNING: label %s already"
820d18719a4STom Rini " exists in /%s", l->label,
821d18719a4STom Rini an->name);
822d18719a4STom Rini continue;
823d18719a4STom Rini }
824d18719a4STom Rini
825d18719a4STom Rini /* insert it */
826d18719a4STom Rini p = build_property(l->label,
827d18719a4STom Rini data_copy_mem(node->fullpath,
828d18719a4STom Rini strlen(node->fullpath) + 1));
829d18719a4STom Rini add_property(an, p);
830d18719a4STom Rini }
831d18719a4STom Rini
832d18719a4STom Rini /* force allocation of a phandle for this node */
833d18719a4STom Rini if (allocph)
834d18719a4STom Rini (void)get_node_phandle(dt, node);
835d18719a4STom Rini }
836d18719a4STom Rini
837d18719a4STom Rini for_each_child(node, c)
838d18719a4STom Rini generate_label_tree_internal(dti, an, c, allocph);
839d18719a4STom Rini }
840d18719a4STom Rini
any_fixup_tree(struct dt_info * dti,struct node * node)841d18719a4STom Rini static bool any_fixup_tree(struct dt_info *dti, struct node *node)
842d18719a4STom Rini {
843d18719a4STom Rini struct node *c;
844d18719a4STom Rini struct property *prop;
845d18719a4STom Rini struct marker *m;
846d18719a4STom Rini
847d18719a4STom Rini for_each_property(node, prop) {
848d18719a4STom Rini m = prop->val.markers;
849d18719a4STom Rini for_each_marker_of_type(m, REF_PHANDLE) {
850d18719a4STom Rini if (!get_node_by_ref(dti->dt, m->ref))
851d18719a4STom Rini return true;
852d18719a4STom Rini }
853d18719a4STom Rini }
854d18719a4STom Rini
855d18719a4STom Rini for_each_child(node, c) {
856d18719a4STom Rini if (any_fixup_tree(dti, c))
857d18719a4STom Rini return true;
858d18719a4STom Rini }
859d18719a4STom Rini
860d18719a4STom Rini return false;
861d18719a4STom Rini }
862d18719a4STom Rini
add_fixup_entry(struct dt_info * dti,struct node * fn,struct node * node,struct property * prop,struct marker * m)863d18719a4STom Rini static void add_fixup_entry(struct dt_info *dti, struct node *fn,
864d18719a4STom Rini struct node *node, struct property *prop,
865d18719a4STom Rini struct marker *m)
866d18719a4STom Rini {
867d18719a4STom Rini char *entry;
868d18719a4STom Rini
869d18719a4STom Rini /* m->ref can only be a REF_PHANDLE, but check anyway */
870d18719a4STom Rini assert(m->type == REF_PHANDLE);
871d18719a4STom Rini
872d18719a4STom Rini /* there shouldn't be any ':' in the arguments */
873d18719a4STom Rini if (strchr(node->fullpath, ':') || strchr(prop->name, ':'))
874d18719a4STom Rini die("arguments should not contain ':'\n");
875d18719a4STom Rini
876d18719a4STom Rini xasprintf(&entry, "%s:%s:%u",
877d18719a4STom Rini node->fullpath, prop->name, m->offset);
878d18719a4STom Rini append_to_property(fn, m->ref, entry, strlen(entry) + 1);
879d18719a4STom Rini
880d18719a4STom Rini free(entry);
881d18719a4STom Rini }
882d18719a4STom Rini
generate_fixups_tree_internal(struct dt_info * dti,struct node * fn,struct node * node)883d18719a4STom Rini static void generate_fixups_tree_internal(struct dt_info *dti,
884d18719a4STom Rini struct node *fn,
885d18719a4STom Rini struct node *node)
886d18719a4STom Rini {
887d18719a4STom Rini struct node *dt = dti->dt;
888d18719a4STom Rini struct node *c;
889d18719a4STom Rini struct property *prop;
890d18719a4STom Rini struct marker *m;
891d18719a4STom Rini struct node *refnode;
892d18719a4STom Rini
893d18719a4STom Rini for_each_property(node, prop) {
894d18719a4STom Rini m = prop->val.markers;
895d18719a4STom Rini for_each_marker_of_type(m, REF_PHANDLE) {
896d18719a4STom Rini refnode = get_node_by_ref(dt, m->ref);
897d18719a4STom Rini if (!refnode)
898d18719a4STom Rini add_fixup_entry(dti, fn, node, prop, m);
899d18719a4STom Rini }
900d18719a4STom Rini }
901d18719a4STom Rini
902d18719a4STom Rini for_each_child(node, c)
903d18719a4STom Rini generate_fixups_tree_internal(dti, fn, c);
904d18719a4STom Rini }
905d18719a4STom Rini
any_local_fixup_tree(struct dt_info * dti,struct node * node)906d18719a4STom Rini static bool any_local_fixup_tree(struct dt_info *dti, struct node *node)
907d18719a4STom Rini {
908d18719a4STom Rini struct node *c;
909d18719a4STom Rini struct property *prop;
910d18719a4STom Rini struct marker *m;
911d18719a4STom Rini
912d18719a4STom Rini for_each_property(node, prop) {
913d18719a4STom Rini m = prop->val.markers;
914d18719a4STom Rini for_each_marker_of_type(m, REF_PHANDLE) {
915d18719a4STom Rini if (get_node_by_ref(dti->dt, m->ref))
916d18719a4STom Rini return true;
917d18719a4STom Rini }
918d18719a4STom Rini }
919d18719a4STom Rini
920d18719a4STom Rini for_each_child(node, c) {
921d18719a4STom Rini if (any_local_fixup_tree(dti, c))
922d18719a4STom Rini return true;
923d18719a4STom Rini }
924d18719a4STom Rini
925d18719a4STom Rini return false;
926d18719a4STom Rini }
927d18719a4STom Rini
add_local_fixup_entry(struct dt_info * dti,struct node * lfn,struct node * node,struct property * prop,struct marker * m,struct node * refnode)928d18719a4STom Rini static void add_local_fixup_entry(struct dt_info *dti,
929d18719a4STom Rini struct node *lfn, struct node *node,
930d18719a4STom Rini struct property *prop, struct marker *m,
931d18719a4STom Rini struct node *refnode)
932d18719a4STom Rini {
933d18719a4STom Rini struct node *wn, *nwn; /* local fixup node, walk node, new */
934e23ffda2STom Rini fdt32_t value_32;
935d18719a4STom Rini char **compp;
936d18719a4STom Rini int i, depth;
937d18719a4STom Rini
938d18719a4STom Rini /* walk back retreiving depth */
939d18719a4STom Rini depth = 0;
940d18719a4STom Rini for (wn = node; wn; wn = wn->parent)
941d18719a4STom Rini depth++;
942d18719a4STom Rini
943d18719a4STom Rini /* allocate name array */
944d18719a4STom Rini compp = xmalloc(sizeof(*compp) * depth);
945d18719a4STom Rini
946d18719a4STom Rini /* store names in the array */
947d18719a4STom Rini for (wn = node, i = depth - 1; wn; wn = wn->parent, i--)
948d18719a4STom Rini compp[i] = wn->name;
949d18719a4STom Rini
950d18719a4STom Rini /* walk the path components creating nodes if they don't exist */
951d18719a4STom Rini for (wn = lfn, i = 1; i < depth; i++, wn = nwn) {
952d18719a4STom Rini /* if no node exists, create it */
953d18719a4STom Rini nwn = get_subnode(wn, compp[i]);
954d18719a4STom Rini if (!nwn)
955d18719a4STom Rini nwn = build_and_name_child_node(wn, compp[i]);
956d18719a4STom Rini }
957d18719a4STom Rini
958d18719a4STom Rini free(compp);
959d18719a4STom Rini
960d18719a4STom Rini value_32 = cpu_to_fdt32(m->offset);
961d18719a4STom Rini append_to_property(wn, prop->name, &value_32, sizeof(value_32));
962d18719a4STom Rini }
963d18719a4STom Rini
generate_local_fixups_tree_internal(struct dt_info * dti,struct node * lfn,struct node * node)964d18719a4STom Rini static void generate_local_fixups_tree_internal(struct dt_info *dti,
965d18719a4STom Rini struct node *lfn,
966d18719a4STom Rini struct node *node)
967d18719a4STom Rini {
968d18719a4STom Rini struct node *dt = dti->dt;
969d18719a4STom Rini struct node *c;
970d18719a4STom Rini struct property *prop;
971d18719a4STom Rini struct marker *m;
972d18719a4STom Rini struct node *refnode;
973d18719a4STom Rini
974d18719a4STom Rini for_each_property(node, prop) {
975d18719a4STom Rini m = prop->val.markers;
976d18719a4STom Rini for_each_marker_of_type(m, REF_PHANDLE) {
977d18719a4STom Rini refnode = get_node_by_ref(dt, m->ref);
978d18719a4STom Rini if (refnode)
979d18719a4STom Rini add_local_fixup_entry(dti, lfn, node, prop, m, refnode);
980d18719a4STom Rini }
981d18719a4STom Rini }
982d18719a4STom Rini
983d18719a4STom Rini for_each_child(node, c)
984d18719a4STom Rini generate_local_fixups_tree_internal(dti, lfn, c);
985d18719a4STom Rini }
986d18719a4STom Rini
generate_label_tree(struct dt_info * dti,char * name,bool allocph)987d18719a4STom Rini void generate_label_tree(struct dt_info *dti, char *name, bool allocph)
988d18719a4STom Rini {
989d18719a4STom Rini if (!any_label_tree(dti, dti->dt))
990d18719a4STom Rini return;
991d18719a4STom Rini generate_label_tree_internal(dti, build_root_node(dti->dt, name),
992d18719a4STom Rini dti->dt, allocph);
993d18719a4STom Rini }
994d18719a4STom Rini
generate_fixups_tree(struct dt_info * dti,char * name)995d18719a4STom Rini void generate_fixups_tree(struct dt_info *dti, char *name)
996d18719a4STom Rini {
997d18719a4STom Rini if (!any_fixup_tree(dti, dti->dt))
998d18719a4STom Rini return;
999d18719a4STom Rini generate_fixups_tree_internal(dti, build_root_node(dti->dt, name),
1000d18719a4STom Rini dti->dt);
1001d18719a4STom Rini }
1002d18719a4STom Rini
generate_local_fixups_tree(struct dt_info * dti,char * name)1003d18719a4STom Rini void generate_local_fixups_tree(struct dt_info *dti, char *name)
1004d18719a4STom Rini {
1005d18719a4STom Rini if (!any_local_fixup_tree(dti, dti->dt))
1006d18719a4STom Rini return;
1007d18719a4STom Rini generate_local_fixups_tree_internal(dti, build_root_node(dti->dt, name),
1008d18719a4STom Rini dti->dt);
1009d18719a4STom Rini }
1010