Browse Source

Initial label support. Also switch to glr-parser mode and get rid of

hacks that were necessary without it.
main
David Gibson 20 years ago
parent
commit
4102d840d9
  1. 10
      Makefile
  2. 2
      TODO
  3. 3
      comment-test.dts
  4. 23
      dtc-lexer.l
  5. 25
      dtc-parser.y
  6. 10
      dtc.h
  7. 54
      flattree.c
  8. 8
      fstree.c
  9. 13
      livetree.c
  10. 8
      test.dts

10
Makefile

@ -1,8 +1,10 @@
TARGETS = dtc TARGETS = dtc
CFLAGS = -Wall -g CFLAGS = -Wall -g


BISON = bison

OBJS = dtc.o livetree.o flattree.o data.o treesource.o fstree.o \ 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) all: $(TARGETS)


@ -11,13 +13,13 @@ dtc: $(OBJS)


$(OBJS): dtc.h $(OBJS): dtc.h


y.tab.c y.tab.h: dtc-parser.y dtc-parser.tab.c dtc-parser.tab.h dtc-parser.output: dtc-parser.y
$(YACC) -d $< $(BISON) -d -v $<


lex.yy.c: dtc-lexer.l lex.yy.c: dtc-lexer.l
$(LEX) $< $(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 dtc-parser.c: dtc-lexer.c



2
TODO

@ -4,8 +4,6 @@
* Report line/column numbers for syntax errors * Report line/column numbers for syntax errors
* Better categorization of errors into severity levels * Better categorization of errors into severity levels
- Generate mem reserve map - 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 * memory reserve section in source
- Testsuite - Testsuite
- Actually number releases, revision control, all that kind of jazz - Actually number releases, revision control, all that kind of jazz

3
comment-test.dts

@ -31,5 +31,8 @@
/** try this */ /** try this */
prop9; prop9;
/* and this **/ /* and this **/
prop10;
child /* finally */ {
};
}; };
/* final comment */ /* final comment */

23
dtc-lexer.l

@ -32,9 +32,9 @@ WS [ \t\n]
%{ %{
#include "dtc.h" #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 ']'; 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 #ifdef LEXDEBUG
fprintf(stderr, "NodeName: %s\n", yytext); fprintf(stderr, "NodeName: %s\n", yytext);
#endif #endif
@ -91,15 +99,16 @@ WS [ \t\n]
return DT_NODENAME; return DT_NODENAME;
} }


{PROPCHAR}+ {
[a-zA-Z_][a-zA-Z0-9_]*: {
#ifdef LEXDEBUG #ifdef LEXDEBUG
fprintf(stderr, "PropName: %s\n", yytext); fprintf(stderr, "Label: %s\n", yytext);
#endif #endif
yylval.str = strdup(yytext); yylval.str = strdup(yytext);
return DT_PROPNAME; yylval.str[yyleng-1] = '\0';
return DT_LABEL;
} }



<*>{WS}+ /* eat whitespace */ <*>{WS}+ /* eat whitespace */


