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 memory region is parented to
the REGISTER_ARRAY object to ensure correct finalizing order.

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.

Reviewed-by: Alistair Francis <[email protected]>
Reviewed-by: Francisco Iglesias <[email protected]>
Reviewed-by: Edgar E. Iglesias <[email protected]>
Signed-off-by: Luc Michel <[email protected]>
---
 include/hw/register.h |  4 ++++
 hw/core/register.c    | 26 ++++++++++++++++++++++----
 2 files changed, 26 insertions(+), 4 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 2553cb15aba..1612ad174f9 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;
 
@@ -265,11 +271,11 @@ static RegisterInfoArray *register_init_block(DeviceState 
*owner,
         r->opaque = owner;
 
         r_array->r[i] = r;
     }
 
-    memory_region_init_io(&r_array->mem, OBJECT(owner), ops, r_array,
+    memory_region_init_io(&r_array->mem, OBJECT(r_array), ops, r_array,
                           device_prefix, memory_size);
 
     return r_array;
 }
 
@@ -307,17 +313,29 @@ 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);
+
     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(&register_array_info);
 }
 
 type_init(register_register_types)
-- 
2.51.0


Reply via email to