Support for specifying memreserve ranges in the source format, based on
a patch by Jon Loeliger <jdl AT freescale.com>, although tweaked substantially.main
parent
586606e35d
commit
f0517db250
2
Makefile
2
Makefile
|
@ -14,7 +14,7 @@ dtc: $(OBJS)
|
|||
$(LINK.c) -o $@ $^
|
||||
|
||||
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) $<
|
||||
|
|
7
data.c
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));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return data_append_data(d, &byte, 1);
|
||||
|
|
26
dtc-lexer.l
26
dtc-lexer.l
|
@ -22,6 +22,7 @@
|
|||
|
||||
%x CELLDATA
|
||||
%x BYTESTRING
|
||||
%x MEMRESERVE
|
||||
|
||||
PROPCHAR [a-zA-Z0-9,._+*#?-]
|
||||
UNITCHAR [0-9a-f,]
|
||||
|
@ -53,6 +54,29 @@ REFCHAR ({PROPCHAR}|{UNITCHAR}|[/@])
|
|||
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]+ {
|
||||
if (yyleng > 2*sizeof(yylval.cval)) {
|
||||
fprintf(stderr,
|
||||
|
@ -116,7 +140,7 @@ REFCHAR ({PROPCHAR}|{UNITCHAR}|[/@])
|
|||
|
||||
<*>"//".*\n /* eat line comments */
|
||||
|
||||
. {
|
||||
<*>. {
|
||||
switch (yytext[0]) {
|
||||
case '<':
|
||||
DPRINT("CELLDATA\n");
|
||||
|
|
39
dtc-parser.y
39
dtc-parser.y
|
@ -24,7 +24,7 @@
|
|||
int yylex (void);
|
||||
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;
|
||||
int datalen;
|
||||
int hexlen;
|
||||
u64 addr;
|
||||
struct reserve_entry re;
|
||||
}
|
||||
|
||||
%token DT_MEMRESERVE
|
||||
%token <addr> DT_ADDR
|
||||
%token <str> DT_PROPNAME
|
||||
%token <str> DT_NODENAME
|
||||
%token <cval> DT_CELL
|
||||
|
@ -51,11 +55,14 @@ extern struct node *device_tree;
|
|||
%token <str> DT_REF
|
||||
|
||||
%type <data> propdata
|
||||
%type <re> memreserve
|
||||
%type <data> memreserves
|
||||
%type <data> celllist
|
||||
%type <data> bytestring
|
||||
%type <prop> propdef
|
||||
%type <proplist> proplist
|
||||
|
||||
%type <node> devicetree
|
||||
%type <node> nodedef
|
||||
%type <node> subnode
|
||||
%type <nodelist> subnodes
|
||||
|
@ -66,9 +73,33 @@ extern struct node *device_tree;
|
|||
|
||||
%%
|
||||
|
||||
devicetree: {
|
||||
assert(device_tree == NULL);
|
||||
} '/' nodedef { device_tree = name_node($3, "", NULL); }
|
||||
sourcefile: memreserves devicetree {
|
||||
the_boot_info = build_boot_info($1, $2);
|
||||
}
|
||||
;
|
||||
|
||||
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 '}' ';' {
|
||||
|
|
18
dtc.c
18
dtc.c
|
@ -102,7 +102,7 @@ static void usage(void)
|
|||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
struct node *dt;
|
||||
struct boot_info *bi;
|
||||
char *inform = "dts";
|
||||
char *outform = "dts";
|
||||
char *outname = "-";
|
||||
|
@ -151,12 +151,12 @@ int main(int argc, char *argv[])
|
|||
|
||||
if (streq(inform, "dts")) {
|
||||
inf = dtc_open_file(arg);
|
||||
dt = dt_from_source(inf);
|
||||
bi = dt_from_source(inf);
|
||||
} else if (streq(inform, "fs")) {
|
||||
dt = dt_from_fs(arg);
|
||||
bi = dt_from_fs(arg);
|
||||
} else if(streq(inform, "dtb")) {
|
||||
inf = dtc_open_file(arg);
|
||||
dt = dt_from_blob(inf);
|
||||
bi = dt_from_blob(inf);
|
||||
} else {
|
||||
die("Unknown input format \"%s\"\n", inform);
|
||||
}
|
||||
|
@ -164,10 +164,10 @@ int main(int argc, char *argv[])
|
|||
if (inf && (inf != stdin))
|
||||
fclose(inf);
|
||||
|
||||
if (! dt)
|
||||
if (! bi || ! bi->dt)
|
||||
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");
|
||||
if (! force)
|
||||
exit(1);
|
||||
|
@ -183,11 +183,11 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
if (streq(outform, "dts")) {
|
||||
write_tree_source(outf, dt, 0);
|
||||
write_tree_source(outf, bi);
|
||||
} else if (streq(outform, "dtb")) {
|
||||
write_dt_blob(outf, dt, outversion, reservenum);
|
||||
write_dt_blob(outf, bi, outversion);
|
||||
} else if (streq(outform, "asm")) {
|
||||
write_dt_asm(outf, dt, outversion, reservenum);
|
||||
write_dt_asm(outf, bi, outversion);
|
||||
} else if (streq(outform, "null")) {
|
||||
/* do nothing */
|
||||
} else {
|
||||
|
|
38
dtc.h
38
dtc.h
|
@ -31,6 +31,10 @@
|
|||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <netinet/in.h>
|
||||
#include <endian.h>
|
||||
#include <byteswap.h>
|
||||
|
||||
#include "flat_dt.h"
|
||||
|
||||
static inline void die(char * str, ...)
|
||||
{
|
||||
|
@ -74,7 +78,13 @@ typedef u32 cell_t;
|
|||
#define cpu_to_be32(x) htonl(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 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_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_zeroes(struct data d, int len);
|
||||
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);
|
||||
|
||||
struct data build_mem_reserve(struct data d);
|
||||
|
||||
/* DT constraints */
|
||||
|
||||
#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);
|
||||
|
||||
/* 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 */
|
||||
|
||||
enum flat_dt_format {
|
||||
|
@ -175,20 +198,19 @@ enum flat_dt_format {
|
|||
FFMT_ASM,
|
||||
};
|
||||
|
||||
void write_dt_blob(FILE *f, struct node *tree, int version, int reservenum);
|
||||
void write_dt_asm(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 boot_info *bi, int version);
|
||||
|
||||
struct node *dt_from_blob(FILE *f);
|
||||
struct boot_info *dt_from_blob(FILE *f);
|
||||
|
||||
/* Tree source */
|
||||
|
||||
void write_tree_source(FILE *f, struct node *tree, int level);
|
||||
|
||||
struct node *dt_from_source(FILE *f);
|
||||
void write_tree_source(FILE *f, struct boot_info *bi);
|
||||
struct boot_info *dt_from_source(FILE *f);
|
||||
|
||||
/* FS trees */
|
||||
|
||||
struct node *dt_from_fs(char *dirname);
|
||||
struct boot_info *dt_from_fs(char *dirname);
|
||||
|
||||
/* misc */
|
||||
|
||||
|
|
109
flattree.c
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,
|
||||
struct version_info *vi,
|
||||
int reservenum,
|
||||
int dtsize, int strsize)
|
||||
struct version_info *vi,
|
||||
struct data *mem_reserve_data,
|
||||
int dtsize, int strsize)
|
||||
{
|
||||
int reserve_off;
|
||||
int reservenum = mem_reserve_data->len / sizeof(struct reserve_entry);
|
||||
int reservesize = (reservenum+1) * sizeof(struct reserve_entry);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
int i;
|
||||
struct data dtbuf = empty_data;
|
||||
struct data strbuf = empty_data;
|
||||
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++) {
|
||||
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;
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
|
@ -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++)
|
||||
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(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;
|
||||
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",
|
||||
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);
|
||||
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_end - _%s_blob_start\n",
|
||||
symprefix, symprefix);
|
||||
for (i = 0; i < reservenum+1; i++) {
|
||||
fprintf(f, "\t.llong\t0\n");
|
||||
fprintf(f, "\t.llong\t0\n");
|
||||
|
||||
if (bi->mem_reserve_data.len > 0) {
|
||||
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");
|
||||
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");
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
char *lslash;
|
||||
|
@ -668,15 +724,19 @@ static struct node *unflatten_tree(struct inbuf *dtbuf,
|
|||
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;
|
||||
char *blob;
|
||||
struct boot_param_header *bph;
|
||||
char *p;
|
||||
struct inbuf dtbuf, strbuf;
|
||||
struct inbuf memresvbuf;
|
||||
int sizeleft;
|
||||
struct data mem_reserve_data;
|
||||
struct node *tree;
|
||||
u32 val;
|
||||
int flags = 0;
|
||||
|
@ -735,18 +795,21 @@ struct node *dt_from_blob(FILE *f)
|
|||
|
||||
off_dt = be32_to_cpu(bph->off_dt_struct);
|
||||
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);
|
||||
|
||||
fprintf(stderr, "\tmagic:\t\t\t0x%x\n", magic);
|
||||
fprintf(stderr, "\ttotalsize:\t\t%d\n", totalsize);
|
||||
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_mem_rsvmap:\t\t0x%x\n",
|
||||
be32_to_cpu(bph->off_mem_rsvmap));
|
||||
fprintf(stderr, "\toff_mem_rsvmap:\t\t0x%x\n", off_mem_rsvmap);
|
||||
fprintf(stderr, "\tversion:\t\t0x%x\n", version );
|
||||
fprintf(stderr, "\tlast_comp_version:\t0x%x\n",
|
||||
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)
|
||||
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;
|
||||
}
|
||||
|
||||
inbuf_init(&memresvbuf,
|
||||
blob + off_mem_rsvmap, blob + totalsize);
|
||||
inbuf_init(&dtbuf, blob + off_dt, blob + totalsize);
|
||||
inbuf_init(&strbuf, blob + off_str, blob + totalsize);
|
||||
|
||||
if (version >= 3)
|
||||
strbuf.limit = strbuf.base + size_str;
|
||||
|
||||
mem_reserve_data = flat_read_mem_reserve(&memresvbuf);
|
||||
|
||||
val = flat_read_word(&dtbuf);
|
||||
|
||||
if (val != OF_DT_BEGIN_NODE)
|
||||
|
@ -787,5 +854,5 @@ struct node *dt_from_blob(FILE *f)
|
|||
|
||||
free(blob);
|
||||
|
||||
return tree;
|
||||
return build_boot_info(mem_reserve_data, tree);
|
||||
}
|
||||
|
|
4
fstree.c
4
fstree.c
|
@ -80,7 +80,7 @@ static struct node *read_fstree(char *dirname)
|
|||
return tree;
|
||||
}
|
||||
|
||||
struct node *dt_from_fs(char *dirname)
|
||||
struct boot_info *dt_from_fs(char *dirname)
|
||||
{
|
||||
struct node *tree;
|
||||
|
||||
|
@ -89,6 +89,6 @@ struct node *dt_from_fs(char *dirname)
|
|||
|
||||
fill_fullpaths(tree, "");
|
||||
|
||||
return tree;
|
||||
return build_boot_info(empty_data, tree);
|
||||
}
|
||||
|
||||
|
|
12
livetree.c
12
livetree.c
|
@ -665,3 +665,15 @@ int check_device_tree(struct node *dt)
|
|||
|
||||
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
4
test.dts
|
@ -1,3 +1,7 @@
|
|||
/memreserve/ 1000000000000000 0000000002000000;
|
||||
/memreserve/ 2000000000000000-20ffffffffffffff;
|
||||
/memreserve/ 0-13;
|
||||
|
||||
/ {
|
||||
model = "MyBoardName";
|
||||
compatible = "MyBoardFamilyName";
|
||||
|
|
51
treesource.c
51
treesource.c
|
@ -20,20 +20,35 @@
|
|||
|
||||
#include "dtc.h"
|
||||
|
||||
struct node *device_tree;
|
||||
|
||||
extern FILE *yyin;
|
||||
extern int yyparse(void);
|
||||
extern void yyerror(char const *);
|
||||
|
||||
struct node *dt_from_source(FILE *f)
|
||||
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 boot_info *dt_from_source(FILE *f)
|
||||
{
|
||||
the_boot_info = NULL;
|
||||
|
||||
yyin = f;
|
||||
if (yyparse() != 0)
|
||||
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)
|
||||
|
@ -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 node *child;
|
||||
|
@ -133,8 +149,29 @@ void write_tree_source(FILE *f, struct node *tree, int level)
|
|||
}
|
||||
for_each_child(tree, child) {
|
||||
fprintf(f, "\n");
|
||||
write_tree_source(f, child, level+1);
|
||||
write_tree_source_node(f, child, level+1);
|
||||
}
|
||||
write_prefix(f, level);
|
||||
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…
Reference in New Issue