Browse Source

Rework tracking of reserve entries during processing. This is initial work

to allow more powerful handling of reserve entries.
main
David Gibson 19 years ago
parent
commit
f040d95b84
  1. 10
      data.c
  2. 17
      dtc-parser.y
  3. 23
      dtc.h
  4. 54
      flattree.c
  5. 2
      fstree.c
  6. 44
      livetree.c
  7. 27
      treesource.c

10
data.c

@ -222,6 +222,16 @@ 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_re(struct data d, struct reserve_entry *re)
{
struct reserve_entry bere;

bere.address = cpu_to_be64(re->address);
bere.size = cpu_to_be64(re->size);

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

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

17
dtc-parser.y

@ -43,7 +43,7 @@ extern struct boot_info *the_boot_info;
int datalen; int datalen;
int hexlen; int hexlen;
u64 addr; u64 addr;
struct reserve_entry re; struct reserve_info *re;
} }


%token DT_MEMRESERVE %token DT_MEMRESERVE
@ -59,7 +59,7 @@ extern struct boot_info *the_boot_info;


%type <data> propdata %type <data> propdata
%type <re> memreserve %type <re> memreserve
%type <data> memreserves %type <re> memreserves
%type <data> celllist %type <data> celllist
%type <data> bytestring %type <data> bytestring
%type <prop> propdef %type <prop> propdef
@ -79,22 +79,19 @@ sourcefile: memreserves devicetree {
} }
; ;


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


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



23
dtc.h

@ -120,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_re(struct data d, struct reserve_entry *re);
struct data data_append_addr(struct data d, u64 addr); 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);
@ -129,8 +130,6 @@ 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
@ -183,12 +182,28 @@ int check_device_tree(struct node *dt);


/* Boot info (tree plus memreserve information */ /* Boot info (tree plus memreserve information */


struct reserve_info {
struct reserve_entry re;

struct reserve_info *next;

char *label;
};

struct reserve_info *build_reserve_entry(u64 start, u64 len, char *label);
struct reserve_info *chain_reserve_entry(struct reserve_info *first,
struct reserve_info *list);
struct reserve_info *add_reserve_entry(struct reserve_info *list,
struct reserve_info *new);


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


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


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

54
flattree.c

@ -287,14 +287,25 @@ static void flatten_tree(struct node *tree, struct emitter *emit,
emit->endnode(etarget, tree->label); emit->endnode(etarget, tree->label);
} }


static struct data flatten_reserve_list(struct reserve_info *reservelist,
struct version_info *vi)
{
struct reserve_info *re;
struct data d = empty_data;

for (re = reservelist; re; re = re->next) {
d = data_append_re(d, &re->re);
}
return d;
}
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,
struct data *mem_reserve_data, int reservesize, 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); reservesize += sizeof(struct reserve_entry);


memset(bph, 0xff, sizeof(*bph)); memset(bph, 0xff, sizeof(*bph));


@ -324,6 +335,7 @@ void write_dt_blob(FILE *f, struct boot_info *bi, int version)
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 data reservebuf;
struct boot_param_header bph; struct boot_param_header bph;
struct reserve_entry termre = {.address = 0, .size = 0}; struct reserve_entry termre = {.address = 0, .size = 0};


@ -340,8 +352,10 @@ void write_dt_blob(FILE *f, struct boot_info *bi, int version)
flatten_tree(bi->dt, &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);


reservebuf = flatten_reserve_list(bi->reservelist, vi);

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


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


@ -356,7 +370,7 @@ void write_dt_blob(FILE *f, struct boot_info *bi, int version)
* Each entry is an (address, size) pair of u64 values. * Each entry is an (address, size) pair of u64 values.
* Always supply a zero-sized temination entry. * Always supply a zero-sized temination entry.
*/ */
fwrite(bi->mem_reserve_data.val, bi->mem_reserve_data.len, 1, f); fwrite(reservebuf.val, reservebuf.len, 1, f);
fwrite(&termre, sizeof(termre), 1, f); fwrite(&termre, sizeof(termre), 1, f);


fwrite(dtbuf.val, dtbuf.len, 1, f); fwrite(dtbuf.val, dtbuf.len, 1, f);
@ -388,6 +402,7 @@ 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;
struct data strbuf = empty_data; struct data strbuf = empty_data;
struct reserve_info *re;
char *symprefix = "dt"; char *symprefix = "dt";


