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


Reply via email to