0001
0002
0003
0004
0005
0006 #include "dtc.h"
0007 #include "srcpos.h"
0008
0009
0010
0011
0012
0013 void add_label(struct label **labels, char *label)
0014 {
0015 struct label *new;
0016
0017
0018 for_each_label_withdel(*labels, new)
0019 if (streq(new->label, label)) {
0020 new->deleted = 0;
0021 return;
0022 }
0023
0024 new = xmalloc(sizeof(*new));
0025 memset(new, 0, sizeof(*new));
0026 new->label = label;
0027 new->next = *labels;
0028 *labels = new;
0029 }
0030
0031 void delete_labels(struct label **labels)
0032 {
0033 struct label *label;
0034
0035 for_each_label(*labels, label)
0036 label->deleted = 1;
0037 }
0038
0039 struct property *build_property(char *name, struct data val,
0040 struct srcpos *srcpos)
0041 {
0042 struct property *new = xmalloc(sizeof(*new));
0043
0044 memset(new, 0, sizeof(*new));
0045
0046 new->name = name;
0047 new->val = val;
0048 new->srcpos = srcpos_copy(srcpos);
0049
0050 return new;
0051 }
0052
0053 struct property *build_property_delete(char *name)
0054 {
0055 struct property *new = xmalloc(sizeof(*new));
0056
0057 memset(new, 0, sizeof(*new));
0058
0059 new->name = name;
0060 new->deleted = 1;
0061
0062 return new;
0063 }
0064
0065 struct property *chain_property(struct property *first, struct property *list)
0066 {
0067 assert(first->next == NULL);
0068
0069 first->next = list;
0070 return first;
0071 }
0072
0073 struct property *reverse_properties(struct property *first)
0074 {
0075 struct property *p = first;
0076 struct property *head = NULL;
0077 struct property *next;
0078
0079 while (p) {
0080 next = p->next;
0081 p->next = head;
0082 head = p;
0083 p = next;
0084 }
0085 return head;
0086 }
0087
0088 struct node *build_node(struct property *proplist, struct node *children,
0089 struct srcpos *srcpos)
0090 {
0091 struct node *new = xmalloc(sizeof(*new));
0092 struct node *child;
0093
0094 memset(new, 0, sizeof(*new));
0095
0096 new->proplist = reverse_properties(proplist);
0097 new->children = children;
0098 new->srcpos = srcpos_copy(srcpos);
0099
0100 for_each_child(new, child) {
0101 child->parent = new;
0102 }
0103
0104 return new;
0105 }
0106
0107 struct node *build_node_delete(struct srcpos *srcpos)
0108 {
0109 struct node *new = xmalloc(sizeof(*new));
0110
0111 memset(new, 0, sizeof(*new));
0112
0113 new->deleted = 1;
0114 new->srcpos = srcpos_copy(srcpos);
0115
0116 return new;
0117 }
0118
0119 struct node *name_node(struct node *node, char *name)
0120 {
0121 assert(node->name == NULL);
0122
0123 node->name = name;
0124
0125 return node;
0126 }
0127
0128 struct node *omit_node_if_unused(struct node *node)
0129 {
0130 node->omit_if_unused = 1;
0131
0132 return node;
0133 }
0134
0135 struct node *reference_node(struct node *node)
0136 {
0137 node->is_referenced = 1;
0138
0139 return node;
0140 }
0141
0142 struct node *merge_nodes(struct node *old_node, struct node *new_node)
0143 {
0144 struct property *new_prop, *old_prop;
0145 struct node *new_child, *old_child;
0146 struct label *l;
0147
0148 old_node->deleted = 0;
0149
0150
0151 for_each_label_withdel(new_node->labels, l)
0152 add_label(&old_node->labels, l->label);
0153
0154
0155
0156 while (new_node->proplist) {
0157
0158 new_prop = new_node->proplist;
0159 new_node->proplist = new_prop->next;
0160 new_prop->next = NULL;
0161
0162 if (new_prop->deleted) {
0163 delete_property_by_name(old_node, new_prop->name);
0164 free(new_prop);
0165 continue;
0166 }
0167
0168
0169 for_each_property_withdel(old_node, old_prop) {
0170 if (streq(old_prop->name, new_prop->name)) {
0171
0172 for_each_label_withdel(new_prop->labels, l)
0173 add_label(&old_prop->labels, l->label);
0174
0175 old_prop->val = new_prop->val;
0176 old_prop->deleted = 0;
0177 free(old_prop->srcpos);
0178 old_prop->srcpos = new_prop->srcpos;
0179 free(new_prop);
0180 new_prop = NULL;
0181 break;
0182 }
0183 }
0184
0185
0186 if (new_prop)
0187 add_property(old_node, new_prop);
0188 }
0189
0190
0191
0192 while (new_node->children) {
0193
0194 new_child = new_node->children;
0195 new_node->children = new_child->next_sibling;
0196 new_child->parent = NULL;
0197 new_child->next_sibling = NULL;
0198
0199 if (new_child->deleted) {
0200 delete_node_by_name(old_node, new_child->name);
0201 free(new_child);
0202 continue;
0203 }
0204
0205
0206 for_each_child_withdel(old_node, old_child) {
0207 if (streq(old_child->name, new_child->name)) {
0208 merge_nodes(old_child, new_child);
0209 new_child = NULL;
0210 break;
0211 }
0212 }
0213
0214
0215 if (new_child)
0216 add_child(old_node, new_child);
0217 }
0218
0219 old_node->srcpos = srcpos_extend(old_node->srcpos, new_node->srcpos);
0220
0221
0222
0223 free(new_node);
0224
0225 return old_node;
0226 }
0227
0228 struct node * add_orphan_node(struct node *dt, struct node *new_node, char *ref)
0229 {
0230 static unsigned int next_orphan_fragment = 0;
0231 struct node *node;
0232 struct property *p;
0233 struct data d = empty_data;
0234 char *name;
0235
0236 if (ref[0] == '/') {
0237 d = data_add_marker(d, TYPE_STRING, ref);
0238 d = data_append_data(d, ref, strlen(ref) + 1);
0239
0240 p = build_property("target-path", d, NULL);
0241 } else {
0242 d = data_add_marker(d, REF_PHANDLE, ref);
0243 d = data_append_integer(d, 0xffffffff, 32);
0244
0245 p = build_property("target", d, NULL);
0246 }
0247
0248 xasprintf(&name, "fragment@%u",
0249 next_orphan_fragment++);
0250 name_node(new_node, "__overlay__");
0251 node = build_node(p, new_node, NULL);
0252 name_node(node, name);
0253
0254 add_child(dt, node);
0255 return dt;
0256 }
0257
0258 struct node *chain_node(struct node *first, struct node *list)
0259 {
0260 assert(first->next_sibling == NULL);
0261
0262 first->next_sibling = list;
0263 return first;
0264 }
0265
0266 void add_property(struct node *node, struct property *prop)
0267 {
0268 struct property **p;
0269
0270 prop->next = NULL;
0271
0272 p = &node->proplist;
0273 while (*p)
0274 p = &((*p)->next);
0275
0276 *p = prop;
0277 }
0278
0279 void delete_property_by_name(struct node *node, char *name)
0280 {
0281 struct property *prop = node->proplist;
0282
0283 while (prop) {
0284 if (streq(prop->name, name)) {
0285 delete_property(prop);
0286 return;
0287 }
0288 prop = prop->next;
0289 }
0290 }
0291
0292 void delete_property(struct property *prop)
0293 {
0294 prop->deleted = 1;
0295 delete_labels(&prop->labels);
0296 }
0297
0298 void add_child(struct node *parent, struct node *child)
0299 {
0300 struct node **p;
0301
0302 child->next_sibling = NULL;
0303 child->parent = parent;
0304
0305 p = &parent->children;
0306 while (*p)
0307 p = &((*p)->next_sibling);
0308
0309 *p = child;
0310 }
0311
0312 void delete_node_by_name(struct node *parent, char *name)
0313 {
0314 struct node *node = parent->children;
0315
0316 while (node) {
0317 if (streq(node->name, name)) {
0318 delete_node(node);
0319 return;
0320 }
0321 node = node->next_sibling;
0322 }
0323 }
0324
0325 void delete_node(struct node *node)
0326 {
0327 struct property *prop;
0328 struct node *child;
0329
0330 node->deleted = 1;
0331 for_each_child(node, child)
0332 delete_node(child);
0333 for_each_property(node, prop)
0334 delete_property(prop);
0335 delete_labels(&node->labels);
0336 }
0337
0338 void append_to_property(struct node *node,
0339 char *name, const void *data, int len,
0340 enum markertype type)
0341 {
0342 struct data d;
0343 struct property *p;
0344
0345 p = get_property(node, name);
0346 if (p) {
0347 d = data_add_marker(p->val, type, name);
0348 d = data_append_data(d, data, len);
0349 p->val = d;
0350 } else {
0351 d = data_add_marker(empty_data, type, name);
0352 d = data_append_data(d, data, len);
0353 p = build_property(name, d, NULL);
0354 add_property(node, p);
0355 }
0356 }
0357
0358 struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size)
0359 {
0360 struct reserve_info *new = xmalloc(sizeof(*new));
0361
0362 memset(new, 0, sizeof(*new));
0363
0364 new->address = address;
0365 new->size = size;
0366
0367 return new;
0368 }
0369
0370 struct reserve_info *chain_reserve_entry(struct reserve_info *first,
0371 struct reserve_info *list)
0372 {
0373 assert(first->next == NULL);
0374
0375 first->next = list;
0376 return first;
0377 }
0378
0379 struct reserve_info *add_reserve_entry(struct reserve_info *list,
0380 struct reserve_info *new)
0381 {
0382 struct reserve_info *last;
0383
0384 new->next = NULL;
0385
0386 if (! list)
0387 return new;
0388
0389 for (last = list; last->next; last = last->next)
0390 ;
0391
0392 last->next = new;
0393
0394 return list;
0395 }
0396
0397 struct dt_info *build_dt_info(unsigned int dtsflags,
0398 struct reserve_info *reservelist,
0399 struct node *tree, uint32_t boot_cpuid_phys)
0400 {
0401 struct dt_info *dti;
0402
0403 dti = xmalloc(sizeof(*dti));
0404 dti->dtsflags = dtsflags;
0405 dti->reservelist = reservelist;
0406 dti->dt = tree;
0407 dti->boot_cpuid_phys = boot_cpuid_phys;
0408
0409 return dti;
0410 }
0411
0412
0413
0414
0415
0416 const char *get_unitname(struct node *node)
0417 {
0418 if (node->name[node->basenamelen] == '\0')
0419 return "";
0420 else
0421 return node->name + node->basenamelen + 1;
0422 }
0423
0424 struct property *get_property(struct node *node, const char *propname)
0425 {
0426 struct property *prop;
0427
0428 for_each_property(node, prop)
0429 if (streq(prop->name, propname))
0430 return prop;
0431
0432 return NULL;
0433 }
0434
0435 cell_t propval_cell(struct property *prop)
0436 {
0437 assert(prop->val.len == sizeof(cell_t));
0438 return fdt32_to_cpu(*((fdt32_t *)prop->val.val));
0439 }
0440
0441 cell_t propval_cell_n(struct property *prop, unsigned int n)
0442 {
0443 assert(prop->val.len / sizeof(cell_t) >= n);
0444 return fdt32_to_cpu(*((fdt32_t *)prop->val.val + n));
0445 }
0446
0447 struct property *get_property_by_label(struct node *tree, const char *label,
0448 struct node **node)
0449 {
0450 struct property *prop;
0451 struct node *c;
0452
0453 *node = tree;
0454
0455 for_each_property(tree, prop) {
0456 struct label *l;
0457
0458 for_each_label(prop->labels, l)
0459 if (streq(l->label, label))
0460 return prop;
0461 }
0462
0463 for_each_child(tree, c) {
0464 prop = get_property_by_label(c, label, node);
0465 if (prop)
0466 return prop;
0467 }
0468
0469 *node = NULL;
0470 return NULL;
0471 }
0472
0473 struct marker *get_marker_label(struct node *tree, const char *label,
0474 struct node **node, struct property **prop)
0475 {
0476 struct marker *m;
0477 struct property *p;
0478 struct node *c;
0479
0480 *node = tree;
0481
0482 for_each_property(tree, p) {
0483 *prop = p;
0484 m = p->val.markers;
0485 for_each_marker_of_type(m, LABEL)
0486 if (streq(m->ref, label))
0487 return m;
0488 }
0489
0490 for_each_child(tree, c) {
0491 m = get_marker_label(c, label, node, prop);
0492 if (m)
0493 return m;
0494 }
0495
0496 *prop = NULL;
0497 *node = NULL;
0498 return NULL;
0499 }
0500
0501 struct node *get_subnode(struct node *node, const char *nodename)
0502 {
0503 struct node *child;
0504
0505 for_each_child(node, child)
0506 if (streq(child->name, nodename))
0507 return child;
0508
0509 return NULL;
0510 }
0511
0512 struct node *get_node_by_path(struct node *tree, const char *path)
0513 {
0514 const char *p;
0515 struct node *child;
0516
0517 if (!path || ! (*path)) {
0518 if (tree->deleted)
0519 return NULL;
0520 return tree;
0521 }
0522
0523 while (path[0] == '/')
0524 path++;
0525
0526 p = strchr(path, '/');
0527
0528 for_each_child(tree, child) {
0529 if (p && strprefixeq(path, (size_t)(p - path), child->name))
0530 return get_node_by_path(child, p+1);
0531 else if (!p && streq(path, child->name))
0532 return child;
0533 }
0534
0535 return NULL;
0536 }
0537
0538 struct node *get_node_by_label(struct node *tree, const char *label)
0539 {
0540 struct node *child, *node;
0541 struct label *l;
0542
0543 assert(label && (strlen(label) > 0));
0544
0545 for_each_label(tree->labels, l)
0546 if (streq(l->label, label))
0547 return tree;
0548
0549 for_each_child(tree, child) {
0550 node = get_node_by_label(child, label);
0551 if (node)
0552 return node;
0553 }
0554
0555 return NULL;
0556 }
0557
0558 struct node *get_node_by_phandle(struct node *tree, cell_t phandle)
0559 {
0560 struct node *child, *node;
0561
0562 if (!phandle_is_valid(phandle)) {
0563 assert(generate_fixups);
0564 return NULL;
0565 }
0566
0567 if (tree->phandle == phandle) {
0568 if (tree->deleted)
0569 return NULL;
0570 return tree;
0571 }
0572
0573 for_each_child(tree, child) {
0574 node = get_node_by_phandle(child, phandle);
0575 if (node)
0576 return node;
0577 }
0578
0579 return NULL;
0580 }
0581
0582 struct node *get_node_by_ref(struct node *tree, const char *ref)
0583 {
0584 if (streq(ref, "/"))
0585 return tree;
0586 else if (ref[0] == '/')
0587 return get_node_by_path(tree, ref);
0588 else
0589 return get_node_by_label(tree, ref);
0590 }
0591
0592 cell_t get_node_phandle(struct node *root, struct node *node)
0593 {
0594 static cell_t phandle = 1;
0595 struct data d = empty_data;
0596
0597 if (phandle_is_valid(node->phandle))
0598 return node->phandle;
0599
0600 while (get_node_by_phandle(root, phandle))
0601 phandle++;
0602
0603 node->phandle = phandle;
0604
0605 d = data_add_marker(d, TYPE_UINT32, NULL);
0606 d = data_append_cell(d, phandle);
0607
0608 if (!get_property(node, "linux,phandle")
0609 && (phandle_format & PHANDLE_LEGACY))
0610 add_property(node, build_property("linux,phandle", d, NULL));
0611
0612 if (!get_property(node, "phandle")
0613 && (phandle_format & PHANDLE_EPAPR))
0614 add_property(node, build_property("phandle", d, NULL));
0615
0616
0617
0618
0619
0620 return node->phandle;
0621 }
0622
0623 uint32_t guess_boot_cpuid(struct node *tree)
0624 {
0625 struct node *cpus, *bootcpu;
0626 struct property *reg;
0627
0628 cpus = get_node_by_path(tree, "/cpus");
0629 if (!cpus)
0630 return 0;
0631
0632
0633 bootcpu = cpus->children;
0634 if (!bootcpu)
0635 return 0;
0636
0637 reg = get_property(bootcpu, "reg");
0638 if (!reg || (reg->val.len != sizeof(uint32_t)))
0639 return 0;
0640
0641
0642
0643 return propval_cell(reg);
0644 }
0645
0646 static int cmp_reserve_info(const void *ax, const void *bx)
0647 {
0648 const struct reserve_info *a, *b;
0649
0650 a = *((const struct reserve_info * const *)ax);
0651 b = *((const struct reserve_info * const *)bx);
0652
0653 if (a->address < b->address)
0654 return -1;
0655 else if (a->address > b->address)
0656 return 1;
0657 else if (a->size < b->size)
0658 return -1;
0659 else if (a->size > b->size)
0660 return 1;
0661 else
0662 return 0;
0663 }
0664
0665 static void sort_reserve_entries(struct dt_info *dti)
0666 {
0667 struct reserve_info *ri, **tbl;
0668 int n = 0, i = 0;
0669
0670 for (ri = dti->reservelist;
0671 ri;
0672 ri = ri->next)
0673 n++;
0674
0675 if (n == 0)
0676 return;
0677
0678 tbl = xmalloc(n * sizeof(*tbl));
0679
0680 for (ri = dti->reservelist;
0681 ri;
0682 ri = ri->next)
0683 tbl[i++] = ri;
0684
0685 qsort(tbl, n, sizeof(*tbl), cmp_reserve_info);
0686
0687 dti->reservelist = tbl[0];
0688 for (i = 0; i < (n-1); i++)
0689 tbl[i]->next = tbl[i+1];
0690 tbl[n-1]->next = NULL;
0691
0692 free(tbl);
0693 }
0694
0695 static int cmp_prop(const void *ax, const void *bx)
0696 {
0697 const struct property *a, *b;
0698
0699 a = *((const struct property * const *)ax);
0700 b = *((const struct property * const *)bx);
0701
0702 return strcmp(a->name, b->name);
0703 }
0704
0705 static void sort_properties(struct node *node)
0706 {
0707 int n = 0, i = 0;
0708 struct property *prop, **tbl;
0709
0710 for_each_property_withdel(node, prop)
0711 n++;
0712
0713 if (n == 0)
0714 return;
0715
0716 tbl = xmalloc(n * sizeof(*tbl));
0717
0718 for_each_property_withdel(node, prop)
0719 tbl[i++] = prop;
0720
0721 qsort(tbl, n, sizeof(*tbl), cmp_prop);
0722
0723 node->proplist = tbl[0];
0724 for (i = 0; i < (n-1); i++)
0725 tbl[i]->next = tbl[i+1];
0726 tbl[n-1]->next = NULL;
0727
0728 free(tbl);
0729 }
0730
0731 static int cmp_subnode(const void *ax, const void *bx)
0732 {
0733 const struct node *a, *b;
0734
0735 a = *((const struct node * const *)ax);
0736 b = *((const struct node * const *)bx);
0737
0738 return strcmp(a->name, b->name);
0739 }
0740
0741 static void sort_subnodes(struct node *node)
0742 {
0743 int n = 0, i = 0;
0744 struct node *subnode, **tbl;
0745
0746 for_each_child_withdel(node, subnode)
0747 n++;
0748
0749 if (n == 0)
0750 return;
0751
0752 tbl = xmalloc(n * sizeof(*tbl));
0753
0754 for_each_child_withdel(node, subnode)
0755 tbl[i++] = subnode;
0756
0757 qsort(tbl, n, sizeof(*tbl), cmp_subnode);
0758
0759 node->children = tbl[0];
0760 for (i = 0; i < (n-1); i++)
0761 tbl[i]->next_sibling = tbl[i+1];
0762 tbl[n-1]->next_sibling = NULL;
0763
0764 free(tbl);
0765 }
0766
0767 static void sort_node(struct node *node)
0768 {
0769 struct node *c;
0770
0771 sort_properties(node);
0772 sort_subnodes(node);
0773 for_each_child_withdel(node, c)
0774 sort_node(c);
0775 }
0776
0777 void sort_tree(struct dt_info *dti)
0778 {
0779 sort_reserve_entries(dti);
0780 sort_node(dti->dt);
0781 }
0782
0783
0784 static struct node *build_and_name_child_node(struct node *parent, char *name)
0785 {
0786 struct node *node;
0787
0788 node = build_node(NULL, NULL, NULL);
0789 name_node(node, xstrdup(name));
0790 add_child(parent, node);
0791
0792 return node;
0793 }
0794
0795 static struct node *build_root_node(struct node *dt, char *name)
0796 {
0797 struct node *an;
0798
0799 an = get_subnode(dt, name);
0800 if (!an)
0801 an = build_and_name_child_node(dt, name);
0802
0803 if (!an)
0804 die("Could not build root node /%s\n", name);
0805
0806 return an;
0807 }
0808
0809 static bool any_label_tree(struct dt_info *dti, struct node *node)
0810 {
0811 struct node *c;
0812
0813 if (node->labels)
0814 return true;
0815
0816 for_each_child(node, c)
0817 if (any_label_tree(dti, c))
0818 return true;
0819
0820 return false;
0821 }
0822
0823 static void generate_label_tree_internal(struct dt_info *dti,
0824 struct node *an, struct node *node,
0825 bool allocph)
0826 {
0827 struct node *dt = dti->dt;
0828 struct node *c;
0829 struct property *p;
0830 struct label *l;
0831
0832
0833 if (node->labels) {
0834
0835
0836 for_each_label(node->labels, l) {
0837
0838
0839 p = get_property(an, l->label);
0840 if (p) {
0841 fprintf(stderr, "WARNING: label %s already"
0842 " exists in /%s", l->label,
0843 an->name);
0844 continue;
0845 }
0846
0847
0848 p = build_property(l->label,
0849 data_copy_escape_string(node->fullpath,
0850 strlen(node->fullpath)),
0851 NULL);
0852 add_property(an, p);
0853 }
0854
0855
0856 if (allocph)
0857 (void)get_node_phandle(dt, node);
0858 }
0859
0860 for_each_child(node, c)
0861 generate_label_tree_internal(dti, an, c, allocph);
0862 }
0863
0864 static bool any_fixup_tree(struct dt_info *dti, struct node *node)
0865 {
0866 struct node *c;
0867 struct property *prop;
0868 struct marker *m;
0869
0870 for_each_property(node, prop) {
0871 m = prop->val.markers;
0872 for_each_marker_of_type(m, REF_PHANDLE) {
0873 if (!get_node_by_ref(dti->dt, m->ref))
0874 return true;
0875 }
0876 }
0877
0878 for_each_child(node, c) {
0879 if (any_fixup_tree(dti, c))
0880 return true;
0881 }
0882
0883 return false;
0884 }
0885
0886 static void add_fixup_entry(struct dt_info *dti, struct node *fn,
0887 struct node *node, struct property *prop,
0888 struct marker *m)
0889 {
0890 char *entry;
0891
0892
0893 assert(m->type == REF_PHANDLE);
0894
0895
0896 if (strchr(node->fullpath, ':') || strchr(prop->name, ':'))
0897 die("arguments should not contain ':'\n");
0898
0899 xasprintf(&entry, "%s:%s:%u",
0900 node->fullpath, prop->name, m->offset);
0901 append_to_property(fn, m->ref, entry, strlen(entry) + 1, TYPE_STRING);
0902
0903 free(entry);
0904 }
0905
0906 static void generate_fixups_tree_internal(struct dt_info *dti,
0907 struct node *fn,
0908 struct node *node)
0909 {
0910 struct node *dt = dti->dt;
0911 struct node *c;
0912 struct property *prop;
0913 struct marker *m;
0914 struct node *refnode;
0915
0916 for_each_property(node, prop) {
0917 m = prop->val.markers;
0918 for_each_marker_of_type(m, REF_PHANDLE) {
0919 refnode = get_node_by_ref(dt, m->ref);
0920 if (!refnode)
0921 add_fixup_entry(dti, fn, node, prop, m);
0922 }
0923 }
0924
0925 for_each_child(node, c)
0926 generate_fixups_tree_internal(dti, fn, c);
0927 }
0928
0929 static bool any_local_fixup_tree(struct dt_info *dti, struct node *node)
0930 {
0931 struct node *c;
0932 struct property *prop;
0933 struct marker *m;
0934
0935 for_each_property(node, prop) {
0936 m = prop->val.markers;
0937 for_each_marker_of_type(m, REF_PHANDLE) {
0938 if (get_node_by_ref(dti->dt, m->ref))
0939 return true;
0940 }
0941 }
0942
0943 for_each_child(node, c) {
0944 if (any_local_fixup_tree(dti, c))
0945 return true;
0946 }
0947
0948 return false;
0949 }
0950
0951 static void add_local_fixup_entry(struct dt_info *dti,
0952 struct node *lfn, struct node *node,
0953 struct property *prop, struct marker *m,
0954 struct node *refnode)
0955 {
0956 struct node *wn, *nwn;
0957 fdt32_t value_32;
0958 char **compp;
0959 int i, depth;
0960
0961
0962 depth = 0;
0963 for (wn = node; wn; wn = wn->parent)
0964 depth++;
0965
0966
0967 compp = xmalloc(sizeof(*compp) * depth);
0968
0969
0970 for (wn = node, i = depth - 1; wn; wn = wn->parent, i--)
0971 compp[i] = wn->name;
0972
0973
0974 for (wn = lfn, i = 1; i < depth; i++, wn = nwn) {
0975
0976 nwn = get_subnode(wn, compp[i]);
0977 if (!nwn)
0978 nwn = build_and_name_child_node(wn, compp[i]);
0979 }
0980
0981 free(compp);
0982
0983 value_32 = cpu_to_fdt32(m->offset);
0984 append_to_property(wn, prop->name, &value_32, sizeof(value_32), TYPE_UINT32);
0985 }
0986
0987 static void generate_local_fixups_tree_internal(struct dt_info *dti,
0988 struct node *lfn,
0989 struct node *node)
0990 {
0991 struct node *dt = dti->dt;
0992 struct node *c;
0993 struct property *prop;
0994 struct marker *m;
0995 struct node *refnode;
0996
0997 for_each_property(node, prop) {
0998 m = prop->val.markers;
0999 for_each_marker_of_type(m, REF_PHANDLE) {
1000 refnode = get_node_by_ref(dt, m->ref);
1001 if (refnode)
1002 add_local_fixup_entry(dti, lfn, node, prop, m, refnode);
1003 }
1004 }
1005
1006 for_each_child(node, c)
1007 generate_local_fixups_tree_internal(dti, lfn, c);
1008 }
1009
1010 void generate_label_tree(struct dt_info *dti, char *name, bool allocph)
1011 {
1012 if (!any_label_tree(dti, dti->dt))
1013 return;
1014 generate_label_tree_internal(dti, build_root_node(dti->dt, name),
1015 dti->dt, allocph);
1016 }
1017
1018 void generate_fixups_tree(struct dt_info *dti, char *name)
1019 {
1020 if (!any_fixup_tree(dti, dti->dt))
1021 return;
1022 generate_fixups_tree_internal(dti, build_root_node(dti->dt, name),
1023 dti->dt);
1024 }
1025
1026 void generate_local_fixups_tree(struct dt_info *dti, char *name)
1027 {
1028 if (!any_local_fixup_tree(dti, dti->dt))
1029 return;
1030 generate_local_fixups_tree_internal(dti, build_root_node(dti->dt, name),
1031 dti->dt);
1032 }