From: Ruslan Ruslichenko <[email protected]> Date: Tue, 20 Jan 2026 23:01:44 +0100 Subject: [PATCH v2 01/33] system/device_tree: update qemu_fdt_getprop_cell
Update 'qemu_fdt_getprop_cell' to allow accessing specific cells within multi-cell property array. This will be used by hardware device tree parsing logic. Signed-off-by: Ruslan Ruslichenko <[email protected]> --- hw/arm/boot.c | 8 ++++---- hw/arm/raspi4b.c | 8 ++++---- hw/arm/vexpress.c | 4 ++-- include/system/device_tree.h | 5 ++--- system/device_tree.c | 18 ++++++++---------- 5 files changed, 20 insertions(+), 23 deletions(-) diff --git a/hw/arm/boot.c b/hw/arm/boot.c index c97d4c4e11..36fefd06d5 100644 --- a/hw/arm/boot.c +++ b/hw/arm/boot.c @@ -509,10 +509,10 @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo, return 0; } - acells = qemu_fdt_getprop_cell(fdt, "/", "#address-cells", - NULL, &error_fatal); - scells = qemu_fdt_getprop_cell(fdt, "/", "#size-cells", - NULL, &error_fatal); + acells = qemu_fdt_getprop_cell(fdt, "/", "#address-cells", 0, + &error_fatal); + scells = qemu_fdt_getprop_cell(fdt, "/", "#size-cells", 0, + &error_fatal); if (acells == 0 || scells == 0) { fprintf(stderr, "dtb file invalid (#address-cells or #size-cells 0)\n"); goto fail; diff --git a/hw/arm/raspi4b.c b/hw/arm/raspi4b.c index 3eeb8f447e..58ddd103b7 100644 --- a/hw/arm/raspi4b.c +++ b/hw/arm/raspi4b.c @@ -42,10 +42,10 @@ static void raspi_add_memory_node(void *fdt, hwaddr mem_base, hwaddr mem_len) uint32_t acells, scells; char *nodename = g_strdup_printf("/memory@%" PRIx64, mem_base); - acells = qemu_fdt_getprop_cell(fdt, "/", "#address-cells", - NULL, &error_fatal); - scells = qemu_fdt_getprop_cell(fdt, "/", "#size-cells", - NULL, &error_fatal); + acells = qemu_fdt_getprop_cell(fdt, "/", "#address-cells", 0, + &error_fatal); + scells = qemu_fdt_getprop_cell(fdt, "/", "#size-cells", 0, + &error_fatal); /* validated by arm_load_dtb */ g_assert(acells && scells); diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c index cc6ae7d4c4..23d2d7deff 100644 --- a/hw/arm/vexpress.c +++ b/hw/arm/vexpress.c @@ -486,9 +486,9 @@ static void vexpress_modify_dtb(const struct arm_boot_info *info, void *fdt) const VEDBoardInfo *daughterboard = (const VEDBoardInfo *)info; acells = qemu_fdt_getprop_cell(fdt, "/", "#address-cells", - NULL, &error_fatal); + 0, &error_fatal); scells = qemu_fdt_getprop_cell(fdt, "/", "#size-cells", - NULL, &error_fatal); + 0, &error_fatal); intc = find_int_controller(fdt); if (!intc) { /* Not fatal, we just won't provide virtio. This will diff --git a/include/system/device_tree.h b/include/system/device_tree.h index 49d8482ed4..5667ff9538 100644 --- a/include/system/device_tree.h +++ b/include/system/device_tree.h @@ -108,14 +108,13 @@ const void *qemu_fdt_getprop(void *fdt, const char *node_path, * @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. + * @cell_id: the index of 32bit cell to retrive * @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, + const char *property, int cell_id, Error **errp); uint32_t qemu_fdt_get_phandle(void *fdt, const char *path); uint32_t qemu_fdt_alloc_phandle(void *fdt); diff --git a/system/device_tree.c b/system/device_tree.c index 1ea1962984..d2db7bd355 100644 --- a/system/device_tree.c +++ b/system/device_tree.c @@ -446,24 +446,22 @@ const void *qemu_fdt_getprop(void *fdt, const char *node_path, } uint32_t qemu_fdt_getprop_cell(void *fdt, const char *node_path, - const char *property, int *lenp, Error **errp) + const char *property, int cell_id, 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, errp); if (!p) { return 0; - } else if (*lenp != 4) { - error_setg(errp, "%s: %s/%s not 4 bytes long (not a cell?)", - __func__, node_path, property); - *lenp = -EINVAL; + } + if (len < (cell_id + 1) * 4) { + error_setg(errp, + "%s: %s/%s is too short, need %d bytes for cell ind %d", + __func__, node_path, property, (cell_id + 1) * 4, cell_id); return 0; } - return be32_to_cpu(*p); + return be32_to_cpu(p[cell_id]); } uint32_t qemu_fdt_get_phandle(void *fdt, const char *path) -- 2.43.0
