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


git-svn-id: svn://coreboot.org/repository/LinuxBIOSv3@361 f3766cd6-281f-0410-b1cd-43a5c92072e9
This commit is contained in:
Ronald G. Minnich 2007-06-19 07:03:35 +00:00
parent eadbcb73c7
commit 14cc48b773
6 changed files with 156 additions and 49 deletions

View file

@ -36,8 +36,6 @@ REFCHAR ({PROPCHAR}|{UNITCHAR}|[/@])
#include "dtc-parser.tab.h"
/*#define LEXDEBUG 1*/
#ifdef LEXDEBUG
#define DPRINT(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)
#else
@ -46,6 +44,21 @@ REFCHAR ({PROPCHAR}|{UNITCHAR}|[/@])
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 @@ char *code = 0;
}
<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 @@ char *code = 0;
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)) {

View file

@ -23,7 +23,6 @@
%{
#include "dtc.h"
int yylex (void);
void yyerror (char const *);
@ -56,13 +55,11 @@ extern struct boot_info *the_boot_info;
%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 @@ extern struct boot_info *the_boot_info;
%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 @@ devicetree: '/' nodedef {
}
;
nodedef: '{' proplist subnodes '}' ';' {
$$ = build_node($2, $3);
nodedef: '{' config proplist subnodes '}' ';' {
$$ = build_node($2, $3, $4);
}
;
@ -120,21 +118,35 @@ proplist: propdef proplist {
}
;
/* 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; }
;
structname: DT_STRING {$$ = $1; }
includepath: DT_STRING { $$ = $1; }
;
structname: DT_FILENAME {$$ = $1; }
;
propdef: label DT_PROPNAME '=' propdata ';' {

View file

@ -150,6 +150,7 @@ struct node {
char *name;
struct property *proplist;
struct node *children;
struct property *config;
struct node *parent;
struct node *next_sibling;
@ -170,10 +171,13 @@ struct node {
#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);

View file

@ -432,6 +432,7 @@ static void linuxbios_emit_data(void *e, struct property *p)
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 @@ static void linuxbios_emit_data(void *e, struct property *p)
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 @@ static void flatten_tree_emit_structdecls(struct node *tree, struct emitter *emi
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);
emit->endnode(etarget, treename);
free(treename);
}
for_each_child(tree, child) {
flatten_tree_emit_structdecls(child, emit, etarget, strbuf, vi);
@ -692,7 +697,7 @@ static void flatten_tree_emit_structinits(struct node *tree, struct emitter *emi
{
char *treename;
struct property *prop;
struct property *configprop, *dtsprop;
struct node *child;
int seen_name_prop = 0;
FILE *f = etarget;
@ -708,6 +713,52 @@ static void flatten_tree_emit_structinits(struct node *tree, struct emitter *emi
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 @@ static void flatten_tree(struct node *tree, struct emitter *emit,
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 @@ static void flatten_tree(struct node *tree, struct emitter *emit,
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 @@ void dt_to_linuxbios(FILE *f, struct boot_info *bi, int version, int boot_cpuid_
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 @@ static struct node *unflatten_tree(struct inbuf *dtbuf,
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);

View file

@ -34,7 +34,7 @@ static struct node *read_fstree(char *dirname)
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;

View file

@ -48,7 +48,7 @@ struct property *chain_property(struct property *first, struct property *list)
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 @@ struct node *build_node(struct property *proplist, struct node *children)
memset(new, 0, sizeof(*new));
new->config = config;
new->proplist = proplist;
new->children = children;