for (i = 0; i < ARRAY_SIZE(version_table); i++) { for (i = 0; i < ARRAY_SIZE(version_table); i++) {
@ -441,13 +456,14 @@ void write_dt_asm(FILE *f, struct boot_info *bi, int version)
fprintf(f, "\t.quad\t0, _%s_blob_end - _%s_blob_start\n", fprintf(f, "\t.quad\t0, _%s_blob_end - _%s_blob_start\n",
symprefix, symprefix); symprefix, symprefix);


if (bi->mem_reserve_data.len > 0) { fprintf(f, "/* Memory reserve map from source file */\n");
fprintf(f, "/* Memory reserve map from source file */\n"); for (re = bi->reservelist; re; re = re->next) {
asm_emit_data(f, bi->mem_reserve_data); fprintf(f, "\t.quad\t0x%016llx\n\t.quad\t0x%016llx\n",
(unsigned long long)re->re.address,
(unsigned long long)re->re.size);
} }


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


emit_label(f, symprefix, "struct_start"); emit_label(f, symprefix, "struct_start");
flatten_tree(bi->dt, &asm_emitter, f, &strbuf, vi); flatten_tree(bi->dt, &asm_emitter, f, &strbuf, vi);
@ -582,11 +598,12 @@ static struct property *flat_read_property(struct inbuf *dtbuf,
} }




static struct data flat_read_mem_reserve(struct inbuf *inb) static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb)
{ {
struct reserve_info *reservelist = NULL;
struct reserve_info *new;
char *p; char *p;
struct reserve_entry re; struct reserve_entry re;
struct data d = empty_data;


/* /*
* Each entry is a pair of u64 (addr, size) values for 4 cell_t's. * Each entry is a pair of u64 (addr, size) values for 4 cell_t's.
@ -600,10 +617,11 @@ static struct data flat_read_mem_reserve(struct inbuf *inb)
if (re.size == 0) if (re.size == 0)
break; break;


d = data_append_data(d, &re, sizeof(re)); new = build_reserve_entry(re.address, re.size, NULL);
reservelist = add_reserve_entry(reservelist, new);
} }


return d; return reservelist;
} }




@ -726,7 +744,7 @@ struct boot_info *dt_from_blob(FILE *f)
struct inbuf dtbuf, strbuf; struct inbuf dtbuf, strbuf;
struct inbuf memresvbuf; struct inbuf memresvbuf;
int sizeleft; int sizeleft;
struct data mem_reserve_data; struct reserve_info *reservelist;
struct node *tree; struct node *tree;
u32 val; u32 val;
int flags = 0; int flags = 0;
@ -829,7 +847,7 @@ struct boot_info *dt_from_blob(FILE *f)
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); reservelist = flat_read_mem_reserve(&memresvbuf);


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


@ -844,5 +862,5 @@ struct boot_info *dt_from_blob(FILE *f)


free(blob); free(blob);


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

2
fstree.c

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


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


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



44
livetree.c

@ -108,6 +108,46 @@ void add_child(struct node *parent, struct node *child)
*p = child; *p = child;
} }


struct reserve_info *build_reserve_entry(u64 address, u64 size, char *label)
{
struct reserve_info *new = xmalloc(sizeof(*new));

new->re.address = address;
new->re.size = size;

new->next = NULL;

new->label = label;

return new;
}

struct reserve_info *chain_reserve_entry(struct reserve_info *first,
struct reserve_info *list)
{
assert(first->next == NULL);

first->next = list;
return first;
}

struct reserve_info *add_reserve_entry(struct reserve_info *list,
struct reserve_info *new)
{
struct reserve_info *last;

new->next = NULL;

if (! list)
return new;

for (last = list; last->next; last = last->next)
;

last->next = new;

return list;
}


/* /*
* Tree accessor functions * Tree accessor functions
@ -682,13 +722,13 @@ int check_device_tree(struct node *dt)
return 1; return 1;
} }


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


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


return bi; return bi;

27
treesource.c

@ -26,18 +26,6 @@ extern void yyerror(char const *);


struct boot_info *the_boot_info; 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) struct boot_info *dt_from_source(FILE *f)
{ {
the_boot_info = NULL; the_boot_info = NULL;
@ -158,19 +146,12 @@ static void write_tree_source_node(FILE *f, struct node *tree, int level)


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

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;


for (re = bi->reservelist; re; re = re->next) {
fprintf(f, "/memreserve/\t%016llx-%016llx;\n", fprintf(f, "/memreserve/\t%016llx-%016llx;\n",
(unsigned long long)be64_to_cpu(re->address), (unsigned long long)re->re.address,
(unsigned long long)(be64_to_cpu(re->address) (unsigned long long)(re->re.address + re->re.size - 1));
+ be64_to_cpu(re->size) - 1));
} }


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

Loading…
Cancel
Save