<*>"/*"([^*]|\*+[^*/])*\*+"/" { <*>"/*"([^*]|\*+[^*/])*\*+"/" {

25
dtc-parser.y

@ -47,6 +47,7 @@ extern struct node *device_tree;
%token <byte> DT_BYTE %token <byte> DT_BYTE
%token <data> DT_STRING %token <data> DT_STRING
%token <str> DT_UNIT %token <str> DT_UNIT
%token <str> DT_LABEL


%type <data> propdata %type <data> propdata
%type <data> celllist %type <data> celllist
@ -57,12 +58,16 @@ extern struct node *device_tree;
%type <node> nodedef %type <node> nodedef
%type <node> subnode %type <node> subnode
%type <nodelist> subnodes %type <nodelist> subnodes
%type <str> label
%type <str> nodename

%glr-parser


%% %%


devicetree: { devicetree: {
assert(device_tree == NULL); assert(device_tree == NULL);
} '/' nodedef { device_tree = name_node($3, ""); } } '/' nodedef { device_tree = name_node($3, "", NULL); }
; ;


nodedef: '{' proplist subnodes '}' ';' { nodedef: '{' proplist subnodes '}' ';' {
@ -78,11 +83,11 @@ proplist: propdef proplist {
} }
; ;


propdef: DT_PROPNAME '=' propdata ';' { propdef: label DT_PROPNAME '=' propdata ';' {
$$ = build_property($1, $3); $$ = build_property($2, $4, $1);
} }
| DT_PROPNAME ';' { | label DT_PROPNAME ';' {
$$ = build_empty_property($1); $$ = build_empty_property($2, $1);
} }
; ;


@ -105,7 +110,15 @@ subnodes: subnode subnodes {
| /* empty */ { $$ = NULL; } | /* 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; }
; ;


%% %%

10
dtc.h

@ -115,6 +115,8 @@ struct property {
struct data val; struct data val;


struct property *next; struct property *next;

char *label;
}; };


struct node { struct node {
@ -130,6 +132,8 @@ struct node {


cell_t phandle; cell_t phandle;
int addr_cells, size_cells; int addr_cells, size_cells;

char *label;
}; };


#define for_each_property(n, p) \ #define for_each_property(n, p) \
@ -138,12 +142,12 @@ struct node {
#define for_each_child(n, c) \ #define for_each_child(n, c) \
for ((c) = (n)->children; (c); (c) = (c)->next_sibling) for ((c) = (n)->children; (c); (c) = (c)->next_sibling)


struct property *build_property(char *name, struct data val); struct property *build_property(char *name, struct data val, char *label);
struct property *build_empty_property(char *name); struct property *build_empty_property(char *name, char *label);
struct property *chain_property(struct property *first, struct property *list); struct property *chain_property(struct property *first, struct property *list);


struct node *build_node(struct property *proplist, struct node *children); 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); struct node *chain_node(struct node *first, struct node *list);


void add_property(struct node *node, struct property *prop); void add_property(struct node *node, struct property *prop);

54
flattree.c

@ -80,9 +80,9 @@ struct emitter {
void (*string)(void *, char *, int); void (*string)(void *, char *, int);
void (*align)(void *, int); void (*align)(void *, int);
void (*data)(void *, struct data); void (*data)(void *, struct data);
void (*beginnode)(void *); void (*beginnode)(void *, char *);
void (*endnode)(void *); void (*endnode)(void *, char *);
void (*property)(void *); void (*property)(void *, char *);
}; };


static void bin_emit_cell(void *e, cell_t val) 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); *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); 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); 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); bin_emit_cell(e, OF_DT_PROP);
} }
@ -142,6 +142,13 @@ struct emitter bin_emitter = {
.property = bin_emit_property, .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) static void asm_emit_cell(void *e, cell_t val)
{ {
FILE *f = e; FILE *f = e;
@ -199,24 +206,36 @@ static void asm_emit_data(void *e, struct data d)
assert(off == d.len); assert(off == d.len);
} }


static void asm_emit_beginnode(void *e) static void asm_emit_beginnode(void *e, char *label)
{ {
FILE *f = e; 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"); 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; FILE *f = e;


fprintf(f, "\t.long\tOF_DT_END_NODE\n"); 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; 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"); 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; struct node *child;
int seen_name_prop = 0; int seen_name_prop = 0;


emit->beginnode(etarget); emit->beginnode(etarget, tree->label);


if (vi->flags & FTF_FULLPATH) if (vi->flags & FTF_FULLPATH)
emit->string(etarget, tree->fullpath, 0); 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); nameoff = stringtable_insert(strbuf, prop->name);


emit->property(etarget); emit->property(etarget, prop->label);
emit->cell(etarget, prop->val.len); emit->cell(etarget, prop->val.len);
emit->cell(etarget, nameoff); 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) { if ((vi->flags & FTF_NAMEPROPS) && !seen_name_prop) {
emit->property(etarget); emit->property(etarget, NULL);
emit->cell(etarget, tree->basenamelen+1); emit->cell(etarget, tree->basenamelen+1);
emit->cell(etarget, stringtable_insert(strbuf, "name")); 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); flatten_tree(child, emit, etarget, strbuf, vi);
} }


emit->endnode(etarget); emit->endnode(etarget, tree->label);
} }


static void make_bph(struct boot_param_header *bph, 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) void write_dt_asm(FILE *f, struct node *tree, int version, int reservenum)
{ {
struct version_info *vi = NULL; 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); 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) static char *nodename_from_path(char *ppath, char *cpath)

8
fstree.c

@ -60,7 +60,8 @@ static struct node *read_fstree(char *dirname)
} else { } else {
prop = build_property(strdup(de->d_name), prop = build_property(strdup(de->d_name),
data_copy_file(pfile, data_copy_file(pfile,
st.st_size)); st.st_size),
NULL);
add_property(tree, prop); add_property(tree, prop);
fclose(pfile); fclose(pfile);
} }
@ -68,7 +69,8 @@ static struct node *read_fstree(char *dirname)
struct node *newchild; struct node *newchild;


newchild = read_fstree(tmpnam); 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); add_child(tree, newchild);
} }


@ -83,7 +85,7 @@ struct node *dt_from_fs(char *dirname)
struct node *tree; struct node *tree;


tree = read_fstree(dirname); tree = read_fstree(dirname);
tree = name_node(tree, ""); tree = name_node(tree, "", NULL);


fill_fullpaths(tree, ""); fill_fullpaths(tree, "");



13
livetree.c

@ -24,7 +24,7 @@
* Tree building functions * 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)); struct property *new = xmalloc(sizeof(*new));


@ -33,10 +33,12 @@ struct property *build_property(char *name, struct data val)


new->next = NULL; new->next = NULL;


new->label = label;

return new; return new;
} }


struct property *build_empty_property(char *name) struct property *build_empty_property(char *name, char *label)
{ {
struct property *new = xmalloc(sizeof(*new)); struct property *new = xmalloc(sizeof(*new));


@ -46,6 +48,8 @@ struct property *build_empty_property(char *name)


new->next = NULL; new->next = NULL;


new->label = label;

return new; return new;
} }


@ -74,11 +78,14 @@ struct node *build_node(struct property *proplist, struct node *children)
return new; 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); assert(node->name == NULL);


node->name = name; node->name = name;

node->label = label;

return node; return node;
} }



8
test.dts

@ -2,9 +2,9 @@
model = "MyBoardName"; model = "MyBoardName";
compatible = "MyBoardFamilyName"; compatible = "MyBoardFamilyName";
#address-cells = <2>; #address-cells = <2>;
#size-cells = <2>; label1: #size-cells = <2>;


cpus { label2: cpus {
linux,phandle = <1>; linux,phandle = <1>;
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;
@ -15,12 +15,14 @@
clock-frequency = <5f5e1000>; clock-frequency = <5f5e1000>;
linux,boot-cpu; linux,boot-cpu;
linux,phandle = <2>; linux,phandle = <2>;
i-cache-size = <10000>;
d-cache-size = <8000>;
}; };


}; };


randomnode { 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]; blob = [0a 0b 0c 0d de ea ad be ef];
}; };



Loading…
Cancel
Save