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
;
118 child
->parent
= parent
;
120 p
= &parent
->children
;
122 p
= &((*p
)->next_sibling
);
127 struct reserve_info
*build_reserve_entry(uint64_t address
, uint64_t size
,
130 struct reserve_info
*new = xmalloc(sizeof(*new));
132 new->re
.address
= address
;
142 struct reserve_info
*chain_reserve_entry(struct reserve_info
*first
,
143 struct reserve_info
*list
)
145 assert(first
->next
== NULL
);
151 struct reserve_info
*add_reserve_entry(struct reserve_info
*list
,
152 struct reserve_info
*new)
154 struct reserve_info
*last
;
161 for (last
= list
; last
->next
; last
= last
->next
)
169 struct boot_info
*build_boot_info(struct reserve_info
*reservelist
,
170 struct node
*tree
, uint32_t boot_cpuid_phys
)
172 struct boot_info
*bi
;
174 bi
= xmalloc(sizeof(*bi
));
175 bi
->reservelist
= reservelist
;
177 bi
->boot_cpuid_phys
= boot_cpuid_phys
;
183 * Tree accessor functions
186 const char *get_unitname(struct node
*node
)
188 if (node
->name
[node
->basenamelen
] == '\0')
191 return node
->name
+ node
->basenamelen
+ 1;
194 struct property
*get_property(struct node
*node
, const char *propname
)
196 struct property
*prop
;
198 for_each_property(node
, prop
)
199 if (streq(prop
->name
, propname
))
205 cell_t
propval_cell(struct property
*prop
)
207 assert(prop
->val
.len
== sizeof(cell_t
));
208 return fdt32_to_cpu(*((cell_t
*)prop
->val
.val
));
211 struct node
*get_subnode(struct node
*node
, const char *nodename
)
215 for_each_child(node
, child
)
216 if (streq(child
->name
, nodename
))
222 struct node
*get_node_by_path(struct node
*tree
, const char *path
)
227 if (!path
|| ! (*path
))
230 while (path
[0] == '/')
233 p
= strchr(path
, '/');
235 for_each_child(tree
, child
) {
236 if (p
&& strneq(path
, child
->name
, p
-path
))
237 return get_node_by_path(child
, p
+1);
238 else if (!p
&& streq(path
, child
->name
))
245 struct node
*get_node_by_label(struct node
*tree
, const char *label
)
247 struct node
*child
, *node
;
249 assert(label
&& (strlen(label
) > 0));
251 if (tree
->label
&& streq(tree
->label
, label
))
254 for_each_child(tree
, child
) {
255 node
= get_node_by_label(child
, label
);
263 struct node
*get_node_by_phandle(struct node
*tree
, cell_t phandle
)
265 struct node
*child
, *node
;
267 assert((phandle
!= 0) && (phandle
!= -1));
269 if (tree
->phandle
== phandle
)
272 for_each_child(tree
, child
) {
273 node
= get_node_by_phandle(child
, phandle
);
281 struct node
*get_node_by_ref(struct node
*tree
, const char *ref
)
284 return get_node_by_path(tree
, ref
);
286 return get_node_by_label(tree
, ref
);
289 cell_t
get_node_phandle(struct node
*root
, struct node
*node
)
291 static cell_t phandle
= 1; /* FIXME: ick, static local */
293 if ((node
->phandle
!= 0) && (node
->phandle
!= -1))
294 return node
->phandle
;
296 assert(! get_property(node
, "linux,phandle"));
298 while (get_node_by_phandle(root
, phandle
))
301 node
->phandle
= phandle
;
303 build_property("linux,phandle",
304 data_append_cell(empty_data
, phandle
),
307 return node
->phandle
;