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 <[EMAIL PROTECTED]>

Acked-by: Stefan Reinauer <[EMAIL PROTECTED]>

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;
 


-- 
linuxbios mailing list
[email protected]
http://www.linuxbios.org/mailman/listinfo/linuxbios

Reply via email to