Deleted Added
full compact
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}