diff options
author | Yanan Wang <wangyanan55@huawei.com> | 2021-10-20 22:21:19 +0800 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2021-10-20 18:17:54 -0700 |
commit | b863f0b75852dfd62b3f31b08eeddd3b03694fc2 (patch) | |
tree | 655042936b760ef153aa1dc136e2af7b566a8917 | |
parent | 31511b6fe0251806f425b5a671c6d211e030162d (diff) |
device_tree: Add qemu_fdt_add_path
qemu_fdt_add_path() works like qemu_fdt_add_subnode(), except it
also adds all missing subnodes from the given path. We'll use it
in a coming patch where we will add cpu-map to the device tree.
And we also tweak an error message of qemu_fdt_add_subnode().
Co-developed-by: Andrew Jones <drjones@redhat.com>
Signed-off-by: Yanan Wang <wangyanan55@huawei.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Andrew Jones <drjones@redhat.com>
Cc: David Gibson <david@gibson.dropbear.id.au>
Cc: Alistair Francis <alistair.francis@wdc.com>
Message-Id: <20211020142125.7516-3-wangyanan55@huawei.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
-rw-r--r-- | include/sysemu/device_tree.h | 1 | ||||
-rw-r--r-- | softmmu/device_tree.c | 44 |
2 files changed, 43 insertions, 2 deletions
diff --git a/include/sysemu/device_tree.h b/include/sysemu/device_tree.h index 8a2fe55622..ef060a9759 100644 --- a/include/sysemu/device_tree.h +++ b/include/sysemu/device_tree.h @@ -121,6 +121,7 @@ uint32_t qemu_fdt_get_phandle(void *fdt, const char *path); uint32_t qemu_fdt_alloc_phandle(void *fdt); int qemu_fdt_nop_node(void *fdt, const char *node_path); int qemu_fdt_add_subnode(void *fdt, const char *name); +int qemu_fdt_add_path(void *fdt, const char *path); #define qemu_fdt_setprop_cells(fdt, node_path, property, ...) \ do { \ diff --git a/softmmu/device_tree.c b/softmmu/device_tree.c index b621f63fba..3965c834ca 100644 --- a/softmmu/device_tree.c +++ b/softmmu/device_tree.c @@ -540,8 +540,8 @@ int qemu_fdt_add_subnode(void *fdt, const char *name) retval = fdt_add_subnode(fdt, parent, basename); if (retval < 0) { - error_report("FDT: Failed to create subnode %s: %s", name, - fdt_strerror(retval)); + error_report("%s: Failed to create subnode %s: %s", + __func__, name, fdt_strerror(retval)); exit(1); } @@ -549,6 +549,46 @@ int qemu_fdt_add_subnode(void *fdt, const char *name) return retval; } +/* + * qemu_fdt_add_path: Like qemu_fdt_add_subnode(), but will add + * all missing subnodes from the given path. + */ +int qemu_fdt_add_path(void *fdt, const char *path) +{ + const char *name; + const char *p = path; + int namelen, retval; + int parent = 0; + + if (path[0] != '/') { + return -1; + } + + while (p) { + name = p + 1; + p = strchr(name, '/'); + namelen = p != NULL ? p - name : strlen(name); + + retval = fdt_subnode_offset_namelen(fdt, parent, name, namelen); + if (retval < 0 && retval != -FDT_ERR_NOTFOUND) { + error_report("%s: Unexpected error in finding subnode %.*s: %s", + __func__, namelen, name, fdt_strerror(retval)); + exit(1); + } else if (retval == -FDT_ERR_NOTFOUND) { + retval = fdt_add_subnode_namelen(fdt, parent, name, namelen); + if (retval < 0) { + error_report("%s: Failed to create subnode %.*s: %s", + __func__, namelen, name, fdt_strerror(retval)); + exit(1); + } + } + + parent = retval; + } + + return retval; +} + void qemu_fdt_dumpdtb(void *fdt, int size) { const char *dumpdtb = current_machine->dumpdtb; |