aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/dtc/flattree.c
diff options
context:
space:
mode:
authorJohn Bonesio <bones@secretlab.ca>2010-11-17 18:28:20 -0500
committerGrant Likely <grant.likely@secretlab.ca>2011-01-03 18:02:49 -0500
commit658f29a51e9830e620bb9a1ce3534b318a38bfeb (patch)
treee6cc7cd9b9e17d97308619fd8516b77bcc038114 /scripts/dtc/flattree.c
parentcd1e65044d4473cca9a01bae7b7938f065044a4b (diff)
of/flattree: Update dtc to current mainline.
Pull in recent changes from the main dtc repository. These changes primarily allow multiple device trees to be declared which are merged by dtc. This feature allows us to include a basic dts file and then provide more information for the specific system through the merging functionality. Changes pulled from git://git.jdl.com/software/dtc.git commit id: 37c0b6a0, "dtc: Add code to make diffing trees easier" Signed-off-by: John Bonesio <bones@secretlab.ca> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'scripts/dtc/flattree.c')
-rw-r--r--scripts/dtc/flattree.c192
1 files changed, 109 insertions, 83 deletions
diff --git a/scripts/dtc/flattree.c b/scripts/dtc/flattree.c
index 76acd28c068d..ead0332c87e1 100644
--- a/scripts/dtc/flattree.c
+++ b/scripts/dtc/flattree.c
@@ -52,9 +52,9 @@ struct emitter {
52 void (*string)(void *, char *, int); 52 void (*string)(void *, char *, int);
53 void (*align)(void *, int); 53 void (*align)(void *, int);
54 void (*data)(void *, struct data); 54 void (*data)(void *, struct data);
55 void (*beginnode)(void *, const char *); 55 void (*beginnode)(void *, struct label *labels);
56 void (*endnode)(void *, const char *); 56 void (*endnode)(void *, struct label *labels);
57 void (*property)(void *, const char *); 57 void (*property)(void *, struct label *labels);
58}; 58};
59 59
60static void bin_emit_cell(void *e, cell_t val) 60static void bin_emit_cell(void *e, cell_t val)
@@ -89,17 +89,17 @@ static void bin_emit_data(void *e, struct data d)
89 *dtbuf = data_append_data(*dtbuf, d.val, d.len); 89 *dtbuf = data_append_data(*dtbuf, d.val, d.len);
90} 90}
91 91
92static void bin_emit_beginnode(void *e, const char *label) 92static void bin_emit_beginnode(void *e, struct label *labels)
93{ 93{
94 bin_emit_cell(e, FDT_BEGIN_NODE); 94 bin_emit_cell(e, FDT_BEGIN_NODE);
95} 95}
96 96
97static void bin_emit_endnode(void *e, const char *label) 97static void bin_emit_endnode(void *e, struct label *labels)
98{ 98{
99 bin_emit_cell(e, FDT_END_NODE); 99 bin_emit_cell(e, FDT_END_NODE);
100} 100}
101 101
102static void bin_emit_property(void *e, const char *label) 102static void bin_emit_property(void *e, struct label *labels)
103{ 103{
104 bin_emit_cell(e, FDT_PROP); 104 bin_emit_cell(e, FDT_PROP);
105} 105}
@@ -127,11 +127,21 @@ static void emit_offset_label(FILE *f, const char *label, int offset)
127 fprintf(f, "%s\t= . + %d\n", label, offset); 127 fprintf(f, "%s\t= . + %d\n", label, offset);
128} 128}
129 129
130#define ASM_EMIT_BELONG(f, fmt, ...) \
131 { \
132 fprintf((f), "\t.byte\t((" fmt ") >> 24) & 0xff\n", __VA_ARGS__); \
133 fprintf((f), "\t.byte\t((" fmt ") >> 16) & 0xff\n", __VA_ARGS__); \
134 fprintf((f), "\t.byte\t((" fmt ") >> 8) & 0xff\n", __VA_ARGS__); \
135 fprintf((f), "\t.byte\t(" fmt ") & 0xff\n", __VA_ARGS__); \
136 }
137
130static void asm_emit_cell(void *e, cell_t val) 138static void asm_emit_cell(void *e, cell_t val)
131{ 139{
132 FILE *f = e; 140 FILE *f = e;
133 141
134 fprintf(f, "\t.long\t0x%x\n", val); 142 fprintf(f, "\t.byte 0x%02x; .byte 0x%02x; .byte 0x%02x; .byte 0x%02x\n",
143 (val >> 24) & 0xff, (val >> 16) & 0xff,
144 (val >> 8) & 0xff, val & 0xff);
135} 145}
136 146
137static void asm_emit_string(void *e, char *str, int len) 147static void asm_emit_string(void *e, char *str, int len)
@@ -156,7 +166,7 @@ static void asm_emit_align(void *e, int a)
156{ 166{
157 FILE *f = e; 167 FILE *f = e;
158 168
159 fprintf(f, "\t.balign\t%d\n", a); 169 fprintf(f, "\t.balign\t%d, 0\n", a);
160} 170}
161 171
162static void asm_emit_data(void *e, struct data d) 172static void asm_emit_data(void *e, struct data d)
@@ -169,8 +179,7 @@ static void asm_emit_data(void *e, struct data d)
169 emit_offset_label(f, m->ref, m->offset); 179 emit_offset_label(f, m->ref, m->offset);
170 180
171 while ((d.len - off) >= sizeof(uint32_t)) { 181 while ((d.len - off) >= sizeof(uint32_t)) {
172 fprintf(f, "\t.long\t0x%x\n", 182 asm_emit_cell(e, fdt32_to_cpu(*((uint32_t *)(d.val+off))));
173 fdt32_to_cpu(*((uint32_t *)(d.val+off))));
174 off += sizeof(uint32_t); 183 off += sizeof(uint32_t);
175 } 184 }
176 185
@@ -182,37 +191,43 @@ static void asm_emit_data(void *e, struct data d)
182 assert(off == d.len); 191 assert(off == d.len);
183} 192}
184 193
185static void asm_emit_beginnode(void *e, const char *label) 194static void asm_emit_beginnode(void *e, struct label *labels)
186{ 195{
187 FILE *f = e; 196 FILE *f = e;
197 struct label *l;
188 198
189 if (label) { 199 for_each_label(labels, l) {
190 fprintf(f, "\t.globl\t%s\n", label); 200 fprintf(f, "\t.globl\t%s\n", l->label);
191 fprintf(f, "%s:\n", label); 201 fprintf(f, "%s:\n", l->label);
192 } 202 }
193 fprintf(f, "\t.long\tFDT_BEGIN_NODE\n"); 203 fprintf(f, "\t/* FDT_BEGIN_NODE */\n");
204 asm_emit_cell(e, FDT_BEGIN_NODE);
194} 205}
195 206
196static void asm_emit_endnode(void *e, const char *label) 207static void asm_emit_endnode(void *e, struct label *labels)
197{ 208{
198 FILE *f = e; 209 FILE *f = e;
210 struct label *l;
199 211
200 fprintf(f, "\t.long\tFDT_END_NODE\n"); 212 fprintf(f, "\t/* FDT_END_NODE */\n");
201 if (label) { 213 asm_emit_cell(e, FDT_END_NODE);
202 fprintf(f, "\t.globl\t%s_end\n", label); 214 for_each_label(labels, l) {
203 fprintf(f, "%s_end:\n", label); 215 fprintf(f, "\t.globl\t%s_end\n", l->label);
216 fprintf(f, "%s_end:\n", l->label);
204 } 217 }
205} 218}
206 219
207static void asm_emit_property(void *e, const char *label) 220static void asm_emit_property(void *e, struct label *labels)
208{ 221{
209 FILE *f = e; 222 FILE *f = e;
223 struct label *l;
210 224
211 if (label) { 225 for_each_label(labels, l) {
212 fprintf(f, "\t.globl\t%s\n", label); 226 fprintf(f, "\t.globl\t%s\n", l->label);
213 fprintf(f, "%s:\n", label); 227 fprintf(f, "%s:\n", l->label);
214 } 228 }
215 fprintf(f, "\t.long\tFDT_PROP\n"); 229 fprintf(f, "\t/* FDT_PROP */\n");
230 asm_emit_cell(e, FDT_PROP);
216} 231}
217 232
218static struct emitter asm_emitter = { 233static struct emitter asm_emitter = {
@@ -248,7 +263,7 @@ static void flatten_tree(struct node *tree, struct emitter *emit,
248 struct node *child; 263 struct node *child;
249 int seen_name_prop = 0; 264 int seen_name_prop = 0;
250 265
251 emit->beginnode(etarget, tree->label); 266 emit->beginnode(etarget, tree->labels);
252 267
253 if (vi->flags & FTF_FULLPATH) 268 if (vi->flags & FTF_FULLPATH)
254 emit->string(etarget, tree->fullpath, 0); 269 emit->string(etarget, tree->fullpath, 0);
@@ -265,7 +280,7 @@ static void flatten_tree(struct node *tree, struct emitter *emit,
265 280
266 nameoff = stringtable_insert(strbuf, prop->name); 281 nameoff = stringtable_insert(strbuf, prop->name);
267 282
268 emit->property(etarget, prop->label); 283 emit->property(etarget, prop->labels);
269 emit->cell(etarget, prop->val.len); 284 emit->cell(etarget, prop->val.len);
270 emit->cell(etarget, nameoff); 285 emit->cell(etarget, nameoff);
271 286
@@ -292,7 +307,7 @@ static void flatten_tree(struct node *tree, struct emitter *emit,
292 flatten_tree(child, emit, etarget, strbuf, vi); 307 flatten_tree(child, emit, etarget, strbuf, vi);
293 } 308 }
294 309
295 emit->endnode(etarget, tree->label); 310 emit->endnode(etarget, tree->labels);
296} 311}
297 312
298static struct data flatten_reserve_list(struct reserve_info *reservelist, 313static struct data flatten_reserve_list(struct reserve_info *reservelist,
@@ -413,10 +428,13 @@ void dt_to_blob(FILE *f, struct boot_info *bi, int version)
413 if (padlen > 0) 428 if (padlen > 0)
414 blob = data_append_zeroes(blob, padlen); 429 blob = data_append_zeroes(blob, padlen);
415 430
416 fwrite(blob.val, blob.len, 1, f); 431 if (fwrite(blob.val, blob.len, 1, f) != 1) {
417 432 if (ferror(f))
418 if (ferror(f)) 433 die("Error writing device tree blob: %s\n",
419 die("Error writing device tree blob: %s\n", strerror(errno)); 434 strerror(errno));
435 else
436 die("Short write on device tree blob\n");
437 }
420 438
421 /* 439 /*
422 * data_merge() frees the right-hand element so only the blob 440 * data_merge() frees the right-hand element so only the blob
@@ -455,39 +473,44 @@ void dt_to_asm(FILE *f, struct boot_info *bi, int version)
455 die("Unknown device tree blob version %d\n", version); 473 die("Unknown device tree blob version %d\n", version);
456 474
457 fprintf(f, "/* autogenerated by dtc, do not edit */\n\n"); 475 fprintf(f, "/* autogenerated by dtc, do not edit */\n\n");
458 fprintf(f, "#define FDT_MAGIC 0x%x\n", FDT_MAGIC);
459 fprintf(f, "#define FDT_BEGIN_NODE 0x%x\n", FDT_BEGIN_NODE);
460 fprintf(f, "#define FDT_END_NODE 0x%x\n", FDT_END_NODE);
461 fprintf(f, "#define FDT_PROP 0x%x\n", FDT_PROP);
462 fprintf(f, "#define FDT_END 0x%x\n", FDT_END);
463 fprintf(f, "\n");
464 476
465 emit_label(f, symprefix, "blob_start"); 477 emit_label(f, symprefix, "blob_start");
466 emit_label(f, symprefix, "header"); 478 emit_label(f, symprefix, "header");
467 fprintf(f, "\t.long\tFDT_MAGIC\t\t\t\t/* magic */\n"); 479 fprintf(f, "\t/* magic */\n");
468 fprintf(f, "\t.long\t_%s_blob_abs_end - _%s_blob_start\t/* totalsize */\n", 480 asm_emit_cell(f, FDT_MAGIC);
469 symprefix, symprefix); 481 fprintf(f, "\t/* totalsize */\n");
470 fprintf(f, "\t.long\t_%s_struct_start - _%s_blob_start\t/* off_dt_struct */\n", 482 ASM_EMIT_BELONG(f, "_%s_blob_abs_end - _%s_blob_start",
483 symprefix, symprefix);
484 fprintf(f, "\t/* off_dt_struct */\n");
485 ASM_EMIT_BELONG(f, "_%s_struct_start - _%s_blob_start",
471 symprefix, symprefix); 486 symprefix, symprefix);
472 fprintf(f, "\t.long\t_%s_strings_start - _%s_blob_start\t/* off_dt_strings */\n", 487 fprintf(f, "\t/* off_dt_strings */\n");
488 ASM_EMIT_BELONG(f, "_%s_strings_start - _%s_blob_start",
473 symprefix, symprefix); 489 symprefix, symprefix);
474 fprintf(f, "\t.long\t_%s_reserve_map - _%s_blob_start\t/* off_dt_strings */\n", 490 fprintf(f, "\t/* off_mem_rsvmap */\n");
491 ASM_EMIT_BELONG(f, "_%s_reserve_map - _%s_blob_start",
475 symprefix, symprefix); 492 symprefix, symprefix);
476 fprintf(f, "\t.long\t%d\t\t\t\t\t/* version */\n", vi->version); 493 fprintf(f, "\t/* version */\n");
477 fprintf(f, "\t.long\t%d\t\t\t\t\t/* last_comp_version */\n", 494 asm_emit_cell(f, vi->version);
478 vi->last_comp_version); 495 fprintf(f, "\t/* last_comp_version */\n");
479 496 asm_emit_cell(f, vi->last_comp_version);
480 if (vi->flags & FTF_BOOTCPUID) 497
481 fprintf(f, "\t.long\t%i\t\t\t\t\t/* boot_cpuid_phys */\n", 498 if (vi->flags & FTF_BOOTCPUID) {
482 bi->boot_cpuid_phys); 499 fprintf(f, "\t/* boot_cpuid_phys */\n");
500 asm_emit_cell(f, bi->boot_cpuid_phys);
501 }
483 502
484 if (vi->flags & FTF_STRTABSIZE) 503 if (vi->flags & FTF_STRTABSIZE) {
485 fprintf(f, "\t.long\t_%s_strings_end - _%s_strings_start\t/* size_dt_strings */\n", 504 fprintf(f, "\t/* size_dt_strings */\n");
486 symprefix, symprefix); 505 ASM_EMIT_BELONG(f, "_%s_strings_end - _%s_strings_start",
506 symprefix, symprefix);
507 }
487 508
488 if (vi->flags & FTF_STRUCTSIZE) 509 if (vi->flags & FTF_STRUCTSIZE) {
489 fprintf(f, "\t.long\t_%s_struct_end - _%s_struct_start\t/* size_dt_struct */\n", 510 fprintf(f, "\t/* size_dt_struct */\n");
511 ASM_EMIT_BELONG(f, "_%s_struct_end - _%s_struct_start",
490 symprefix, symprefix); 512 symprefix, symprefix);
513 }
491 514
492 /* 515 /*
493 * Reserve map entries. 516 * Reserve map entries.
@@ -505,16 +528,17 @@ void dt_to_asm(FILE *f, struct boot_info *bi, int version)
505 * as it appears .quad isn't available in some assemblers. 528 * as it appears .quad isn't available in some assemblers.
506 */ 529 */
507 for (re = bi->reservelist; re; re = re->next) { 530 for (re = bi->reservelist; re; re = re->next) {
508 if (re->label) { 531 struct label *l;
509 fprintf(f, "\t.globl\t%s\n", re->label); 532
510 fprintf(f, "%s:\n", re->label); 533 for_each_label(re->labels, l) {
534 fprintf(f, "\t.globl\t%s\n", l->label);
535 fprintf(f, "%s:\n", l->label);
511 } 536 }
512 fprintf(f, "\t.long\t0x%08x, 0x%08x\n", 537 ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.address >> 32));
513 (unsigned int)(re->re.address >> 32), 538 ASM_EMIT_BELONG(f, "0x%08x",
514 (unsigned int)(re->re.address & 0xffffffff)); 539 (unsigned int)(re->re.address & 0xffffffff));
515 fprintf(f, "\t.long\t0x%08x, 0x%08x\n", 540 ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.size >> 32));
516 (unsigned int)(re->re.size >> 32), 541 ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.size & 0xffffffff));
517 (unsigned int)(re->re.size & 0xffffffff));
518 } 542 }
519 for (i = 0; i < reservenum; i++) { 543 for (i = 0; i < reservenum; i++) {
520 fprintf(f, "\t.long\t0, 0\n\t.long\t0, 0\n"); 544 fprintf(f, "\t.long\t0, 0\n\t.long\t0, 0\n");
@@ -524,7 +548,9 @@ void dt_to_asm(FILE *f, struct boot_info *bi, int version)
524 548
525 emit_label(f, symprefix, "struct_start"); 549 emit_label(f, symprefix, "struct_start");
526 flatten_tree(bi->dt, &asm_emitter, f, &strbuf, vi); 550 flatten_tree(bi->dt, &asm_emitter, f, &strbuf, vi);
527 fprintf(f, "\t.long\tFDT_END\n"); 551
552 fprintf(f, "\t/* FDT_END */\n");
553 asm_emit_cell(f, FDT_END);
528 emit_label(f, symprefix, "struct_end"); 554 emit_label(f, symprefix, "struct_end");
529 555
530 emit_label(f, symprefix, "strings_start"); 556 emit_label(f, symprefix, "strings_start");
@@ -601,7 +627,7 @@ static char *flat_read_string(struct inbuf *inb)
601 len++; 627 len++;
602 } while ((*p++) != '\0'); 628 } while ((*p++) != '\0');
603 629
604 str = strdup(inb->ptr); 630 str = xstrdup(inb->ptr);
605 631
606 inb->ptr += len; 632 inb->ptr += len;
607 633
@@ -643,7 +669,7 @@ static char *flat_read_stringtable(struct inbuf *inb, int offset)
643 p++; 669 p++;
644 } 670 }
645 671
646 return strdup(inb->base + offset); 672 return xstrdup(inb->base + offset);
647} 673}
648 674
649static struct property *flat_read_property(struct inbuf *dtbuf, 675static struct property *flat_read_property(struct inbuf *dtbuf,
@@ -663,7 +689,7 @@ static struct property *flat_read_property(struct inbuf *dtbuf,
663 689
664 val = flat_read_data(dtbuf, proplen); 690 val = flat_read_data(dtbuf, proplen);
665 691
666 return build_property(name, val, NULL); 692 return build_property(name, val);
667} 693}
668 694
669 695
@@ -688,7 +714,7 @@ static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb)
688 if (re.size == 0) 714 if (re.size == 0)
689 break; 715 break;
690 716
691 new = build_reserve_entry(re.address, re.size, NULL); 717 new = build_reserve_entry(re.address, re.size);
692 reservelist = add_reserve_entry(reservelist, new); 718 reservelist = add_reserve_entry(reservelist, new);
693 } 719 }
694 720
@@ -710,7 +736,7 @@ static char *nodename_from_path(const char *ppath, const char *cpath)
710 if (!streq(ppath, "/")) 736 if (!streq(ppath, "/"))
711 plen++; 737 plen++;
712 738
713 return strdup(cpath + plen); 739 return xstrdup(cpath + plen);
714} 740}
715 741
716static struct node *unflatten_tree(struct inbuf *dtbuf, 742static struct node *unflatten_tree(struct inbuf *dtbuf,
@@ -776,7 +802,7 @@ static struct node *unflatten_tree(struct inbuf *dtbuf,
776 802
777struct boot_info *dt_from_blob(const char *fname) 803struct boot_info *dt_from_blob(const char *fname)
778{ 804{
779 struct dtc_file *dtcf; 805 FILE *f;
780 uint32_t magic, totalsize, version, size_dt, boot_cpuid_phys; 806 uint32_t magic, totalsize, version, size_dt, boot_cpuid_phys;
781 uint32_t off_dt, off_str, off_mem_rsvmap; 807 uint32_t off_dt, off_str, off_mem_rsvmap;
782 int rc; 808 int rc;
@@ -791,14 +817,14 @@ struct boot_info *dt_from_blob(const char *fname)
791 uint32_t val; 817 uint32_t val;
792 int flags = 0; 818 int flags = 0;
793 819
794 dtcf = dtc_open_file(fname, NULL); 820 f = srcfile_relative_open(fname, NULL);
795 821
796 rc = fread(&magic, sizeof(magic), 1, dtcf->file); 822 rc = fread(&magic, sizeof(magic), 1, f);
797 if (ferror(dtcf->file)) 823 if (ferror(f))
798 die("Error reading DT blob magic number: %s\n", 824 die("Error reading DT blob magic number: %s\n",
799 strerror(errno)); 825 strerror(errno));
800 if (rc < 1) { 826 if (rc < 1) {
801 if (feof(dtcf->file)) 827 if (feof(f))
802 die("EOF reading DT blob magic number\n"); 828 die("EOF reading DT blob magic number\n");
803 else 829 else
804 die("Mysterious short read reading magic number\n"); 830 die("Mysterious short read reading magic number\n");
@@ -808,11 +834,11 @@ struct boot_info *dt_from_blob(const char *fname)
808 if (magic != FDT_MAGIC) 834 if (magic != FDT_MAGIC)
809 die("Blob has incorrect magic number\n"); 835 die("Blob has incorrect magic number\n");
810 836
811 rc = fread(&totalsize, sizeof(totalsize), 1, dtcf->file); 837 rc = fread(&totalsize, sizeof(totalsize), 1, f);
812 if (ferror(dtcf->file)) 838 if (ferror(f))
813 die("Error reading DT blob size: %s\n", strerror(errno)); 839 die("Error reading DT blob size: %s\n", strerror(errno));
814 if (rc < 1) { 840 if (rc < 1) {
815 if (feof(dtcf->file)) 841 if (feof(f))
816 die("EOF reading DT blob size\n"); 842 die("EOF reading DT blob size\n");
817 else 843 else
818 die("Mysterious short read reading blob size\n"); 844 die("Mysterious short read reading blob size\n");
@@ -832,12 +858,12 @@ struct boot_info *dt_from_blob(const char *fname)
832 p = blob + sizeof(magic) + sizeof(totalsize); 858 p = blob + sizeof(magic) + sizeof(totalsize);
833 859
834 while (sizeleft) { 860 while (sizeleft) {
835 if (feof(dtcf->file)) 861 if (feof(f))
836 die("EOF before reading %d bytes of DT blob\n", 862 die("EOF before reading %d bytes of DT blob\n",
837 totalsize); 863 totalsize);
838 864
839 rc = fread(p, 1, sizeleft, dtcf->file); 865 rc = fread(p, 1, sizeleft, f);
840 if (ferror(dtcf->file)) 866 if (ferror(f))
841 die("Error reading DT blob: %s\n", 867 die("Error reading DT blob: %s\n",
842 strerror(errno)); 868 strerror(errno));
843 869
@@ -900,7 +926,7 @@ struct boot_info *dt_from_blob(const char *fname)
900 926
901 free(blob); 927 free(blob);
902 928
903 dtc_close_file(dtcf); 929 fclose(f);
904 930
905 return build_boot_info(reservelist, tree, boot_cpuid_phys); 931 return build_boot_info(reservelist, tree, boot_cpuid_phys);
906} 932}