mirror of
https://github.com/fail0verflow/switch-coreboot.git
synced 2025-05-04 01:39:18 -04:00
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:
parent
eadbcb73c7
commit
14cc48b773
6 changed files with 156 additions and 49 deletions
|
@ -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)) {
|
||||
|
|
|
@ -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 ';' {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue