Browse Source

Support for specifying memreserve ranges in the source format, based on

a patch by Jon Loeliger <jdl AT freescale.com>, although tweaked
substantially.
main
David Gibson 20 years ago
parent
commit
f0517db250
  1. 2
      Makefile
  2. 7
      data.c
  3. 26
      dtc-lexer.l
  4. 39
      dtc-parser.y
  5. 18
      dtc.c
  6. 38
      dtc.h
  7. 109
      flattree.c
  8. 4
      fstree.c
  9. 12
      livetree.c
  10. 4
      test.dts
  11. 51
      treesource.c

2
Makefile

@ -14,7 +14,7 @@ dtc: $(OBJS)
$(LINK.c) -o $@ $^ $(LINK.c) -o $@ $^


dtc-parser.tab.c dtc-parser.tab.h dtc-parser.output: dtc-parser.y dtc-parser.tab.c dtc-parser.tab.h dtc-parser.output: dtc-parser.y
$(BISON) -d -v $< $(BISON) -d $<


lex.yy.c: dtc-lexer.l lex.yy.c: dtc-lexer.l
$(LEX) $< $(LEX) $<

7
data.c

@ -229,6 +229,13 @@ struct data data_append_cell(struct data d, cell_t word)
return data_append_data(d, &beword, sizeof(beword)); return data_append_data(d, &beword, sizeof(beword));
} }


struct data data_append_addr(struct data d, u64 addr)
{
u64 beaddr = cpu_to_be64(addr);

return data_append_data(d, &beaddr, sizeof(beaddr));
}

