diff options
author | John Bonesio <bones@secretlab.ca> | 2010-11-17 18:28:20 -0500 |
---|---|---|
committer | Grant Likely <grant.likely@secretlab.ca> | 2011-01-03 18:02:49 -0500 |
commit | 658f29a51e9830e620bb9a1ce3534b318a38bfeb (patch) | |
tree | e6cc7cd9b9e17d97308619fd8516b77bcc038114 /scripts/dtc/dtc-parser.y | |
parent | cd1e65044d4473cca9a01bae7b7938f065044a4b (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.y | 160 |
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 | ||
27 | YYLTYPE yylloc; | ||
28 | |||
29 | extern int yylex(void); | 29 | extern int yylex(void); |
30 | extern void print_error(char const *fmt, ...); | ||
31 | extern void yyerror(char const *s); | ||
30 | 32 | ||
31 | extern struct boot_info *the_boot_info; | 33 | extern struct boot_info *the_boot_info; |
32 | extern int treesource_error; | 34 | extern 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 | ||
88 | sourcefile: | 85 | sourcefile: |
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 | ||
110 | memreserve: | 104 | memreserve: |
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 | |||
117 | v0_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 | |||
128 | v0_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 | ||
150 | devicetree: | 123 | devicetree: |
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 | ||
175 | propdef: | 162 | propdef: |
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 | ||
272 | cellbase: | ||
273 | /* empty */ | ||
274 | { | ||
275 | $$ = 16; | ||
276 | } | ||
277 | | DT_BASE | ||
278 | ; | ||
279 | |||
280 | cellval: | 263 | cellval: |
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 | ||
291 | bytestring: | 270 | bytestring: |
@@ -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 | ||
322 | subnode: | 301 | subnode: |
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 | |||
329 | label: | ||
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 | ||
342 | void yyerrorf(char const *s, ...) | 315 | void 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 | ||
359 | void yyerror (char const *s) | 326 | void yyerror(char const *s) { |
360 | { | 327 | print_error("%s", s); |
361 | yyerrorf("%s", s); | ||
362 | } | 328 | } |
363 | 329 | ||
364 | static unsigned long long eval_literal(const char *s, int base, int bits) | 330 | static 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 | } |