]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/powerpc/boot/dtc-src/treesource.c
a6a7767976364498a99b1a3c6c7d4d8f6071446a
[linux-2.6-omap-h63xx.git] / arch / powerpc / boot / dtc-src / treesource.c
1 /*
2  * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
3  *
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of the
8  * License, or (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  *  General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
18  *                                                                   USA
19  */
20
21 #include "dtc.h"
22 #include "srcpos.h"
23
24 extern FILE *yyin;
25 extern int yyparse(void);
26 extern void yyerror(char const *);
27
28 struct boot_info *the_boot_info;
29
30 struct boot_info *dt_from_source(const char *fname)
31 {
32         the_boot_info = NULL;
33
34         push_input_file(fname);
35
36         if (yyparse() != 0)
37                 return NULL;
38
39         fill_fullpaths(the_boot_info->dt, "");
40
41         return the_boot_info;
42 }
43
44 static void write_prefix(FILE *f, int level)
45 {
46         int i;
47
48         for (i = 0; i < level; i++)
49                 fputc('\t', f);
50 }
51
52 int isstring(char c)
53 {
54         return (isprint(c)
55                 || (c == '\0')
56                 || strchr("\a\b\t\n\v\f\r", c));
57 }
58
59 static void write_propval_string(FILE *f, struct data val)
60 {
61         const char *str = val.val;
62         int i;
63         int newchunk = 1;
64         struct marker *m = val.markers;
65
66         assert(str[val.len-1] == '\0');
67
68         for (i = 0; i < (val.len-1); i++) {
69                 char c = str[i];
70
71                 if (newchunk) {
72                         while (m && (m->offset <= i)) {
73                                 if (m->type == LABEL) {
74                                         assert(m->offset == i);
75                                         fprintf(f, "%s: ", m->ref);
76                                 }
77                                 m = m->next;
78                         }
79                         fprintf(f, "\"");
80                         newchunk = 0;
81                 }
82
83                 switch (c) {
84                 case '\a':
85                         fprintf(f, "\\a");
86                         break;
87                 case '\b':
88                         fprintf(f, "\\b");
89                         break;
90                 case '\t':
91                         fprintf(f, "\\t");
92                         break;
93                 case '\n':
94                         fprintf(f, "\\n");
95                         break;
96                 case '\v':
97                         fprintf(f, "\\v");
98                         break;
99                 case '\f':
100                         fprintf(f, "\\f");
101                         break;
102                 case '\r':
103                         fprintf(f, "\\r");
104                         break;
105                 case '\\':
106                         fprintf(f, "\\\\");
107                         break;
108                 case '\"':
109                         fprintf(f, "\\\"");
110                         break;
111                 case '\0':
112                         fprintf(f, "\", ");
113                         newchunk = 1;
114                         break;
115                 default:
116                         if (isprint(c))
117                                 fprintf(f, "%c", c);
118                         else
119                                 fprintf(f, "\\x%02hhx", c);
120                 }
121         }
122         fprintf(f, "\"");
123
124         /* Wrap up any labels at the end of the value */
125         for_each_marker_of_type(m, LABEL) {
126                 assert (m->offset == val.len);
127                 fprintf(f, " %s:", m->ref);
128         }
129 }
130
131 static void write_propval_cells(FILE *f, struct data val)
132 {
133         void *propend = val.val + val.len;
134         cell_t *cp = (cell_t *)val.val;
135         struct marker *m = val.markers;
136
137         fprintf(f, "<");
138         for (;;) {
139                 while (m && (m->offset <= ((char *)cp - val.val))) {
140                         if (m->type == LABEL) {
141                                 assert(m->offset == ((char *)cp - val.val));
142                                 fprintf(f, "%s: ", m->ref);
143                         }
144                         m = m->next;
145                 }
146
147                 fprintf(f, "0x%x", be32_to_cpu(*cp++));
148                 if ((void *)cp >= propend)
149                         break;
150                 fprintf(f, " ");
151         }
152
153         /* Wrap up any labels at the end of the value */
154         for_each_marker_of_type(m, LABEL) {
155                 assert (m->offset == val.len);
156                 fprintf(f, " %s:", m->ref);
157         }
158         fprintf(f, ">");
159 }
160
161 static void write_propval_bytes(FILE *f, struct data val)
162 {
163         void *propend = val.val + val.len;
164         const char *bp = val.val;
165         struct marker *m = val.markers;
166
167         fprintf(f, "[");
168         for (;;) {
169                 while (m && (m->offset == (bp-val.val))) {
170                         if (m->type == LABEL)
171                                 fprintf(f, "%s: ", m->ref);
172                         m = m->next;
173                 }
174
175                 fprintf(f, "%02hhx", *bp++);
176                 if ((void *)bp >= propend)
177                         break;
178                 fprintf(f, " ");
179         }
180
181         /* Wrap up any labels at the end of the value */
182         for_each_marker_of_type(m, LABEL) {
183                 assert (m->offset == val.len);
184                 fprintf(f, " %s:", m->ref);
185         }
186         fprintf(f, "]");
187 }
188
189 static void write_propval(FILE *f, struct property *prop)
190 {
191         int len = prop->val.len;
192         const char *p = prop->val.val;
193         struct marker *m = prop->val.markers;
194         int nnotstring = 0, nnul = 0;
195         int nnotstringlbl = 0, nnotcelllbl = 0;
196         int i;
197
198         if (len == 0) {
199                 fprintf(f, ";\n");
200                 return;
201         }
202
203         for (i = 0; i < len; i++) {
204                 if (! isstring(p[i]))
205                         nnotstring++;
206                 if (p[i] == '\0')
207                         nnul++;
208         }
209
210         for_each_marker_of_type(m, LABEL) {
211                 if ((m->offset > 0) && (prop->val.val[m->offset - 1] != '\0'))
212                         nnotstringlbl++;
213                 if ((m->offset % sizeof(cell_t)) != 0)
214                         nnotcelllbl++;
215         }
216
217         fprintf(f, " = ");
218         if ((p[len-1] == '\0') && (nnotstring == 0) && (nnul < (len-nnul))
219             && (nnotstringlbl == 0)) {
220                 write_propval_string(f, prop->val);
221         } else if (((len % sizeof(cell_t)) == 0) && (nnotcelllbl == 0)) {
222                 write_propval_cells(f, prop->val);
223         } else {
224                 write_propval_bytes(f, prop->val);
225         }
226
227         fprintf(f, ";\n");
228 }
229
230 static void write_tree_source_node(FILE *f, struct node *tree, int level)
231 {
232         struct property *prop;
233         struct node *child;
234
235         write_prefix(f, level);
236         if (tree->label)
237                 fprintf(f, "%s: ", tree->label);
238         if (tree->name && (*tree->name))
239                 fprintf(f, "%s {\n", tree->name);
240         else
241                 fprintf(f, "/ {\n");
242
243         for_each_property(tree, prop) {
244                 write_prefix(f, level+1);
245                 if (prop->label)
246                         fprintf(f, "%s: ", prop->label);
247                 fprintf(f, "%s", prop->name);
248                 write_propval(f, prop);
249         }
250         for_each_child(tree, child) {
251                 fprintf(f, "\n");
252                 write_tree_source_node(f, child, level+1);
253         }
254         write_prefix(f, level);
255         fprintf(f, "};\n");
256 }
257
258
259 void dt_to_source(FILE *f, struct boot_info *bi)
260 {
261         struct reserve_info *re;
262
263         fprintf(f, "/dts-v1/;\n\n");
264
265         for (re = bi->reservelist; re; re = re->next) {
266                 if (re->label)
267                         fprintf(f, "%s: ", re->label);
268                 fprintf(f, "/memreserve/\t0x%016llx 0x%016llx;\n",
269                         (unsigned long long)re->re.address,
270                         (unsigned long long)re->re.size);
271         }
272
273         write_tree_source_node(f, bi->dt, 0);
274 }
275