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(a)gmail.com>
Acked-by: Stefan Reinauer <stepan(a)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;