diff options
author | Stephen Warren <swarren@nvidia.com> | 2012-09-28 17:25:59 -0400 |
---|---|---|
committer | Rob Herring <rob.herring@calxeda.com> | 2012-10-01 12:11:35 -0400 |
commit | cd296721a9645f9f28800a072490fa15458d1fb7 (patch) | |
tree | 492b9a268a48af07844fbbd39519f95676ee73fe /scripts/dtc/fdtdump.c | |
parent | acc2097934b5403b97f95763fe99fc115b818061 (diff) |
dtc: import latest upstream dtc
This updates scripts/dtc to commit 317a5d9 "dtc: zero out new label
objects" from git://git.jdl.com/software/dtc.git.
This adds features such as:
* /bits/ syntax for cell data.
* Math expressions within cell data.
* The ability to delete properties or nodes.
* Support for #line directives in the input file, which allows the use of
cpp on *.dts.
* -i command-line option (/include/ path)
* -W/-E command-line options for error/warning control.
* Removal of spew to STDOUT containing the filename being compiled.
* Many additions to the libfdt API.
Signed-off-by: Stephen Warren <swarren@nvidia.com>
Acked-by: Jon Loeliger <jdl@jdl.com>
Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Diffstat (limited to 'scripts/dtc/fdtdump.c')
-rw-r--r-- | scripts/dtc/fdtdump.c | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/scripts/dtc/fdtdump.c b/scripts/dtc/fdtdump.c new file mode 100644 index 000000000000..207a46d64864 --- /dev/null +++ b/scripts/dtc/fdtdump.c | |||
@@ -0,0 +1,162 @@ | |||
1 | /* | ||
2 | * fdtdump.c - Contributed by Pantelis Antoniou <pantelis.antoniou AT gmail.com> | ||
3 | */ | ||
4 | |||
5 | #include <stdint.h> | ||
6 | #include <stdio.h> | ||
7 | #include <stdlib.h> | ||
8 | #include <string.h> | ||
9 | #include <ctype.h> | ||
10 | |||
11 | #include <fdt.h> | ||
12 | #include <libfdt_env.h> | ||
13 | |||
14 | #include "util.h" | ||
15 | |||
16 | #define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1)) | ||
17 | #define PALIGN(p, a) ((void *)(ALIGN((unsigned long)(p), (a)))) | ||
18 | #define GET_CELL(p) (p += 4, *((const uint32_t *)(p-4))) | ||
19 | |||
20 | static void print_data(const char *data, int len) | ||
21 | { | ||
22 | int i; | ||
23 | const char *p = data; | ||
24 | |||
25 | /* no data, don't print */ | ||
26 | if (len == 0) | ||
27 | return; | ||
28 | |||
29 | if (util_is_printable_string(data, len)) { | ||
30 | printf(" = \"%s\"", (const char *)data); | ||
31 | } else if ((len % 4) == 0) { | ||
32 | printf(" = <"); | ||
33 | for (i = 0; i < len; i += 4) | ||
34 | printf("0x%08x%s", fdt32_to_cpu(GET_CELL(p)), | ||
35 | i < (len - 4) ? " " : ""); | ||
36 | printf(">"); | ||
37 | } else { | ||
38 | printf(" = ["); | ||
39 | for (i = 0; i < len; i++) | ||
40 | printf("%02x%s", *p++, i < len - 1 ? " " : ""); | ||
41 | printf("]"); | ||
42 | } | ||
43 | } | ||
44 | |||
45 | static void dump_blob(void *blob) | ||
46 | { | ||
47 | struct fdt_header *bph = blob; | ||
48 | uint32_t off_mem_rsvmap = fdt32_to_cpu(bph->off_mem_rsvmap); | ||
49 | uint32_t off_dt = fdt32_to_cpu(bph->off_dt_struct); | ||
50 | uint32_t off_str = fdt32_to_cpu(bph->off_dt_strings); | ||
51 | struct fdt_reserve_entry *p_rsvmap = | ||
52 | (struct fdt_reserve_entry *)((char *)blob + off_mem_rsvmap); | ||
53 | const char *p_struct = (const char *)blob + off_dt; | ||
54 | const char *p_strings = (const char *)blob + off_str; | ||
55 | uint32_t version = fdt32_to_cpu(bph->version); | ||
56 | uint32_t totalsize = fdt32_to_cpu(bph->totalsize); | ||
57 | uint32_t tag; | ||
58 | const char *p, *s, *t; | ||
59 | int depth, sz, shift; | ||
60 | int i; | ||
61 | uint64_t addr, size; | ||
62 | |||
63 | depth = 0; | ||
64 | shift = 4; | ||
65 | |||
66 | printf("/dts-v1/;\n"); | ||
67 | printf("// magic:\t\t0x%x\n", fdt32_to_cpu(bph->magic)); | ||
68 | printf("// totalsize:\t\t0x%x (%d)\n", totalsize, totalsize); | ||
69 | printf("// off_dt_struct:\t0x%x\n", off_dt); | ||
70 | printf("// off_dt_strings:\t0x%x\n", off_str); | ||
71 | printf("// off_mem_rsvmap:\t0x%x\n", off_mem_rsvmap); | ||
72 | printf("// version:\t\t%d\n", version); | ||
73 | printf("// last_comp_version:\t%d\n", | ||
74 | fdt32_to_cpu(bph->last_comp_version)); | ||
75 | if (version >= 2) | ||
76 | printf("// boot_cpuid_phys:\t0x%x\n", | ||
77 | fdt32_to_cpu(bph->boot_cpuid_phys)); | ||
78 | |||
79 | if (version >= 3) | ||
80 | printf("// size_dt_strings:\t0x%x\n", | ||
81 | fdt32_to_cpu(bph->size_dt_strings)); | ||
82 | if (version >= 17) | ||
83 | printf("// size_dt_struct:\t0x%x\n", | ||
84 | fdt32_to_cpu(bph->size_dt_struct)); | ||
85 | printf("\n"); | ||
86 | |||
87 | for (i = 0; ; i++) { | ||
88 | addr = fdt64_to_cpu(p_rsvmap[i].address); | ||
89 | size = fdt64_to_cpu(p_rsvmap[i].size); | ||
90 | if (addr == 0 && size == 0) | ||
91 | break; | ||
92 | |||
93 | printf("/memreserve/ %llx %llx;\n", | ||
94 | (unsigned long long)addr, (unsigned long long)size); | ||
95 | } | ||
96 | |||
97 | p = p_struct; | ||
98 | while ((tag = fdt32_to_cpu(GET_CELL(p))) != FDT_END) { | ||
99 | |||
100 | /* printf("tag: 0x%08x (%d)\n", tag, p - p_struct); */ | ||
101 | |||
102 | if (tag == FDT_BEGIN_NODE) { | ||
103 | s = p; | ||
104 | p = PALIGN(p + strlen(s) + 1, 4); | ||
105 | |||
106 | if (*s == '\0') | ||
107 | s = "/"; | ||
108 | |||
109 | printf("%*s%s {\n", depth * shift, "", s); | ||
110 | |||
111 | depth++; | ||
112 | continue; | ||
113 | } | ||
114 | |||
115 | if (tag == FDT_END_NODE) { | ||
116 | depth--; | ||
117 | |||
118 | printf("%*s};\n", depth * shift, ""); | ||
119 | continue; | ||
120 | } | ||
121 | |||
122 | if (tag == FDT_NOP) { | ||
123 | printf("%*s// [NOP]\n", depth * shift, ""); | ||
124 | continue; | ||
125 | } | ||
126 | |||
127 | if (tag != FDT_PROP) { | ||
128 | fprintf(stderr, "%*s ** Unknown tag 0x%08x\n", depth * shift, "", tag); | ||
129 | break; | ||
130 | } | ||
131 | sz = fdt32_to_cpu(GET_CELL(p)); | ||
132 | s = p_strings + fdt32_to_cpu(GET_CELL(p)); | ||
133 | if (version < 16 && sz >= 8) | ||
134 | p = PALIGN(p, 8); | ||
135 | t = p; | ||
136 | |||
137 | p = PALIGN(p + sz, 4); | ||
138 | |||
139 | printf("%*s%s", depth * shift, "", s); | ||
140 | print_data(t, sz); | ||
141 | printf(";\n"); | ||
142 | } | ||
143 | } | ||
144 | |||
145 | |||
146 | int main(int argc, char *argv[]) | ||
147 | { | ||
148 | char *buf; | ||
149 | |||
150 | if (argc < 2) { | ||
151 | fprintf(stderr, "supply input filename\n"); | ||
152 | return 5; | ||
153 | } | ||
154 | |||
155 | buf = utilfdt_read(argv[1]); | ||
156 | if (buf) | ||
157 | dump_blob(buf); | ||
158 | else | ||
159 | return 10; | ||
160 | |||
161 | return 0; | ||
162 | } | ||