symbian-qemu-0.9.1-12/dtc-trunk/livetree.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /*
       
     2  * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
       
     3  *
       
     4  *
       
     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.
       
     9  *
       
    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.
       
    14  *
       
    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
       
    18  *                                                                   USA
       
    19  */
       
    20 
       
    21 #include "dtc.h"
       
    22 
       
    23 /*
       
    24  * Tree building functions
       
    25  */
       
    26 
       
    27 struct property *build_property(char *name, struct data val, char *label)
       
    28 {
       
    29 	struct property *new = xmalloc(sizeof(*new));
       
    30 
       
    31 	new->name = name;
       
    32 	new->val = val;
       
    33 
       
    34 	new->next = NULL;
       
    35 
       
    36 	new->label = label;
       
    37 
       
    38 	return new;
       
    39 }
       
    40 
       
    41 struct property *chain_property(struct property *first, struct property *list)
       
    42 {
       
    43 	assert(first->next == NULL);
       
    44 
       
    45 	first->next = list;
       
    46 	return first;
       
    47 }
       
    48 
       
    49 struct property *reverse_properties(struct property *first)
       
    50 {
       
    51 	struct property *p = first;
       
    52 	struct property *head = NULL;
       
    53 	struct property *next;
       
    54 
       
    55 	while (p) {
       
    56 		next = p->next;
       
    57 		p->next = head;
       
    58 		head = p;
       
    59 		p = next;
       
    60 	}
       
    61 	return head;
       
    62 }
       
    63 
       
    64 struct node *build_node(struct property *proplist, struct node *children)
       
    65 {
       
    66 	struct node *new = xmalloc(sizeof(*new));
       
    67 	struct node *child;
       
    68 
       
    69 	memset(new, 0, sizeof(*new));
       
    70 
       
    71 	new->proplist = reverse_properties(proplist);
       
    72 	new->children = children;
       
    73 
       
    74 	for_each_child(new, child) {
       
    75 		child->parent = new;
       
    76 	}
       
    77 
       
    78 	return new;
       
    79 }
       
    80 
       
    81 struct node *name_node(struct node *node, char *name, char * label)
       
    82 {
       
    83 	assert(node->name == NULL);
       
    84 
       
    85 	node->name = name;
       
    86 
       
    87 	node->label = label;
       
    88 
       
    89 	return node;
       
    90 }
       
    91 
       
    92 struct node *chain_node(struct node *first, struct node *list)
       
    93 {
       
    94 	assert(first->next_sibling == NULL);
       
    95 
       
    96 	first->next_sibling = list;
       
    97 	return first;
       
    98 }
       
    99 
       
   100 void add_property(struct node *node, struct property *prop)
       
   101 {
       
   102 	struct property **p;
       
   103 
       
   104 	prop->next = NULL;
       
   105 
       
   106 	p = &node->proplist;
       
   107 	while (*p)
       
   108 		p = &((*p)->next);
       
   109 
       
   110 	*p = prop;
       
   111 }
       
   112 
       
   113 void add_child(struct node *parent, struct node *child)
       
   114 {
       
   115 	struct node **p;
       
   116 
       
   117 	child->next_sibling = NULL;
       
   118 	child->parent = parent;
       
   119 
       
   120 	p = &parent->children;
       
   121 	while (*p)
       
   122 		p = &((*p)->next_sibling);
       
   123 
       
   124 	*p = child;
       
   125 }
       
   126 
       
   127 struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size,
       
   128 					 char *label)
       
   129 {
       
   130 	struct reserve_info *new = xmalloc(sizeof(*new));
       
   131 
       
   132 	new->re.address = address;
       
   133 	new->re.size = size;
       
   134 
       
   135 	new->next = NULL;
       
   136 
       
   137 	new->label = label;
       
   138 
       
   139 	return new;
       
   140 }
       
   141 
       
   142 struct reserve_info *chain_reserve_entry(struct reserve_info *first,
       
   143 					struct reserve_info *list)
       
   144 {
       
   145 	assert(first->next == NULL);
       
   146 
       
   147 	first->next = list;
       
   148 	return first;
       
   149 }
       
   150 
       
   151 struct reserve_info *add_reserve_entry(struct reserve_info *list,
       
   152 				      struct reserve_info *new)
       
   153 {
       
   154 	struct reserve_info *last;
       
   155 
       
   156 	new->next = NULL;
       
   157 
       
   158 	if (! list)
       
   159 		return new;
       
   160 
       
   161 	for (last = list; last->next; last = last->next)
       
   162 		;
       
   163 
       
   164 	last->next = new;
       
   165 
       
   166 	return list;
       
   167 }
       
   168 
       
   169 struct boot_info *build_boot_info(struct reserve_info *reservelist,
       
   170 				  struct node *tree, uint32_t boot_cpuid_phys)
       
   171 {
       
   172 	struct boot_info *bi;
       
   173 
       
   174 	bi = xmalloc(sizeof(*bi));
       
   175 	bi->reservelist = reservelist;
       
   176 	bi->dt = tree;
       
   177 	bi->boot_cpuid_phys = boot_cpuid_phys;
       
   178 
       
   179 	return bi;
       
   180 }
       
   181 
       
   182 /*
       
   183  * Tree accessor functions
       
   184  */
       
   185 
       
   186 const char *get_unitname(struct node *node)
       
   187 {
       
   188 	if (node->name[node->basenamelen] == '\0')
       
   189 		return "";
       
   190 	else
       
   191 		return node->name + node->basenamelen + 1;
       
   192 }
       
   193 
       
   194 struct property *get_property(struct node *node, const char *propname)
       
   195 {
       
   196 	struct property *prop;
       
   197 
       
   198 	for_each_property(node, prop)
       
   199 		if (streq(prop->name, propname))
       
   200 			return prop;
       
   201 
       
   202 	return NULL;
       
   203 }
       
   204 
       
   205 cell_t propval_cell(struct property *prop)
       
   206 {
       
   207 	assert(prop->val.len == sizeof(cell_t));
       
   208 	return fdt32_to_cpu(*((cell_t *)prop->val.val));
       
   209 }
       
   210 
       
   211 struct node *get_subnode(struct node *node, const char *nodename)
       
   212 {
       
   213 	struct node *child;
       
   214 
       
   215 	for_each_child(node, child)
       
   216 		if (streq(child->name, nodename))
       
   217 			return child;
       
   218 
       
   219 	return NULL;
       
   220 }
       
   221 
       
   222 struct node *get_node_by_path(struct node *tree, const char *path)
       
   223 {
       
   224 	const char *p;
       
   225 	struct node *child;
       
   226 
       
   227 	if (!path || ! (*path))
       
   228 		return tree;
       
   229 
       
   230 	while (path[0] == '/')
       
   231 		path++;
       
   232 
       
   233 	p = strchr(path, '/');
       
   234 
       
   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))
       
   239 			return child;
       
   240 	}
       
   241 
       
   242 	return NULL;
       
   243 }
       
   244 
       
   245 struct node *get_node_by_label(struct node *tree, const char *label)
       
   246 {
       
   247 	struct node *child, *node;
       
   248 
       
   249 	assert(label && (strlen(label) > 0));
       
   250 
       
   251 	if (tree->label && streq(tree->label, label))
       
   252 		return tree;
       
   253 
       
   254 	for_each_child(tree, child) {
       
   255 		node = get_node_by_label(child, label);
       
   256 		if (node)
       
   257 			return node;
       
   258 	}
       
   259 
       
   260 	return NULL;
       
   261 }
       
   262 
       
   263 struct node *get_node_by_phandle(struct node *tree, cell_t phandle)
       
   264 {
       
   265 	struct node *child, *node;
       
   266 
       
   267 	assert((phandle != 0) && (phandle != -1));
       
   268 
       
   269 	if (tree->phandle == phandle)
       
   270 		return tree;
       
   271 
       
   272 	for_each_child(tree, child) {
       
   273 		node = get_node_by_phandle(child, phandle);
       
   274 		if (node)
       
   275 			return node;
       
   276 	}
       
   277 
       
   278 	return NULL;
       
   279 }
       
   280 
       
   281 struct node *get_node_by_ref(struct node *tree, const char *ref)
       
   282 {
       
   283 	if (ref[0] == '/')
       
   284 		return get_node_by_path(tree, ref);
       
   285 	else
       
   286 		return get_node_by_label(tree, ref);
       
   287 }
       
   288 
       
   289 cell_t get_node_phandle(struct node *root, struct node *node)
       
   290 {
       
   291 	static cell_t phandle = 1; /* FIXME: ick, static local */
       
   292 
       
   293 	if ((node->phandle != 0) && (node->phandle != -1))
       
   294 		return node->phandle;
       
   295 
       
   296 	assert(! get_property(node, "linux,phandle"));
       
   297 
       
   298 	while (get_node_by_phandle(root, phandle))
       
   299 		phandle++;
       
   300 
       
   301 	node->phandle = phandle;
       
   302 	add_property(node,
       
   303 		     build_property("linux,phandle",
       
   304 				    data_append_cell(empty_data, phandle),
       
   305 				    NULL));
       
   306 
       
   307 	return node->phandle;
       
   308 }