2 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
24 * Tree building functions
27 struct property
*build_property(char *name
, struct data val
, char *label
)
29 struct property
*new = xmalloc(sizeof(*new));
41 struct property
*chain_property(struct property
*first
, struct property
*list
)
43 assert(first
->next
== NULL
);
49 struct property
*reverse_properties(struct property
*first
)
51 struct property
*p
= first
;
52 struct property
*head
= NULL
;
53 struct property
*next
;
64 struct node
*build_node(struct property
*proplist
, struct node
*children
)
66 struct node
*new = xmalloc(sizeof(*new));
69 memset(new, 0, sizeof(*new));
71 new->proplist
= reverse_properties(proplist
);
72 new->children
= children
;
74 for_each_child(new, child
) {
81 struct node
*name_node(struct node
*node
, char *name
, char * label
)
83 assert(node
->name
== NULL
);
92 struct node
*chain_node(struct node
*first
, struct node
*list
)
94 assert(first
->next_sibling
== NULL
);
96 first
->next_sibling
= list
;
100 void add_property(struct node
*node
, struct property
*prop
)
113 void add_child(struct node
*parent
, struct node
*child
)
117 child
->next_sibling
= NULL
;
119 p
= &parent
->children
;
121 p
= &((*p
)->next_sibling
);
126 struct reserve_info
*build_reserve_entry(u64 address
, u64 size
, char *label
)
128 struct reserve_info
*new = xmalloc(sizeof(*new));
130 new->re
.address
= address
;
140 struct reserve_info
*chain_reserve_entry(struct reserve_info
*first
,
141 struct reserve_info
*list
)
143 assert(first
->next
== NULL
);
149 struct reserve_info
*add_reserve_entry(struct reserve_info
*list
,
150 struct reserve_info
*new)
152 struct reserve_info
*last
;
159 for (last
= list
; last
->next
; last
= last
->next
)
167 struct boot_info
*build_boot_info(struct reserve_info
*reservelist
,
170 struct boot_info
*bi
;
172 bi
= xmalloc(sizeof(*bi
));
173 bi
->reservelist
= reservelist
;
180 * Tree accessor functions
183 const char *get_unitname(struct node
*node
)
185 if (node
->name
[node
->basenamelen
] == '\0')
188 return node
->name
+ node
->basenamelen
+ 1;
191 struct property
*get_property(struct node
*node
, const char *propname
)
193 struct property
*prop
;
195 for_each_property(node
, prop
)
196 if (streq(prop
->name
, propname
))
202 cell_t
propval_cell(struct property
*prop
)
204 assert(prop
->val
.len
== sizeof(cell_t
));
205 return be32_to_cpu(*((cell_t
*)prop
->val
.val
));
208 struct node
*get_subnode(struct node
*node
, const char *nodename
)
212 for_each_child(node
, child
)
213 if (streq(child
->name
, nodename
))
219 struct node
*get_node_by_path(struct node
*tree
, const char *path
)
224 if (!path
|| ! (*path
))
227 while (path
[0] == '/')
230 p
= strchr(path
, '/');
232 for_each_child(tree
, child
) {
233 if (p
&& strneq(path
, child
->name
, p
-path
))
234 return get_node_by_path(child
, p
+1);
235 else if (!p
&& streq(path
, child
->name
))
242 struct node
*get_node_by_label(struct node
*tree
, const char *label
)
244 struct node
*child
, *node
;
246 assert(label
&& (strlen(label
) > 0));
248 if (tree
->label
&& streq(tree
->label
, label
))
251 for_each_child(tree
, child
) {
252 node
= get_node_by_label(child
, label
);
260 struct node
*get_node_by_phandle(struct node
*tree
, cell_t phandle
)
262 struct node
*child
, *node
;
264 assert((phandle
!= 0) && (phandle
!= -1));
266 if (tree
->phandle
== phandle
)
269 for_each_child(tree
, child
) {
270 node
= get_node_by_phandle(child
, phandle
);
278 struct node
*get_node_by_ref(struct node
*tree
, const char *ref
)
281 return get_node_by_path(tree
, ref
);
283 return get_node_by_label(tree
, ref
);
286 cell_t
get_node_phandle(struct node
*root
, struct node
*node
)
288 static cell_t phandle
= 1; /* FIXME: ick, static local */
290 if ((node
->phandle
!= 0) && (node
->phandle
!= -1))
291 return node
->phandle
;
293 assert(! get_property(node
, "linux,phandle"));
295 while (get_node_by_phandle(root
, phandle
))
298 node
->phandle
= phandle
;
300 build_property("linux,phandle",
301 data_append_cell(empty_data
, phandle
),
304 return node
->phandle
;