Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
treesource.c
Go to the documentation of this file.
1 /*
2  * (C) Copyright David Gibson <[email protected]>, 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 YYLTYPE yylloc;
27 
30 
31 struct boot_info *dt_from_source(const char *fname)
32 {
33  the_boot_info = NULL;
34  treesource_error = 0;
35 
36  srcfile_push(fname);
37  yyin = current_srcfile->f;
38  yylloc.file = current_srcfile;
39 
40  if (yyparse() != 0)
41  die("Unable to parse input tree\n");
42 
43  if (treesource_error)
44  die("Syntax error parsing input tree\n");
45 
46  return the_boot_info;
47 }
48 
49 static void write_prefix(FILE *f, int level)
50 {
51  int i;
52 
53  for (i = 0; i < level; i++)
54  fputc('\t', f);
55 }
56 
57 static int isstring(char c)
58 {
59  return (isprint(c)
60  || (c == '\0')
61  || strchr("\a\b\t\n\v\f\r", c));
62 }
63 
64 static void write_propval_string(FILE *f, struct data val)
65 {
66  const char *str = val.val;
67  int i;
68  struct marker *m = val.markers;
69 
70  assert(str[val.len-1] == '\0');
71 
72  while (m && (m->offset == 0)) {
73  if (m->type == LABEL)
74  fprintf(f, "%s: ", m->ref);
75  m = m->next;
76  }
77  fprintf(f, "\"");
78 
79  for (i = 0; i < (val.len-1); i++) {
80  char c = str[i];
81 
82  switch (c) {
83  case '\a':
84  fprintf(f, "\\a");
85  break;
86  case '\b':
87  fprintf(f, "\\b");
88  break;
89  case '\t':
90  fprintf(f, "\\t");
91  break;
92  case '\n':
93  fprintf(f, "\\n");
94  break;
95  case '\v':
96  fprintf(f, "\\v");
97  break;
98  case '\f':
99  fprintf(f, "\\f");
100  break;
101  case '\r':
102  fprintf(f, "\\r");
103  break;
104  case '\\':
105  fprintf(f, "\\\\");
106  break;
107  case '\"':
108  fprintf(f, "\\\"");
109  break;
110  case '\0':
111  fprintf(f, "\", ");
112  while (m && (m->offset < i)) {
113  if (m->type == LABEL) {
114  assert(m->offset == (i+1));
115  fprintf(f, "%s: ", m->ref);
116  }
117  m = m->next;
118  }
119  fprintf(f, "\"");
120  break;
121  default:
122  if (isprint(c))
123  fprintf(f, "%c", c);
124  else
125  fprintf(f, "\\x%02hhx", c);
126  }
127  }
128  fprintf(f, "\"");
129 
130  /* Wrap up any labels at the end of the value */
132  assert (m->offset == val.len);
133  fprintf(f, " %s:", m->ref);
134  }
135 }
136 
137 static void write_propval_cells(FILE *f, struct data val)
138 {
139  void *propend = val.val + val.len;
140  cell_t *cp = (cell_t *)val.val;
141  struct marker *m = val.markers;
142 
143  fprintf(f, "<");
144  for (;;) {
145  while (m && (m->offset <= ((char *)cp - val.val))) {
146  if (m->type == LABEL) {
147  assert(m->offset == ((char *)cp - val.val));
148  fprintf(f, "%s: ", m->ref);
149  }
150  m = m->next;
151  }
152 
153  fprintf(f, "0x%x", fdt32_to_cpu(*cp++));
154  if ((void *)cp >= propend)
155  break;
156  fprintf(f, " ");
157  }
158 
159  /* Wrap up any labels at the end of the value */
161  assert (m->offset == val.len);
162  fprintf(f, " %s:", m->ref);
163  }
164  fprintf(f, ">");
165 }
166 
167 static void write_propval_bytes(FILE *f, struct data val)
168 {
169  void *propend = val.val + val.len;
170  const char *bp = val.val;
171  struct marker *m = val.markers;
172 
173  fprintf(f, "[");
174  for (;;) {
175  while (m && (m->offset == (bp-val.val))) {
176  if (m->type == LABEL)
177  fprintf(f, "%s: ", m->ref);
178  m = m->next;
179  }
180 
181  fprintf(f, "%02hhx", *bp++);
182  if ((const void *)bp >= propend)
183  break;
184  fprintf(f, " ");
185  }
186 
187  /* Wrap up any labels at the end of the value */
189  assert (m->offset == val.len);
190  fprintf(f, " %s:", m->ref);
191  }
192  fprintf(f, "]");
193 }
194 
195 static void write_propval(FILE *f, struct property *prop)
196 {
197  int len = prop->val.len;
198  const char *p = prop->val.val;
199  struct marker *m = prop->val.markers;
200  int nnotstring = 0, nnul = 0;
201  int nnotstringlbl = 0, nnotcelllbl = 0;
202  int i;
203 
204  if (len == 0) {
205  fprintf(f, ";\n");
206  return;
207  }
208 
209  for (i = 0; i < len; i++) {
210  if (! isstring(p[i]))
211  nnotstring++;
212  if (p[i] == '\0')
213  nnul++;
214  }
215 
217  if ((m->offset > 0) && (prop->val.val[m->offset - 1] != '\0'))
218  nnotstringlbl++;
219  if ((m->offset % sizeof(cell_t)) != 0)
220  nnotcelllbl++;
221  }
222 
223  fprintf(f, " = ");
224  if ((p[len-1] == '\0') && (nnotstring == 0) && (nnul < (len-nnul))
225  && (nnotstringlbl == 0)) {
226  write_propval_string(f, prop->val);
227  } else if (((len % sizeof(cell_t)) == 0) && (nnotcelllbl == 0)) {
228  write_propval_cells(f, prop->val);
229  } else {
230  write_propval_bytes(f, prop->val);
231  }
232 
233  fprintf(f, ";\n");
234 }
235 
236 static void write_tree_source_node(FILE *f, struct node *tree, int level)
237 {
238  struct property *prop;
239  struct node *child;
240  struct label *l;
241 
242  write_prefix(f, level);
243  for_each_label(tree->labels, l)
244  fprintf(f, "%s: ", l->label);
245  if (tree->name && (*tree->name))
246  fprintf(f, "%s {\n", tree->name);
247  else
248  fprintf(f, "/ {\n");
249 
250  for_each_property(tree, prop) {
251  write_prefix(f, level+1);
252  for_each_label(prop->labels, l)
253  fprintf(f, "%s: ", l->label);
254  fprintf(f, "%s", prop->name);
255  write_propval(f, prop);
256  }
257  for_each_child(tree, child) {
258  fprintf(f, "\n");
259  write_tree_source_node(f, child, level+1);
260  }
261  write_prefix(f, level);
262  fprintf(f, "};\n");
263 }
264 
265 
266 void dt_to_source(FILE *f, struct boot_info *bi)
267 {
268  struct reserve_info *re;
269 
270  fprintf(f, "/dts-v1/;\n\n");
271 
272  for (re = bi->reservelist; re; re = re->next) {
273  struct label *l;
274 
275  for_each_label(re->labels, l)
276  fprintf(f, "%s: ", l->label);
277  fprintf(f, "/memreserve/\t0x%016llx 0x%016llx;\n",
278  (unsigned long long)re->re.address,
279  (unsigned long long)re->re.size);
280  }
281 
282  write_tree_source_node(f, bi->dt, 0);
283 }
284