Author: rminnich Date: 2007-06-19 09:03:35 +0200 (Tue, 19 Jun 2007) New Revision: 361
Modified: LinuxBIOSv3/util/dtc/dtc-lexer.l LinuxBIOSv3/util/dtc/dtc-parser.y LinuxBIOSv3/util/dtc/dtc.h LinuxBIOSv3/util/dtc/flattree.c LinuxBIOSv3/util/dtc/fstree.c LinuxBIOSv3/util/dtc/livetree.c Log: Changes to allow us to use the dtc to create C structures for the static tree. Now requires newer flex, 2.5.4 at least.
Signed-off-by: Ronald G. Minnich rminnich@gmail.com
Acked-by: Stefan Reinauer stepan@coresystems.de
M dtc/dtc-lexer.l M dtc/flattree.c M dtc/dtc.h M dtc/livetree.c M dtc/fstree.c M dtc/dtc-parser.y
Modified: LinuxBIOSv3/util/dtc/dtc-lexer.l =================================================================== --- LinuxBIOSv3/util/dtc/dtc-lexer.l 2007-06-19 05:04:48 UTC (rev 360) +++ LinuxBIOSv3/util/dtc/dtc-lexer.l 2007-06-19 07:03:35 UTC (rev 361) @@ -36,8 +36,6 @@
#include "dtc-parser.tab.h"
-/*#define LEXDEBUG 1*/ - #ifdef LEXDEBUG #define DPRINT(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__) #else @@ -46,6 +44,21 @@
char *code = 0;
+YY_BUFFER_STATE bstack = NULL; + +void +switchin(FILE *f){ + YY_BUFFER_STATE b; + bstack = yy_current_buffer; + b = yy_create_buffer(f, 8192); + yy_switch_to_buffer(b); + +} + +void +switchback(void){ + yy_switch_to_buffer(bstack); +} %}
%% @@ -68,7 +81,7 @@ }
<PASSTHROUGH>.* { - DPRINT("Matchingin passthrough %s\n", yytext); + DPRINT("Matching in passthrough %s\n", yytext); /* you tell me why echo does not work */ /*ECHO;*/ strcat(code, yytext); @@ -101,6 +114,12 @@ return ';'; }
+"/config/" { + yylloc.first_line = yylineno; + DPRINT("Keyword: /config/\n"); + return DT_CONFIG; + } + <CELLDATA>[0-9a-fA-F]+ { yylloc.first_line = yylineno; if ((unsigned long)yyleng > 2*sizeof(yylval.cval)) {
Modified: LinuxBIOSv3/util/dtc/dtc-parser.y =================================================================== --- LinuxBIOSv3/util/dtc/dtc-parser.y 2007-06-19 05:04:48 UTC (rev 360) +++ LinuxBIOSv3/util/dtc/dtc-parser.y 2007-06-19 07:03:35 UTC (rev 361) @@ -23,7 +23,6 @@
%{ #include "dtc.h" - int yylex (void); void yyerror (char const *);
@@ -56,13 +55,11 @@ %token <str> DT_UNIT %token <str> DT_LABEL %token <str> DT_REF -%token <str> DT_CONFIG +%token <str> DT_FILENAME +%token <proplist> DT_CONFIG
%type <data> propdata %type <re> memreserve -/* -%type <re> config - */ %type <re> memreserves %type <data> celllist %type <data> bytestring @@ -72,6 +69,7 @@ %type <node> devicetree %type <node> nodedef %type <node> subnode +%type <proplist> config %type <nodelist> subnodes %type <str> label %type <str> nodename @@ -107,8 +105,8 @@ } ;
-nodedef: '{' proplist subnodes '}' ';' { - $$ = build_node($2, $3); +nodedef: '{' config proplist subnodes '}' ';' { + $$ = build_node($2, $3, $4); } ;
@@ -120,21 +118,35 @@ } ;
-/* I doubt we will do this -config: DT_CONFIG '(' includepath ',' structname ')' ';' { - $$ = setupconfig($3, $5); +config: DT_CONFIG '(' + includepath { + void switchin(FILE *f); + + /* switch ... */ + char path[1024]; + FILE *f; + /* TODO: keep track of which of these we have read in. If we have already done it, then + * don't do it twice. + */ + sprintf(path, "%s/dts", $3.val); + f = fopen(path, "r"); + if (! f){ + perror(path); + exit(1); + } + switchin(f); + } '{' proplist '}' ';' { + void switchback(void); + switchback(); } + ')' ';' { $$ = $6} | - { - $$ = NULL; - } ; - */
-includepath: DT_STRING { $$ = $1; } +includepath: DT_STRING { $$ = $1; } ;
-structname: DT_STRING {$$ = $1; } +structname: DT_FILENAME {$$ = $1; } ;
propdef: label DT_PROPNAME '=' propdata ';' {
Modified: LinuxBIOSv3/util/dtc/dtc.h =================================================================== --- LinuxBIOSv3/util/dtc/dtc.h 2007-06-19 05:04:48 UTC (rev 360) +++ LinuxBIOSv3/util/dtc/dtc.h 2007-06-19 07:03:35 UTC (rev 361) @@ -150,6 +150,7 @@ char *name; struct property *proplist; struct node *children; + struct property *config;
struct node *parent; struct node *next_sibling; @@ -170,10 +171,13 @@ #define for_each_child(n, c) \ for ((c) = (n)->children; (c); (c) = (c)->next_sibling)
+#define for_each_config(n, p) \ + for ((p) = (n)->config; (p); (p) = (p)->next) + struct property *build_property(char *name, struct data val, char *label); 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 *config, struct property *proplist, struct node *children); struct node *name_node(struct node *node, char *name, char *label); struct node *chain_node(struct node *first, struct node *list);
Modified: LinuxBIOSv3/util/dtc/flattree.c =================================================================== --- LinuxBIOSv3/util/dtc/flattree.c 2007-06-19 05:04:48 UTC (rev 360) +++ LinuxBIOSv3/util/dtc/flattree.c 2007-06-19 07:03:35 UTC (rev 361) @@ -432,6 +432,7 @@ FILE *f = e; int i; char *cleanname; + int vallen = d.len > 4 ? 4 : d.len;
/* nothing to do? */ if (d.len == 0) @@ -441,8 +442,10 @@ fprintf(f, "\t.%s = {", cleanname); free(cleanname);
- for(i = 0; i < d.len; i++) - fprintf(f, "0x%02x,", d.val[i]); + /* sorry, but right now, u32 is all you get */ + fprintf(f, "0"); + for(i = 0; i < vallen; i++) + fprintf(f, "|(0x%02x<<%d)", d.val[i], (3-i)*8);
fprintf(f, "},\n"); } @@ -649,33 +652,35 @@ int seen_name_prop = 0; FILE *f = etarget;
- treename = clean(tree->name, 0); - emit->beginnode(etarget, treename); + if (tree->config){ + treename = clean(tree->name, 0); + emit->beginnode(etarget, treename);
#if 0 - if (vi->flags & FTF_FULLPATH) - emit->string(etarget, tree->fullpath, 0); - else - emit->string(etarget, tree->name, 0); + if (vi->flags & FTF_FULLPATH) + emit->string(etarget, tree->fullpath, 0); + else + emit->string(etarget, tree->name, 0); #endif
- for_each_property(tree, prop) { - char *cleanname; - if (streq(prop->name, "name")) - seen_name_prop = 1; - cleanname = clean(prop->name, 0); - fprintf(f, "\tu8 %s[%d];\n", cleanname, prop->val.len); - free(cleanname); + for_each_config(tree, prop) { + char *cleanname; + if (streq(prop->name, "name")) + seen_name_prop = 1; + cleanname = clean(prop->name, 0); + fprintf(f, "\tu32 %s;\n", cleanname); + free(cleanname);
- } + } #if 0 - if ((vi->flags & FTF_NAMEPROPS) && !seen_name_prop) { - fprintf(f, "\tu8 %s[%d];\n", prop->name, prop->val.len); + if ((vi->flags & FTF_NAMEPROPS) && !seen_name_prop) { + fprintf(f, "\tu8 %s[%d];\n", prop->name, prop->val.len); + } +#endif + emit->endnode(etarget, treename); + free(treename); } -#endif - emit->endnode(etarget, treename); - free(treename);
for_each_child(tree, child) { flatten_tree_emit_structdecls(child, emit, etarget, strbuf, vi); @@ -692,7 +697,7 @@ { char *treename;
- struct property *prop; + struct property *configprop, *dtsprop; struct node *child; int seen_name_prop = 0; FILE *f = etarget; @@ -708,6 +713,52 @@ else emit->string(etarget, tree->name, 0); #endif + /* here is the real action. What we have to do, given a -> config entry, is this: + * foreach property(tree->config) + * search for the property in this node's property list + * if found, then emit that with its initialization + * else emit the one from the config + * if there is a property in the list not in the config -> error + * later on, get smart, and remove properties as they are found. + * for now, be stupid. + */ + + if (tree->config){ + treename = clean(tree->name, 0); + emit->beginnode(etarget, treename); +#if 0 + if (vi->flags & FTF_FULLPATH) + emit->string(etarget, tree->fullpath, 0); + else + emit->string(etarget, tree->name, 0); +#endif + + for_each_config(tree, configprop) { + char *cleanname; + int found = 0; +#if 0 + cleanname = clean(configprop->name, 0); + fprintf(f, "\tu32 %s = \n", cleanname); + free(cleanname); +#endif + for_each_property(tree, dtsprop) { + if (streq(dtsprop->name,configprop->name)){ + emit->data(etarget, dtsprop); + found = 1; + } + } + if (! found) + emit->data(etarget, configprop); + + } +#if 0 + if ((vi->flags & FTF_NAMEPROPS) && !seen_name_configprop) { + fprintf(f, "\tu8 %s[%d];\n", configprop->name, configprop->val.len); + } +#endif + emit->endnode(etarget, treename); + free(treename); + } /* for_each_property(tree, prop) { if (streq(prop->name, "name")) @@ -739,7 +790,7 @@ void *etarget, struct data *strbuf, struct version_info *vi) { - struct property *prop; + struct property *prop, *config; struct node *child; int seen_name_prop = 0;
@@ -787,6 +838,26 @@ flatten_tree(child, emit, etarget, strbuf, vi); }
+ for_each_config(tree, prop) { + int nameoff; + + if (streq(prop->name, "name")) + seen_name_prop = 1; + + nameoff = stringtable_insert(strbuf, prop->name); + + emit->property(etarget, prop->label); + emit->cell(etarget, prop->val.len); + emit->cell(etarget, nameoff); + + if ((vi->flags & FTF_VARALIGN) && (prop->val.len >= 8)) + emit->align(etarget, 8); + + emit->data(etarget, prop); + emit->align(etarget, sizeof(cell_t)); + } + + emit->endnode(etarget, tree->label); }
@@ -1149,7 +1220,7 @@ fprintf(f, "%s\n", code);
-// flatten_tree_emit_structdecls(bi->dt, &linuxbios_emitter, f, &strbuf, vi); + flatten_tree_emit_structdecls(bi->dt, &linuxbios_emitter, f, &strbuf, vi); flatten_tree_emit_structinits(bi->dt, &linuxbios_emitter, f, &strbuf, vi); data_free(strbuf); /* */ @@ -1360,7 +1431,7 @@ struct node *node; u32 val;
- node = build_node(NULL, NULL); + node = build_node(NULL, NULL, NULL);
if (flags & FTF_FULLPATH) { node->fullpath = flat_read_string(dtbuf);
Modified: LinuxBIOSv3/util/dtc/fstree.c =================================================================== --- LinuxBIOSv3/util/dtc/fstree.c 2007-06-19 05:04:48 UTC (rev 360) +++ LinuxBIOSv3/util/dtc/fstree.c 2007-06-19 07:03:35 UTC (rev 361) @@ -34,7 +34,7 @@ if (! d) die("opendir(): %s\n", strerror(errno));
- tree = build_node(NULL, NULL); + tree = build_node(NULL, NULL, NULL);
while ((de = readdir(d)) != NULL) { char *tmpnam;
Modified: LinuxBIOSv3/util/dtc/livetree.c =================================================================== --- LinuxBIOSv3/util/dtc/livetree.c 2007-06-19 05:04:48 UTC (rev 360) +++ LinuxBIOSv3/util/dtc/livetree.c 2007-06-19 07:03:35 UTC (rev 361) @@ -48,7 +48,7 @@ return first; }
-struct node *build_node(struct property *proplist, struct node *children) +struct node *build_node(struct property *config, struct property *proplist, struct node *children) { static struct node *last_node = NULL;
@@ -57,6 +57,7 @@
memset(new, 0, sizeof(*new));
+ new->config = config; new->proplist = proplist; new->children = children;