From: David Gibson <david@gibson.dropbear.id.au>
To: Ruslan Ruslichenko <ruslichenko.r@gmail.com>
Cc: qemu-devel@nongnu.org, qemu-arm@nongnu.org,
peter.maydell@linaro.org, artem_mygaiev@epam.com,
volodymyr_babchuk@epam.com, takahiro.nakata.wr@renesas.com,
"Edgar E . Iglesias" <edgar.iglesias@gmail.com>,
Ruslan_Ruslichenko@epam.com,
Alistair Francis <alistair@alistair23.me>
Subject: Re: [PATCH 01/27] system/device_tree: update qemu_fdt_getprop/_cell
Date: Tue, 27 Jan 2026 12:56:49 +1100 [thread overview]
Message-ID: <aXgbYR9Sdu7dIHdY@zatzit> (raw)
In-Reply-To: <20260126174313.1418150-2-ruslichenko.r@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 7866 bytes --]
On Mon, Jan 26, 2026 at 06:42:47PM +0100, Ruslan Ruslichenko wrote:
> From: Ruslan Ruslichenko <Ruslan_Ruslichenko@epam.com>
>
> Update 'qemu_fdt_getprop' and 'qemu_fdt_getprop_cell'
> to support property inheritence from parent node,
> in case 'inherit' argument is set.
A bare bool parameter is pretty ugly and requires updating every
existing caller. I'd suggest adding a new function for the inheriting
version, instead.
> Update 'qemu_fdt_getprop_cell' to allow accessing
> specific cells within multi-cell property array.
>
> Introduced 'qemu_devtreedd_getparent' as it is needed
> by both internal and external users.
>
> This will be used by hardware device tree parsing logic.
>
> Signed-off-by: Ruslan Ruslichenko <Ruslan_Ruslichenko@epam.com>
> ---
> hw/arm/boot.c | 8 ++++----
> hw/arm/raspi4b.c | 8 ++++----
> hw/arm/vexpress.c | 4 ++--
> hw/arm/xlnx-zcu102.c | 3 ++-
> include/system/device_tree.h | 32 +++++++++++++++++++-------------
> system/device_tree.c | 33 ++++++++++++++++++++++++---------
> 6 files changed, 55 insertions(+), 33 deletions(-)
>
> diff --git a/hw/arm/boot.c b/hw/arm/boot.c
> index c97d4c4e11..829b8ba12f 100644
[snip]
> diff --git a/include/system/device_tree.h b/include/system/device_tree.h
> index 49d8482ed4..f34b8b7ef9 100644
> --- a/include/system/device_tree.h
> +++ b/include/system/device_tree.h
> @@ -96,27 +96,28 @@ int qemu_fdt_setprop_phandle(void *fdt, const char *node_path,
> * @node_path: node path
> * @property: name of the property to find
> * @lenp: fdt error if any or length of the property on success
> + * @inherit: if not found in node, look for property in parent
> * @errp: handle to an error object
> *
> * returns a pointer to the property on success and NULL on failure
> */
> const void *qemu_fdt_getprop(void *fdt, const char *node_path,
> const char *property, int *lenp,
> - Error **errp);
> + bool inherit, Error **errp);
> /**
> - * qemu_fdt_getprop_cell: retrieve the value of a given 4 byte property
> - * @fdt: pointer to the device tree blob
> - * @node_path: node path
> - * @property: name of the property to find
> - * @lenp: fdt error if any or -EINVAL if the property size is different from
> - * 4 bytes, or 4 (expected length of the property) upon success.
> - * @errp: handle to an error object
> - *
> - * returns the property value on success
> - */
Spurious change to all the whitespace here.
> +* qemu_fdt_getprop_cell: retrieve the value of a given 4 byte property
This description is no longer accurate after your change.
> +* @fdt: pointer to the device tree blob
> +* @node_path: node path
> +* @property: name of the property to find
> +* @ofset: the index of 32bit cell to retrive
s/ofset/offset/. But, in any case in libfdt context 'offset' always
refers to a byte offset, so I think this is a potentially misleading
name.
> +* @inherit: if not found in node, look for property in parent
> +* @errp: handle to an error object
> +*
> +* returns the property value on success
> +*/
> uint32_t qemu_fdt_getprop_cell(void *fdt, const char *node_path,
> - const char *property, int *lenp,
> - Error **errp);
> + const char *property, int offset,
> + bool inherit, Error **errp);
> 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);
> @@ -193,6 +194,11 @@ int qemu_fdt_setprop_sized_cells_from_array(void *fdt,
> })
>
>
> +int qemu_devtree_getparent(void *fdt, char *node_path,
> + const char *current);
> +
> +#define DT_PATH_LENGTH 1024
> +
> /**
> * qemu_fdt_randomize_seeds:
> * @fdt: device tree blob
> diff --git a/system/device_tree.c b/system/device_tree.c
> index 1ea1962984..41bde0ba5a 100644
> --- a/system/device_tree.c
> +++ b/system/device_tree.c
> @@ -429,7 +429,8 @@ int qemu_fdt_setprop_string_array(void *fdt, const char *node_path,
> }
>
> const void *qemu_fdt_getprop(void *fdt, const char *node_path,
> - const char *property, int *lenp, Error **errp)
> + const char *property, int *lenp,
> + bool inherit, Error **errp)
> {
> int len;
> const void *r;
> @@ -439,31 +440,35 @@ const void *qemu_fdt_getprop(void *fdt, const char *node_path,
> }
> r = fdt_getprop(fdt, findnode_nofail(fdt, node_path), property, lenp);
> if (!r) {
> + char parent[DT_PATH_LENGTH];
> + if (inherit && !qemu_devtree_getparent(fdt, parent, node_path)) {
> + return qemu_fdt_getprop(fdt, parent, property, lenp, true, errp);
> + }
This is a pretty horribly expensive way of doing it. On a flattened
tree, findnode_nofail() and devtree_getparent() each need to scan the
tree from the start, and you do both for each layer of the tree. You
could instead scan the tree once from the root, updating a pointer to
the deepest copy of the property found so far.
> error_setg(errp, "%s: Couldn't get %s/%s: %s", __func__,
> node_path, property, fdt_strerror(*lenp));
> + return NULL;
> }
> return r;
> }
>
> uint32_t qemu_fdt_getprop_cell(void *fdt, const char *node_path,
> - const char *property, int *lenp, Error **errp)
> + const char *property, int offset,
> + bool inherit, Error **errp)
> {
> int len;
> const uint32_t *p;
>
> - if (!lenp) {
> - lenp = &len;
> - }
> - p = qemu_fdt_getprop(fdt, node_path, property, lenp, errp);
> + p = qemu_fdt_getprop(fdt, node_path, property, &len,
> + inherit, errp);
> if (!p) {
> return 0;
> - } else if (*lenp != 4) {
> + }
> + if (len < (offset + 1) * 4) {
> error_setg(errp, "%s: %s/%s not 4 bytes long (not a cell?)",
> __func__, node_path, property);
Error message is no longer accurate.
> - *lenp = -EINVAL;
> return 0;
> }
> - return be32_to_cpu(*p);
> + return be32_to_cpu(p[offset]);
> }
>
> uint32_t qemu_fdt_get_phandle(void *fdt, const char *path)
> @@ -633,6 +638,16 @@ out:
> return ret;
> }
>
> +int qemu_devtree_getparent(void *fdt, char *node_path, const char *current)
This inherently needs to scan the tree from the beginning at least
once, but the implementation is much worse than that.
> +{
> + int offset = fdt_path_offset(fdt, current);
This scans the tree from the start.
> + int parent_offset = fdt_supernode_atdepth_offset(fdt, offset,
> + fdt_node_depth(fdt, offset) - 1, NULL);
This does it twice more (one for fdt_node_depth() and one for
fdt_supernode_atdepth_offset()).
> +
> + return parent_offset >= 0 ?
> + fdt_get_path(fdt, parent_offset, node_path, DT_PATH_LENGTH) : 1;
This does it a fourth time.
Since you're starting from a path, not an offset, you could instead
chop off the last path component, then do a single fdt_get_path().
> +}
> +
> void qmp_dumpdtb(const char *filename, Error **errp)
> {
> ERRP_GUARD();
> --
> 2.43.0
>
--
David Gibson (he or they) | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you, not the other way
| around.
http://www.ozlabs.org/~dgibson
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
next prev parent reply other threads:[~2026-01-27 2:19 UTC|newest]
Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-01-26 17:42 [PATCH 00/27] hw/arm: Add generic FDT-based machine and infrastructure Ruslan Ruslichenko
2026-01-26 17:42 ` [PATCH 01/27] system/device_tree: update qemu_fdt_getprop/_cell Ruslan Ruslichenko
2026-01-27 1:56 ` David Gibson [this message]
2026-01-26 17:42 ` [PATCH 02/27] system/device_tree: add few parsing and traversal helpers Ruslan Ruslichenko
2026-01-27 2:19 ` David Gibson
2026-01-27 21:22 ` Ruslan Ruslichenko
2026-01-26 17:42 ` [PATCH 03/27] util/log: add log entry for fdt generic utils Ruslan Ruslichenko
2026-01-26 17:42 ` [PATCH 04/27] hw/core: introduce generic FDT device model registry Ruslan Ruslichenko
2026-01-26 17:42 ` [PATCH 05/27] hw/core/fdt_generic: implement FDT machine creation helpers Ruslan Ruslichenko
2026-01-26 17:42 ` [PATCH 06/27] hw/core/fdt_generic: add cpu clusters management Ruslan Ruslichenko
2026-01-26 17:42 ` [PATCH 07/27] hw/core/fdt_generic_util: implement main fdt parse routine Ruslan Ruslichenko
2026-01-26 17:42 ` [PATCH 08/27] hw/core/fdt_generic_util: implement fdt_init_qdev Ruslan Ruslichenko
2026-01-26 17:42 ` [PATCH 09/27] hw/core/fdt_generic_util: initilize qdev properties from fdt Ruslan Ruslichenko
2026-01-26 17:42 ` [PATCH 10/27] hw/core/fdt_generic_util: actually realize device Ruslan Ruslichenko
2026-01-26 17:42 ` [PATCH 11/27] hw/core/fdt_generic_util: add TYPE_FDT_GENERIC_MMAP Ruslan Ruslichenko
2026-01-26 17:42 ` [PATCH 12/27] hw/core/fdt_generic_util: add TYPE_FDT_GENERIC_INTC Ruslan Ruslichenko
2026-01-26 17:42 ` [PATCH 13/27] hw/core/fdt_generic_util: implement fdt_get_irq/_info API Ruslan Ruslichenko
2026-01-26 17:43 ` [PATCH 14/27] hw/core/fdt_generic_util: map device memory Ruslan Ruslichenko
2026-01-26 17:43 ` [PATCH 15/27] hw/core/fdt_generic_util: Connect device irqs Ruslan Ruslichenko
2026-01-26 17:43 ` [PATCH 16/27] hw/core/fdt_generic_util: realize cpu clusters Ruslan Ruslichenko
2026-01-26 17:43 ` [PATCH 17/27] hw/core: add fdt_generic to the build Ruslan Ruslichenko
2026-01-26 17:43 ` [PATCH 18/27] hw/core/machine: add '-hw-dtb' option for machine Ruslan Ruslichenko
2026-01-27 8:40 ` Zhao Liu
2026-01-27 20:12 ` Ruslan Ruslichenko
2026-01-26 17:43 ` [PATCH 19/27] hw/arm: add generic ARM machine initialized by FDT Ruslan Ruslichenko
2026-01-26 17:43 ` [PATCH 20/27] hw/core/sysbus: implement FDT_GENERIC_MMAP_CLASS interface Ruslan Ruslichenko
2026-01-26 17:43 ` [PATCH 21/27] hw/intc/arm_gic: implement FDT_GENERIC_INTC and fdt support Ruslan Ruslichenko
2026-01-26 17:43 ` [PATCH 22/27] target/arm/cpu: add fdt support for armv8-timer Ruslan Ruslichenko
2026-01-26 17:43 ` [PATCH 23/27] qom/object: export object_resolve_link() Ruslan Ruslichenko
2026-01-26 17:43 ` [PATCH 24/27] system/memory: add setters for MemoryRegion properties Ruslan Ruslichenko
2026-01-26 17:43 ` [PATCH 25/27] system/memory: implement FDT_GENERIC_MMAP interface Ruslan Ruslichenko
2026-01-26 17:43 ` [PATCH 26/27] hw/core/fdt_generic_util: initialize serial devices Ruslan Ruslichenko
2026-01-26 17:43 ` [PATCH 27/27] system/memory: add QOM aliases for fdt support Ruslan Ruslichenko
2026-01-27 10:02 ` [PATCH 00/27] hw/arm: Add generic FDT-based machine and infrastructure Peter Maydell
2026-01-27 14:29 ` BALATON Zoltan
2026-01-27 18:18 ` Ruslan Ruslichenko
2026-01-28 17:48 ` Alex Bennée
2026-01-28 21:41 ` BALATON Zoltan
2026-01-29 12:23 ` Alex Bennée
2026-01-29 15:39 ` Ruslan Ruslichenko
2026-02-06 18:34 ` Alex Bennée
2026-01-29 16:11 ` Edgar E. Iglesias
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aXgbYR9Sdu7dIHdY@zatzit \
--to=david@gibson.dropbear.id.au \
--cc=Ruslan_Ruslichenko@epam.com \
--cc=alistair@alistair23.me \
--cc=artem_mygaiev@epam.com \
--cc=edgar.iglesias@gmail.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=ruslichenko.r@gmail.com \
--cc=takahiro.nakata.wr@renesas.com \
--cc=volodymyr_babchuk@epam.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.