~ubuntu-branches/ubuntu/saucy/device-tree-compiler/saucy

« back to all changes in this revision

Viewing changes to ftdump.c

  • Committer: Steve Langasek
  • Date: 2011-02-28 17:57:27 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: steve.langasek@linaro.org-20110228175727-le7jcacnya18tqhz
mergeĀ upstreamĀ 1.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * ftdump.c - Contributed by Pantelis Antoniou <pantelis.antoniou AT gmail.com>
 
3
 */
 
4
 
 
5
#include <stdint.h>
 
6
#include <stdio.h>
 
7
#include <string.h>
 
8
#include <ctype.h>
 
9
 
 
10
#include <fdt.h>
 
11
#include <libfdt_env.h>
 
12
 
 
13
#define ALIGN(x, a)     (((x) + ((a) - 1)) & ~((a) - 1))
 
14
#define PALIGN(p, a)    ((void *)(ALIGN((unsigned long)(p), (a))))
 
15
#define GET_CELL(p)     (p += 4, *((uint32_t *)(p-4)))
 
16
 
 
17
static int is_printable_string(const void *data, int len)
 
18
{
 
19
        const char *s = data;
 
20
        const char *ss;
 
21
 
 
22
        /* zero length is not */
 
23
        if (len == 0)
 
24
                return 0;
 
25
 
 
26
        /* must terminate with zero */
 
27
        if (s[len - 1] != '\0')
 
28
                return 0;
 
29
 
 
30
        ss = s;
 
31
        while (*s && isprint(*s))
 
32
                s++;
 
33
 
 
34
        /* not zero, or not done yet */
 
35
        if (*s != '\0' || (s + 1 - ss) < len)
 
36
                return 0;
 
37
 
 
38
        return 1;
 
39
}
 
40
 
 
41
static void print_data(const void *data, int len)
 
42
{
 
43
        int i;
 
44
        const uint8_t *s;
 
45
 
 
46
        /* no data, don't print */
 
47
        if (len == 0)
 
48
                return;
 
49
 
 
50
        if (is_printable_string(data, len)) {
 
51
                printf(" = \"%s\"", (const char *)data);
 
52
        } else if ((len % 4) == 0) {
 
53
                printf(" = <");
 
54
                for (i = 0; i < len; i += 4)
 
55
                        printf("%08x%s", *((const uint32_t *)data + i),
 
56
                               i < (len - 4) ? " " : "");
 
57
                printf(">");
 
58
        } else {
 
59
                printf(" = [");
 
60
                for (i = 0, s = data; i < len; i++)
 
61
                        printf("%02x%s", s[i], i < len - 1 ? " " : "");
 
62
                printf("]");
 
63
        }
 
64
}
 
65
 
 
66
static void dump_blob(void *blob)
 
