[PATCH] hw/core/register: add register_array_get_owner

Luc Michel posted 1 patch 1 month ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260424155646.533334-1-luc.michel@amd.com
Maintainers: Alistair Francis <alistair@alistair23.me>, "Edgar E. Iglesias" <edgar.iglesias@gmail.com>, Peter Maydell <peter.maydell@linaro.org>, Francisco Iglesias <francisco.iglesias@amd.com>
include/hw/core/register.h        | 11 +++++++++++
hw/core/register.c                |  5 +++++
hw/nvram/xlnx-versal-efuse-ctrl.c |  4 ++--
hw/nvram/xlnx-zynqmp-efuse.c      |  4 ++--
hw/ssi/xlnx-versal-ospi.c         | 10 +++-------
5 files changed, 23 insertions(+), 11 deletions(-)
[PATCH] hw/core/register: add register_array_get_owner
Posted by Luc Michel 1 month ago
Add the register_array_get_owner function to the register API. This
function can be used to retrieve the device owning the given
RegisterInfoArray.

This was previously done inline by some devices.
5c6367bc1c8850f74812eeaaf87cff9911be58de modified the way register
blocks are created and parented to the device. Since this is an
implementation detail of the register API, it makes sense to have a
function for this.

Use it in the Versal OSPI and Versal/ZynqMP eFuse models instead of
tinkering with the API internals.

Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3421
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3422
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3423
Signed-off-by: Luc Michel <luc.michel@amd.com>
---
 include/hw/core/register.h        | 11 +++++++++++
 hw/core/register.c                |  5 +++++
 hw/nvram/xlnx-versal-efuse-ctrl.c |  4 ++--
 hw/nvram/xlnx-zynqmp-efuse.c      |  4 ++--
 hw/ssi/xlnx-versal-ospi.c         | 10 +++-------
 5 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/include/hw/core/register.h b/include/hw/core/register.h
index 1f265f4ed71..c6f648fe95e 100644
--- a/include/hw/core/register.h
+++ b/include/hw/core/register.h
@@ -207,6 +207,17 @@ RegisterInfoArray *register_init_block64(DeviceState *owner,
                                          uint64_t *data,
                                          const MemoryRegionOps *ops,
                                          bool debug_enabled,
                                          uint64_t memory_size);
 
+/**
+ * register_array_get_owner
+ *
+ * Retrieve the device owning the register info array @reg_array.
+ *
+ * @reg_array The register info array to retrieve the owner from
+ *
+ * Returns: the device owning @reg_array
+ */
+DeviceState *register_array_get_owner(const RegisterInfoArray *reg_array);
+
 #endif
diff --git a/hw/core/register.c b/hw/core/register.c
index c3f3c936e70..99ca5e17758 100644
--- a/hw/core/register.c
+++ b/hw/core/register.c
@@ -320,10 +320,15 @@ static void register_array_finalize(Object *obj)
     RegisterInfoArray *r_array = REGISTER_ARRAY(obj);
 
     g_free(r_array->r);
 }
 
