aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/dtc/dtc-parser.y
diff options
context:
space:
mode:
authorJohn Bonesio <bones@secretlab.ca>2010-11-17 18:28:20 -0500
committerGrant Likely <grant.likely@secretlab.ca>2011-01-03 18:02:49 -0500
commit658f29a51e9830e620bb9a1ce3534b318a38bfeb (patch)
treee6cc7cd9b9e17d97308619fd8516b77bcc038114 /scripts/dtc/dtc-parser.y
parentcd1e65044d4473cca9a01bae7b7938f065044a4b (diff)
of/flattree: Update dtc to current mainline.
Pull in recent changes from the main dtc repository. These changes primarily allow multiple device trees to be declared which are merged by dtc. This feature allows us to include a basic dts file and then provide more information for the specific system through the merging functionality. Changes pulled from git://git.jdl.com/software/dtc.git commit id: 37c0b6a0, "dtc: Add code to make diffing trees easier" Signed-off-by: John Bonesio <bones@secretlab.ca> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'scripts/dtc/dtc-parser.y')
-rw-r--r--scripts/dtc/dtc-parser.y160
1 files changed, 63 insertions, 97 deletions
diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y
index b2ab562420ea..5e84a67fc1d2 100644
--- a/scripts/dtc/dtc-parser.y
+++ b/scripts/dtc/dtc-parser.y
@@ -18,15 +18,17 @@
18 * USA 18 * USA
19 */ 19 */
20 20
21%locations
22
23%{ 21%{
24#include <stdio.h> 22#include <stdio.h>
25 23
26#include "dtc.h" 24#include "dtc.h"
27#include "srcpos.h" 25#include "srcpos.h"
28 26
27YYLTYPE yylloc;
28
29extern int yylex(void); 29extern int yylex(void);
30extern void print_error(char const *fmt, ...);
31extern void yyerror(char const *s);
30 32
31extern struct boot_info *the_boot_info; 33extern struct boot_info *the_boot_info;
32extern int treesource_error; 34extern int treesource_error;
@@ -55,7 +57,6 @@ static unsigned long long eval_literal(const char *s, int base, int bits);
55%token DT_MEMRESERVE 57%token DT_MEMRESERVE
56%token <propnodename> DT_PROPNODENAME 58%token <propnodename> DT_PROPNODENAME
57%token <literal> DT_LITERAL 59%token <literal> DT_LITERAL
58%token <literal> DT_LEGACYLITERAL
59%token <cbase> DT_BASE 60%token <cbase> DT_BASE
60%token <byte> DT_BYTE 61%token <byte> DT_BYTE
61%token <data> DT_STRING 62%token <data> DT_STRING
@@ -67,11 +68,8 @@ static unsigned long long eval_literal(const char *s, int base, int bits);
67%type <data> propdataprefix 68%type <data> propdataprefix
68%type <re> memreserve 69%type <re> memreserve
69%type <re> memreserves 70%type <re> memreserves
70%type <re> v0_memreserve
71%type <re> v0_memreserves
72%type <addr> addr 71%type <addr> addr
73%type <data> celllist 72%type <data> celllist
74%type <cbase> cellbase
75%type <cell> cellval 73%type <cell> cellval
76%type <data> bytestring 74%type <data> bytestring
77%type <prop> propdef 75%type <prop> propdef
@@ -81,18 +79,14 @@ static unsigned long long eval_literal(const char *s, int base, int bits);
81%type <node> nodedef 79%type <node> nodedef
82%type <node> subnode 80%type <node> subnode
83%type <nodelist> subnodes 81%type <nodelist> subnodes
84%type <labelref> label
85 82
86%% 83%%
87 84
88sourcefile: 85sourcefile:
89 DT_V1 ';' memreserves devicetree 86 DT_V1 ';' memreserves devicetree
90 { 87 {
91 the_boot_info = build_boot_info($3, $4, 0); 88 the_boot_info = build_boot_info($3, $4,
92 } 89 guess_boot_cpuid($4));
93 | v0_memreserves devicetree
94 {
95 the_boot_info = build_boot_info($1, $2, 0);
96 } 90 }
97 ; 91 ;
98 92
@@ -108,31 +102,14 @@ memreserves:
108 ; 102 ;
109 103
110memreserve: 104memreserve:
111 label DT_MEMRESERVE addr addr ';' 105 DT_MEMRESERVE addr addr ';'
112 { 106 {
113 $$ = build_reserve_entry($3, $4, $1); 107 $$ = build_reserve_entry($2, $3);
114 } 108 }
115 ; 109 | DT_LABEL memreserve
116
117v0_memreserves:
118 /* empty */
119 { 110 {
120 $$ = NULL; 111 add_label(&$2->labels, $1);
121 } 112 $$ = $2;
122 | v0_memreserve v0_memreserves
123 {
124 $$ = chain_reserve_entry($1, $2);
125 };
126 ;
127
128v0_memreserve:
129 memreserve
130 {
131 $$ = $1;
132 }
133 | label DT_MEMRESERVE addr '-' addr ';'
134 {
135 $$ = build_reserve_entry($3, $5 - $3 + 1, $1);
136 } 113 }
137 ; 114 ;
138 115
@@ -141,16 +118,26 @@ addr:
141 { 118 {
142 $$ = eval_literal($1, 0, 64); 119 $$ = eval_literal($1, 0, 64);
143 } 120 }
144 | DT_LEGACYLITERAL
145 {
146 $$ = eval_literal($1, 16, 64);
147 }
148 ; 121 ;
149 122
150devicetree: 123devicetree:
151 '/' nodedef 124 '/' nodedef
152 { 125 {
153 $$ = name_node($2, "", NULL); 126 $$ = name_node($2, "");
127 }
128 | devicetree '/' nodedef
129 {
130 $$ = merge_nodes($1, $3);
131 }
132 | devicetree DT_REF nodedef
133 {
134 struct node *target = get_node_by_ref($1, $2);
135
136 if (target)
137 merge_nodes(target, $3);
138 else
139 print_error("label or path, '%s', not found", $2);
140 $$ = $1;
154 } 141 }
155 ; 142 ;
156 143
@@ -173,13 +160,18 @@ proplist:
173 ; 160 ;
174 161
175propdef: 162propdef:
176 label DT_PROPNODENAME '=' propdata ';' 163 DT_PROPNODENAME '=' propdata ';'
164 {
165 $$ = build_property($1, $3);
166 }
167 | DT_PROPNODENAME ';'
177 { 168 {
178 $$ = build_property($2, $4, $1); 169 $$ = build_property($1, empty_data);
179 } 170 }
180 | label DT_PROPNODENAME ';' 171 | DT_LABEL propdef
181 { 172 {
182 $$ = build_property($2, empty_data, $1); 173 add_label(&$2->labels, $1);
174 $$ = $2;
183 } 175 }
184 ; 176 ;
185 177
@@ -202,31 +194,30 @@ propdata:
202 } 194 }
203 | propdataprefix DT_INCBIN '(' DT_STRING ',' addr ',' addr ')' 195 | propdataprefix DT_INCBIN '(' DT_STRING ',' addr ',' addr ')'
204 { 196 {
205 struct search_path path = { srcpos_file->dir, NULL, NULL }; 197 FILE *f = srcfile_relative_open($4.val, NULL);
206 struct dtc_file *file = dtc_open_file($4.val, &path); 198 struct data d;
207 struct data d = empty_data;
208 199
209 if ($6 != 0) 200 if ($6 != 0)
210 if (fseek(file->file, $6, SEEK_SET) != 0) 201 if (fseek(f, $6, SEEK_SET) != 0)
211 yyerrorf("Couldn't seek to offset %llu in \"%s\": %s", 202 print_error("Couldn't seek to offset %llu in \"%s\": %s",
212 (unsigned long long)$6, 203 (unsigned long long)$6,
213 $4.val, strerror(errno)); 204 $4.val,
205 strerror(errno));
214 206
215 d = data_copy_file(file->file, $8); 207 d = data_copy_file(f, $8);
216 208
217 $$ = data_merge($1, d); 209 $$ = data_merge($1, d);
218 dtc_close_file(file); 210 fclose(f);
219 } 211 }
220 | propdataprefix DT_INCBIN '(' DT_STRING ')' 212 | propdataprefix DT_INCBIN '(' DT_STRING ')'
221 { 213 {
222 struct search_path path = { srcpos_file->dir, NULL, NULL }; 214 FILE *f = srcfile_relative_open($4.val, NULL);
223 struct dtc_file *file = dtc_open_file($4.val, &path);
224 struct data d = empty_data; 215 struct data d = empty_data;
225 216
226 d = data_copy_file(file->file, -1); 217 d = data_copy_file(f, -1);
227 218
228 $$ = data_merge($1, d); 219 $$ = data_merge($1, d);
229 dtc_close_file(file); 220 fclose(f);
230 } 221 }
231 | propdata DT_LABEL 222 | propdata DT_LABEL
232 { 223 {
@@ -269,23 +260,11 @@ celllist:
269 } 260 }
270 ; 261 ;
271 262
272cellbase:
273 /* empty */
274 {
275 $$ = 16;
276 }
277 | DT_BASE
278 ;
279
280cellval: 263cellval:
281 DT_LITERAL 264 DT_LITERAL
282 { 265 {
283 $$ = eval_literal($1, 0, 32); 266 $$ = eval_literal($1, 0, 32);
284 } 267 }
285 | cellbase DT_LEGACYLITERAL
286 {
287 $$ = eval_literal($2, $1, 32);
288 }
289 ; 268 ;
290 269
291bytestring: 270bytestring:
@@ -308,57 +287,44 @@ subnodes:
308 { 287 {
309 $$ = NULL; 288 $$ = NULL;
310 } 289 }
311 | subnode subnodes 290 | subnode subnodes
312 { 291 {
313 $$ = chain_node($1, $2); 292 $$ = chain_node($1, $2);
314 } 293 }
315 | subnode propdef 294 | subnode propdef
316 { 295 {
317 yyerror("syntax error: properties must precede subnodes"); 296 print_error("syntax error: properties must precede subnodes");
318 YYERROR; 297 YYERROR;
319 } 298 }
320 ; 299 ;
321 300
322subnode: 301subnode:
323 label DT_PROPNODENAME nodedef 302 DT_PROPNODENAME nodedef
324 { 303 {
325 $$ = name_node($3, $2, $1); 304 $$ = name_node($2, $1);
326 } 305 }
327 ; 306 | DT_LABEL subnode
328
329label:
330 /* empty */
331 { 307 {
332 $$ = NULL; 308 add_label(&$2->labels, $1);
333 } 309 $$ = $2;
334 | DT_LABEL
335 {
336 $$ = $1;
337 } 310 }
338 ; 311 ;
339 312
340%% 313%%
341 314
342void yyerrorf(char const *s, ...) 315void print_error(char const *fmt, ...)
343{ 316{
344 const char *fname = srcpos_file ? srcpos_file->name : "<no-file>";
345 va_list va; 317 va_list va;
346 va_start(va, s);
347
348 if (strcmp(fname, "-") == 0)
349 fname = "stdin";
350 318
351 fprintf(stderr, "%s:%d ", fname, yylloc.first_line); 319 va_start(va, fmt);
352 vfprintf(stderr, s, va); 320 srcpos_verror(&yylloc, fmt, va);
353 fprintf(stderr, "\n"); 321 va_end(va);
354 322
355 treesource_error = 1; 323 treesource_error = 1;
356 va_end(va);
357} 324}
358 325
359void yyerror (char const *s) 326void yyerror(char const *s) {
360{ 327 print_error("%s", s);
361 yyerrorf("%s", s);
362} 328}
363 329
364static unsigned long long eval_literal(const char *s, int base, int bits) 330static unsigned long long eval_literal(const char *s, int base, int bits)
@@ -369,11 +335,11 @@ static unsigned long long eval_literal(const char *s, int base, int bits)
369 errno = 0; 335 errno = 0;
370 val = strtoull(s, &e, base); 336 val = strtoull(s, &e, base);
371 if (*e) 337 if (*e)
372 yyerror("bad characters in literal"); 338 print_error("bad characters in literal");
373 else if ((errno == ERANGE) 339 else if ((errno == ERANGE)
374 || ((bits < 64) && (val >= (1ULL << bits)))) 340 || ((bits < 64) && (val >= (1ULL << bits))))
375 yyerror("literal out of range"); 341 print_error("literal out of range");
376 else if (errno != 0) 342 else if (errno != 0)
377 yyerror("bad literal"); 343 print_error("bad literal");
378 return val; 344 return val;
379} 345}