67
{
 
68
        struct fdt_header *bph = blob;
 
69
        uint32_t off_mem_rsvmap = fdt32_to_cpu(bph->off_mem_rsvmap);
 
70
        uint32_t off_dt = fdt32_to_cpu(bph->off_dt_struct);
 
71
        uint32_t off_str = fdt32_to_cpu(bph->off_dt_strings);
 
72
        struct fdt_reserve_entry *p_rsvmap =
 
73
                (struct fdt_reserve_entry *)((char *)blob + off_mem_rsvmap);
 
74
        char *p_struct = (char *)blob + off_dt;
 
75
        char *p_strings = (char *)blob + off_str;
 
76
        uint32_t version = fdt32_to_cpu(bph->version);
 
77
        uint32_t totalsize = fdt32_to_cpu(bph->totalsize);
 
78
        uint32_t tag;
 
79
        char *p;
 
80
        char *s, *t;
 
81
        int depth, sz, shift;
 
82
        int i;
 
83
        uint64_t addr, size;
 
84
 
 
85
        depth = 0;
 
86
        shift = 4;
 
87
 
 
88
        printf("// magic:\t\t0x%x\n", fdt32_to_cpu(bph->magic));
 
89
        printf("// totalsize:\t\t0x%x (%d)\n", totalsize, totalsize);
 
90
        printf("// off_dt_struct:\t0x%x\n", off_dt);
 
91
        printf("// off_dt_strings:\t0x%x\n", off_str);
 
92
        printf("// off_mem_rsvmap:\t0x%x\n", off_mem_rsvmap);
 
93
        printf("// version:\t\t%d\n", version);
 
94
        printf("// last_comp_version:\t%d\n",
 
95
               fdt32_to_cpu(bph->last_comp_version));
 
96
        if (version >= 2)
 
97
                printf("// boot_cpuid_phys:\t0x%x\n",
 
98
                       fdt32_to_cpu(bph->boot_cpuid_phys));
 
99
 
 
100
        if (version >= 3)
 
101
                printf("// size_dt_strings:\t0x%x\n",
 
102
                       fdt32_to_cpu(bph->size_dt_strings));
 
103
        if (version >= 17)
 
104
                printf("// size_dt_struct:\t0x%x\n",
 
105
                       fdt32_to_cpu(bph->size_dt_struct));
 
106
        printf("\n");
 
107
 
 
108
        for (i = 0; ; i++) {
 
109
                addr = fdt64_to_cpu(p_rsvmap[i].address);
 
110
                size = fdt64_to_cpu(p_rsvmap[i].size);
 
111
                if (addr == 0 && size == 0)
 
112
                        break;
 
113
 
 
114
                printf("/memreserve/ %llx %llx;\n",
 
115
                       (unsigned long long)addr, (unsigned long long)size);
 
116
        }
 
117
 
 
118
        p = p_struct;
 
119
        while ((tag = fdt32_to_cpu(GET_CELL(p))) != FDT_END) {
 
120
 
 
121
                /* printf("tag: 0x%08x (%d)\n", tag, p - p_struct); */
 
122
 
 
123
                if (tag == FDT_BEGIN_NODE) {
 
124
                        s = p;
 
125
                        p = PALIGN(p + strlen(s) + 1, 4);
 
126
 
 
127
                        if (*s == '\0')
 
128
                                s = "/";
 
129
 
 
130
                        printf("%*s%s {\n", depth * shift, "", s);
 
131
 
 
132
                        depth++;
 
133
                        continue;
 
134
                }
 
135
 
 
136
                if (tag == FDT_END_NODE) {
 
137
                        depth--;
 
138
 
 
139
                        printf("%*s};\n", depth * shift, "");
 
140
                        continue;
 
141
                }
 
142
 
 
143
                if (tag == FDT_NOP) {
 
144
                        printf("%*s// [NOP]\n", depth * shift, "");
 
145
                        continue;
 
146
                }
 
147
 
 
148
                if (tag != FDT_PROP) {
 
149
                        fprintf(stderr, "%*s ** Unknown tag 0x%08x\n", depth * shift, "", tag);
 
150
                        break;
 
151
                }
 
152
                sz = fdt32_to_cpu(GET_CELL(p));
 
153
                s = p_strings + fdt32_to_cpu(GET_CELL(p));
 
154
                if (version < 16 && sz >= 8)
 
155
                        p = PALIGN(p, 8);
 
156
                t = p;
 
157
 
 
158
                p = PALIGN(p + sz, 4);
 
159
 
 
160
                printf("%*s%s", depth * shift, "", s);
 
161
                print_data(t, sz);
 
162
                printf(";\n");
 
163
        }
 
164
}
 
165
 
 
166
 
 
167
int main(int argc, char *argv[])
 
168
{
 
169
        FILE *fp;
 
170
        char buf[16384];        /* 16k max */
 
171
        int size;
 
172
 
 
173
        if (argc < 2) {
 
174
                fprintf(stderr, "supply input filename\n");
 
175
                return 5;
 
176
        }
 
177
 
 
178
        fp = fopen(argv[1], "rb");
 
179
        if (fp == NULL) {
 
180
                fprintf(stderr, "unable to open %s\n", argv[1]);
 
181
                return 10;
 
182
        }
 
183
 
 
184
        size = fread(buf, 1, sizeof(buf), fp);
 
185
        if (size == sizeof(buf)) {      /* too large */
 
186
                fprintf(stderr, "file too large\n");
 
187
                return 10;
 
188
        }
 
189
 
 
190
        dump_blob(buf);
 
191
 
 
192
        fclose(fp);
 
193
 
 
194
        return 0;
 
195
}