diff options
-rw-r--r-- | data.c | 10 | ||||
-rw-r--r-- | dtc-parser.y | 17 | ||||
-rw-r--r-- | dtc.h | 23 | ||||
-rw-r--r-- | flattree.c | 54 | ||||
-rw-r--r-- | fstree.c | 2 | ||||
-rw-r--r-- | livetree.c | 44 | ||||
-rw-r--r-- | treesource.c | 27 |
7 files changed, 119 insertions, 58 deletions
@@ -222,6 +222,16 @@ struct data data_append_cell(struct data d, cell_t word) 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) { u64 beaddr = cpu_to_be64(addr); diff --git a/dtc-parser.y b/dtc-parser.y index 1bfbfa3..16d2277 100644 --- a/dtc-parser.y +++ b/dtc-parser.y @@ -43,7 +43,7 @@ extern struct boot_info *the_boot_info; int datalen; int hexlen; u64 addr; - struct reserve_entry re; + struct reserve_info *re; } %token DT_MEMRESERVE @@ -59,7 +59,7 @@ extern struct boot_info *the_boot_info; %type <data> propdata %type <re> memreserve -%type <data> memreserves +%type <re> memreserves %type <data> celllist %type <data> bytestring %type <prop> propdef @@ -79,22 +79,19 @@ sourcefile: memreserves devicetree { } ; -memreserves: memreserves memreserve { - $$ = data_append_addr(data_append_addr($1, $2.address), - $2.size); +memreserves: memreserve memreserves { + $$ = chain_reserve_entry($1, $2); } | /* empty */ { - $$ = empty_data; + $$ = NULL; } ; memreserve: DT_MEMRESERVE DT_ADDR DT_ADDR ';' { - $$.address = $2; - $$.size = $3; + $$ = build_reserve_entry($2, $3, NULL); } | DT_MEMRESERVE DT_ADDR '-' DT_ADDR ';' { - $$.address = $2; - $$.size = $4 - $2 + 1; + $$ = build_reserve_entry($2, $4 - $2 + 1, NULL); } ; @@ -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_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_byte(struct data d, uint8_t byte); 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); -struct data build_mem_reserve(struct data d); - /* DT constraints */ #define MAX_PROPNAME_LEN 31 @@ -183,12 +182,28 @@ int check_device_tree(struct node *dt); /* 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 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 boot_info *build_boot_info(struct data mem_reserve_data, +struct boot_info *build_boot_info(struct reserve_info *reservelist, struct node *tree); /* Flattened trees */ @@ -287,14 +287,25 @@ static void flatten_tree(struct node *tree, struct emitter *emit, 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, struct version_info *vi, - struct data *mem_reserve_data, - int dtsize, int strsize) + int reservesize, 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); + + reservesize += sizeof(struct reserve_entry); memset(bph, 0xff, sizeof(*bph)); @@ -324,6 +335,7 @@ void write_dt_blob(FILE *f, struct boot_info *bi, int version) int i; struct data dtbuf = empty_data; struct data strbuf = empty_data; + struct data reservebuf; struct boot_param_header bph; 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); bin_emit_cell(&dtbuf, OF_DT_END); + reservebuf = flatten_reserve_list(bi->reservelist, vi); + /* 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); @@ -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. * 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(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; int i; struct data strbuf = empty_data; + struct reserve_info *re; char *symprefix = "dt"; 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", symprefix, symprefix); - 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, "/* Memory reserve map from source file */\n"); + for (re = bi->reservelist; re; re = re->next) { + 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"); + fprintf(f, "\t.quad\t0\n\t.quad\t0\n"); emit_label(f, symprefix, "struct_start"); 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; struct reserve_entry re; - struct data d = empty_data; /* * 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) 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 memresvbuf; int sizeleft; - struct data mem_reserve_data; + struct reserve_info *reservelist; struct node *tree; u32 val; int flags = 0; @@ -829,7 +847,7 @@ struct boot_info *dt_from_blob(FILE *f) if (version >= 3) 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); @@ -844,5 +862,5 @@ struct boot_info *dt_from_blob(FILE *f) free(blob); - return build_boot_info(mem_reserve_data, tree); + return build_boot_info(reservelist, tree); } @@ -89,6 +89,6 @@ struct boot_info *dt_from_fs(char *dirname) fill_fullpaths(tree, ""); - return build_boot_info(empty_data, tree); + return build_boot_info(NULL, tree); } @@ -108,6 +108,46 @@ void add_child(struct node *parent, struct node *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 @@ -682,13 +722,13 @@ int check_device_tree(struct node *dt) 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 boot_info *bi; bi = xmalloc(sizeof(*bi)); - bi->mem_reserve_data = mem_reserve_data; + bi->reservelist = reservelist; bi->dt = tree; return bi; diff --git a/treesource.c b/treesource.c index a568bf7..45c039e 100644 --- a/treesource.c +++ b/treesource.c @@ -26,18 +26,6 @@ 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 boot_info *dt_from_source(FILE *f) { 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) { - 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; + struct reserve_info *re; + for (re = bi->reservelist; re; re = re->next) { fprintf(f, "/memreserve/\t%016llx-%016llx;\n", - (unsigned long long)be64_to_cpu(re->address), - (unsigned long long)(be64_to_cpu(re->address) - + be64_to_cpu(re->size) - 1)); + (unsigned long long)re->re.address, + (unsigned long long)(re->re.address + re->re.size - 1)); } write_tree_source_node(f, bi->dt, 0); |