struct data data_append_byte(struct data d, uint8_t byte) struct data data_append_byte(struct data d, uint8_t byte)
{ {
return data_append_data(d, &byte, 1); return data_append_data(d, &byte, 1);

26
dtc-lexer.l

@ -22,6 +22,7 @@


%x CELLDATA %x CELLDATA
%x BYTESTRING %x BYTESTRING
%x MEMRESERVE


PROPCHAR [a-zA-Z0-9,._+*#?-] PROPCHAR [a-zA-Z0-9,._+*#?-]
UNITCHAR [0-9a-f,] UNITCHAR [0-9a-f,]
@ -53,6 +54,29 @@ REFCHAR ({PROPCHAR}|{UNITCHAR}|[/@])
return DT_STRING; return DT_STRING;
} }


"/memreserve/" {
DPRINT("Keyword: /memreserve/\n");
BEGIN(MEMRESERVE);
return DT_MEMRESERVE;
}

<MEMRESERVE>[0-9a-fA-F]+ {
if (yyleng > 2*sizeof(yylval.addr)) {
fprintf(stderr, "Address value %s too large\n",
yytext);
}
yylval.addr = (u64) strtoull(yytext, NULL, 16);
DPRINT("Addr: %llx\n",
(unsigned long long)yylval.addr);
return DT_ADDR;
}

<MEMRESERVE>";" {
DPRINT("/MEMRESERVE\n");
BEGIN(INITIAL);
return ';';
}

<CELLDATA>[0-9a-fA-F]+ { <CELLDATA>[0-9a-fA-F]+ {
if (yyleng > 2*sizeof(yylval.cval)) { if (yyleng > 2*sizeof(yylval.cval)) {
fprintf(stderr, fprintf(stderr,
@ -116,7 +140,7 @@ REFCHAR ({PROPCHAR}|{UNITCHAR}|[/@])


<*>"//".*\n /* eat line comments */ <*>"//".*\n /* eat line comments */


. { <*>. {
switch (yytext[0]) { switch (yytext[0]) {
case '<': case '<':
DPRINT("CELLDATA\n"); DPRINT("CELLDATA\n");

39
dtc-parser.y

@ -24,7 +24,7 @@
int yylex (void); int yylex (void);
void yyerror (char const *); void yyerror (char const *);


extern struct node *device_tree; extern struct boot_info *the_boot_info;


%} %}


@ -39,8 +39,12 @@ extern struct node *device_tree;
struct node *nodelist; struct node *nodelist;
int datalen; int datalen;
int hexlen; int hexlen;
u64 addr;
struct reserve_entry re;
} }


%token DT_MEMRESERVE
%token <addr> DT_ADDR
%token <str> DT_PROPNAME %token <str> DT_PROPNAME
%token <str> DT_NODENAME %token <str> DT_NODENAME
%token <cval> DT_CELL %token <cval> DT_CELL
@ -51,11 +55,14 @@ extern struct node *device_tree;
%token <str> DT_REF %token <str> DT_REF


%type <data> propdata %type <data> propdata
%type <re> memreserve
%type <data> memreserves
%type <data> celllist %type <data> celllist
%type <data> bytestring %type <data> bytestring
%type <prop> propdef %type <prop> propdef
%type <proplist> proplist %type <proplist> proplist


%type <node> devicetree
%type <node> nodedef %type <node> nodedef
%type <node> subnode %type <node> subnode
%type <nodelist> subnodes %type <nodelist> subnodes
@ -66,9 +73,33 @@ extern struct node *device_tree;


%% %%


devicetree: { sourcefile: memreserves devicetree {
assert(device_tree == NULL); the_boot_info = build_boot_info($1, $2);
} '/' nodedef { device_tree = name_node($3, "", NULL); } }
;

memreserves: memreserves memreserve {
$$ = data_append_addr(data_append_addr($1, $2.address),
$2.size);
}
| /* empty */ {
$$ = empty_data;
}
;

memreserve: DT_MEMRESERVE DT_ADDR DT_ADDR ';' {
$$.address = $2;
$$.size = $3;
}
| DT_MEMRESERVE DT_ADDR '-' DT_ADDR ';' {
$$.address = $2;
$$.size = $4 - $2 + 1;
}
;

devicetree: '/' nodedef {
$$ = name_node($2, "", NULL);
}
; ;


nodedef: '{' proplist subnodes '}' ';' { nodedef: '{' proplist subnodes '}' ';' {

18
dtc.c

@ -102,7 +102,7 @@ static void usage(void)


int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
struct node *dt; struct boot_info *bi;
char *inform = "dts"; char *inform = "dts";
char *outform = "dts"; char *outform = "dts";
char *outname = "-"; char *outname = "-";
@ -151,12 +151,12 @@ int main(int argc, char *argv[])


if (streq(inform, "dts")) { if (streq(inform, "dts")) {
inf = dtc_open_file(arg); inf = dtc_open_file(arg);
dt = dt_from_source(inf); bi = dt_from_source(inf);
} else if (streq(inform, "fs")) { } else if (streq(inform, "fs")) {
dt = dt_from_fs(arg); bi = dt_from_fs(arg);
} else if(streq(inform, "dtb")) { } else if(streq(inform, "dtb")) {
inf = dtc_open_file(arg); inf = dtc_open_file(arg);
dt = dt_from_blob(inf); bi = dt_from_blob(inf);
} else { } else {
die("Unknown input format \"%s\"\n", inform); die("Unknown input format \"%s\"\n", inform);
} }
@ -164,10 +164,10 @@ int main(int argc, char *argv[])
if (inf && (inf != stdin)) if (inf && (inf != stdin))
fclose(inf); fclose(inf);


if (! dt) if (! bi || ! bi->dt)
die("Couldn't read input tree\n"); die("Couldn't read input tree\n");


if (! check_device_tree(dt)) { if (! check_device_tree(bi->dt)) {
fprintf(stderr, "Input tree has errors\n"); fprintf(stderr, "Input tree has errors\n");
if (! force) if (! force)
exit(1); exit(1);
@ -183,11 +183,11 @@ int main(int argc, char *argv[])
} }


if (streq(outform, "dts")) { if (streq(outform, "dts")) {
write_tree_source(outf, dt, 0); write_tree_source(outf, bi);
} else if (streq(outform, "dtb")) { } else if (streq(outform, "dtb")) {
write_dt_blob(outf, dt, outversion, reservenum); write_dt_blob(outf, bi, outversion);
} else if (streq(outform, "asm")) { } else if (streq(outform, "asm")) {
write_dt_asm(outf, dt, outversion, reservenum); write_dt_asm(outf, bi, outversion);
} else if (streq(outform, "null")) { } else if (streq(outform, "null")) {
/* do nothing */ /* do nothing */
} else { } else {

38
dtc.h

@ -31,6 +31,10 @@
#include <errno.h> #include <errno.h>
#include <unistd.h> #include <unistd.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <endian.h>
#include <byteswap.h>

#include "flat_dt.h"


static inline void die(char * str, ...) static inline void die(char * str, ...)
{ {
@ -74,7 +78,13 @@ typedef u32 cell_t;
#define cpu_to_be32(x) htonl(x) #define cpu_to_be32(x) htonl(x)
#define be32_to_cpu(x) ntohl(x) #define be32_to_cpu(x) ntohl(x)



#if __BYTE_ORDER == __BIG_ENDIAN
#define cpu_to_be64(x) (x)
#define be64_to_cpu(x) (x)
#else
#define cpu_to_be64(x) bswap_64(x)
#define be64_to_cpu(x) bswap_64(x)
#endif


#define streq(a, b) (strcmp((a), (b)) == 0) #define streq(a, b) (strcmp((a), (b)) == 0)
#define strneq(a, b, n) (strncmp((a), (b), (n)) == 0) #define strneq(a, b, n) (strncmp((a), (b), (n)) == 0)
@ -110,6 +120,7 @@ struct data data_copy_file(FILE *f, size_t len);


struct data data_append_data(struct data d, void *p, int len); struct data data_append_data(struct data d, void *p, int len);
struct data data_append_cell(struct data d, cell_t word); struct data data_append_cell(struct data d, cell_t word);
struct data data_append_addr(struct data d, u64 addr);
struct data data_append_byte(struct data d, uint8_t byte); struct data data_append_byte(struct data d, uint8_t byte);
struct data data_append_zeroes(struct data d, int len); struct data data_append_zeroes(struct data d, int len);
struct data data_append_align(struct data d, int align); struct data data_append_align(struct data d, int align);
@ -118,6 +129,8 @@ struct data data_add_fixup(struct data d, char *ref);


int data_is_one_string(struct data d); int data_is_one_string(struct data d);


struct data build_mem_reserve(struct data d);

/* DT constraints */ /* DT constraints */


#define MAX_PROPNAME_LEN 31 #define MAX_PROPNAME_LEN 31
@ -168,6 +181,16 @@ void add_child(struct node *parent, struct node *child);


int check_device_tree(struct node *dt); int check_device_tree(struct node *dt);


/* Boot info (tree plus memreserve information */

struct boot_info {
struct data mem_reserve_data; /* mem reserve from header */
struct node *dt; /* the device tree */
};

struct boot_info *build_boot_info(struct data mem_reserve_data,
struct node *tree);

/* Flattened trees */ /* Flattened trees */


enum flat_dt_format { enum flat_dt_format {
@ -175,20 +198,19 @@ enum flat_dt_format {
FFMT_ASM, FFMT_ASM,
}; };


void write_dt_blob(FILE *f, struct node *tree, int version, int reservenum); void write_dt_blob(FILE *f, struct boot_info *bi, int version);
void write_dt_asm(FILE *f, struct node *tree, int version, int reservenum); void write_dt_asm(FILE *f, struct boot_info *bi, int version);


struct node *dt_from_blob(FILE *f); struct boot_info *dt_from_blob(FILE *f);


/* Tree source */ /* Tree source */


void write_tree_source(FILE *f, struct node *tree, int level); void write_tree_source(FILE *f, struct boot_info *bi);

struct boot_info *dt_from_source(FILE *f);
struct node *dt_from_source(FILE *f);


/* FS trees */ /* FS trees */


struct node *dt_from_fs(char *dirname); struct boot_info *dt_from_fs(char *dirname);


/* misc */ /* misc */



109
flattree.c

@ -287,11 +287,12 @@ static void flatten_tree(struct node *tree, struct emitter *emit,
} }


static void make_bph(struct boot_param_header *bph, static void make_bph(struct boot_param_header *bph,
struct version_info *vi, struct version_info *vi,
int reservenum, struct data *mem_reserve_data,
int dtsize, int strsize) int dtsize, int strsize)
{ {
int reserve_off; int reserve_off;
int reservenum = mem_reserve_data->len / sizeof(struct reserve_entry);
int reservesize = (reservenum+1) * sizeof(struct reserve_entry); int reservesize = (reservenum+1) * sizeof(struct reserve_entry);


memset(bph, 0xff, sizeof(*bph)); memset(bph, 0xff, sizeof(*bph));
@ -316,14 +317,14 @@ static void make_bph(struct boot_param_header *bph,
bph->size_dt_strings = cpu_to_be32(strsize); bph->size_dt_strings = cpu_to_be32(strsize);
} }


void write_dt_blob(FILE *f, struct node *tree, int version, int reservenum) void write_dt_blob(FILE *f, struct boot_info *bi, int version)
{ {
struct version_info *vi = NULL; struct version_info *vi = NULL;
int i; int i;
struct data dtbuf = empty_data; struct data dtbuf = empty_data;
struct data strbuf = empty_data; struct data strbuf = empty_data;
struct boot_param_header bph; struct boot_param_header bph;
struct reserve_entry re = {.address = 0, .size = 0}; struct reserve_entry termre = {.address = 0, .size = 0};


for (i = 0; i < ARRAY_SIZE(version_table); i++) { for (i = 0; i < ARRAY_SIZE(version_table); i++) {
if (version_table[i].version == version) if (version_table[i].version == version)
@ -335,10 +336,11 @@ void write_dt_blob(FILE *f, struct node *tree, int version, int reservenum)
dtbuf = empty_data; dtbuf = empty_data;
strbuf = empty_data; strbuf = empty_data;


flatten_tree(tree, &bin_emitter, &dtbuf, &strbuf, vi); flatten_tree(bi->dt, &bin_emitter, &dtbuf, &strbuf, vi);
bin_emit_cell(&dtbuf, OF_DT_END); bin_emit_cell(&dtbuf, OF_DT_END);


make_bph(&bph, vi, reservenum, dtbuf.len, strbuf.len); /* Make header */
make_bph(&bph, vi, &bi->mem_reserve_data, dtbuf.len, strbuf.len);


fwrite(&bph, vi->hdr_size, 1, f); fwrite(&bph, vi->hdr_size, 1, f);


@ -346,8 +348,15 @@ void write_dt_blob(FILE *f, struct node *tree, int version, int reservenum)
for (i = vi->hdr_size; i < be32_to_cpu(bph.off_mem_rsvmap); i++) for (i = vi->hdr_size; i < be32_to_cpu(bph.off_mem_rsvmap); i++)
fputc(0, f); fputc(0, f);


for (i = 0; i < reservenum+1; i++) /*
fwrite(&re, sizeof(re), 1, f); * Reserve map entries.
* Since the blob is relocatable, the address of the map is not
* determinable here, so no entry is made for the DT itself.
* Each entry is an (address, size) pair of u64 values.
* Always supply a zero-sized temination entry.
*/
fwrite(bi->mem_reserve_data.val, bi->mem_reserve_data.len, 1, f);
fwrite(&termre, sizeof(termre), 1, f);


fwrite(dtbuf.val, dtbuf.len, 1, f); fwrite(dtbuf.val, dtbuf.len, 1, f);
fwrite(strbuf.val, strbuf.len, 1, f); fwrite(strbuf.val, strbuf.len, 1, f);
@ -373,7 +382,7 @@ void dump_stringtable_asm(FILE *f, struct data strbuf)
} }
} }


void write_dt_asm(FILE *f, struct node *tree, int version, int reservenum) void write_dt_asm(FILE *f, struct boot_info *bi, int version)
{ {
struct version_info *vi = NULL; struct version_info *vi = NULL;
int i; int i;
@ -417,20 +426,30 @@ void write_dt_asm(FILE *f, struct node *tree, int version, int reservenum)
fprintf(f, "\t.long\t_%s_strings_end - _%s_strings_start\t/* size_dt_strings */\n", fprintf(f, "\t.long\t_%s_strings_end - _%s_strings_start\t/* size_dt_strings */\n",
symprefix, symprefix); symprefix, symprefix);


/* align the reserve map to a doubleword boundary */ /*
* Reserve map entries.
* Align the reserve map to a doubleword boundary.
* Each entry is an (address, size) pair of u64 values.
* Since the ASM file variant can relocate and compute the address
* and size of the the device tree itself, and an entry for it.
* Always supply a zero-sized temination entry.
*/
asm_emit_align(f, 8); asm_emit_align(f, 8);
emit_label(f, symprefix, "reserve_map"); emit_label(f, symprefix, "reserve_map");
/* reserve map entry for the device tree itself */
fprintf(f, "\t.long\t0, _%s_blob_start\n", symprefix); fprintf(f, "\t.long\t0, _%s_blob_start\n", symprefix);
fprintf(f, "\t.long\t0, _%s_blob_end - _%s_blob_start\n", fprintf(f, "\t.long\t0, _%s_blob_end - _%s_blob_start\n",
symprefix, symprefix); symprefix, symprefix);
for (i = 0; i < reservenum+1; i++) {
fprintf(f, "\t.llong\t0\n"); if (bi->mem_reserve_data.len > 0) {
fprintf(f, "\t.llong\t0\n"); fprintf(f, "/* Memory reserve map from source file */\n");
asm_emit_data(f, bi->mem_reserve_data);
} }


fprintf(f, "\t.llong\t0\n");
fprintf(f, "\t.llong\t0\n");

emit_label(f, symprefix, "struct_start"); emit_label(f, symprefix, "struct_start");
flatten_tree(tree, &asm_emitter, f, &strbuf, vi); flatten_tree(bi->dt, &asm_emitter, f, &strbuf, vi);
fprintf(f, "\t.long\tOF_DT_END\n"); fprintf(f, "\t.long\tOF_DT_END\n");
emit_label(f, symprefix, "struct_end"); emit_label(f, symprefix, "struct_end");


@ -561,6 +580,43 @@ struct property *flat_read_property(struct inbuf *dtbuf, struct inbuf *strbuf,
return build_property(name, val, NULL); return build_property(name, val, NULL);
} }



static struct data flat_read_mem_reserve(struct inbuf *inb)
{
char *p;
int len = 0;
int done = 0;
cell_t cells[4];
struct data d;

d = empty_data;

/*
* Each entry is a pair of u64 (addr, size) values for 4 cell_t's.
* List terminates at an entry with size equal to zero.
*
* First pass, count entries.
*/
p = inb->ptr;
do {
flat_read_chunk(inb, &cells[0], 4 * sizeof(cell_t));
if (cells[2] == 0 && cells[3] == 0) {
done = 1;
} else {
++len;
}
} while (!done);

/*
* Back up for pass two, reading the whole data value.
*/
inb->ptr = p;
d = flat_read_data(inb, len * 4 * sizeof(cell_t));

return d;
}


static char *nodename_from_path(char *ppath, char *cpath) static char *nodename_from_path(char *ppath, char *cpath)
{ {
char *lslash; char *lslash;
@ -668,15 +724,19 @@ static struct node *unflatten_tree(struct inbuf *dtbuf,
return node; return node;
} }


struct node *dt_from_blob(FILE *f)
struct boot_info *dt_from_blob(FILE *f)
{ {
u32 magic, totalsize, off_dt, off_str, version, size_str; u32 magic, totalsize, version, size_str;
u32 off_dt, off_str, off_mem_rsvmap;
int rc; int rc;
char *blob; char *blob;
struct boot_param_header *bph; struct boot_param_header *bph;
char *p; char *p;
struct inbuf dtbuf, strbuf; struct inbuf dtbuf, strbuf;
struct inbuf memresvbuf;
int sizeleft; int sizeleft;
struct data mem_reserve_data;
struct node *tree; struct node *tree;
u32 val; u32 val;
int flags = 0; int flags = 0;
@ -735,18 +795,21 @@ struct node *dt_from_blob(FILE *f)


off_dt = be32_to_cpu(bph->off_dt_struct); off_dt = be32_to_cpu(bph->off_dt_struct);
off_str = be32_to_cpu(bph->off_dt_strings); off_str = be32_to_cpu(bph->off_dt_strings);
off_mem_rsvmap = be32_to_cpu(bph->off_mem_rsvmap);
version = be32_to_cpu(bph->version); version = be32_to_cpu(bph->version);


fprintf(stderr, "\tmagic:\t\t\t0x%x\n", magic); fprintf(stderr, "\tmagic:\t\t\t0x%x\n", magic);
fprintf(stderr, "\ttotalsize:\t\t%d\n", totalsize); fprintf(stderr, "\ttotalsize:\t\t%d\n", totalsize);
fprintf(stderr, "\toff_dt_struct:\t\t0x%x\n", off_dt); fprintf(stderr, "\toff_dt_struct:\t\t0x%x\n", off_dt);
fprintf(stderr, "\toff_dt_strings:\t\t0x%x\n", off_str); fprintf(stderr, "\toff_dt_strings:\t\t0x%x\n", off_str);
fprintf(stderr, "\toff_mem_rsvmap:\t\t0x%x\n", fprintf(stderr, "\toff_mem_rsvmap:\t\t0x%x\n", off_mem_rsvmap);
be32_to_cpu(bph->off_mem_rsvmap));
fprintf(stderr, "\tversion:\t\t0x%x\n", version ); fprintf(stderr, "\tversion:\t\t0x%x\n", version );
fprintf(stderr, "\tlast_comp_version:\t0x%x\n", fprintf(stderr, "\tlast_comp_version:\t0x%x\n",
be32_to_cpu(bph->last_comp_version)); be32_to_cpu(bph->last_comp_version));


if (off_mem_rsvmap >= totalsize)
die("Mem Reserve structure offset exceeds total size\n");

if (off_dt >= totalsize) if (off_dt >= totalsize)
die("DT structure offset exceeds total size\n"); die("DT structure offset exceeds total size\n");


@ -768,12 +831,16 @@ struct node *dt_from_blob(FILE *f)
flags |= FTF_FULLPATH | FTF_NAMEPROPS | FTF_VARALIGN; flags |= FTF_FULLPATH | FTF_NAMEPROPS | FTF_VARALIGN;
} }


inbuf_init(&memresvbuf,
blob + off_mem_rsvmap, blob + totalsize);
inbuf_init(&dtbuf, blob + off_dt, blob + totalsize); inbuf_init(&dtbuf, blob + off_dt, blob + totalsize);
inbuf_init(&strbuf, blob + off_str, blob + totalsize); inbuf_init(&strbuf, blob + off_str, blob + totalsize);


if (version >= 3) if (version >= 3)
strbuf.limit = strbuf.base + size_str; strbuf.limit = strbuf.base + size_str;


mem_reserve_data = flat_read_mem_reserve(&memresvbuf);

val = flat_read_word(&dtbuf); val = flat_read_word(&dtbuf);


if (val != OF_DT_BEGIN_NODE) if (val != OF_DT_BEGIN_NODE)
@ -787,5 +854,5 @@ struct node *dt_from_blob(FILE *f)


free(blob); free(blob);


return tree; return build_boot_info(mem_reserve_data, tree);
} }

4
fstree.c

@ -80,7 +80,7 @@ static struct node *read_fstree(char *dirname)
return tree; return tree;
} }


struct node *dt_from_fs(char *dirname) struct boot_info *dt_from_fs(char *dirname)
{ {
struct node *tree; struct node *tree;


@ -89,6 +89,6 @@ struct node *dt_from_fs(char *dirname)


fill_fullpaths(tree, ""); fill_fullpaths(tree, "");


return tree; return build_boot_info(empty_data, tree);
} }



12
livetree.c

@ -665,3 +665,15 @@ int check_device_tree(struct node *dt)


return 1; return 1;
} }

struct boot_info *build_boot_info(struct data mem_reserve_data,
struct node *tree)
{
struct boot_info *bi;

bi = xmalloc(sizeof(*bi));
bi->mem_reserve_data = mem_reserve_data;
bi->dt = tree;

return bi;
}

4
test.dts

@ -1,3 +1,7 @@
/memreserve/ 1000000000000000 0000000002000000;
/memreserve/ 2000000000000000-20ffffffffffffff;
/memreserve/ 0-13;

/ { / {
model = "MyBoardName"; model = "MyBoardName";
compatible = "MyBoardFamilyName"; compatible = "MyBoardFamilyName";

51
treesource.c

@ -20,20 +20,35 @@


#include "dtc.h" #include "dtc.h"


struct node *device_tree;

extern FILE *yyin; extern FILE *yyin;
extern int yyparse(void); extern int yyparse(void);
extern void yyerror(char const *);

struct boot_info *the_boot_info;

struct data build_mem_reserve(struct data d)
{
/*
* FIXME: Should reconcile the -R parameter here now?
*/
if (d.len % 16 != 0) {
yyerror("Memory Reserve entries are <u64 addr, u64 size>\n");
}
return d;
}



struct node *dt_from_source(FILE *f) struct boot_info *dt_from_source(FILE *f)
{ {
the_boot_info = NULL;

yyin = f; yyin = f;
if (yyparse() != 0) if (yyparse() != 0)
return NULL; return NULL;


fill_fullpaths(device_tree, ""); fill_fullpaths(the_boot_info->dt, "");


return device_tree; return the_boot_info;
} }


static void write_prefix(FILE *f, int level) static void write_prefix(FILE *f, int level)
@ -75,7 +90,8 @@ static enum proptype guess_type(struct property *prop)
} }


void write_tree_source(FILE *f, struct node *tree, int level)
void write_tree_source_node(FILE *f, struct node *tree, int level)
{ {
struct property *prop; struct property *prop;
struct node *child; struct node *child;
@ -133,8 +149,29 @@ void write_tree_source(FILE *f, struct node *tree, int level)
} }
for_each_child(tree, child) { for_each_child(tree, child) {
fprintf(f, "\n"); fprintf(f, "\n");
write_tree_source(f, child, level+1); write_tree_source_node(f, child, level+1);
} }
write_prefix(f, level); write_prefix(f, level);
fprintf(f, "};\n"); fprintf(f, "};\n");
} }


void write_tree_source(FILE *f, struct boot_info *bi)
{
int i;

assert((bi->mem_reserve_data.len % sizeof(struct reserve_entry)) == 0);
for (i = 0;
i < (bi->mem_reserve_data.len / sizeof(struct reserve_entry));
i++) {
struct reserve_entry *re = ((struct reserve_entry *)
bi->mem_reserve_data.val) + i;

fprintf(f, "/memreserve/\t%016llx-%016llx;\n",
(unsigned long long)re->address,
(unsigned long long)re->address + re->size - 1);
}

write_tree_source_node(f, bi->dt, 0);
}


Loading…
Cancel
Save