From: Ruslan Ruslichenko <Ruslan_Ruslichenko@epam.com>
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 <Ruslan_Ruslichenko@epam.com>
---
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