+DeviceState *register_array_get_owner(const RegisterInfoArray *reg_array)
+{
+    return DEVICE(OBJECT(reg_array)->parent);
+}
+
 static const TypeInfo register_array_info = {
     .name  = TYPE_REGISTER_ARRAY,
     .parent = TYPE_OBJECT,
     .instance_size = sizeof(RegisterInfoArray),
     .instance_finalize = register_array_finalize,
diff --git a/hw/nvram/xlnx-versal-efuse-ctrl.c b/hw/nvram/xlnx-versal-efuse-ctrl.c
index 69acdfa3047..f5d5587cb65 100644
--- a/hw/nvram/xlnx-versal-efuse-ctrl.c
+++ b/hw/nvram/xlnx-versal-efuse-ctrl.c
@@ -617,15 +617,15 @@ static const RegisterAccessInfo efuse_ctrl_regs_info[] = {
 static void efuse_ctrl_reg_write(void *opaque, hwaddr addr,
                                  uint64_t data, unsigned size)
 {
     RegisterInfoArray *reg_array = opaque;
     XlnxVersalEFuseCtrl *s;
-    Object *dev;
+    DeviceState *dev;
 
     assert(reg_array != NULL);
 
-    dev = reg_array->mem.owner;
+    dev = register_array_get_owner(reg_array);
     assert(dev);
 
     s = XLNX_VERSAL_EFUSE_CTRL(dev);
 
     if (addr != A_WR_LOCK && s->regs[R_WR_LOCK]) {
diff --git a/hw/nvram/xlnx-zynqmp-efuse.c b/hw/nvram/xlnx-zynqmp-efuse.c
index e6bc54fc6bd..028120f824d 100644
--- a/hw/nvram/xlnx-zynqmp-efuse.c
+++ b/hw/nvram/xlnx-zynqmp-efuse.c
@@ -722,15 +722,15 @@ static RegisterAccessInfo zynqmp_efuse_regs_info[] = {
 static void zynqmp_efuse_reg_write(void *opaque, hwaddr addr,
                                    uint64_t data, unsigned size)
 {
     RegisterInfoArray *reg_array = opaque;
     XlnxZynqMPEFuse *s;
-    Object *dev;
+    DeviceState *dev;
 
     assert(reg_array != NULL);
 
-    dev = reg_array->mem.owner;
+    dev = register_array_get_owner(reg_array);
     assert(dev);
 
     s = XLNX_ZYNQMP_EFUSE(dev);
 
     if (addr != A_WR_LOCK && s->regs[R_WR_LOCK]) {
diff --git a/hw/ssi/xlnx-versal-ospi.c b/hw/ssi/xlnx-versal-ospi.c
index 467f0ce7033..e25e4c26c2e 100644
--- a/hw/ssi/xlnx-versal-ospi.c
+++ b/hw/ssi/xlnx-versal-ospi.c
@@ -1567,19 +1567,15 @@ static RegisterAccessInfo ospi_regs_info[] = {
         .ro = 0xffffffff,
     }
 };
 
 /* Return dev-obj from reg-region created by register_init_block32 */
-static XlnxVersalOspi *xilinx_ospi_of_mr(void *mr_accessor)
+static XlnxVersalOspi *xilinx_ospi_of_mr(void *opaque)
 {
-    RegisterInfoArray *reg_array = mr_accessor;
-    Object *dev;
+    RegisterInfoArray *reg_array = REGISTER_ARRAY(opaque);
 
-    dev = reg_array->mem.owner;
-    assert(dev);
-
-    return XILINX_VERSAL_OSPI(dev);
+    return XILINX_VERSAL_OSPI(register_array_get_owner(reg_array));
 }
 
 static void ospi_write(void *opaque, hwaddr addr, uint64_t value,
         unsigned int size)
 {
-- 
2.53.0
Re: [PATCH] hw/core/register: add register_array_get_owner
Posted by Michael Tokarev 3 weeks, 3 days ago
On 24.04.2026 18:56, Luc Michel wrote:
> Add the register_array_get_owner function to the register API. This
> function can be used to retrieve the device owning the given
> RegisterInfoArray.
> 
> This was previously done inline by some devices.
> 5c6367bc1c8850f74812eeaaf87cff9911be58de modified the way register
> blocks are created and parented to the device. Since this is an
> implementation detail of the register API, it makes sense to have a
> function for this.
> 
> Use it in the Versal OSPI and Versal/ZynqMP eFuse models instead of
> tinkering with the API internals.
> 
> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3421
> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3422
> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3423
> Signed-off-by: Luc Michel <luc.michel@amd.com>
> ---
>   include/hw/core/register.h        | 11 +++++++++++
>   hw/core/register.c                |  5 +++++
>   hw/nvram/xlnx-versal-efuse-ctrl.c |  4 ++--
>   hw/nvram/xlnx-zynqmp-efuse.c      |  4 ++--
>   hw/ssi/xlnx-versal-ospi.c         | 10 +++-------
>   5 files changed, 23 insertions(+), 11 deletions(-)

This looks like a qemu-stable material (for 11.0.x series), I'm picking
it up.  Please let me know if I shouldn't.

Thanks,

/mjt
Re: [PATCH] hw/core/register: add register_array_get_owner
Posted by Luc Michel 3 weeks, 3 days ago
On 19:45 Thu 30 Apr     , Michael Tokarev wrote:
> On 24.04.2026 18:56, Luc Michel wrote:
> > Add the register_array_get_owner function to the register API. This
> > function can be used to retrieve the device owning the given
> > RegisterInfoArray.
> > 
> > This was previously done inline by some devices.
> > 5c6367bc1c8850f74812eeaaf87cff9911be58de modified the way register
> > blocks are created and parented to the device. Since this is an
> > implementation detail of the register API, it makes sense to have a
> > function for this.
> > 
> > Use it in the Versal OSPI and Versal/ZynqMP eFuse models instead of
> > tinkering with the API internals.
> > 
> > Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3421
> > Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3422
> > Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3423
> > Signed-off-by: Luc Michel <luc.michel@amd.com>
> > ---
> >   include/hw/core/register.h        | 11 +++++++++++
> >   hw/core/register.c                |  5 +++++
> >   hw/nvram/xlnx-versal-efuse-ctrl.c |  4 ++--
> >   hw/nvram/xlnx-zynqmp-efuse.c      |  4 ++--
> >   hw/ssi/xlnx-versal-ospi.c         | 10 +++-------
> >   5 files changed, 23 insertions(+), 11 deletions(-)
> 
> This looks like a qemu-stable material (for 11.0.x series), I'm picking
> it up.  Please let me know if I shouldn't.

Indeed, thank you!

Luc

> 
> Thanks,
> 
> /mjt

--
Re: [PATCH] hw/core/register: add register_array_get_owner
Posted by Thomas Huth 1 month ago
On 24/04/2026 17.56, Luc Michel wrote:
> Add the register_array_get_owner function to the register API. This
> function can be used to retrieve the device owning the given
> RegisterInfoArray.
> 
> This was previously done inline by some devices.
> 5c6367bc1c8850f74812eeaaf87cff9911be58de modified the way register
> blocks are created and parented to the device. Since this is an
> implementation detail of the register API, it makes sense to have a
> function for this.
> 
> Use it in the Versal OSPI and Versal/ZynqMP eFuse models instead of
> tinkering with the API internals.
> 
> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3421
> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3422
> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3423
> Signed-off-by: Luc Michel <luc.michel@amd.com>
> ---
>   include/hw/core/register.h        | 11 +++++++++++
>   hw/core/register.c                |  5 +++++
>   hw/nvram/xlnx-versal-efuse-ctrl.c |  4 ++--
>   hw/nvram/xlnx-zynqmp-efuse.c      |  4 ++--
>   hw/ssi/xlnx-versal-ospi.c         | 10 +++-------
>   5 files changed, 23 insertions(+), 11 deletions(-)

Thanks for the fix!

Tested-by: Thomas Huth <thuth@redhat.com>
Re: [PATCH] hw/core/register: add register_array_get_owner
Posted by Alistair Francis 1 month ago
On Sat, Apr 25, 2026 at 1:59 AM Luc Michel <luc.michel@amd.com> wrote:
>
> Add the register_array_get_owner function to the register API. This
> function can be used to retrieve the device owning the given
> RegisterInfoArray.
>
> This was previously done inline by some devices.
> 5c6367bc1c8850f74812eeaaf87cff9911be58de modified the way register
> blocks are created and parented to the device. Since this is an
> implementation detail of the register API, it makes sense to have a
> function for this.
>
> Use it in the Versal OSPI and Versal/ZynqMP eFuse models instead of
> tinkering with the API internals.
>
> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3421
> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3422
> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3423
> Signed-off-by: Luc Michel <luc.michel@amd.com>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  include/hw/core/register.h        | 11 +++++++++++
>  hw/core/register.c                |  5 +++++
>  hw/nvram/xlnx-versal-efuse-ctrl.c |  4 ++--
>  hw/nvram/xlnx-zynqmp-efuse.c      |  4 ++--
>  hw/ssi/xlnx-versal-ospi.c         | 10 +++-------
>  5 files changed, 23 insertions(+), 11 deletions(-)
>
> diff --git a/include/hw/core/register.h b/include/hw/core/register.h
> index 1f265f4ed71..c6f648fe95e 100644
> --- a/include/hw/core/register.h
> +++ b/include/hw/core/register.h
> @@ -207,6 +207,17 @@ RegisterInfoArray *register_init_block64(DeviceState *owner,
>                                           uint64_t *data,
>                                           const MemoryRegionOps *ops,
>                                           bool debug_enabled,
>                                           uint64_t memory_size);
>
> +/**
> + * register_array_get_owner
> + *
> + * Retrieve the device owning the register info array @reg_array.
> + *
> + * @reg_array The register info array to retrieve the owner from
> + *
> + * Returns: the device owning @reg_array
> + */
> +DeviceState *register_array_get_owner(const RegisterInfoArray *reg_array);
> +
>  #endif
> diff --git a/hw/core/register.c b/hw/core/register.c
> index c3f3c936e70..99ca5e17758 100644
> --- a/hw/core/register.c
> +++ b/hw/core/register.c
> @@ -320,10 +320,15 @@ static void register_array_finalize(Object *obj)
>      RegisterInfoArray *r_array = REGISTER_ARRAY(obj);
>
>      g_free(r_array->r);
>  }
>
> +DeviceState *register_array_get_owner(const RegisterInfoArray *reg_array)
> +{
> +    return DEVICE(OBJECT(reg_array)->parent);
> +}
> +
>  static const TypeInfo register_array_info = {
>      .name  = TYPE_REGISTER_ARRAY,
>      .parent = TYPE_OBJECT,
>      .instance_size = sizeof(RegisterInfoArray),
>      .instance_finalize = register_array_finalize,
> diff --git a/hw/nvram/xlnx-versal-efuse-ctrl.c b/hw/nvram/xlnx-versal-efuse-ctrl.c
> index 69acdfa3047..f5d5587cb65 100644
> --- a/hw/nvram/xlnx-versal-efuse-ctrl.c
> +++ b/hw/nvram/xlnx-versal-efuse-ctrl.c
> @@ -617,15 +617,15 @@ static const RegisterAccessInfo efuse_ctrl_regs_info[] = {
>  static void efuse_ctrl_reg_write(void *opaque, hwaddr addr,
>                                   uint64_t data, unsigned size)
>  {
>      RegisterInfoArray *reg_array = opaque;
>      XlnxVersalEFuseCtrl *s;
> -    Object *dev;
> +    DeviceState *dev;
>
>      assert(reg_array != NULL);
>
> -    dev = reg_array->mem.owner;
> +    dev = register_array_get_owner(reg_array);
>      assert(dev);
>
>      s = XLNX_VERSAL_EFUSE_CTRL(dev);
>
>      if (addr != A_WR_LOCK && s->regs[R_WR_LOCK]) {
> diff --git a/hw/nvram/xlnx-zynqmp-efuse.c b/hw/nvram/xlnx-zynqmp-efuse.c
> index e6bc54fc6bd..028120f824d 100644
> --- a/hw/nvram/xlnx-zynqmp-efuse.c
> +++ b/hw/nvram/xlnx-zynqmp-efuse.c
> @@ -722,15 +722,15 @@ static RegisterAccessInfo zynqmp_efuse_regs_info[] = {
>  static void zynqmp_efuse_reg_write(void *opaque, hwaddr addr,
>                                     uint64_t data, unsigned size)
>  {
>      RegisterInfoArray *reg_array = opaque;
>      XlnxZynqMPEFuse *s;
> -    Object *dev;
> +    DeviceState *dev;
>
>      assert(reg_array != NULL);
>
> -    dev = reg_array->mem.owner;
> +    dev = register_array_get_owner(reg_array);
>      assert(dev);
>
>      s = XLNX_ZYNQMP_EFUSE(dev);
>
>      if (addr != A_WR_LOCK && s->regs[R_WR_LOCK]) {
> diff --git a/hw/ssi/xlnx-versal-ospi.c b/hw/ssi/xlnx-versal-ospi.c
> index 467f0ce7033..e25e4c26c2e 100644
> --- a/hw/ssi/xlnx-versal-ospi.c
> +++ b/hw/ssi/xlnx-versal-ospi.c
> @@ -1567,19 +1567,15 @@ static RegisterAccessInfo ospi_regs_info[] = {
>          .ro = 0xffffffff,
>      }
>  };
>
>  /* Return dev-obj from reg-region created by register_init_block32 */
> -static XlnxVersalOspi *xilinx_ospi_of_mr(void *mr_accessor)
> +static XlnxVersalOspi *xilinx_ospi_of_mr(void *opaque)
>  {
> -    RegisterInfoArray *reg_array = mr_accessor;
> -    Object *dev;
> +    RegisterInfoArray *reg_array = REGISTER_ARRAY(opaque);
>
> -    dev = reg_array->mem.owner;
> -    assert(dev);
> -
> -    return XILINX_VERSAL_OSPI(dev);
> +    return XILINX_VERSAL_OSPI(register_array_get_owner(reg_array));
>  }
>
>  static void ospi_write(void *opaque, hwaddr addr, uint64_t value,
>          unsigned int size)
>  {
> --
> 2.53.0
>
>
Re: [PATCH] hw/core/register: add register_array_get_owner
Posted by Philippe Mathieu-Daudé 1 month ago
On 24/4/26 17:56, Luc Michel wrote:
> Add the register_array_get_owner function to the register API. This
> function can be used to retrieve the device owning the given
> RegisterInfoArray.
> 
> This was previously done inline by some devices.
> 5c6367bc1c8850f74812eeaaf87cff9911be58de modified the way register
> blocks are created and parented to the device. Since this is an
> implementation detail of the register API, it makes sense to have a
> function for this.
> 
> Use it in the Versal OSPI and Versal/ZynqMP eFuse models instead of
> tinkering with the API internals.
Fixes: 5c6367bc1c8 ("hw/core/register: add the REGISTER_ARRAY type")

> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3421
> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3422
> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3423
> Signed-off-by: Luc Michel <luc.michel@amd.com>
> ---
>   include/hw/core/register.h        | 11 +++++++++++
>   hw/core/register.c                |  5 +++++
>   hw/nvram/xlnx-versal-efuse-ctrl.c |  4 ++--
>   hw/nvram/xlnx-zynqmp-efuse.c      |  4 ++--
>   hw/ssi/xlnx-versal-ospi.c         | 10 +++-------
>   5 files changed, 23 insertions(+), 11 deletions(-)


> diff --git a/hw/core/register.c b/hw/core/register.c
> index c3f3c936e70..99ca5e17758 100644
> --- a/hw/core/register.c
> +++ b/hw/core/register.c
> @@ -320,10 +320,15 @@ static void register_array_finalize(Object *obj)
>       RegisterInfoArray *r_array = REGISTER_ARRAY(obj);
>   
>       g_free(r_array->r);
>   }
>   
> +DeviceState *register_array_get_owner(const RegisterInfoArray *reg_array)
> +{
> +    return DEVICE(OBJECT(reg_array)->parent);

Odd, we have object_class_get_parent() but no object_get_parent().

> +}

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>