summaryrefslogtreecommitdiff
path: root/scripts/dtc/dtc-parser.y
diff options
context:
space:
mode:
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 @@
* USA
*/
-%locations
-
%{
#include <stdio.h>
#include "dtc.h"
#include "srcpos.h"
+YYLTYPE yylloc;
+
extern int yylex(void);
+extern void print_error(char const *fmt, ...);
+extern void yyerror(char const *s);
extern struct boot_info *the_boot_info;
extern int treesource_error;
@@ -55,7 +57,6 @@ static unsigned long long eval_literal(const char *s, int base, int bits);
%token DT_MEMRESERVE
%token <propnodename> DT_PROPNODENAME
%token <literal> DT_LITERAL
-%token <literal> DT_LEGACYLITERAL
%token <cbase> DT_BASE
%token <byte> DT_BYTE
%token <data> DT_STRING
@@ -67,11 +68,8 @@ static unsigned long long eval_literal(const char *s, int base, int bits);
%type <data> propdataprefix
%type <re> memreserve
%type <re> memreserves
-%type <re> v0_memreserve
-%type <re> v0_memreserves
%type <addr> addr
%type <data> celllist
-%type <cbase> cellbase
%type <cell> cellval
%type <data> bytestring
%type <prop> propdef
@@ -81,18 +79,14 @@ static unsigned long long eval_literal(const char *s, int base, int bits);
%type <node> nodedef
%type <node> subnode
%type <nodelist> subnodes
-%type <labelref> label
%%
sourcefile:
DT_V1 ';' memreserves devicetree
{
- the_boot_info = build_boot_info($3, $4, 0);
- }
- | v0_memreserves devicetree
- {
- the_boot_info = build_boot_info($1, $2, 0);
+ the_boot_info = build_boot_info($3, $4,
+ guess_boot_cpuid($4));
}
;
@@ -108,31 +102,14 @@ memreserves:
;
memreserve:
- label DT_MEMRESERVE addr addr ';'
+ DT_MEMRESERVE addr addr ';'
{
- $$ = build_reserve_entry($3, $4, $1);
+ $$ = build_reserve_entry($2, $3);
}
- ;
-
-v0_memreserves:
- /* empty */
+ | DT_LABEL memreserve
{
- $$ = NULL;
- }
- | v0_memreserve v0_memreserves
- {
- $$ = chain_reserve_entry($1, $2);
- };
- ;
-
-v0_memreserve:
- memreserve
- {
- $$ = $1;
- }
- | label DT_MEMRESERVE addr '-' addr ';'
- {
- $$ = build_reserve_entry($3, $5 - $3 + 1, $1);
+ add_label(&$2->labels, $1);
+ $$ = $2;
}
;
@@ -141,16 +118,26 @@ addr:
{
$$ = eval_literal($1, 0, 64);
}
- | DT_LEGACYLITERAL
- {
- $$ = eval_literal($1, 16, 64);
- }
;
devicetree:
'/' nodedef
{
- $$ = name_node($2, "", NULL);
+ $$ = name_node($2, "");
+ }
+ | devicetree '/' nodedef
+ {
+ $$ = merge_nodes($1, $3);
+ }
+ | devicetree DT_REF nodedef
+ {
+ struct node *target = get_node_by_ref($1, $2);
+
+ if (target)
+ merge_nodes(target, $3);
+ else
+ print_error("label or path, '%s', not found", $2);
+ $$ = $1;
}
;
@@ -173,13 +160,18 @@ proplist:
;
propdef:
- label DT_PROPNODENAME '=' propdata ';'
+ DT_PROPNODENAME '=' propdata ';'
+ {
+ $$ = build_property($1, $3);
+ }
+ | DT_PROPNODENAME ';'
{
- $$ = build_property($2, $4, $1);
+ $$ = build_property($1, empty_data);
}
- | label DT_PROPNODENAME ';'
+ | DT_LABEL propdef
{
- $$ = build_property($2, empty_data, $1);
+ add_label(&$2->labels, $1);
+ $$ = $2;
}
;
@@ -202,31 +194,30 @@ propdata:
}
| 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;
+ FILE *f = srcfile_relative_open($4.val, NULL);
+ struct data d;
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));
+ if (fseek(f, $6, SEEK_SET) != 0)
+ print_error("Couldn't seek to offset %llu in \"%s\": %s",
+ (unsigned long long)$6,
+ $4.val,
+ strerror(errno));
- d = data_copy_file(file->file, $8);
+ d = data_copy_file(f, $8);
$$ = data_merge($1, d);
- dtc_close_file(file);
+ fclose(f);
}
| propdataprefix DT_INCBIN '(' DT_STRING ')'
{
- struct search_path path = { srcpos_file->dir, NULL, NULL };
- struct dtc_file *file = dtc_open_file($4.val, &path);
+ FILE *f = srcfile_relative_open($4.val, NULL);
struct data d = empty_data;
- d = data_copy_file(file->file, -1);
+ d = data_copy_file(f, -1);
$$ = data_merge($1, d);
- dtc_close_file(file);
+ fclose(f);
}
| propdata DT_LABEL
{
@@ -269,23 +260,11 @@ celllist:
}
;
-cellbase:
- /* empty */
- {
- $$ = 16;
- }
- | DT_BASE
- ;
-
cellval:
DT_LITERAL
{
$$ = eval_literal($1, 0, 32);
}
- | cellbase DT_LEGACYLITERAL
- {
- $$ = eval_literal($2, $1, 32);
- }
;
bytestring:
@@ -308,57 +287,44 @@ subnodes:
{
$$ = NULL;
}
- | subnode subnodes
+ | subnode subnodes
{
$$ = chain_node($1, $2);
}
| subnode propdef
{
- yyerror("syntax error: properties must precede subnodes");
+ print_error("syntax error: properties must precede subnodes");
YYERROR;
}
;
subnode:
- label DT_PROPNODENAME nodedef
+ DT_PROPNODENAME nodedef
{
- $$ = name_node($3, $2, $1);
+ $$ = name_node($2, $1);
}
- ;
-
-label:
- /* empty */
+ | DT_LABEL subnode
{
- $$ = NULL;
- }
- | DT_LABEL
- {
- $$ = $1;
+ add_label(&$2->labels, $1);
+ $$ = $2;
}
;
%%
-void yyerrorf(char const *s, ...)
+void print_error(char const *fmt, ...)
{
- 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 ", fname, yylloc.first_line);
- vfprintf(stderr, s, va);
- fprintf(stderr, "\n");
+ va_start(va, fmt);
+ srcpos_verror(&yylloc, fmt, va);
+ va_end(va);
treesource_error = 1;
- va_end(va);
}
-void yyerror (char const *s)
-{
- yyerrorf("%s", s);
+void yyerror(char const *s) {
+ print_error("%s", s);
}
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)
errno = 0;
val = strtoull(s, &e, base);
if (*e)
- yyerror("bad characters in literal");
+ print_error("bad characters in literal");
else if ((errno == ERANGE)
|| ((bits < 64) && (val >= (1ULL << bits))))
- yyerror("literal out of range");
+ print_error("literal out of range");
else if (errno != 0)
- yyerror("bad literal");
+ print_error("bad literal");
return val;
}