summaryrefslogtreecommitdiffstats
path: root/scripts/dtc/livetree.c
diff options
context:
space:
mode:
authorRob Herring <robh@kernel.org>2017-01-04 11:45:20 -0500
committerRob Herring <robh@kernel.org>2017-01-04 11:47:53 -0500
commit6f05afcbb031722ec1eff77dde188ff2edf8940e (patch)
tree495052132dcba998f88e38d128d9781adfdc9272 /scripts/dtc/livetree.c
parent0c744ea4f77d72b3dcebb7a8f2684633ec79be88 (diff)
scripts/dtc: Update to upstream version 0931cea3ba20
Sync to upstream dtc commit 0931cea3ba20 ("dtc: fdtdump: check fdt if not in scanning mode"). In particular, this pulls in dtc overlay support. This adds the following commits from upstream: f88865469b65 dtc: Fix memory leak in character literal parsing 00fbb8696b66 Rename boot_info 1ef86ad2c24f dtc: Clean up /dts-v1/ and /plugin/ handling in grammar e3c769aa9c16 dtc: Don't always generate __symbols__ for plugins c96cb3c0169e tests: Don't use -@ on plugin de/recompile tests 66381538ce24 tests: Remove "suppression of fixups" tests ba765b273f0f tests: Clarify dtc overlay tests 6ea8cd944fcd tests: More thorough tests of libfdt overlay application without dtc 7d8ef6e1db97 tests: Correct fdt handling of overlays without fixups and base trees without symbols b4dc0ed8b127 tests: Fix double expansion bugs in test code 3ea879dc0c8f tests: Split overlay tests into those with do/don't exercise dtc plugin generation 47b4d66a2f11 tests: Test auto-alias generation on base tree, not overlay 72e1ad811523 tests: Make overlay/plugin tests unconditional e7b3c3b5951b tests: Add overlay tests 9637e3f772a9 tests: Add check_path test 20f29d8d41f6 dtc: Plugin and fixup support a2c92cac53f8 dtc: Document the dynamic plugin internals 8f70ac39801d checks: Pass boot_info instead of root node ea10f953878f libfdt: add missing errors to fdt_strerror() daa75e8fa594 libfdt: fix fdt_stringlist_search() e28eff5b787a libfdt: fix fdt_stringlist_count() ae97c7722840 tests: overlay: Rename the device tree blobs to be more explicit 96162d2bd9cb tests: overlay: Add test suffix to the compiled blobs 5ce8634733b7 libfdt: Add fdt_overlay_apply to the exported symbols 804a9db90ad2 fdt: strerr: Remove spurious BADOVERLAY e8c3a1a493fa tests: overlay: Move back the bad fixup tests 7a72d89d3f81 libfdt: overlay: Fix symbols and fixups nodes condition cabbaa972cdd libfdt: overlay: Report a bad overlay for mismatching local fixups deb0a5c1aeaa libfdt: Add BADPHANDLE error string 7b7a6be9ba15 libfdt: Don't use 'index' as a local variable name aea8860d831e tests: Add tests cases for the overlay code 0cdd06c5135b libfdt: Add overlay application function 39240cc865cf libfdt: Extend the reach of FDT_ERR_BADPHANDLE 4aa3a6f5e6d9 libfdt: Add new errors for the overlay code 6d1832c9e64b dtc: Remove "home page" link 45fd440a9561 Fix some typing errors in libfdt.h and livetree.c a59be4939c13 Merge tag 'v1.4.2' a34bb721caca dtc: Fix assorted problems in the testcases for the -a option 874f40588d3e Implement the -a option to pad dtb aligned ec02b34c05be dtc: Makefile improvements for release uploading 1ed45d40a137 dtc: Bump version to 1.4.2 36fd7331fb11 libfdt: simplify fdt_del_mem_rsv() d877364e4a0f libfdt: Add fdt_setprop_inplace_namelen_partial 3e9037aaad44 libfdt: Add fdt_getprop_namelen_w 84e0e1346c68 libfdt: Add max phandle retrieval function d29126c90acb libfdt: Add iterator over properties 902d0f0953d0 libfdt: Add a subnodes iterator macro c539075ba8ba fdtput.c: Fix memory leak. f79ddb83e185 fdtget.c: Fix memory leak 1074ee54b63f convert-dtsv0-lexer.l: fix memory leak e24d39a024e6 fdtdump.c: make sure size_t argument to memchr is always unsigned. 44a59713cf05 Remove unused srcpos_dump() function cb9241ae3453 DTC: Fix memory leak on flatname. 1ee0ae24ea09 Simplify check field and macro names 9d97527a8621 Remove property check functions 2e709d158e11 Remove tree check functions c4cb12e193e3 Alter grammar to allow multiple /dts-v1/ tags d71d25d76012 Use xasprintf() in srcpos 9dc404958e9c util: Add xasprintf portable asprintf variant beef80b8b55f Correct a missing space in a fdt_header cast 68d43cec1253 Correct line lengths in libfdt.h b0dbceafd49a Correct space-after-tab in libfdt.h Signed-off-by: Rob Herring <robh@kernel.org>
Diffstat (limited to 'scripts/dtc/livetree.c')
-rw-r--r--scripts/dtc/livetree.c299
1 files changed, 283 insertions, 16 deletions
diff --git a/scripts/dtc/livetree.c b/scripts/dtc/livetree.c
index e229b84432f9..afa2f67b142a 100644
--- a/scripts/dtc/livetree.c
+++ b/scripts/dtc/livetree.c
@@ -204,7 +204,7 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
204 } 204 }
205 } 205 }
206 206
207 /* if no collision occured, add child to the old node. */ 207 /* if no collision occurred, add child to the old node. */
208 if (new_child) 208 if (new_child)
209 add_child(old_node, new_child); 209 add_child(old_node, new_child);
210 } 210 }
@@ -296,6 +296,23 @@ void delete_node(struct node *node)
296 delete_labels(&node->labels); 296 delete_labels(&node->labels);
297} 297}
298 298
299void append_to_property(struct node *node,
300 char *name, const void *data, int len)
301{
302 struct data d;
303 struct property *p;
304
305 p = get_property(node, name);
306 if (p) {
307 d = data_append_data(p->val, data, len);
308 p->val = d;
309 } else {
310 d = data_append_data(empty_data, data, len);
311 p = build_property(name, d);
312 add_property(node, p);
313 }
314}
315
299struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size) 316struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size)
300{ 317{
301 struct reserve_info *new = xmalloc(sizeof(*new)); 318 struct reserve_info *new = xmalloc(sizeof(*new));
@@ -335,17 +352,19 @@ struct reserve_info *add_reserve_entry(struct reserve_info *list,
335 return list; 352 return list;
336} 353}
337 354
338struct boot_info *build_boot_info(struct reserve_info *reservelist, 355struct dt_info *build_dt_info(unsigned int dtsflags,
339 struct node *tree, uint32_t boot_cpuid_phys) 356 struct reserve_info *reservelist,
357 struct node *tree, uint32_t boot_cpuid_phys)
340{ 358{
341 struct boot_info *bi; 359 struct dt_info *dti;
342 360
343 bi = xmalloc(sizeof(*bi)); 361 dti = xmalloc(sizeof(*dti));
344 bi->reservelist = reservelist; 362 dti->dtsflags = dtsflags;
345 bi->dt = tree; 363 dti->reservelist = reservelist;
346 bi->boot_cpuid_phys = boot_cpuid_phys; 364 dti->dt = tree;
365 dti->boot_cpuid_phys = boot_cpuid_phys;
347 366
348 return bi; 367 return dti;
349} 368}
350 369
351/* 370/*
@@ -592,12 +611,12 @@ static int cmp_reserve_info(const void *ax, const void *bx)
592 return 0; 611 return 0;
593} 612}
594 613
595static void sort_reserve_entries(struct boot_info *bi) 614static void sort_reserve_entries(struct dt_info *dti)
596{ 615{
597 struct reserve_info *ri, **tbl; 616 struct reserve_info *ri, **tbl;
598 int n = 0, i = 0; 617 int n = 0, i = 0;
599 618
600 for (ri = bi->reservelist; 619 for (ri = dti->reservelist;
601 ri; 620 ri;
602 ri = ri->next) 621 ri = ri->next)
603 n++; 622 n++;
@@ -607,14 +626,14 @@ static void sort_reserve_entries(struct boot_info *bi)
607 626
608 tbl = xmalloc(n * sizeof(*tbl)); 627 tbl = xmalloc(n * sizeof(*tbl));
609 628
610 for (ri = bi->reservelist; 629 for (ri = dti->reservelist;
611 ri; 630 ri;
612 ri = ri->next) 631 ri = ri->next)
613 tbl[i++] = ri; 632 tbl[i++] = ri;
614 633
615 qsort(tbl, n, sizeof(*tbl), cmp_reserve_info); 634 qsort(tbl, n, sizeof(*tbl), cmp_reserve_info);
616 635
617 bi->reservelist = tbl[0]; 636 dti->reservelist = tbl[0];
618 for (i = 0; i < (n-1); i++) 637 for (i = 0; i < (n-1); i++)
619 tbl[i]->next = tbl[i+1]; 638 tbl[i]->next = tbl[i+1];
620 tbl[n-1]->next = NULL; 639 tbl[n-1]->next = NULL;
@@ -704,8 +723,256 @@ static void sort_node(struct node *node)
704 sort_node(c); 723 sort_node(c);
705} 724}
706 725
707void sort_tree(struct boot_info *bi) 726void sort_tree(struct dt_info *dti)
727{
728 sort_reserve_entries(dti);
729 sort_node(dti->dt);
730}
731
732/* utility helper to avoid code duplication */
733static struct node *build_and_name_child_node(struct node *parent, char *name)
734{
735 struct node *node;
736
737 node = build_node(NULL, NULL);
738 name_node(node, xstrdup(name));
739 add_child(parent, node);
740
741 return node;
742}
743
744static struct node *build_root_node(struct node *dt, char *name)
745{
746 struct node *an;
747
748 an = get_subnode(dt, name);
749 if (!an)
750 an = build_and_name_child_node(dt, name);
751
752 if (!an)
753 die("Could not build root node /%s\n", name);
754
755 return an;
756}
757
758static bool any_label_tree(struct dt_info *dti, struct node *node)
759{
760 struct node *c;
761
762 if (node->labels)
763 return true;
764
765 for_each_child(node, c)
766 if (any_label_tree(dti, c))
767 return true;
768
769 return false;
770}
771
772static void generate_label_tree_internal(struct dt_info *dti,
773 struct node *an, struct node *node,
774 bool allocph)
775{
776 struct node *dt = dti->dt;
777 struct node *c;
778 struct property *p;
779 struct label *l;
780
781 /* if there are labels */
782 if (node->labels) {
783
784 /* now add the label in the node */
785 for_each_label(node->labels, l) {
786
787 /* check whether the label already exists */
788 p = get_property(an, l->label);
789 if (p) {
790 fprintf(stderr, "WARNING: label %s already"
791 " exists in /%s", l->label,
792 an->name);
793 continue;
794 }
795
796 /* insert it */
797 p = build_property(l->label,
798 data_copy_mem(node->fullpath,
799 strlen(node->fullpath) + 1));
800 add_property(an, p);
801 }
802
803 /* force allocation of a phandle for this node */
804 if (allocph)
805 (void)get_node_phandle(dt, node);
806 }
807
808 for_each_child(node, c)
809 generate_label_tree_internal(dti, an, c, allocph);
810}
811
812static bool any_fixup_tree(struct dt_info *dti, struct node *node)
813{
814 struct node *c;
815 struct property *prop;
816 struct marker *m;
817
818 for_each_property(node, prop) {
819 m = prop->val.markers;
820 for_each_marker_of_type(m, REF_PHANDLE) {
821 if (!get_node_by_ref(dti->dt, m->ref))
822 return true;
823 }
824 }
825
826 for_each_child(node, c) {
827 if (any_fixup_tree(dti, c))
828 return true;
829 }
830
831 return false;
832}
833
834static void add_fixup_entry(struct dt_info *dti, struct node *fn,
835 struct node *node, struct property *prop,
836 struct marker *m)
708{ 837{
709 sort_reserve_entries(bi); 838 char *entry;
710 sort_node(bi->dt); 839
840 /* m->ref can only be a REF_PHANDLE, but check anyway */
841 assert(m->type == REF_PHANDLE);
842
843 /* there shouldn't be any ':' in the arguments */
844 if (strchr(node->fullpath, ':') || strchr(prop->name, ':'))
845 die("arguments should not contain ':'\n");
846
847 xasprintf(&entry, "%s:%s:%u",
848 node->fullpath, prop->name, m->offset);
849 append_to_property(fn, m->ref, entry, strlen(entry) + 1);
850}
851
852static void generate_fixups_tree_internal(struct dt_info *dti,
853 struct node *fn,
854 struct node *node)
855{
856 struct node *dt = dti->dt;
857 struct node *c;
858 struct property *prop;
859 struct marker *m;
860 struct node *refnode;
861
862 for_each_property(node, prop) {
863 m = prop->val.markers;
864 for_each_marker_of_type(m, REF_PHANDLE) {
865 refnode = get_node_by_ref(dt, m->ref);
866 if (!refnode)
867 add_fixup_entry(dti, fn, node, prop, m);
868 }
869 }
870
871 for_each_child(node, c)
872 generate_fixups_tree_internal(dti, fn, c);
873}
874
875static bool any_local_fixup_tree(struct dt_info *dti, struct node *node)
876{
877 struct node *c;
878 struct property *prop;
879 struct marker *m;
880
881 for_each_property(node, prop) {
882 m = prop->val.markers;
883 for_each_marker_of_type(m, REF_PHANDLE) {
884 if (get_node_by_ref(dti->dt, m->ref))
885 return true;
886 }
887 }
888
889 for_each_child(node, c) {
890 if (any_local_fixup_tree(dti, c))
891 return true;
892 }
893
894 return false;
895}
896
897static void add_local_fixup_entry(struct dt_info *dti,
898 struct node *lfn, struct node *node,
899 struct property *prop, struct marker *m,
900 struct node *refnode)
901{
902 struct node *wn, *nwn; /* local fixup node, walk node, new */
903 uint32_t value_32;
904 char **compp;
905 int i, depth;
906
907 /* walk back retreiving depth */
908 depth = 0;
909 for (wn = node; wn; wn = wn->parent)
910 depth++;
911
912 /* allocate name array */
913 compp = xmalloc(sizeof(*compp) * depth);
914
915 /* store names in the array */
916 for (wn = node, i = depth - 1; wn; wn = wn->parent, i--)
917 compp[i] = wn->name;
918
919 /* walk the path components creating nodes if they don't exist */
920 for (wn = lfn, i = 1; i < depth; i++, wn = nwn) {
921 /* if no node exists, create it */
922 nwn = get_subnode(wn, compp[i]);
923 if (!nwn)
924 nwn = build_and_name_child_node(wn, compp[i]);
925 }
926
927 free(compp);
928
929 value_32 = cpu_to_fdt32(m->offset);
930 append_to_property(wn, prop->name, &value_32, sizeof(value_32));
931}
932
933static void generate_local_fixups_tree_internal(struct dt_info *dti,
934 struct node *lfn,
935 struct node *node)
936{
937 struct node *dt = dti->dt;
938 struct node *c;
939 struct property *prop;
940 struct marker *m;
941 struct node *refnode;
942
943 for_each_property(node, prop) {
944 m = prop->val.markers;
945 for_each_marker_of_type(m, REF_PHANDLE) {
946 refnode = get_node_by_ref(dt, m->ref);
947 if (refnode)
948 add_local_fixup_entry(dti, lfn, node, prop, m, refnode);
949 }
950 }
951
952 for_each_child(node, c)
953 generate_local_fixups_tree_internal(dti, lfn, c);
954}
955
956void generate_label_tree(struct dt_info *dti, char *name, bool allocph)
957{
958 if (!any_label_tree(dti, dti->dt))
959 return;
960 generate_label_tree_internal(dti, build_root_node(dti->dt, name),
961 dti->dt, allocph);
962}
963
964void generate_fixups_tree(struct dt_info *dti, char *name)
965{
966 if (!any_fixup_tree(dti, dti->dt))
967 return;
968 generate_fixups_tree_internal(dti, build_root_node(dti->dt, name),
969 dti->dt);
970}
971
972void generate_local_fixups_tree(struct dt_info *dti, char *name)
973{
974 if (!any_local_fixup_tree(dti, dti->dt))
975 return;
976 generate_local_fixups_tree_internal(dti, build_root_node(dti->dt, name),
977 dti->dt);
711} 978}