From: Li Liu <john.li...@huawei.com> The outputed stream format is compatile with 'dtc -I dtb -O dts xxx.dtb'.
Signed-off-by: Li Liu <john.li...@huawei.com> --- device_tree.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/device_tree.c b/device_tree.c index 14d4015..1e407d2 100644 --- a/device_tree.c +++ b/device_tree.c @@ -416,3 +416,83 @@ static void dts_write_data(FILE *fp, const char *data, int len) fprintf(fp, "]"); } } + +static void dts_write_prefix(FILE *fp, int depth) +{ + int i; + + for (i = 0; i < depth; i++) { + fprintf(fp, "%c", '\t'); + } +} + +#define PALIGN(p, a) ((void *)(QEMU_ALIGN_UP((unsigned long)(p), (a)))) +#define GET_CELL(p) (p += 4, *((const uint32_t *)(p - 4))) + +static void qemu_write_dts(FILE *fp, void *fdt) +{ + const char *p, *name, *data; + uint32_t tag; + int len, num, depth = 0; + int i; + + const char *fdt_struct = (const char *)fdt + fdt_off_dt_struct(fdt); + const char *fdt_strings = (const char *)fdt + fdt_off_dt_strings(fdt); + + fprintf(fp, "/dts-v1/;\n"); + + num = fdt_num_mem_rsv(fdt); + fprintf(fp, "%s", num ? "\n" : ""); + for (i = 0; i < num; i++) { + uint64_t addr, size; + + fdt_get_mem_rsv(fdt, i, &addr, &size); + fprintf(fp, "/memreserve/\t0x%016llx 0x%016llx;\n", + (unsigned long long)addr, (unsigned long long)size); + } + + p = fdt_struct; + while ((tag = fdt32_to_cpu(GET_CELL(p))) != FDT_END) { + if (tag == FDT_BEGIN_NODE) { + name = p; + p = PALIGN(p + strlen(name) + 1, 4); + if (*name == '\0') { + name = "/"; + } + + fprintf(fp, "\n"); + dts_write_prefix(fp, depth); + fprintf(fp, "%s {\n", name); + + depth++; + continue; + } + + if (tag == FDT_END_NODE) { + depth--; + + dts_write_prefix(fp, depth); + fprintf(fp, "};\n"); + continue; + } + + if (tag == FDT_NOP) { + continue; + } + + if (tag != FDT_PROP) { + fprintf(stderr, "FDT: Unknown tag 0x%08x\n", tag); + break; + } + + len = fdt32_to_cpu(GET_CELL(p)); + name = fdt_strings + fdt32_to_cpu(GET_CELL(p)); + data = p; + p = PALIGN(p + len, 4); + + dts_write_prefix(fp, depth); + fprintf(fp, "%s", name); + dts_write_data(fp, data, len); + fprintf(fp, ";\n"); + } +} -- 1.7.9.5