diff options
Diffstat (limited to 'arch/powerpc/boot/dtc-src/dtc-parser.y')
-rw-r--r-- | arch/powerpc/boot/dtc-src/dtc-parser.y | 67 |
1 files changed, 55 insertions, 12 deletions
diff --git a/arch/powerpc/boot/dtc-src/dtc-parser.y b/arch/powerpc/boot/dtc-src/dtc-parser.y index 002ea7fef184..b2ab562420ea 100644 --- a/arch/powerpc/boot/dtc-src/dtc-parser.y +++ b/arch/powerpc/boot/dtc-src/dtc-parser.y | |||
@@ -21,14 +21,17 @@ | |||
21 | %locations | 21 | %locations |
22 | 22 | ||
23 | %{ | 23 | %{ |
24 | #include <stdio.h> | ||
25 | |||
24 | #include "dtc.h" | 26 | #include "dtc.h" |
25 | #include "srcpos.h" | 27 | #include "srcpos.h" |
26 | 28 | ||
27 | int yylex(void); | 29 | extern int yylex(void); |
28 | unsigned long long eval_literal(const char *s, int base, int bits); | ||
29 | 30 | ||
30 | extern struct boot_info *the_boot_info; | 31 | extern struct boot_info *the_boot_info; |
32 | extern int treesource_error; | ||
31 | 33 | ||
34 | static unsigned long long eval_literal(const char *s, int base, int bits); | ||
32 | %} | 35 | %} |
33 | 36 | ||
34 | %union { | 37 | %union { |
@@ -36,10 +39,10 @@ extern struct boot_info *the_boot_info; | |||
36 | char *literal; | 39 | char *literal; |
37 | char *labelref; | 40 | char *labelref; |
38 | unsigned int cbase; | 41 | unsigned int cbase; |
39 | u8 byte; | 42 | uint8_t byte; |
40 | struct data data; | 43 | struct data data; |
41 | 44 | ||
42 | u64 addr; | 45 | uint64_t addr; |
43 | cell_t cell; | 46 | cell_t cell; |
44 | struct property *prop; | 47 | struct property *prop; |
45 | struct property *proplist; | 48 | struct property *proplist; |
@@ -58,6 +61,7 @@ extern struct boot_info *the_boot_info; | |||
58 | %token <data> DT_STRING | 61 | %token <data> DT_STRING |
59 | %token <labelref> DT_LABEL | 62 | %token <labelref> DT_LABEL |
60 | %token <labelref> DT_REF | 63 | %token <labelref> DT_REF |
64 | %token DT_INCBIN | ||
61 | 65 | ||
62 | %type <data> propdata | 66 | %type <data> propdata |
63 | %type <data> propdataprefix | 67 | %type <data> propdataprefix |
@@ -84,11 +88,11 @@ extern struct boot_info *the_boot_info; | |||
84 | sourcefile: | 88 | sourcefile: |
85 | DT_V1 ';' memreserves devicetree | 89 | DT_V1 ';' memreserves devicetree |
86 | { | 90 | { |
87 | the_boot_info = build_boot_info($3, $4); | 91 | the_boot_info = build_boot_info($3, $4, 0); |
88 | } | 92 | } |
89 | | v0_memreserves devicetree | 93 | | v0_memreserves devicetree |
90 | { | 94 | { |
91 | the_boot_info = build_boot_info($1, $2); | 95 | the_boot_info = build_boot_info($1, $2, 0); |
92 | } | 96 | } |
93 | ; | 97 | ; |
94 | 98 | ||
@@ -196,6 +200,34 @@ propdata: | |||
196 | { | 200 | { |
197 | $$ = data_add_marker($1, REF_PATH, $2); | 201 | $$ = data_add_marker($1, REF_PATH, $2); |
198 | } | 202 | } |
203 | | propdataprefix DT_INCBIN '(' DT_STRING ',' addr ',' addr ')' | ||
204 | { | ||
205 | struct search_path path = { srcpos_file->dir, NULL, NULL }; | ||
206 | struct dtc_file *file = dtc_open_file($4.val, &path); | ||
207 | struct data d = empty_data; | ||
208 | |||
209 | if ($6 != 0) | ||
210 | if (fseek(file->file, $6, SEEK_SET) != 0) | ||
211 | yyerrorf("Couldn't seek to offset %llu in \"%s\": %s", | ||
212 | (unsigned long long)$6, | ||
213 | $4.val, strerror(errno)); | ||
214 | |||
215 | d = data_copy_file(file->file, $8); | ||
216 | |||
217 | $$ = data_merge($1, d); | ||
218 | dtc_close_file(file); | ||
219 | } | ||
220 | | propdataprefix DT_INCBIN '(' DT_STRING ')' | ||
221 | { | ||
222 | struct search_path path = { srcpos_file->dir, NULL, NULL }; | ||
223 | struct dtc_file *file = dtc_open_file($4.val, &path); | ||
224 | struct data d = empty_data; | ||
225 | |||
226 | d = data_copy_file(file->file, -1); | ||
227 | |||
228 | $$ = data_merge($1, d); | ||
229 | dtc_close_file(file); | ||
230 | } | ||
199 | | propdata DT_LABEL | 231 | | propdata DT_LABEL |
200 | { | 232 | { |
201 | $$ = data_add_marker($1, LABEL, $2); | 233 | $$ = data_add_marker($1, LABEL, $2); |
@@ -282,7 +314,7 @@ subnodes: | |||
282 | } | 314 | } |
283 | | subnode propdef | 315 | | subnode propdef |
284 | { | 316 | { |
285 | yyerror("syntax error: properties must precede subnodes\n"); | 317 | yyerror("syntax error: properties must precede subnodes"); |
286 | YYERROR; | 318 | YYERROR; |
287 | } | 319 | } |
288 | ; | 320 | ; |
@@ -307,18 +339,29 @@ label: | |||
307 | 339 | ||
308 | %% | 340 | %% |
309 | 341 | ||
310 | void yyerror (char const *s) | 342 | void yyerrorf(char const *s, ...) |
311 | { | 343 | { |
312 | const char *fname = srcpos_filename_for_num(yylloc.filenum); | 344 | const char *fname = srcpos_file ? srcpos_file->name : "<no-file>"; |
345 | va_list va; | ||
346 | va_start(va, s); | ||
313 | 347 | ||
314 | if (strcmp(fname, "-") == 0) | 348 | if (strcmp(fname, "-") == 0) |
315 | fname = "stdin"; | 349 | fname = "stdin"; |
316 | 350 | ||
317 | fprintf(stderr, "%s:%d %s\n", | 351 | fprintf(stderr, "%s:%d ", fname, yylloc.first_line); |
318 | fname, yylloc.first_line, s); | 352 | vfprintf(stderr, s, va); |
353 | fprintf(stderr, "\n"); | ||
354 | |||
355 | treesource_error = 1; | ||
356 | va_end(va); | ||
357 | } | ||
358 | |||
359 | void yyerror (char const *s) | ||
360 | { | ||
361 | yyerrorf("%s", s); | ||
319 | } | 362 | } |
320 | 363 | ||
321 | unsigned long long eval_literal(const char *s, int base, int bits) | 364 | static unsigned long long eval_literal(const char *s, int base, int bits) |
322 | { | 365 | { |
323 | unsigned long long val; | 366 | unsigned long long val; |
324 | char *e; | 367 | char *e; |