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 @@ %locations %{ +#include <stdio.h> + #include "dtc.h" #include "srcpos.h" -int yylex(void); -unsigned long long eval_literal(const char *s, int base, int bits); +extern int yylex(void); extern struct boot_info *the_boot_info; +extern int treesource_error; +static unsigned long long eval_literal(const char *s, int base, int bits); %} %union { @@ -36,10 +39,10 @@ extern struct boot_info *the_boot_info; char *literal; char *labelref; unsigned int cbase; - u8 byte; + uint8_t byte; struct data data; - u64 addr; + uint64_t addr; cell_t cell; struct property *prop; struct property *proplist; @@ -58,6 +61,7 @@ extern struct boot_info *the_boot_info; %token <data> DT_STRING %token <labelref> DT_LABEL %token <labelref> DT_REF +%token DT_INCBIN %type <data> propdata %type <data> propdataprefix @@ -84,11 +88,11 @@ extern struct boot_info *the_boot_info; sourcefile: DT_V1 ';' memreserves devicetree { - the_boot_info = build_boot_info($3, $4); + the_boot_info = build_boot_info($3, $4, 0); } | v0_memreserves devicetree { - the_boot_info = build_boot_info($1, $2); + the_boot_info = build_boot_info($1, $2, 0); } ; @@ -196,6 +200,34 @@ propdata: { $$ = data_add_marker($1, REF_PATH, $2); } + | propdataprefix DT_INCBIN '(' DT_STRING ',' addr ',' addr ')' + { + struct search_path path = { srcpos_file->dir, NULL, NULL }; + struct dtc_file *file = dtc_open_file($4.val, &path); + struct data d = empty_data; + + if ($6 != 0) + if (fseek(file->file, $6, SEEK_SET) != 0) + yyerrorf("Couldn't seek to offset %llu in \"%s\": %s", + (unsigned long long)$6, + $4.val, strerror(errno)); + + d = data_copy_file(file->file, $8); + + $$ = data_merge($1, d); + dtc_close_file(file); + } + | propdataprefix DT_INCBIN '(' DT_STRING ')' + { + struct search_path path = { srcpos_file->dir, NULL, NULL }; + struct dtc_file *file = dtc_open_file($4.val, &path); + struct data d = empty_data; + + d = data_copy_file(file->file, -1); + + $$ = data_merge($1, d); + dtc_close_file(file); + } | propdata DT_LABEL { $$ = data_add_marker($1, LABEL, $2); @@ -282,7 +314,7 @@ subnodes: } | subnode propdef { - yyerror("syntax error: properties must precede subnodes\n"); + yyerror("syntax error: properties must precede subnodes"); YYERROR; } ; @@ -307,18 +339,29 @@ label: %% -void yyerror (char const *s) +void yyerrorf(char const *s, ...) { - const char *fname = srcpos_filename_for_num(yylloc.filenum); + const char *fname = srcpos_file ? srcpos_file->name : "<no-file>"; + va_list va; + va_start(va, s); if (strcmp(fname, "-") == 0) fname = "stdin"; - fprintf(stderr, "%s:%d %s\n", - fname, yylloc.first_line, s); + fprintf(stderr, "%s:%d ", fname, yylloc.first_line); + vfprintf(stderr, s, va); + fprintf(stderr, "\n"); + + treesource_error = 1; + va_end(va); +} + +void yyerror (char const *s) +{ + yyerrorf("%s", s); } -unsigned long long eval_literal(const char *s, int base, int bits) +static unsigned long long eval_literal(const char *s, int base, int bits) { unsigned long long val; char *e; |