Introduce the REGISTER_ARRAY QOM type. This type reuses the existing
RegisterInfoArray struct. When `register_init_block' is called, it creates
a REGISTER_ARRAY object and parents it to the calling device. This way
it gets finalized when the device is.
The finalize function of the REGISTER_ARRAY type performs the necessary
cleaning that used to be done by `register_finalize_block'. The latter
is left empty and will be removed when all the register API users have
been refactored.
Signed-off-by: Luc Michel <luc.michel@amd.com>
---
include/hw/register.h | 4 ++++
hw/core/register.c | 24 +++++++++++++++++++++---
2 files changed, 25 insertions(+), 3 deletions(-)
diff --git a/include/hw/register.h b/include/hw/register.h
index 4d13ea183c7..65c82600e06 100644
--- a/include/hw/register.h
+++ b/include/hw/register.h
@@ -81,10 +81,12 @@ struct RegisterInfo {
const RegisterAccessInfo *access;
void *opaque;
};
+#define TYPE_REGISTER_ARRAY "qemu-register-array"
+OBJECT_DECLARE_SIMPLE_TYPE(RegisterInfoArray, REGISTER_ARRAY)
/**
* This structure is used to group all of the individual registers which are
* modeled using the RegisterInfo structure.
*
@@ -94,10 +96,12 @@ struct RegisterInfo {
*
* @mem: optional Memory region for the register
*/
struct RegisterInfoArray {
+ Object parent_obj;
+
MemoryRegion mem;
int num_elements;
RegisterInfo **r;
diff --git a/hw/core/register.c b/hw/core/register.c
index 57dde29710c..4d1cce02a55 100644
--- a/hw/core/register.c
+++ b/hw/core/register.c
@@ -243,14 +243,20 @@ static RegisterInfoArray *register_init_block(DeviceState *owner,
bool debug_enabled,
uint64_t memory_size,
size_t data_size_bits)
{
const char *device_prefix = object_get_typename(OBJECT(owner));
- RegisterInfoArray *r_array = g_new0(RegisterInfoArray, 1);
+ Object *obj;
+ RegisterInfoArray *r_array;
int data_size = data_size_bits >> 3;
int i;
+ obj = object_new(TYPE_REGISTER_ARRAY);
+ object_property_add_child(OBJECT(owner), "reg-array[*]", obj);
+ object_unref(obj);
+
+ r_array = REGISTER_ARRAY(obj);
r_array->r = g_new0(RegisterInfo *, num);
r_array->num_elements = num;
r_array->debug = debug_enabled;
r_array->prefix = device_prefix;
@@ -307,18 +313,30 @@ RegisterInfoArray *register_init_block64(DeviceState *owner,
{
return register_init_block(owner, rae, num, ri, (void *)
data, ops, debug_enabled, memory_size, 64);
}
-void register_finalize_block(RegisterInfoArray *r_array)
+static void register_array_finalize(Object *obj)
{
+ RegisterInfoArray *r_array = REGISTER_ARRAY(obj);
+
object_unparent(OBJECT(&r_array->mem));
g_free(r_array->r);
- g_free(r_array);
}
+void register_finalize_block(RegisterInfoArray *r_array)
+{
+}
+
+static const TypeInfo register_array_info = {
+ .name = TYPE_REGISTER_ARRAY,
+ .parent = TYPE_OBJECT,
+ .instance_size = sizeof(RegisterInfoArray),
+ .instance_finalize = register_array_finalize,
+};
static void register_register_types(void)
{
+ type_register_static(®ister_array_info);
}
type_init(register_register_types)
--
2.50.1
On Wed, Sep 17, 2025 at 9:51 PM Luc Michel <luc.michel@amd.com> wrote:
>
> Introduce the REGISTER_ARRAY QOM type. This type reuses the existing
> RegisterInfoArray struct. When `register_init_block' is called, it creates
> a REGISTER_ARRAY object and parents it to the calling device. This way
> it gets finalized when the device is.
>
> The finalize function of the REGISTER_ARRAY type performs the necessary
> cleaning that used to be done by `register_finalize_block'. The latter
> is left empty and will be removed when all the register API users have
> been refactored.
>
> Signed-off-by: Luc Michel <luc.michel@amd.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> include/hw/register.h | 4 ++++
> hw/core/register.c | 24 +++++++++++++++++++++---
> 2 files changed, 25 insertions(+), 3 deletions(-)
>
> diff --git a/include/hw/register.h b/include/hw/register.h
> index 4d13ea183c7..65c82600e06 100644
> --- a/include/hw/register.h
> +++ b/include/hw/register.h
> @@ -81,10 +81,12 @@ struct RegisterInfo {
> const RegisterAccessInfo *access;
>
> void *opaque;
> };
>
> +#define TYPE_REGISTER_ARRAY "qemu-register-array"
> +OBJECT_DECLARE_SIMPLE_TYPE(RegisterInfoArray, REGISTER_ARRAY)
>
> /**
> * This structure is used to group all of the individual registers which are
> * modeled using the RegisterInfo structure.
> *
> @@ -94,10 +96,12 @@ struct RegisterInfo {
> *
> * @mem: optional Memory region for the register
> */
>
> struct RegisterInfoArray {
> + Object parent_obj;
> +
> MemoryRegion mem;
>
> int num_elements;
> RegisterInfo **r;
>
> diff --git a/hw/core/register.c b/hw/core/register.c
> index 57dde29710c..4d1cce02a55 100644
> --- a/hw/core/register.c
> +++ b/hw/core/register.c
> @@ -243,14 +243,20 @@ static RegisterInfoArray *register_init_block(DeviceState *owner,
> bool debug_enabled,
> uint64_t memory_size,
> size_t data_size_bits)
> {
> const char *device_prefix = object_get_typename(OBJECT(owner));
> - RegisterInfoArray *r_array = g_new0(RegisterInfoArray, 1);
> + Object *obj;
> + RegisterInfoArray *r_array;
> int data_size = data_size_bits >> 3;
> int i;
>
> + obj = object_new(TYPE_REGISTER_ARRAY);
> + object_property_add_child(OBJECT(owner), "reg-array[*]", obj);
> + object_unref(obj);
> +
> + r_array = REGISTER_ARRAY(obj);
> r_array->r = g_new0(RegisterInfo *, num);
> r_array->num_elements = num;
> r_array->debug = debug_enabled;
> r_array->prefix = device_prefix;
>
> @@ -307,18 +313,30 @@ RegisterInfoArray *register_init_block64(DeviceState *owner,
> {
> return register_init_block(owner, rae, num, ri, (void *)
> data, ops, debug_enabled, memory_size, 64);
> }
>
> -void register_finalize_block(RegisterInfoArray *r_array)
> +static void register_array_finalize(Object *obj)
> {
> + RegisterInfoArray *r_array = REGISTER_ARRAY(obj);
> +
> object_unparent(OBJECT(&r_array->mem));
> g_free(r_array->r);
> - g_free(r_array);
> }
>
> +void register_finalize_block(RegisterInfoArray *r_array)
> +{
> +}
> +
> +static const TypeInfo register_array_info = {
> + .name = TYPE_REGISTER_ARRAY,
> + .parent = TYPE_OBJECT,
> + .instance_size = sizeof(RegisterInfoArray),
> + .instance_finalize = register_array_finalize,
> +};
>
> static void register_register_types(void)
> {
> + type_register_static(®ister_array_info);
> }
>
> type_init(register_register_types)
> --
> 2.50.1
>
>
On Wed, Sep 17, 2025 at 01:44:43PM +0200, Luc Michel wrote:
> Introduce the REGISTER_ARRAY QOM type. This type reuses the existing
> RegisterInfoArray struct. When `register_init_block' is called, it creates
> a REGISTER_ARRAY object and parents it to the calling device. This way
> it gets finalized when the device is.
>
> The finalize function of the REGISTER_ARRAY type performs the necessary
> cleaning that used to be done by `register_finalize_block'. The latter
> is left empty and will be removed when all the register API users have
> been refactored.
>
> Signed-off-by: Luc Michel <luc.michel@amd.com>
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
> ---
> include/hw/register.h | 4 ++++
> hw/core/register.c | 24 +++++++++++++++++++++---
> 2 files changed, 25 insertions(+), 3 deletions(-)
>
> diff --git a/include/hw/register.h b/include/hw/register.h
> index 4d13ea183c7..65c82600e06 100644
> --- a/include/hw/register.h
> +++ b/include/hw/register.h
> @@ -81,10 +81,12 @@ struct RegisterInfo {
> const RegisterAccessInfo *access;
>
> void *opaque;
> };
>
> +#define TYPE_REGISTER_ARRAY "qemu-register-array"
> +OBJECT_DECLARE_SIMPLE_TYPE(RegisterInfoArray, REGISTER_ARRAY)
>
> /**
> * This structure is used to group all of the individual registers which are
> * modeled using the RegisterInfo structure.
> *
> @@ -94,10 +96,12 @@ struct RegisterInfo {
> *
> * @mem: optional Memory region for the register
> */
>
> struct RegisterInfoArray {
> + Object parent_obj;
> +
> MemoryRegion mem;
>
> int num_elements;
> RegisterInfo **r;
>
> diff --git a/hw/core/register.c b/hw/core/register.c
> index 57dde29710c..4d1cce02a55 100644
> --- a/hw/core/register.c
> +++ b/hw/core/register.c
> @@ -243,14 +243,20 @@ static RegisterInfoArray *register_init_block(DeviceState *owner,
> bool debug_enabled,
> uint64_t memory_size,
> size_t data_size_bits)
> {
> const char *device_prefix = object_get_typename(OBJECT(owner));
> - RegisterInfoArray *r_array = g_new0(RegisterInfoArray, 1);
> + Object *obj;
> + RegisterInfoArray *r_array;
> int data_size = data_size_bits >> 3;
> int i;
>
> + obj = object_new(TYPE_REGISTER_ARRAY);
> + object_property_add_child(OBJECT(owner), "reg-array[*]", obj);
> + object_unref(obj);
> +
> + r_array = REGISTER_ARRAY(obj);
> r_array->r = g_new0(RegisterInfo *, num);
> r_array->num_elements = num;
> r_array->debug = debug_enabled;
> r_array->prefix = device_prefix;
>
> @@ -307,18 +313,30 @@ RegisterInfoArray *register_init_block64(DeviceState *owner,
> {
> return register_init_block(owner, rae, num, ri, (void *)
> data, ops, debug_enabled, memory_size, 64);
> }
>
> -void register_finalize_block(RegisterInfoArray *r_array)
> +static void register_array_finalize(Object *obj)
> {
> + RegisterInfoArray *r_array = REGISTER_ARRAY(obj);
> +
> object_unparent(OBJECT(&r_array->mem));
> g_free(r_array->r);
> - g_free(r_array);
> }
>
> +void register_finalize_block(RegisterInfoArray *r_array)
> +{
> +}
> +
> +static const TypeInfo register_array_info = {
> + .name = TYPE_REGISTER_ARRAY,
> + .parent = TYPE_OBJECT,
> + .instance_size = sizeof(RegisterInfoArray),
> + .instance_finalize = register_array_finalize,
> +};
>
> static void register_register_types(void)
> {
> + type_register_static(®ister_array_info);
> }
>
> type_init(register_register_types)
> --
> 2.50.1
>
© 2016 - 2026 Red Hat, Inc.