diff options
author | Rob Herring <robh@kernel.org> | 2017-01-04 11:45:20 -0500 |
---|---|---|
committer | Rob Herring <robh@kernel.org> | 2017-01-04 11:47:53 -0500 |
commit | 6f05afcbb031722ec1eff77dde188ff2edf8940e (patch) | |
tree | 495052132dcba998f88e38d128d9781adfdc9272 /scripts/dtc/livetree.c | |
parent | 0c744ea4f77d72b3dcebb7a8f2684633ec79be88 (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.c | 299 |
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 | ||
299 | void 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 | |||
299 | struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size) | 316 | struct 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 | ||
338 | struct boot_info *build_boot_info(struct reserve_info *reservelist, | 355 | struct 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 | ||
595 | static void sort_reserve_entries(struct boot_info *bi) | 614 | static 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 | ||
707 | void sort_tree(struct boot_info *bi) | 726 | void 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 */ | ||
733 | static 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 | |||
744 | static 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 | |||
758 | static 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 | |||
772 | static 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 | |||
812 | static 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 | |||
834 | static 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 | |||
852 | static 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 | |||
875 | static 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 | |||
897 | static 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 | |||
933 | static 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 | |||
956 | void 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 | |||
964 | void 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 | |||
972 | void 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 | } |