diff --git a/Makefile b/Makefile index 1dca00b..f9a1050 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,10 @@ TARGETS = dtc CFLAGS = -Wall -g +BISON = bison + OBJS = dtc.o livetree.o flattree.o data.o treesource.o fstree.o \ - y.tab.o lex.yy.o + dtc-parser.tab.o lex.yy.o all: $(TARGETS) @@ -11,13 +13,13 @@ dtc: $(OBJS) $(OBJS): dtc.h -y.tab.c y.tab.h: dtc-parser.y - $(YACC) -d $< +dtc-parser.tab.c dtc-parser.tab.h dtc-parser.output: dtc-parser.y + $(BISON) -d -v $< lex.yy.c: dtc-lexer.l $(LEX) $< -lex.yy.o: lex.yy.c y.tab.h +lex.yy.o: lex.yy.c dtc-parser.tab.h dtc-parser.c: dtc-lexer.c diff --git a/TODO b/TODO index 7136979..3342474 100644 --- a/TODO +++ b/TODO @@ -4,8 +4,6 @@ * Report line/column numbers for syntax errors * Better categorization of errors into severity levels - Generate mem reserve map - * Command line options to place a number of blank entries to be - filled in by bootloader * memory reserve section in source - Testsuite - Actually number releases, revision control, all that kind of jazz diff --git a/comment-test.dts b/comment-test.dts index b8d5637..0174347 100644 --- a/comment-test.dts +++ b/comment-test.dts @@ -31,5 +31,8 @@ /** try this */ prop9; /* and this **/ + prop10; + child /* finally */ { + }; }; /* final comment */ diff --git a/dtc-lexer.l b/dtc-lexer.l index 02283a9..4819e54 100644 --- a/dtc-lexer.l +++ b/dtc-lexer.l @@ -32,9 +32,9 @@ WS [ \t\n] %{ #include "dtc.h" -#include "y.tab.h" +#include "dtc-parser.tab.h" -#undef LEXDEBUG 1 +/*#define LEXDEBUG 1 */ %} @@ -83,7 +83,15 @@ WS [ \t\n] return ']'; } -{PROPCHAR}+(@{UNITCHAR}+)?/{WS}*\{ { +{PROPCHAR}+ { +#ifdef LEXDEBUG + fprintf(stderr, "PropName: %s\n", yytext); +#endif + yylval.str = strdup(yytext); + return DT_PROPNAME; + } + +{PROPCHAR}+(@{UNITCHAR}+)? { #ifdef LEXDEBUG fprintf(stderr, "NodeName: %s\n", yytext); #endif @@ -91,15 +99,16 @@ WS [ \t\n] return DT_NODENAME; } -{PROPCHAR}+ { + +[a-zA-Z_][a-zA-Z0-9_]*: { #ifdef LEXDEBUG - fprintf(stderr, "PropName: %s\n", yytext); + fprintf(stderr, "Label: %s\n", yytext); #endif yylval.str = strdup(yytext); - return DT_PROPNAME; + yylval.str[yyleng-1] = '\0'; + return DT_LABEL; } - <*>{WS}+ /* eat whitespace */ <*>"/*"([^*]|\*+[^*/])*\*+"/" { diff --git a/dtc-parser.y b/dtc-parser.y index f177fb7..785acd1 100644 --- a/dtc-parser.y +++ b/dtc-parser.y @@ -47,6 +47,7 @@ extern struct node *device_tree; %token DT_BYTE %token DT_STRING %token DT_UNIT +%token DT_LABEL %type propdata %type celllist @@ -57,12 +58,16 @@ extern struct node *device_tree; %type nodedef %type subnode %type subnodes +%type label +%type nodename + +%glr-parser %% devicetree: { assert(device_tree == NULL); - } '/' nodedef { device_tree = name_node($3, ""); } + } '/' nodedef { device_tree = name_node($3, "", NULL); } ; nodedef: '{' proplist subnodes '}' ';' { @@ -78,11 +83,11 @@ proplist: propdef proplist { } ; -propdef: DT_PROPNAME '=' propdata ';' { - $$ = build_property($1, $3); +propdef: label DT_PROPNAME '=' propdata ';' { + $$ = build_property($2, $4, $1); } - | DT_PROPNAME ';' { - $$ = build_empty_property($1); + | label DT_PROPNAME ';' { + $$ = build_empty_property($2, $1); } ; @@ -105,7 +110,15 @@ subnodes: subnode subnodes { | /* empty */ { $$ = NULL; } ; -subnode: DT_NODENAME nodedef { $$ = name_node($2, $1); } +subnode: label nodename nodedef { $$ = name_node($3, $2, $1); } + ; + +nodename: DT_NODENAME { $$ = $1; } + | DT_PROPNAME { $$ = $1; } + ; + +label: DT_LABEL { $$ = $1; } + | /* empty */ { $$ = NULL; } ; %% diff --git a/dtc.h b/dtc.h index 75a1ac5..cbd5eb7 100644 --- a/dtc.h +++ b/dtc.h @@ -115,6 +115,8 @@ struct property { struct data val; struct property *next; + + char *label; }; struct node { @@ -130,6 +132,8 @@ struct node { cell_t phandle; int addr_cells, size_cells; + + char *label; }; #define for_each_property(n, p) \ @@ -138,12 +142,12 @@ struct node { #define for_each_child(n, c) \ for ((c) = (n)->children; (c); (c) = (c)->next_sibling) -struct property *build_property(char *name, struct data val); -struct property *build_empty_property(char *name); +struct property *build_property(char *name, struct data val, char *label); +struct property *build_empty_property(char *name, char *label); struct property *chain_property(struct property *first, struct property *list); struct node *build_node(struct property *proplist, struct node *children); -struct node *name_node(struct node *node, char *name); +struct node *name_node(struct node *node, char *name, char *label); struct node *chain_node(struct node *first, struct node *list); void add_property(struct node *node, struct property *prop); diff --git a/flattree.c b/flattree.c index 76d7e5d..f5b7ca1 100644 --- a/flattree.c +++ b/flattree.c @@ -80,9 +80,9 @@ struct emitter { void (*string)(void *, char *, int); void (*align)(void *, int); void (*data)(void *, struct data); - void (*beginnode)(void *); - void (*endnode)(void *); - void (*property)(void *); + void (*beginnode)(void *, char *); + void (*endnode)(void *, char *); + void (*property)(void *, char *); }; static void bin_emit_cell(void *e, cell_t val) @@ -117,17 +117,17 @@ static void bin_emit_data(void *e, struct data d) *dtbuf = data_append_data(*dtbuf, d.val, d.len); } -static void bin_emit_beginnode(void *e) +static void bin_emit_beginnode(void *e, char *label) { bin_emit_cell(e, OF_DT_BEGIN_NODE); } -static void bin_emit_endnode(void *e) +static void bin_emit_endnode(void *e, char *label) { bin_emit_cell(e, OF_DT_END_NODE); } -static void bin_emit_property(void *e) +static void bin_emit_property(void *e, char *label) { bin_emit_cell(e, OF_DT_PROP); } @@ -142,6 +142,13 @@ struct emitter bin_emitter = { .property = bin_emit_property, }; +void emit_label(FILE *f, char *prefix, char *label) +{ + fprintf(f, "\t.globl\t%s_%s\n", prefix, label); + fprintf(f, "%s_%s:\n", prefix, label); + fprintf(f, "_%s_%s:\n", prefix, label); +} + static void asm_emit_cell(void *e, cell_t val) { FILE *f = e; @@ -199,24 +206,36 @@ static void asm_emit_data(void *e, struct data d) assert(off == d.len); } -static void asm_emit_beginnode(void *e) +static void asm_emit_beginnode(void *e, char *label) { FILE *f = e; + if (label) { + fprintf(f, "\t.globl\t%s\n", label); + fprintf(f, "%s:\n", label); + } fprintf(f, "\t.long\tOF_DT_BEGIN_NODE\n"); } -static void asm_emit_endnode(void *e) +static void asm_emit_endnode(void *e, char *label) { FILE *f = e; fprintf(f, "\t.long\tOF_DT_END_NODE\n"); + if (label) { + fprintf(f, "\t.globl\t%s_end\n", label); + fprintf(f, "%s_end:\n", label); + } } -static void asm_emit_property(void *e) +static void asm_emit_property(void *e, char *label) { FILE *f = e; + if (label) { + fprintf(f, "\t.globl\t%s\n", label); + fprintf(f, "%s:\n", label); + } fprintf(f, "\t.long\tOF_DT_PROP\n"); } @@ -253,7 +272,7 @@ static void flatten_tree(struct node *tree, struct emitter *emit, struct node *child; int seen_name_prop = 0; - emit->beginnode(etarget); + emit->beginnode(etarget, tree->label); if (vi->flags & FTF_FULLPATH) emit->string(etarget, tree->fullpath, 0); @@ -270,7 +289,7 @@ static void flatten_tree(struct node *tree, struct emitter *emit, nameoff = stringtable_insert(strbuf, prop->name); - emit->property(etarget); + emit->property(etarget, prop->label); emit->cell(etarget, prop->val.len); emit->cell(etarget, nameoff); @@ -282,7 +301,7 @@ static void flatten_tree(struct node *tree, struct emitter *emit, } if ((vi->flags & FTF_NAMEPROPS) && !seen_name_prop) { - emit->property(etarget); + emit->property(etarget, NULL); emit->cell(etarget, tree->basenamelen+1); emit->cell(etarget, stringtable_insert(strbuf, "name")); @@ -296,7 +315,7 @@ static void flatten_tree(struct node *tree, struct emitter *emit, flatten_tree(child, emit, etarget, strbuf, vi); } - emit->endnode(etarget); + emit->endnode(etarget, tree->label); } static void make_bph(struct boot_param_header *bph, @@ -377,13 +396,6 @@ void dump_stringtable_asm(FILE *f, struct data strbuf) } } -void emit_label(FILE *f, char *prefix, char *label) -{ - fprintf(f, "\t.globl\t%s_%s\n", prefix, label); - fprintf(f, "%s_%s:\n", prefix, label); - fprintf(f, "_%s_%s:\n", prefix, label); -} - void write_dt_asm(FILE *f, struct node *tree, int version, int reservenum) { struct version_info *vi = NULL; @@ -566,7 +578,7 @@ struct property *flat_read_property(struct inbuf *dtbuf, struct inbuf *strbuf, val = flat_read_data(dtbuf, proplen); - return build_property(name, val); + return build_property(name, val, NULL); } static char *nodename_from_path(char *ppath, char *cpath) diff --git a/fstree.c b/fstree.c index 5fe8e40..0b85aa8 100644 --- a/fstree.c +++ b/fstree.c @@ -60,7 +60,8 @@ static struct node *read_fstree(char *dirname) } else { prop = build_property(strdup(de->d_name), data_copy_file(pfile, - st.st_size)); + st.st_size), + NULL); add_property(tree, prop); fclose(pfile); } @@ -68,7 +69,8 @@ static struct node *read_fstree(char *dirname) struct node *newchild; newchild = read_fstree(tmpnam); - newchild = name_node(newchild, strdup(de->d_name)); + newchild = name_node(newchild, strdup(de->d_name), + NULL); add_child(tree, newchild); } @@ -83,7 +85,7 @@ struct node *dt_from_fs(char *dirname) struct node *tree; tree = read_fstree(dirname); - tree = name_node(tree, ""); + tree = name_node(tree, "", NULL); fill_fullpaths(tree, ""); diff --git a/livetree.c b/livetree.c index 227b5e8..04f5228 100644 --- a/livetree.c +++ b/livetree.c @@ -24,7 +24,7 @@ * Tree building functions */ -struct property *build_property(char *name, struct data val) +struct property *build_property(char *name, struct data val, char *label) { struct property *new = xmalloc(sizeof(*new)); @@ -33,10 +33,12 @@ struct property *build_property(char *name, struct data val) new->next = NULL; + new->label = label; + return new; } -struct property *build_empty_property(char *name) +struct property *build_empty_property(char *name, char *label) { struct property *new = xmalloc(sizeof(*new)); @@ -46,6 +48,8 @@ struct property *build_empty_property(char *name) new->next = NULL; + new->label = label; + return new; } @@ -74,11 +78,14 @@ struct node *build_node(struct property *proplist, struct node *children) return new; } -struct node *name_node(struct node *node, char *name) +struct node *name_node(struct node *node, char *name, char * label) { assert(node->name == NULL); node->name = name; + + node->label = label; + return node; } diff --git a/test.dts b/test.dts index bda4288..dce7c52 100644 --- a/test.dts +++ b/test.dts @@ -2,9 +2,9 @@ model = "MyBoardName"; compatible = "MyBoardFamilyName"; #address-cells = <2>; - #size-cells = <2>; + label1: #size-cells = <2>; - cpus { + label2: cpus { linux,phandle = <1>; #address-cells = <1>; #size-cells = <0>; @@ -15,12 +15,14 @@ clock-frequency = <5f5e1000>; linux,boot-cpu; linux,phandle = <2>; + i-cache-size = <10000>; + d-cache-size = <8000>; }; }; randomnode { - string = "\xff\0stuffstuff\t\t\t\n\n\n\n"; + string = "\xff\0stuffstuff\t\t\t\n\n\n"; blob = [0a 0b 0c 0d de ea ad be ef]; };