flattree.c (204488) | flattree.c (238742) |
---|---|
1/* 2 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005. 3 * 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License as 7 * published by the Free Software Foundation; either version 2 of the 8 * License, or (at your option) any later version. --- 38 unchanged lines hidden (view full) --- 47 FTF_BOOTCPUID|FTF_STRTABSIZE|FTF_STRUCTSIZE|FTF_NOPS}, 48}; 49 50struct emitter { 51 void (*cell)(void *, cell_t); 52 void (*string)(void *, char *, int); 53 void (*align)(void *, int); 54 void (*data)(void *, struct data); | 1/* 2 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005. 3 * 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License as 7 * published by the Free Software Foundation; either version 2 of the 8 * License, or (at your option) any later version. --- 38 unchanged lines hidden (view full) --- 47 FTF_BOOTCPUID|FTF_STRTABSIZE|FTF_STRUCTSIZE|FTF_NOPS}, 48}; 49 50struct emitter { 51 void (*cell)(void *, cell_t); 52 void (*string)(void *, char *, int); 53 void (*align)(void *, int); 54 void (*data)(void *, struct data); |
55 void (*beginnode)(void *, const char *); 56 void (*endnode)(void *, const char *); 57 void (*property)(void *, const char *); | 55 void (*beginnode)(void *, struct label *labels); 56 void (*endnode)(void *, struct label *labels); 57 void (*property)(void *, struct label *labels); |
58}; 59 60static void bin_emit_cell(void *e, cell_t val) 61{ 62 struct data *dtbuf = e; 63 64 *dtbuf = data_append_cell(*dtbuf, val); 65} --- 18 unchanged lines hidden (view full) --- 84 85static void bin_emit_data(void *e, struct data d) 86{ 87 struct data *dtbuf = e; 88 89 *dtbuf = data_append_data(*dtbuf, d.val, d.len); 90} 91 | 58}; 59 60static void bin_emit_cell(void *e, cell_t val) 61{ 62 struct data *dtbuf = e; 63 64 *dtbuf = data_append_cell(*dtbuf, val); 65} --- 18 unchanged lines hidden (view full) --- 84 85static void bin_emit_data(void *e, struct data d) 86{ 87 struct data *dtbuf = e; 88 89 *dtbuf = data_append_data(*dtbuf, d.val, d.len); 90} 91 |
92static void bin_emit_beginnode(void *e, const char *label) | 92static void bin_emit_beginnode(void *e, struct label *labels) |
93{ 94 bin_emit_cell(e, FDT_BEGIN_NODE); 95} 96 | 93{ 94 bin_emit_cell(e, FDT_BEGIN_NODE); 95} 96 |
97static void bin_emit_endnode(void *e, const char *label) | 97static void bin_emit_endnode(void *e, struct label *labels) |
98{ 99 bin_emit_cell(e, FDT_END_NODE); 100} 101 | 98{ 99 bin_emit_cell(e, FDT_END_NODE); 100} 101 |
102static void bin_emit_property(void *e, const char *label) | 102static void bin_emit_property(void *e, struct label *labels) |
103{ 104 bin_emit_cell(e, FDT_PROP); 105} 106 107static struct emitter bin_emitter = { 108 .cell = bin_emit_cell, 109 .string = bin_emit_string, 110 .align = bin_emit_align, --- 75 unchanged lines hidden (view full) --- 186 while ((d.len - off) >= 1) { 187 fprintf(f, "\t.byte\t0x%hhx\n", d.val[off]); 188 off += 1; 189 } 190 191 assert(off == d.len); 192} 193 | 103{ 104 bin_emit_cell(e, FDT_PROP); 105} 106 107static struct emitter bin_emitter = { 108 .cell = bin_emit_cell, 109 .string = bin_emit_string, 110 .align = bin_emit_align, --- 75 unchanged lines hidden (view full) --- 186 while ((d.len - off) >= 1) { 187 fprintf(f, "\t.byte\t0x%hhx\n", d.val[off]); 188 off += 1; 189 } 190 191 assert(off == d.len); 192} 193 |
194static void asm_emit_beginnode(void *e, const char *label) | 194static void asm_emit_beginnode(void *e, struct label *labels) |
195{ 196 FILE *f = e; | 195{ 196 FILE *f = e; |
197 struct label *l; |
|
197 | 198 |
198 if (label) { 199 fprintf(f, "\t.globl\t%s\n", label); 200 fprintf(f, "%s:\n", label); | 199 for_each_label(labels, l) { 200 fprintf(f, "\t.globl\t%s\n", l->label); 201 fprintf(f, "%s:\n", l->label); |
201 } 202 fprintf(f, "\t/* FDT_BEGIN_NODE */\n"); 203 asm_emit_cell(e, FDT_BEGIN_NODE); 204} 205 | 202 } 203 fprintf(f, "\t/* FDT_BEGIN_NODE */\n"); 204 asm_emit_cell(e, FDT_BEGIN_NODE); 205} 206 |
206static void asm_emit_endnode(void *e, const char *label) | 207static void asm_emit_endnode(void *e, struct label *labels) |
207{ 208 FILE *f = e; | 208{ 209 FILE *f = e; |
210 struct label *l; |
|
209 210 fprintf(f, "\t/* FDT_END_NODE */\n"); 211 asm_emit_cell(e, FDT_END_NODE); | 211 212 fprintf(f, "\t/* FDT_END_NODE */\n"); 213 asm_emit_cell(e, FDT_END_NODE); |
212 if (label) { 213 fprintf(f, "\t.globl\t%s_end\n", label); 214 fprintf(f, "%s_end:\n", label); | 214 for_each_label(labels, l) { 215 fprintf(f, "\t.globl\t%s_end\n", l->label); 216 fprintf(f, "%s_end:\n", l->label); |
215 } 216} 217 | 217 } 218} 219 |
218static void asm_emit_property(void *e, const char *label) | 220static void asm_emit_property(void *e, struct label *labels) |
219{ 220 FILE *f = e; | 221{ 222 FILE *f = e; |
223 struct label *l; |
|
221 | 224 |
222 if (label) { 223 fprintf(f, "\t.globl\t%s\n", label); 224 fprintf(f, "%s:\n", label); | 225 for_each_label(labels, l) { 226 fprintf(f, "\t.globl\t%s\n", l->label); 227 fprintf(f, "%s:\n", l->label); |
225 } 226 fprintf(f, "\t/* FDT_PROP */\n"); 227 asm_emit_cell(e, FDT_PROP); 228} 229 230static struct emitter asm_emitter = { 231 .cell = asm_emit_cell, 232 .string = asm_emit_string, --- 22 unchanged lines hidden (view full) --- 255static void flatten_tree(struct node *tree, struct emitter *emit, 256 void *etarget, struct data *strbuf, 257 struct version_info *vi) 258{ 259 struct property *prop; 260 struct node *child; 261 int seen_name_prop = 0; 262 | 228 } 229 fprintf(f, "\t/* FDT_PROP */\n"); 230 asm_emit_cell(e, FDT_PROP); 231} 232 233static struct emitter asm_emitter = { 234 .cell = asm_emit_cell, 235 .string = asm_emit_string, --- 22 unchanged lines hidden (view full) --- 258static void flatten_tree(struct node *tree, struct emitter *emit, 259 void *etarget, struct data *strbuf, 260 struct version_info *vi) 261{ 262 struct property *prop; 263 struct node *child; 264 int seen_name_prop = 0; 265 |
263 emit->beginnode(etarget, tree->label); | 266 emit->beginnode(etarget, tree->labels); |
264 265 if (vi->flags & FTF_FULLPATH) 266 emit->string(etarget, tree->fullpath, 0); 267 else 268 emit->string(etarget, tree->name, 0); 269 270 emit->align(etarget, sizeof(cell_t)); 271 272 for_each_property(tree, prop) { 273 int nameoff; 274 275 if (streq(prop->name, "name")) 276 seen_name_prop = 1; 277 278 nameoff = stringtable_insert(strbuf, prop->name); 279 | 267 268 if (vi->flags & FTF_FULLPATH) 269 emit->string(etarget, tree->fullpath, 0); 270 else 271 emit->string(etarget, tree->name, 0); 272 273 emit->align(etarget, sizeof(cell_t)); 274 275 for_each_property(tree, prop) { 276 int nameoff; 277 278 if (streq(prop->name, "name")) 279 seen_name_prop = 1; 280 281 nameoff = stringtable_insert(strbuf, prop->name); 282 |
280 emit->property(etarget, prop->label); | 283 emit->property(etarget, prop->labels); |
281 emit->cell(etarget, prop->val.len); 282 emit->cell(etarget, nameoff); 283 284 if ((vi->flags & FTF_VARALIGN) && (prop->val.len >= 8)) 285 emit->align(etarget, 8); 286 287 emit->data(etarget, prop->val); 288 emit->align(etarget, sizeof(cell_t)); --- 10 unchanged lines hidden (view full) --- 299 emit->string(etarget, tree->name, tree->basenamelen); 300 emit->align(etarget, sizeof(cell_t)); 301 } 302 303 for_each_child(tree, child) { 304 flatten_tree(child, emit, etarget, strbuf, vi); 305 } 306 | 284 emit->cell(etarget, prop->val.len); 285 emit->cell(etarget, nameoff); 286 287 if ((vi->flags & FTF_VARALIGN) && (prop->val.len >= 8)) 288 emit->align(etarget, 8); 289 290 emit->data(etarget, prop->val); 291 emit->align(etarget, sizeof(cell_t)); --- 10 unchanged lines hidden (view full) --- 302 emit->string(etarget, tree->name, tree->basenamelen); 303 emit->align(etarget, sizeof(cell_t)); 304 } 305 306 for_each_child(tree, child) { 307 flatten_tree(child, emit, etarget, strbuf, vi); 308 } 309 |
307 emit->endnode(etarget, tree->label); | 310 emit->endnode(etarget, tree->labels); |
308} 309 310static struct data flatten_reserve_list(struct reserve_info *reservelist, 311 struct version_info *vi) 312{ 313 struct reserve_info *re; 314 struct data d = empty_data; 315 static struct fdt_reserve_entry null_re = {0,0}; --- 204 unchanged lines hidden (view full) --- 520 521 fprintf(f, "/* Memory reserve map from source file */\n"); 522 523 /* 524 * Use .long on high and low halfs of u64s to avoid .quad 525 * as it appears .quad isn't available in some assemblers. 526 */ 527 for (re = bi->reservelist; re; re = re->next) { | 311} 312 313static struct data flatten_reserve_list(struct reserve_info *reservelist, 314 struct version_info *vi) 315{ 316 struct reserve_info *re; 317 struct data d = empty_data; 318 static struct fdt_reserve_entry null_re = {0,0}; --- 204 unchanged lines hidden (view full) --- 523 524 fprintf(f, "/* Memory reserve map from source file */\n"); 525 526 /* 527 * Use .long on high and low halfs of u64s to avoid .quad 528 * as it appears .quad isn't available in some assemblers. 529 */ 530 for (re = bi->reservelist; re; re = re->next) { |
528 if (re->label) { 529 fprintf(f, "\t.globl\t%s\n", re->label); 530 fprintf(f, "%s:\n", re->label); | 531 struct label *l; 532 533 for_each_label(re->labels, l) { 534 fprintf(f, "\t.globl\t%s\n", l->label); 535 fprintf(f, "%s:\n", l->label); |
531 } 532 ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.address >> 32)); 533 ASM_EMIT_BELONG(f, "0x%08x", 534 (unsigned int)(re->re.address & 0xffffffff)); 535 ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.size >> 32)); 536 ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.size & 0xffffffff)); 537 } 538 for (i = 0; i < reservenum; i++) { --- 140 unchanged lines hidden (view full) --- 679 680 name = flat_read_stringtable(strbuf, stroff); 681 682 if ((flags & FTF_VARALIGN) && (proplen >= 8)) 683 flat_realign(dtbuf, 8); 684 685 val = flat_read_data(dtbuf, proplen); 686 | 536 } 537 ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.address >> 32)); 538 ASM_EMIT_BELONG(f, "0x%08x", 539 (unsigned int)(re->re.address & 0xffffffff)); 540 ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.size >> 32)); 541 ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.size & 0xffffffff)); 542 } 543 for (i = 0; i < reservenum; i++) { --- 140 unchanged lines hidden (view full) --- 684 685 name = flat_read_stringtable(strbuf, stroff); 686 687 if ((flags & FTF_VARALIGN) && (proplen >= 8)) 688 flat_realign(dtbuf, 8); 689 690 val = flat_read_data(dtbuf, proplen); 691 |
687 return build_property(name, val, NULL); | 692 return build_property(name, val); |
688} 689 690 691static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb) 692{ 693 struct reserve_info *reservelist = NULL; 694 struct reserve_info *new; | 693} 694 695 696static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb) 697{ 698 struct reserve_info *reservelist = NULL; 699 struct reserve_info *new; |
695 const char *p; | |
696 struct fdt_reserve_entry re; 697 698 /* 699 * Each entry is a pair of u64 (addr, size) values for 4 cell_t's. 700 * List terminates at an entry with size equal to zero. 701 * 702 * First pass, count entries. 703 */ | 700 struct fdt_reserve_entry re; 701 702 /* 703 * Each entry is a pair of u64 (addr, size) values for 4 cell_t's. 704 * List terminates at an entry with size equal to zero. 705 * 706 * First pass, count entries. 707 */ |
704 p = inb->ptr; | |
705 while (1) { 706 flat_read_chunk(inb, &re, sizeof(re)); 707 re.address = fdt64_to_cpu(re.address); 708 re.size = fdt64_to_cpu(re.size); 709 if (re.size == 0) 710 break; 711 | 708 while (1) { 709 flat_read_chunk(inb, &re, sizeof(re)); 710 re.address = fdt64_to_cpu(re.address); 711 re.size = fdt64_to_cpu(re.size); 712 if (re.size == 0) 713 break; 714 |
712 new = build_reserve_entry(re.address, re.size, NULL); | 715 new = build_reserve_entry(re.address, re.size); |
713 reservelist = add_reserve_entry(reservelist, new); 714 } 715 716 return reservelist; 717} 718 719 720static char *nodename_from_path(const char *ppath, const char *cpath) --- 71 unchanged lines hidden (view full) --- 792 } while (val != FDT_END_NODE); 793 794 return node; 795} 796 797 798struct boot_info *dt_from_blob(const char *fname) 799{ | 716 reservelist = add_reserve_entry(reservelist, new); 717 } 718 719 return reservelist; 720} 721 722 723static char *nodename_from_path(const char *ppath, const char *cpath) --- 71 unchanged lines hidden (view full) --- 795 } while (val != FDT_END_NODE); 796 797 return node; 798} 799 800 801struct boot_info *dt_from_blob(const char *fname) 802{ |
800 struct dtc_file *dtcf; | 803 FILE *f; |
801 uint32_t magic, totalsize, version, size_dt, boot_cpuid_phys; 802 uint32_t off_dt, off_str, off_mem_rsvmap; 803 int rc; 804 char *blob; 805 struct fdt_header *fdt; 806 char *p; 807 struct inbuf dtbuf, strbuf; 808 struct inbuf memresvbuf; 809 int sizeleft; 810 struct reserve_info *reservelist; 811 struct node *tree; 812 uint32_t val; 813 int flags = 0; 814 | 804 uint32_t magic, totalsize, version, size_dt, boot_cpuid_phys; 805 uint32_t off_dt, off_str, off_mem_rsvmap; 806 int rc; 807 char *blob; 808 struct fdt_header *fdt; 809 char *p; 810 struct inbuf dtbuf, strbuf; 811 struct inbuf memresvbuf; 812 int sizeleft; 813 struct reserve_info *reservelist; 814 struct node *tree; 815 uint32_t val; 816 int flags = 0; 817 |
815 dtcf = dtc_open_file(fname, NULL); | 818 f = srcfile_relative_open(fname, NULL); |
816 | 819 |
817 rc = fread(&magic, sizeof(magic), 1, dtcf->file); 818 if (ferror(dtcf->file)) | 820 rc = fread(&magic, sizeof(magic), 1, f); 821 if (ferror(f)) |
819 die("Error reading DT blob magic number: %s\n", 820 strerror(errno)); 821 if (rc < 1) { | 822 die("Error reading DT blob magic number: %s\n", 823 strerror(errno)); 824 if (rc < 1) { |
822 if (feof(dtcf->file)) | 825 if (feof(f)) |
823 die("EOF reading DT blob magic number\n"); 824 else 825 die("Mysterious short read reading magic number\n"); 826 } 827 828 magic = fdt32_to_cpu(magic); 829 if (magic != FDT_MAGIC) 830 die("Blob has incorrect magic number\n"); 831 | 826 die("EOF reading DT blob magic number\n"); 827 else 828 die("Mysterious short read reading magic number\n"); 829 } 830 831 magic = fdt32_to_cpu(magic); 832 if (magic != FDT_MAGIC) 833 die("Blob has incorrect magic number\n"); 834 |
832 rc = fread(&totalsize, sizeof(totalsize), 1, dtcf->file); 833 if (ferror(dtcf->file)) | 835 rc = fread(&totalsize, sizeof(totalsize), 1, f); 836 if (ferror(f)) |
834 die("Error reading DT blob size: %s\n", strerror(errno)); 835 if (rc < 1) { | 837 die("Error reading DT blob size: %s\n", strerror(errno)); 838 if (rc < 1) { |
836 if (feof(dtcf->file)) | 839 if (feof(f)) |
837 die("EOF reading DT blob size\n"); 838 else 839 die("Mysterious short read reading blob size\n"); 840 } 841 842 totalsize = fdt32_to_cpu(totalsize); 843 if (totalsize < FDT_V1_SIZE) 844 die("DT blob size (%d) is too small\n", totalsize); 845 846 blob = xmalloc(totalsize); 847 848 fdt = (struct fdt_header *)blob; 849 fdt->magic = cpu_to_fdt32(magic); 850 fdt->totalsize = cpu_to_fdt32(totalsize); 851 852 sizeleft = totalsize - sizeof(magic) - sizeof(totalsize); 853 p = blob + sizeof(magic) + sizeof(totalsize); 854 855 while (sizeleft) { | 840 die("EOF reading DT blob size\n"); 841 else 842 die("Mysterious short read reading blob size\n"); 843 } 844 845 totalsize = fdt32_to_cpu(totalsize); 846 if (totalsize < FDT_V1_SIZE) 847 die("DT blob size (%d) is too small\n", totalsize); 848 849 blob = xmalloc(totalsize); 850 851 fdt = (struct fdt_header *)blob; 852 fdt->magic = cpu_to_fdt32(magic); 853 fdt->totalsize = cpu_to_fdt32(totalsize); 854 855 sizeleft = totalsize - sizeof(magic) - sizeof(totalsize); 856 p = blob + sizeof(magic) + sizeof(totalsize); 857 858 while (sizeleft) { |
856 if (feof(dtcf->file)) | 859 if (feof(f)) |
857 die("EOF before reading %d bytes of DT blob\n", 858 totalsize); 859 | 860 die("EOF before reading %d bytes of DT blob\n", 861 totalsize); 862 |
860 rc = fread(p, 1, sizeleft, dtcf->file); 861 if (ferror(dtcf->file)) | 863 rc = fread(p, 1, sizeleft, f); 864 if (ferror(f)) |
862 die("Error reading DT blob: %s\n", 863 strerror(errno)); 864 865 sizeleft -= rc; 866 p += rc; 867 } 868 869 off_dt = fdt32_to_cpu(fdt->off_dt_struct); --- 46 unchanged lines hidden (view full) --- 916 tree = unflatten_tree(&dtbuf, &strbuf, "", flags); 917 918 val = flat_read_word(&dtbuf); 919 if (val != FDT_END) 920 die("Device tree blob doesn't end with FDT_END\n"); 921 922 free(blob); 923 | 865 die("Error reading DT blob: %s\n", 866 strerror(errno)); 867 868 sizeleft -= rc; 869 p += rc; 870 } 871 872 off_dt = fdt32_to_cpu(fdt->off_dt_struct); --- 46 unchanged lines hidden (view full) --- 919 tree = unflatten_tree(&dtbuf, &strbuf, "", flags); 920 921 val = flat_read_word(&dtbuf); 922 if (val != FDT_END) 923 die("Device tree blob doesn't end with FDT_END\n"); 924 925 free(blob); 926 |
924 dtc_close_file(dtcf); | 927 fclose(f); |
925 926 return build_boot_info(reservelist, tree, boot_cpuid_phys); 927} | 928 929 return build_boot_info(reservelist, tree, boot_cpuid_phys); 930} |