1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005. 4 */ 5 6 #include "dtc.h" 7 #include "srcpos.h" 8 9 /* 10 * Tree building functions 11 */ 12 13 void add_label(struct label **labels, char *label) 14 { 15 struct label *new; 16 17 /* Make sure the label isn't already there */ 18 for_each_label_withdel(*labels, new) 19 if (streq(new->label, label)) { 20 new->deleted = 0; 21 return; 22 } 23 24 new = xmalloc(sizeof(*new)); 25 memset(new, 0, sizeof(*new)); 26 new->label = label; 27 new->next = *labels; 28 *labels = new; 29 } 30 31 void delete_labels(struct label **labels) 32 { 33 struct label *label; 34 35 for_each_label(*labels, label) 36 label->deleted = 1; 37 } 38 39 struct property *build_property(const char *name, struct data val, 40 struct srcpos *srcpos) 41 { 42 struct property *new = xmalloc(sizeof(*new)); 43 44 memset(new, 0, sizeof(*new)); 45 46 new->name = xstrdup(name); 47 new->val = val; 48 new->srcpos = srcpos_copy(srcpos); 49 50 return new; 51 } 52 53 struct property *build_property_delete(const char *name) 54 { 55 struct property *new = xmalloc(sizeof(*new)); 56 57 memset(new, 0, sizeof(*new)); 58 59 new->name = xstrdup(name); 60 new->deleted = 1; 61 62 return new; 63 } 64 65 struct property *chain_property(struct property *first, struct property *list) 66 { 67 assert(first->next == NULL); 68 69 first->next = list; 70 return first; 71 } 72 73 struct property *reverse_properties(struct property *first) 74 { 75 struct property *p = first; 76 struct property *head = NULL; 77 struct property *next; 78 79 while (p) { 80 next = p->next; 81 p->next = head; 82 head = p; 83 p = next; 84 } 85 return head; 86 } 87 88 struct node *build_node(struct property *proplist, struct node *children, 89 struct srcpos *srcpos) 90 { 91 struct node *new = xmalloc(sizeof(*new)); 92 struct node *child; 93 94 memset(new, 0, sizeof(*new)); 95 96 new->proplist = reverse_properties(proplist); 97 new->children = children; 98 new->srcpos = srcpos_copy(srcpos); 99 100 for_each_child(new, child) { 101 child->parent = new; 102 } 103 104 return new; 105 } 106 107 struct node *build_node_delete(struct srcpos *srcpos) 108 { 109 struct node *new = xmalloc(sizeof(*new)); 110 111 memset(new, 0, sizeof(*new)); 112 113 new->deleted = 1; 114 new->srcpos = srcpos_copy(srcpos); 115 116 return new; 117 } 118 119 struct node *name_node(struct node *node, const char *name) 120 { 121 assert(node->name == NULL); 122 123 node->name = xstrdup(name); 124 125 return node; 126 } 127 128 struct node *omit_node_if_unused(struct node *node) 129 { 130 node->omit_if_unused = 1; 131 132 return node; 133 } 134 135 struct node *reference_node(struct node *node) 136 { 137 node->is_referenced = 1; 138 139 return node; 140 } 141 142 struct node *merge_nodes(struct node *old_node, struct node *new_node) 143 { 144 struct property *new_prop, *old_prop; 145 struct node *new_child, *old_child; 146 struct label *l; 147 148 old_node->deleted = 0; 149 150 /* Add new node labels to old node */ 151 for_each_label_withdel(new_node->labels, l) 152 add_label(&old_node->labels, l->label); 153 154 /* Move properties from the new node to the old node. If there 155 * is a collision, replace the old value with the new */ 156 while (new_node->proplist) { 157 /* Pop the property off the list */ 158 new_prop = new_node->proplist; 159 new_node->proplist = new_prop->next; 160 new_prop->next = NULL; 161 162 if (new_prop->deleted) { 163 delete_property_by_name(old_node, new_prop->name); 164 free(new_prop); 165 continue; 166 } 167 168 /* Look for a collision, set new value if there is */ 169 for_each_property_withdel(old_node, old_prop) { 170 if (streq(old_prop->name, new_prop->name)) { 171 /* Add new labels to old property */ 172 for_each_label_withdel(new_prop->labels, l) 173 add_label(&old_prop->labels, l->label); 174 175 old_prop->val = new_prop->val; 176 old_prop->deleted = 0; 177 srcpos_free(old_prop->srcpos); 178 old_prop->srcpos = new_prop->srcpos; 179 free(new_prop); 180 new_prop = NULL; 181 break; 182 } 183 } 184 185 /* if no collision occurred, add property to the old node. */ 186 if (new_prop) 187 add_property(old_node, new_prop); 188 } 189 190 /* Move the override child nodes into the primary node. If 191 * there is a collision, then merge the nodes. */ 192 while (new_node->children) { 193 /* Pop the child node off the list */ 194 new_child = new_node->children; 195 new_node->children = new_child->next_sibling; 196 new_child->parent = NULL; 197 new_child->next_sibling = NULL; 198 199 if (new_child->deleted) { 200 delete_node_by_name(old_node, new_child->name); 201 free(new_child); 202 continue; 203 } 204 205 /* Search for a collision. Merge if there is */ 206 for_each_child_withdel(old_node, old_child) { 207 if (streq(old_child->name, new_child->name)) { 208 merge_nodes(old_child, new_child); 209 new_child = NULL; 210 break; 211 } 212 } 213 214 /* if no collision occurred, add child to the old node. */ 215 if (new_child) 216 add_child(old_node, new_child); 217 } 218 219 old_node->srcpos = srcpos_extend(old_node->srcpos, new_node->srcpos); 220 221 /* The new node contents are now merged into the old node. Free 222 * the new node. */ 223 free(new_node); 224 225 return old_node; 226 } 227 228 struct node * add_orphan_node(struct node *dt, struct node *new_node, char *ref) 229 { 230 static unsigned int next_orphan_fragment = 0; 231 struct node *node; 232 struct property *p; 233 struct data d = empty_data; 234 char *name; 235 236 if (ref[0] == '/') { 237 d = data_add_marker(d, TYPE_STRING, ref); 238 d = data_append_data(d, ref, strlen(ref) + 1); 239 240 p = build_property("target-path", d, NULL); 241 } else { 242 d = data_add_marker(d, REF_PHANDLE, ref); 243 d = data_append_integer(d, 0xffffffff, 32); 244 245 p = build_property("target", d, NULL); 246 } 247 248 xasprintf(&name, "fragment@%u", 249 next_orphan_fragment++); 250 name_node(new_node, "__overlay__"); 251 node = build_node(p, new_node, NULL); 252 name_node(node, name); 253 free(name); 254 255 add_child(dt, node); 256 return dt; 257 } 258 259 struct node *chain_node(struct node *first, struct node *list) 260 { 261 assert(first->next_sibling == NULL); 262 263 first->next_sibling = list; 264 return first; 265 } 266 267 void add_property(struct node *node, struct property *prop) 268 { 269 struct property **p; 270 271 prop->next = NULL; 272 273 p = &node->proplist; 274 while (*p) 275 p = &((*p)->next); 276 277 *p = prop; 278 } 279 280 void delete_property_by_name(struct node *node, char *name) 281 { 282 struct property *prop = node->proplist; 283 284 while (prop) { 285 if (streq(prop->name, name)) { 286 delete_property(prop); 287 return; 288 } 289 prop = prop->next; 290 } 291 } 292 293 void delete_property(struct property *prop) 294 { 295 prop->deleted = 1; 296 delete_labels(&prop->labels); 297 } 298 299 void add_child(struct node *parent, struct node *child) 300 { 301 struct node **p; 302 303 child->next_sibling = NULL; 304 child->parent = parent; 305 306 p = &parent->children; 307 while (*p) 308 p = &((*p)->next_sibling); 309 310 *p = child; 311 } 312 313 void delete_node_by_name(struct node *parent, char *name) 314 { 315 struct node *node = parent->children; 316 317 while (node) { 318 if (streq(node->name, name)) { 319 delete_node(node); 320 return; 321 } 322 node = node->next_sibling; 323 } 324 } 325 326 void delete_node(struct node *node) 327 { 328 struct property *prop; 329 struct node *child; 330 331 node->deleted = 1; 332 for_each_child(node, child) 333 delete_node(child); 334 for_each_property(node, prop) 335 delete_property(prop); 336 delete_labels(&node->labels); 337 } 338 339 void append_to_property(struct node *node, 340 char *name, const void *data, int len, 341 enum markertype type) 342 { 343 struct property *p; 344 345 p = get_property(node, name); 346 if (!p) { 347 p = build_property(name, empty_data, NULL); 348 add_property(node, p); 349 } 350 351 p->val = data_add_marker(p->val, type, name); 352 p->val = data_append_data(p->val, data, len); 353 } 354 355 static int append_unique_str_to_property(struct node *node, 356 char *name, const char *data, int len) 357 { 358 struct property *p; 359 360 p = get_property(node, name); 361 if (p) { 362 const char *s; 363 364 if (p->val.len && p->val.val[p->val.len - 1] != '\0') 365 /* The current content doesn't look like a string */ 366 return -1; 367 368 for (s = p->val.val; s < p->val.val + p->val.len; s = strchr(s, '\0') + 1) { 369 if (strcmp(data, s) == 0) 370 /* data already contained in node.name */ 371 return 0; 372 } 373 } else { 374 p = build_property(name, empty_data, NULL); 375 add_property(node, p); 376 } 377 378 p->val = data_add_marker(p->val, TYPE_STRING, name); 379 p->val = data_append_data(p->val, data, len); 380 381 return 0; 382 } 383 384 static int append_unique_u32_to_property(struct node *node, char *name, fdt32_t value) 385 { 386 struct property *p; 387 388 p = get_property(node, name); 389 if (p) { 390 const fdt32_t *v, *val_end = (const fdt32_t *)p->val.val + p->val.len / 4; 391 392 if (p->val.len % 4 != 0) 393 /* The current content doesn't look like a u32 array */ 394 return -1; 395 396 for (v = (const void *)p->val.val; v < val_end; v++) { 397 if (*v == value) 398 /* value already contained */ 399 return 0; 400 } 401 } else { 402 p = build_property(name, empty_data, NULL); 403 add_property(node, p); 404 } 405 406 p->val = data_add_marker(p->val, TYPE_UINT32, name); 407 p->val = data_append_data(p->val, &value, 4); 408 409 return 0; 410 } 411 412 struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size) 413 { 414 struct reserve_info *new = xmalloc(sizeof(*new)); 415 416 memset(new, 0, sizeof(*new)); 417 418 new->address = address; 419 new->size = size; 420 421 return new; 422 } 423 424 struct reserve_info *chain_reserve_entry(struct reserve_info *first, 425 struct reserve_info *list) 426 { 427 assert(first->next == NULL); 428 429 first->next = list; 430 return first; 431 } 432 433 struct reserve_info *add_reserve_entry(struct reserve_info *list, 434 struct reserve_info *new) 435 { 436 struct reserve_info *last; 437 438 new->next = NULL; 439 440 if (! list) 441 return new; 442 443 for (last = list; last->next; last = last->next) 444 ; 445 446 last->next = new; 447 448 return list; 449 } 450 451 struct dt_info *build_dt_info(unsigned int dtsflags, 452 struct reserve_info *reservelist, 453 struct node *tree, uint32_t boot_cpuid_phys) 454 { 455 struct dt_info *dti; 456 457 dti = xmalloc(sizeof(*dti)); 458 dti->dtsflags = dtsflags; 459 dti->reservelist = reservelist; 460 dti->dt = tree; 461 dti->boot_cpuid_phys = boot_cpuid_phys; 462 463 return dti; 464 } 465 466 /* 467 * Tree accessor functions 468 */ 469 470 const char *get_unitname(struct node *node) 471 { 472 if (node->name[node->basenamelen] == '\0') 473 return ""; 474 else 475 return node->name + node->basenamelen + 1; 476 } 477 478 struct property *get_property(struct node *node, const char *propname) 479 { 480 struct property *prop; 481 482 for_each_property(node, prop) 483 if (streq(prop->name, propname)) 484 return prop; 485 486 return NULL; 487 } 488 489 cell_t propval_cell(struct property *prop) 490 { 491 assert(prop->val.len == sizeof(cell_t)); 492 return fdt32_to_cpu(*((fdt32_t *)prop->val.val)); 493 } 494 495 cell_t propval_cell_n(struct property *prop, unsigned int n) 496 { 497 assert(prop->val.len / sizeof(cell_t) > n); 498 return fdt32_to_cpu(*((fdt32_t *)prop->val.val + n)); 499 } 500 501 struct property *get_property_by_label(struct node *tree, const char *label, 502 struct node **node) 503 { 504 struct property *prop; 505 struct node *c; 506 507 *node = tree; 508 509 for_each_property(tree, prop) { 510 struct label *l; 511 512 for_each_label(prop->labels, l) 513 if (streq(l->label, label)) 514 return prop; 515 } 516 517 for_each_child(tree, c) { 518 prop = get_property_by_label(c, label, node); 519 if (prop) 520 return prop; 521 } 522 523 *node = NULL; 524 return NULL; 525 } 526 527 struct marker *get_marker_label(struct node *tree, const char *label, 528 struct node **node, struct property **prop) 529 { 530 struct marker *m; 531 struct property *p; 532 struct node *c; 533 534 *node = tree; 535 536 for_each_property(tree, p) { 537 *prop = p; 538 m = p->val.markers; 539 for_each_marker_of_type(m, LABEL) 540 if (streq(m->ref, label)) 541 return m; 542 } 543 544 for_each_child(tree, c) { 545 m = get_marker_label(c, label, node, prop); 546 if (m) 547 return m; 548 } 549 550 *prop = NULL; 551 *node = NULL; 552 return NULL; 553 } 554 555 struct node *get_subnode(struct node *node, const char *nodename) 556 { 557 struct node *child; 558 559 for_each_child(node, child) 560 if (streq(child->name, nodename) && !child->deleted) 561 return child; 562 563 return NULL; 564 } 565 566 struct node *get_node_by_path(struct node *tree, const char *path) 567 { 568 const char *p; 569 struct node *child; 570 571 if (!path || ! (*path)) { 572 if (tree->deleted) 573 return NULL; 574 return tree; 575 } 576 577 while (path[0] == '/') 578 path++; 579 580 p = strchr(path, '/'); 581 582 for_each_child(tree, child) { 583 if (p && strprefixeq(path, (size_t)(p - path), child->name)) 584 return get_node_by_path(child, p+1); 585 else if (!p && streq(path, child->name)) 586 return child; 587 } 588 589 return NULL; 590 } 591 592 struct node *get_node_by_label(struct node *tree, const char *label) 593 { 594 struct node *child, *node; 595 struct label *l; 596 597 assert(label && (strlen(label) > 0)); 598 599 for_each_label(tree->labels, l) 600 if (streq(l->label, label)) 601 return tree; 602 603 for_each_child(tree, child) { 604 node = get_node_by_label(child, label); 605 if (node) 606 return node; 607 } 608 609 return NULL; 610 } 611 612 struct node *get_node_by_phandle(struct node *tree, cell_t phandle) 613 { 614 struct node *child, *node; 615 616 if (!phandle_is_valid(phandle)) { 617 assert(generate_fixups); 618 return NULL; 619 } 620 621 if (tree->phandle == phandle) { 622 if (tree->deleted) 623 return NULL; 624 return tree; 625 } 626 627 for_each_child(tree, child) { 628 node = get_node_by_phandle(child, phandle); 629 if (node) 630 return node; 631 } 632 633 return NULL; 634 } 635 636 struct node *get_node_by_ref(struct node *tree, const char *ref) 637 { 638 struct node *target = tree; 639 const char *label = NULL, *path = NULL; 640 641 if (streq(ref, "/")) 642 return tree; 643 644 if (ref[0] == '/') 645 path = ref; 646 else 647 label = ref; 648 649 if (label) { 650 const char *slash = strchr(label, '/'); 651 char *buf = NULL; 652 653 if (slash) { 654 buf = xstrndup(label, slash - label); 655 label = buf; 656 path = slash + 1; 657 } 658 659 target = get_node_by_label(tree, label); 660 661 free(buf); 662 663 if (!target) 664 return NULL; 665 } 666 667 if (path) 668 target = get_node_by_path(target, path); 669 670 return target; 671 } 672 673 static void add_phandle_property(struct node *node, 674 const char *name, int format) 675 { 676 struct data d; 677 678 if (!(phandle_format & format)) 679 return; 680 if (get_property(node, name)) 681 return; 682 683 d = data_add_marker(empty_data, TYPE_UINT32, NULL); 684 d = data_append_cell(d, node->phandle); 685 686 add_property(node, build_property(name, d, NULL)); 687 } 688 689 cell_t get_node_phandle(struct node *root, struct node *node) 690 { 691 static cell_t phandle = 1; /* FIXME: ick, static local */ 692 693 if (phandle_is_valid(node->phandle)) 694 return node->phandle; 695 696 while (get_node_by_phandle(root, phandle)) 697 phandle++; 698 699 node->phandle = phandle; 700 701 add_phandle_property(node, "linux,phandle", PHANDLE_LEGACY); 702 add_phandle_property(node, "phandle", PHANDLE_EPAPR); 703 704 /* If the node *does* have a phandle property, we must 705 * be dealing with a self-referencing phandle, which will be 706 * fixed up momentarily in the caller */ 707 708 return node->phandle; 709 } 710 711 uint32_t guess_boot_cpuid(struct node *tree) 712 { 713 struct node *cpus, *bootcpu; 714 struct property *reg; 715 716 cpus = get_node_by_path(tree, "/cpus"); 717 if (!cpus) 718 return 0; 719 720 721 bootcpu = cpus->children; 722 if (!bootcpu) 723 return 0; 724 725 reg = get_property(bootcpu, "reg"); 726 if (!reg || (reg->val.len != sizeof(uint32_t))) 727 return 0; 728 729 /* FIXME: Sanity check node? */ 730 731 return propval_cell(reg); 732 } 733 734 static int cmp_reserve_info(const void *ax, const void *bx) 735 { 736 const struct reserve_info *a, *b; 737 738 a = *((const struct reserve_info * const *)ax); 739 b = *((const struct reserve_info * const *)bx); 740 741 if (a->address < b->address) 742 return -1; 743 else if (a->address > b->address) 744 return 1; 745 else if (a->size < b->size) 746 return -1; 747 else if (a->size > b->size) 748 return 1; 749 else 750 return 0; 751 } 752 753 static void sort_reserve_entries(struct dt_info *dti) 754 { 755 struct reserve_info *ri, **tbl; 756 int n = 0, i = 0; 757 758 for (ri = dti->reservelist; 759 ri; 760 ri = ri->next) 761 n++; 762 763 if (n == 0) 764 return; 765 766 tbl = xmalloc(n * sizeof(*tbl)); 767 768 for (ri = dti->reservelist; 769 ri; 770 ri = ri->next) 771 tbl[i++] = ri; 772 773 qsort(tbl, n, sizeof(*tbl), cmp_reserve_info); 774 775 dti->reservelist = tbl[0]; 776 for (i = 0; i < (n-1); i++) 777 tbl[i]->next = tbl[i+1]; 778 tbl[n-1]->next = NULL; 779 780 free(tbl); 781 } 782 783 static int cmp_prop(const void *ax, const void *bx) 784 { 785 const struct property *a, *b; 786 787 a = *((const struct property * const *)ax); 788 b = *((const struct property * const *)bx); 789 790 return strcmp(a->name, b->name); 791 } 792 793 static void sort_properties(struct node *node) 794 { 795 int n = 0, i = 0; 796 struct property *prop, **tbl; 797 798 for_each_property_withdel(node, prop) 799 n++; 800 801 if (n == 0) 802 return; 803 804 tbl = xmalloc(n * sizeof(*tbl)); 805 806 for_each_property_withdel(node, prop) 807 tbl[i++] = prop; 808 809 qsort(tbl, n, sizeof(*tbl), cmp_prop); 810 811 node->proplist = tbl[0]; 812 for (i = 0; i < (n-1); i++) 813 tbl[i]->next = tbl[i+1]; 814 tbl[n-1]->next = NULL; 815 816 free(tbl); 817 } 818 819 static int cmp_subnode(const void *ax, const void *bx) 820 { 821 const struct node *a, *b; 822 823 a = *((const struct node * const *)ax); 824 b = *((const struct node * const *)bx); 825 826 return strcmp(a->name, b->name); 827 } 828 829 static void sort_subnodes(struct node *node) 830 { 831 int n = 0, i = 0; 832 struct node *subnode, **tbl; 833 834 for_each_child_withdel(node, subnode) 835 n++; 836 837 if (n == 0) 838 return; 839 840 tbl = xmalloc(n * sizeof(*tbl)); 841 842 for_each_child_withdel(node, subnode) 843 tbl[i++] = subnode; 844 845 qsort(tbl, n, sizeof(*tbl), cmp_subnode); 846 847 node->children = tbl[0]; 848 for (i = 0; i < (n-1); i++) 849 tbl[i]->next_sibling = tbl[i+1]; 850 tbl[n-1]->next_sibling = NULL; 851 852 free(tbl); 853 } 854 855 static void sort_node(struct node *node) 856 { 857 struct node *c; 858 859 sort_properties(node); 860 sort_subnodes(node); 861 for_each_child_withdel(node, c) 862 sort_node(c); 863 } 864 865 void sort_tree(struct dt_info *dti) 866 { 867 sort_reserve_entries(dti); 868 sort_node(dti->dt); 869 } 870 871 /* utility helper to avoid code duplication */ 872 static struct node *build_and_name_child_node(struct node *parent, const char *name) 873 { 874 struct node *node; 875 876 node = build_node(NULL, NULL, NULL); 877 name_node(node, name); 878 add_child(parent, node); 879 880 return node; 881 } 882 883 static struct node *build_root_node(struct node *dt, const char *name) 884 { 885 struct node *an; 886 887 an = get_subnode(dt, name); 888 if (!an) 889 an = build_and_name_child_node(dt, name); 890 891 if (!an) 892 die("Could not build root node /%s\n", name); 893 894 return an; 895 } 896 897 static bool any_label_tree(struct dt_info *dti, struct node *node) 898 { 899 struct node *c; 900 901 if (node->labels) 902 return true; 903 904 for_each_child(node, c) 905 if (any_label_tree(dti, c)) 906 return true; 907 908 return false; 909 } 910 911 static void generate_label_tree_internal(struct dt_info *dti, 912 struct node *an, struct node *node, 913 bool allocph) 914 { 915 struct node *dt = dti->dt; 916 struct node *c; 917 struct property *p; 918 struct label *l; 919 920 /* if there are labels */ 921 if (node->labels) { 922 923 /* now add the label in the node */ 924 for_each_label(node->labels, l) { 925 926 /* check whether the label already exists */ 927 p = get_property(an, l->label); 928 if (p) { 929 fprintf(stderr, "WARNING: label %s already" 930 " exists in /%s", l->label, 931 an->name); 932 continue; 933 } 934 935 /* insert it */ 936 p = build_property(l->label, 937 data_copy_escape_string(node->fullpath, 938 strlen(node->fullpath)), 939 NULL); 940 add_property(an, p); 941 } 942 943 /* force allocation of a phandle for this node */ 944 if (allocph) 945 (void)get_node_phandle(dt, node); 946 } 947 948 for_each_child(node, c) 949 generate_label_tree_internal(dti, an, c, allocph); 950 } 951 952 static bool any_fixup_tree(struct dt_info *dti, struct node *node) 953 { 954 struct node *c; 955 struct property *prop; 956 struct marker *m; 957 958 for_each_property(node, prop) { 959 m = prop->val.markers; 960 for_each_marker_of_type(m, REF_PHANDLE) { 961 if (!get_node_by_ref(dti->dt, m->ref)) 962 return true; 963 } 964 } 965 966 for_each_child(node, c) { 967 if (any_fixup_tree(dti, c)) 968 return true; 969 } 970 971 return false; 972 } 973 974 static int add_fixup_entry(struct dt_info *dti, struct node *fn, 975 struct node *node, struct property *prop, 976 struct marker *m) 977 { 978 char *entry; 979 int ret; 980 981 /* m->ref can only be a REF_PHANDLE, but check anyway */ 982 assert(m->type == REF_PHANDLE); 983 984 /* The format only permits fixups for references to label, not 985 * references to path */ 986 if (strchr(m->ref, '/')) 987 die("Can't generate fixup for reference to path &{%s}\n", 988 m->ref); 989 990 /* there shouldn't be any ':' in the arguments */ 991 if (strchr(node->fullpath, ':') || strchr(prop->name, ':')) 992 die("arguments should not contain ':'\n"); 993 994 xasprintf(&entry, "%s:%s:%u", 995 node->fullpath, prop->name, m->offset); 996 ret = append_unique_str_to_property(fn, m->ref, entry, strlen(entry) + 1); 997 998 free(entry); 999 1000 return ret; 1001 } 1002 1003 static int generate_fixups_tree_internal(struct dt_info *dti, 1004 struct node *fn, 1005 struct node *node) 1006 { 1007 struct node *dt = dti->dt; 1008 struct node *c; 1009 struct property *prop; 1010 struct marker *m; 1011 struct node *refnode; 1012 int ret = 0; 1013 1014 for_each_property(node, prop) { 1015 m = prop->val.markers; 1016 for_each_marker_of_type(m, REF_PHANDLE) { 1017 refnode = get_node_by_ref(dt, m->ref); 1018 if (!refnode) 1019 if (add_fixup_entry(dti, fn, node, prop, m)) 1020 ret = -1; 1021 } 1022 } 1023 1024 for_each_child(node, c) 1025 if (generate_fixups_tree_internal(dti, fn, c)) 1026 ret = -1; 1027 1028 return ret; 1029 } 1030 1031 static bool any_local_fixup_tree(struct dt_info *dti, struct node *node) 1032 { 1033 struct node *c; 1034 struct property *prop; 1035 struct marker *m; 1036 1037 for_each_property(node, prop) { 1038 m = prop->val.markers; 1039 for_each_marker_of_type(m, REF_PHANDLE) { 1040 if (get_node_by_ref(dti->dt, m->ref)) 1041 return true; 1042 } 1043 } 1044 1045 for_each_child(node, c) { 1046 if (any_local_fixup_tree(dti, c)) 1047 return true; 1048 } 1049 1050 return false; 1051 } 1052 1053 static int add_local_fixup_entry(struct dt_info *dti, 1054 struct node *lfn, struct node *node, 1055 struct property *prop, struct marker *m, 1056 struct node *refnode) 1057 { 1058 struct node *wn, *nwn; /* local fixup node, walk node, new */ 1059 fdt32_t value_32; 1060 char **compp; 1061 int i, depth; 1062 1063 /* walk back retrieving depth */ 1064 depth = 0; 1065 for (wn = node; wn; wn = wn->parent) 1066 depth++; 1067 1068 /* allocate name array */ 1069 compp = xmalloc(sizeof(*compp) * depth); 1070 1071 /* store names in the array */ 1072 for (wn = node, i = depth - 1; wn; wn = wn->parent, i--) 1073 compp[i] = wn->name; 1074 1075 /* walk the path components creating nodes if they don't exist */ 1076 for (wn = lfn, i = 1; i < depth; i++, wn = nwn) { 1077 /* if no node exists, create it */ 1078 nwn = build_root_node(wn, compp[i]); 1079 } 1080 1081 free(compp); 1082 1083 value_32 = cpu_to_fdt32(m->offset); 1084 return append_unique_u32_to_property(wn, prop->name, value_32); 1085 } 1086 1087 static int generate_local_fixups_tree_internal(struct dt_info *dti, 1088 struct node *lfn, 1089 struct node *node) 1090 { 1091 struct node *dt = dti->dt; 1092 struct node *c; 1093 struct property *prop; 1094 struct marker *m; 1095 struct node *refnode; 1096 int ret = 0; 1097 1098 for_each_property(node, prop) { 1099 m = prop->val.markers; 1100 for_each_marker_of_type(m, REF_PHANDLE) { 1101 refnode = get_node_by_ref(dt, m->ref); 1102 if (refnode) 1103 if (add_local_fixup_entry(dti, lfn, node, prop, m, refnode)) 1104 ret = -1; 1105 } 1106 } 1107 1108 for_each_child(node, c) 1109 if (generate_local_fixups_tree_internal(dti, lfn, c)) 1110 ret = -1; 1111 1112 return ret; 1113 } 1114 1115 void generate_labels_from_tree(struct dt_info *dti, const char *name) 1116 { 1117 struct node *an; 1118 struct property *p; 1119 1120 an = get_subnode(dti->dt, name); 1121 if (!an) 1122 return; 1123 1124 for_each_property(an, p) { 1125 struct node *labeled_node; 1126 1127 labeled_node = get_node_by_path(dti->dt, p->val.val); 1128 if (labeled_node) 1129 add_label(&labeled_node->labels, p->name); 1130 else if (quiet < 1) 1131 fprintf(stderr, "Warning: Path %s referenced in property %s/%s missing", 1132 p->val.val, name, p->name); 1133 } 1134 } 1135 1136 void generate_label_tree(struct dt_info *dti, const char *name, bool allocph) 1137 { 1138 if (!any_label_tree(dti, dti->dt)) 1139 return; 1140 generate_label_tree_internal(dti, build_root_node(dti->dt, name), 1141 dti->dt, allocph); 1142 } 1143 1144 void generate_fixups_tree(struct dt_info *dti, const char *name) 1145 { 1146 if (!any_fixup_tree(dti, dti->dt)) 1147 return; 1148 if (generate_fixups_tree_internal(dti, build_root_node(dti->dt, name), dti->dt)) 1149 fprintf(stderr, 1150 "Warning: Preexisting data in %s malformed, some content could not be added.\n", 1151 name); 1152 } 1153 1154 void fixup_phandles(struct dt_info *dti, const char *name) 1155 { 1156 struct node *an; 1157 struct property *fp; 1158 1159 an = get_subnode(dti->dt, name); 1160 if (!an) 1161 return; 1162 1163 for_each_property(an, fp) { 1164 char *fnext = fp->val.val; 1165 char *fv; 1166 unsigned int fl; 1167 1168 while ((fl = fp->val.len - (fnext - fp->val.val))) { 1169 char *propname, *soffset; 1170 struct node *n; 1171 struct property *p; 1172 long offset; 1173 1174 fv = fnext; 1175 fnext = memchr(fv, 0, fl); 1176 1177 if (!fnext) { 1178 if (quiet < 1) 1179 fprintf(stderr, "Warning: Malformed fixup entry for label %s\n", 1180 fp->name); 1181 break; 1182 } 1183 fnext += 1; 1184 1185 propname = memchr(fv, ':', fnext - 1 - fv); 1186 if (!propname) { 1187 if (quiet < 1) 1188 fprintf(stderr, "Warning: Malformed fixup entry for label %s\n", 1189 fp->name); 1190 continue; 1191 } 1192 propname++; 1193 1194 soffset = memchr(propname, ':', fnext - 1 - propname); 1195 if (!soffset) { 1196 if (quiet < 1) 1197 fprintf(stderr, "Warning: Malformed fixup entry for label %s\n", 1198 fp->name); 1199 continue; 1200 } 1201 soffset++; 1202 1203 /* 1204 * temporarily modify the property to not have to create 1205 * a copy for the node path. 1206 */ 1207 *(propname - 1) = '\0'; 1208 1209 n = get_node_by_path(dti->dt, fv); 1210 if (!n && quiet < 1) 1211 fprintf(stderr, "Warning: Label %s references non-existing node %s\n", 1212 fp->name, fv); 1213 1214 *(propname - 1) = ':'; 1215 1216 if (!n) 1217 continue; 1218 1219 /* 1220 * temporarily modify the property to not have to create 1221 * a copy for the property name. 1222 */ 1223 *(soffset - 1) = '\0'; 1224 1225 p = get_property(n, propname); 1226 1227 if (!p && quiet < 1) 1228 fprintf(stderr, "Warning: Label %s references non-existing property %s in node %s\n", 1229 fp->name, n->fullpath, propname); 1230 1231 *(soffset - 1) = ':'; 1232 1233 if (!p) 1234 continue; 1235 1236 offset = strtol(soffset, NULL, 0); 1237 if (offset < 0 || offset + 4 > p->val.len) { 1238 if (quiet < 1) 1239 fprintf(stderr, 1240 "Warning: Label %s contains invalid offset for property %s in node %s\n", 1241 fp->name, p->name, n->fullpath); 1242 continue; 1243 } 1244 1245 property_add_marker(p, REF_PHANDLE, offset, fp->name); 1246 } 1247 } 1248 } 1249 1250 void generate_local_fixups_tree(struct dt_info *dti, const char *name) 1251 { 1252 if (!any_local_fixup_tree(dti, dti->dt)) 1253 return; 1254 if (generate_local_fixups_tree_internal(dti, build_root_node(dti->dt, name), dti->dt)) 1255 fprintf(stderr, 1256 "Warning: Preexisting data in %s malformed, some content could not be added.\n", 1257 name); 1258 } 1259 1260 static void local_fixup_phandles_node(struct dt_info *dti, struct node *lf, struct node *n) 1261 { 1262 struct property *lfp; 1263 struct node *lfsubnode; 1264 1265 for_each_property(lf, lfp) { 1266 struct property *p = get_property(n, lfp->name); 1267 fdt32_t *offsets = (fdt32_t *)lfp->val.val; 1268 size_t i; 1269 1270 if (!p) { 1271 if (quiet < 1) 1272 fprintf(stderr, "Warning: Property %s in %s referenced in __local_fixups__ missing\n", 1273 lfp->name, n->fullpath); 1274 continue; 1275 } 1276 1277 /* 1278 * Each property in the __local_fixups__ tree is a concatenation 1279 * of offsets, so it must be a multiple of sizeof(fdt32_t). 1280 */ 1281 if (lfp->val.len % sizeof(fdt32_t)) { 1282 if (quiet < 1) 1283 fprintf(stderr, "Warning: property %s in /__local_fixups__%s malformed\n", 1284 lfp->name, n->fullpath); 1285 continue; 1286 } 1287 1288 for (i = 0; i < lfp->val.len / sizeof(fdt32_t); i++) 1289 add_phandle_marker(dti, p, dtb_ld32(offsets + i)); 1290 } 1291 1292 for_each_child(lf, lfsubnode) { 1293 struct node *subnode = get_subnode(n, lfsubnode->name); 1294 1295 if (!subnode) { 1296 if (quiet < 1) 1297 fprintf(stderr, "Warning: node %s/%s referenced in __local_fixups__ missing\n", 1298 lfsubnode->name, n->fullpath); 1299 continue; 1300 } 1301 1302 local_fixup_phandles_node(dti, lfsubnode, subnode); 1303 } 1304 } 1305 1306 void local_fixup_phandles(struct dt_info *dti, const char *name) 1307 { 1308 struct node *an; 1309 1310 an = get_subnode(dti->dt, name); 1311 if (!an) 1312 return; 1313 1314 local_fixup_phandles_node(dti, an, dti->dt); 1315 } 1316