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(®ister_array_info); } type_init(register_register_types) -- 2.51.0
