staticstruct data flatten_reserve_list(struct reserve_info *reservelist, struct version_info *vi)
{ struct reserve_info *re; struct data d = empty_data; unsignedint j;
for (re = reservelist; re; re = re->next) {
d = data_append_re(d, re->address, re->size);
} /* * Add additional reserved slots if the user asked for them.
*/ for (j = 0; j < reservenum; j++) {
d = data_append_re(d, 0, 0);
}
return d;
}
staticvoid make_fdt_header(struct fdt_header *fdt, struct version_info *vi, int reservesize, int dtsize, int strsize, int boot_cpuid_phys)
{ int reserve_off;
if (vi->flags & FTF_BOOTCPUID)
fdt->boot_cpuid_phys = cpu_to_fdt32(boot_cpuid_phys); if (vi->flags & FTF_STRTABSIZE)
fdt->size_dt_strings = cpu_to_fdt32(strsize); if (vi->flags & FTF_STRUCTSIZE)
fdt->size_dt_struct = cpu_to_fdt32(dtsize);
}
void dt_to_blob(FILE *f, struct dt_info *dti, int version)
{ struct version_info *vi = NULL; unsignedint i; struct data blob = empty_data; struct data reservebuf = empty_data; struct data dtbuf = empty_data; struct data strbuf = empty_data; struct fdt_header fdt; int padlen = 0;
for (i = 0; i < ARRAY_SIZE(version_table); i++) { if (version_table[i].version == version)
vi = &version_table[i];
} if (!vi)
die("Unknown device tree blob version %d\n", version);
/* Make header */
make_fdt_header(&fdt, vi, reservebuf.len, dtbuf.len, strbuf.len,
dti->boot_cpuid_phys);
/* * If the user asked for more space than is used, adjust the totalsize.
*/ if (minsize > 0) {
padlen = minsize - fdt32_to_cpu(fdt.totalsize); if (padlen < 0) {
padlen = 0; if (quiet < 1)
fprintf(stderr, "Warning: blob size %"PRIu32" >= minimum size %d\n",
fdt32_to_cpu(fdt.totalsize), minsize);
}
}
if (padlen > 0) { int tsize = fdt32_to_cpu(fdt.totalsize);
tsize += padlen;
fdt.totalsize = cpu_to_fdt32(tsize);
}
/* * Assemble the blob: start with the header, add with alignment * the reserve buffer, add the reserve map terminating zeroes, * the device tree itself, and finally the strings.
*/
blob = data_append_data(blob, &fdt, vi->hdr_size);
blob = data_append_align(blob, 8);
blob = data_merge(blob, reservebuf);
blob = data_append_zeroes(blob, sizeof(struct fdt_reserve_entry));
blob = data_merge(blob, dtbuf);
blob = data_merge(blob, strbuf);
/* * If the user asked for more space than is used, pad out the blob.
*/ if (padlen > 0)
blob = data_append_zeroes(blob, padlen);
if (fwrite(blob.val, blob.len, 1, f) != 1) { if (ferror(f))
die("Error writing device tree blob: %s\n",
strerror(errno)); else
die("Short write on device tree blob\n");
}
/* * data_merge() frees the right-hand element so only the blob * remains to be freed.
*/
data_free(blob);
}
staticvoid dump_stringtable_asm(FILE *f, struct data strbuf)
{ constchar *p; int len;
p = strbuf.val;
while (p < (strbuf.val + strbuf.len)) {
len = strlen(p);
fprintf(f, "\t.asciz \"%s\"\n", p);
p += len+1;
}
}
for (i = 0; i < ARRAY_SIZE(version_table); i++) { if (version_table[i].version == version)
vi = &version_table[i];
} if (!vi)
die("Unknown device tree blob version %d\n", version);
fprintf(f, "/* autogenerated by dtc, do not edit */\n\n");
/* * Reserve map entries. * Align the reserve map to a doubleword boundary. * Each entry is an (address, size) pair of u64 values. * Always supply a zero-sized temination entry.
*/
asm_emit_align(f, 8);
emit_label(f, symprefix, "reserve_map");
fprintf(f, "/* Memory reserve map from source file */\n");
/* * Use .long on high and low halves of u64s to avoid .quad * as it appears .quad isn't available in some assemblers.
*/ for (re = dti->reservelist; re; re = re->next) { struct label *l;
/* * If the user asked for more space than is used, pad it out.
*/ if (minsize > 0) {
fprintf(f, "\t.space\t%d - (_%s_blob_end - _%s_blob_start), 0\n",
minsize, symprefix, symprefix);
} if (padsize > 0) {
fprintf(f, "\t.space\t%d, 0\n", padsize);
} if (alignsize > 0)
asm_emit_align(f, alignsize);
emit_label(f, symprefix, "blob_abs_end");
staticvoid flat_read_chunk(struct inbuf *inb, void *p, int len)
{ if ((inb->ptr + len) > inb->limit)
die("Premature end of data parsing flat device tree\n");
/* * Each entry is a pair of u64 (addr, size) values for 4 cell_t's. * List terminates at an entry with size equal to zero. * * First pass, count entries.
*/ while (1) {
uint64_t address, size;
val = flat_read_word(dtbuf); switch (val) { case FDT_PROP: if (node->children)
fprintf(stderr, "Warning: Flat tree input has " "subnodes preceding a property.\n");
prop = flat_read_property(dtbuf, strbuf, flags);
add_property(node, prop); break;
case FDT_BEGIN_NODE:
child = unflatten_tree(dtbuf,strbuf, flatname, flags);
add_child(node, child); break;
case FDT_END_NODE: break;
case FDT_END:
die("Premature FDT_END in device tree blob\n"); break;
case FDT_NOP: if (!(flags & FTF_NOPS))
fprintf(stderr, "Warning: NOP tag found in flat tree" " version <16\n");
/* Ignore */ break;
default:
die("Invalid opcode word %08x in device tree blob\n",
val);
}
} while (val != FDT_END_NODE);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.