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