QOM Super class access
v3 cover QOM Super class access
From: Peter Crosthwaite <[email protected]>
This series enables QOM super class access and demostrates some usages. Replaces the save->override->call via FooClass technique, to reduce some of the boiler plate in recently fully QOMified devices.
Applied the change to ARM CPU, MB CPU and some of Andreas's recently QOMified i386 devices, all which have the save->override->call issue. ARMCPU I've done a brief test on and seems to work.
ARM CPU was particularly difficult, as it has 3 layers of heirachy, where a non-concrete class (TYPE_ARM_CPU) need to super class itself (to TYPE_CPU). This sees the need for super-classers to specify their expected base class level. See patches for illustration.
The main future work to the series is to apply the change pattern to the reset of the tree
changed since V2:
Removed object_class_get_parent_by_name
introduce FOO_PARENT_CLASS macros
changed since V1:
Simplified to use object_class_get_parent_by_type (suggest by Hu Tao)
Peter Crosthwaite (4):
target-arm/cpu.c: delete un-needed instance/class sizes
target-arm: Use parent classes for reset + realize
target-microblaze: Use parent class for reset + realize
i8254: Use parent class for realize
hw/i386/kvm/i8254.c | 19 ++++--------------- hw/timer/i8254.c | 17 ++++------------- target-arm/cpu-qom.h | 22 ++-------------------- target-arm/cpu.c | 16 +++++----------- target-microblaze/cpu-qom.h | 22 ++-------------------- target-microblaze/cpu.c | 14 ++++---------- 6 files changed, 21 insertions(+), 89 deletions(-)
Signature · 1 line
1.8.3.rc1.44.gb387c77.dirty
PATCH v3 1/4 target-arm/cpu.c: delete un-needed instance/class sizes
From: Peter Crosthwaite <[email protected]>
Since commit aca59af612840772f18598363b65a25bf02bb569 QOM automatically inherits class and instance size from the parent class. No need to redefine as the same value as the parent.
---
changed since v2:
Added fixing commit reference (AF review).
target-arm/cpu.c | 2 -- 1 file changed, 2 deletions(-)
target-arm/cpu.c +0 -2
@@ -818,9 +818,7 @@ static void cpu_register(const ARMCPUInfo *info) {TypeInfo type_info = { .parent =TYPE_ARM_CPU , - .instance_size =sizeof (ARMCPU ), .instance_init = info->initfn, - .class_size =sizeof (ARMCPUClass), .class_init = info->class_init, };
Signature · 1 line
1.8.3.rc1.44.gb387c77.dirty
PATCH v3 2/4 target-arm: Use parent classes for reset + realize
In reply to [email protected]From: Peter Crosthwaite <[email protected]>
ARMCPUClass is only needed for parent-class abstract function access. Just use parent classes for reset and realize access and remove ARMCPUClass completely.
---
target-arm/cpu-qom.h | 22 ++-------------------- target-arm/cpu.c | 14 +++++--------- 2 files changed, 7 insertions(+), 29 deletions(-)
target-arm/cpu-qom.h +2 -20
@@ -24,28 +24,10 @@#define TYPE_ARM_CPU "arm-cpu" -#define ARM_CPU_CLASS (klass) \ - OBJECT_CLASS_CHECK(ARMCPUClass, (klass), TYPE_ARM_CPU)#define ARM_CPU (obj) \ OBJECT_CHECK(ARMCPU, (obj), TYPE_ARM_CPU) -#define ARM_CPU_GET_CLASS (obj) \ - OBJECT_GET_CLASS(ARMCPUClass, (obj), TYPE_ARM_CPU) - -/** -* ARMCPUClass: -* @parent_realize: The parent class' realize handler. -* @parent_reset: The parent class' reset handler. -* -* An ARM CPU model. -*/ -typedef struct ARMCPUClass { -/*< private >*/ -CPUClass parent_class; -/*< public >*/ - -DeviceRealize parent_realize; -void (*parent_reset)(CPUState *cpu); -}ARMCPUClass ; +#define ARM_CPU_PARENT_CLASS \ + object_class_get_parent(object_class_by_name(TYPE_ARM_CPU))/** * ARMCPU:
target-arm/cpu.c +5 -9
@@ -60,10 +60,10 @@ static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)static void arm_cpu_reset (CPUState *s) {ARMCPU *cpu =ARM_CPU (s); -ARMCPUClass *acc =ARM_CPU_GET_CLASS (cpu); +CPUClass *cc_parent =CPU_CLASS (ARM_CPU_PARENT_CLASS );CPUARMState *env = &cpu->env; - acc->parent_reset (s); + cc_parent->reset (s);memset (env,0 , offsetof(CPUARMState , breakpoints));g_hash_table_foreach (cpu->cp_regs, cp_reg_reset, cpu);
@@ -153,7 +153,7 @@ static void arm_cpu_finalizefn(Object *obj)static void arm_cpu_realizefn (DeviceState *dev,Error **errp) {ARMCPU *cpu =ARM_CPU (dev); -ARMCPUClass *acc =ARM_CPU_GET_CLASS (dev); +DeviceClass *dc_parent =DEVICE_CLASS (ARM_CPU_PARENT_CLASS );CPUARMState *env = &cpu->env;/* Some features automatically imply others: */
@@ -204,7 +204,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)cpu_reset (CPU (cpu)); - acc->parent_realize (dev, errp); + dc_parent->realize (dev, errp); }/* CPU models */
@@ -798,14 +798,11 @@ static const ARMCPUInfo arm_cpus[] = {static void arm_cpu_class_init (ObjectClass *oc,void *data) { -ARMCPUClass *acc =ARM_CPU_CLASS (oc); -CPUClass *cc =CPU_CLASS (acc); +CPUClass *cc =CPU_CLASS (oc);DeviceClass *dc =DEVICE_CLASS (oc); - acc->parent_realize = dc->realize; dc->realize = arm_cpu_realizefn; - acc->parent_reset = cc->reset; cc->reset = arm_cpu_reset; cc->class_by_name = arm_cpu_class_by_name;
@@ -834,7 +831,6 @@ static const TypeInfo arm_cpu_type_info = { .instance_init = arm_cpu_initfn, .instance_finalize = arm_cpu_finalizefn, .abstract = true, - .class_size = sizeof(ARMCPUClass), .class_init = arm_cpu_class_init, };
Signature · 1 line
1.8.3.rc1.44.gb387c77.dirty
PATCH v3 3/4 target-microblaze: Use parent class for reset + realize
In reply to [email protected]From: Peter Crosthwaite <[email protected]>
MicroblazeCPUClass is only needed for parent-class abstract function access. Just use parent classes for reset and realize access and remove MicroblazeCPUClass completely.
---
target-microblaze/cpu-qom.h | 22 ++-------------------- target-microblaze/cpu.c | 14 ++++---------- 2 files changed, 6 insertions(+), 30 deletions(-)
target-microblaze/cpu-qom.h +2 -20
@@ -24,28 +24,10 @@#define TYPE_MICROBLAZE_CPU "microblaze-cpu" -#define MICROBLAZE_CPU_CLASS (klass) \ - OBJECT_CLASS_CHECK(MicroBlazeCPUClass, (klass), TYPE_MICROBLAZE_CPU)#define MICROBLAZE_CPU (obj) \ OBJECT_CHECK(MicroBlazeCPU, (obj), TYPE_MICROBLAZE_CPU) -#define MICROBLAZE_CPU_GET_CLASS (obj) \ - OBJECT_GET_CLASS(MicroBlazeCPUClass, (obj), TYPE_MICROBLAZE_CPU) - -/** -* MicroBlazeCPUClass: -* @parent_realize: The parent class' realize handler. -* @parent_reset: The parent class' reset handler. -* -* A MicroBlaze CPU model. -*/ -typedef struct MicroBlazeCPUClass { -/*< private >*/ -CPUClass parent_class; -/*< public >*/ - -DeviceRealize parent_realize; -void (*parent_reset)(CPUState *cpu); -}MicroBlazeCPUClass ; +#define MICROBLAZE_CPU_PARENT_CLASS \ + object_class_get_parent(object_class_by_name(TYPE_MICROBLAZE_CPU))/** * MicroBlazeCPU:
target-microblaze/cpu.c +4 -10
@@ -25,15 +25,14 @@#include "hw/qdev-properties.h" #include "migration/vmstate.h" -/* CPUClass::reset() */ static void mb_cpu_reset (CPUState *s) {MicroBlazeCPU *cpu =MICROBLAZE_CPU (s); -MicroBlazeCPUClass *mcc =MICROBLAZE_CPU_GET_CLASS (cpu); +CPUClass *cc_parent =CPU_CLASS (MICROBLAZE_CPU_PARENT_CLASS );CPUMBState *env = &cpu->env; - mcc->parent_reset (s); + cc_parent->reset (s);memset (env,0 , offsetof(CPUMBState , breakpoints)); env->res_addr =RES_ADDR_NONE ;
@@ -84,11 +83,10 @@ static void mb_cpu_reset(CPUState *s)static void mb_cpu_realizefn (DeviceState *dev,Error **errp) {MicroBlazeCPU *cpu =MICROBLAZE_CPU (dev); -MicroBlazeCPUClass *mcc =MICROBLAZE_CPU_GET_CLASS (dev); - +DeviceClass *dc_parent =DEVICE_CLASS (MICROBLAZE_CPU_PARENT_CLASS );cpu_reset (CPU (cpu)); - mcc->parent_realize (dev, errp); + dc_parent->realize (dev, errp); }static void mb_cpu_initfn (Object *obj)
@@ -123,12 +121,9 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data) {DeviceClass *dc =DEVICE_CLASS (oc);CPUClass *cc =CPU_CLASS (oc); -MicroBlazeCPUClass *mcc =MICROBLAZE_CPU_CLASS (oc); - mcc->parent_realize = dc->realize; dc->realize = mb_cpu_realizefn; - mcc->parent_reset = cc->reset; cc->reset = mb_cpu_reset; cc->do_interrupt = mb_cpu_do_interrupt;
@@ -143,7 +138,6 @@ static const TypeInfo mb_cpu_type_info = { .parent = TYPE_CPU, .instance_size = sizeof(MicroBlazeCPU), .instance_init = mb_cpu_initfn, - .class_size = sizeof(MicroBlazeCPUClass), .class_init = mb_cpu_class_init, };
Signature · 1 line
1.8.3.rc1.44.gb387c77.dirty
PATCH v3 4/4 i8254: Use parent class for realize
In reply to [email protected]From: Peter Crosthwaite <[email protected]>
[KVM]PITClass is only needed for parent-class realize function access. Just use parent classes for realize access and remove [KVM]PITClass completely.
---
hw/i386/kvm/i8254.c | 19 ++++--------------- hw/timer/i8254.c | 17 ++++------------- 2 files changed, 8 insertions(+), 28 deletions(-)
hw/i386/kvm/i8254.c +4 -15
@@ -33,10 +33,8 @@#define CALIBRATION_ROUNDS 3#define KVM_PIT (obj) OBJECT_CHECK(KVMPITState, (obj), TYPE_KVM_I8254) -#define KVM_PIT_CLASS (class) \ - OBJECT_CLASS_CHECK(KVMPITClass, (class), TYPE_KVM_I8254) -#define KVM_PIT_GET_CLASS (obj) \ - OBJECT_GET_CLASS(KVMPITClass, (obj), TYPE_KVM_I8254) +#define KVM_PIT_PARENT_CLASS \ + object_class_get_parent(object_class_by_name(TYPE_KVM_I8254)) typedef struct KVMPITState { PITCommonState parent_obj;
@@ -46,12 +44,6 @@ typedef struct KVMPITState {int64_t kernel_clock_offset; } KVMPITState; -typedef struct KVMPITClass { -PITCommonClass parent_class; - -DeviceRealize parent_realize; -}KVMPITClass ; -static int64_t abs64 (int64_t v) {return v <0 ? -v : v;
@@ -250,7 +242,7 @@ static void kvm_pit_vm_state_change(void *opaque, int running,static void kvm_pit_realizefn (DeviceState *dev,Error **errp) {PITCommonState *pit =PIT_COMMON (dev); -KVMPITClass *kpc =KVM_PIT_GET_CLASS (dev); +DeviceClass *dc_parent =DEVICE_CLASS (KVM_PIT_PARENT_CLASS );KVMPITState *s =KVM_PIT (pit);struct kvm_pit_config config = { .flags =0 ,
@@ -294,7 +286,7 @@ static void kvm_pit_realizefn(DeviceState *dev, Error **errp)qemu_add_vm_change_state_handler (kvm_pit_vm_state_change, s); - kpc->parent_realize (dev, errp); + dc_parent->realize (dev, errp); }static Property kvm_pit_properties[] = {
@@ -306,11 +298,9 @@ static Property kvm_pit_properties[] = {static void kvm_pit_class_init (ObjectClass *klass,void *data) { -KVMPITClass *kpc =KVM_PIT_CLASS (klass);PITCommonClass *k =PIT_COMMON_CLASS (klass);DeviceClass *dc =DEVICE_CLASS (klass); - kpc->parent_realize = dc->realize; dc->realize = kvm_pit_realizefn; k->set_channel_gate = kvm_pit_set_gate; k->get_channel_info = kvm_pit_get_channel_info;
@@ -325,7 +315,6 @@ static const TypeInfo kvm_pit_info = { .parent = TYPE_PIT_COMMON, .instance_size = sizeof(KVMPITState), .class_init = kvm_pit_class_init, - .class_size = sizeof(KVMPITClass), };static void kvm_pit_register (void )
hw/timer/i8254.c +4 -13
@@ -35,14 +35,8 @@#define RW_STATE_WORD0 3#define RW_STATE_WORD1 4 -#define PIT_CLASS (class) OBJECT_CLASS_CHECK(PITClass, (class), TYPE_I8254) -#define PIT_GET_CLASS (obj) OBJECT_GET_CLASS(PITClass, (obj), TYPE_I8254) - -typedef struct PITClass { -PITCommonClass parent_class; - -DeviceRealize parent_realize; -}PITClass ; +#define I8254_PARENT_CLASS \ + object_class_get_parent(object_class_by_name(TYPE_I8254))static void pit_irq_timer_update (PITChannelState *s,int64_t current_time);
@@ -325,7 +319,7 @@ static void pit_post_load(PITCommonState *s)static void pit_realizefn (DeviceState *dev,Error **err) {PITCommonState *pit =PIT_COMMON (dev); -PITClass *pc =PIT_GET_CLASS (dev); +DeviceClass *dc_parent =DEVICE_CLASS (I8254_PARENT_CLASS );PITChannelState *s; s = &pit->channels[0 ];
@@ -338,7 +332,7 @@ static void pit_realizefn(DeviceState *dev, Error **err)qdev_init_gpio_in (dev, pit_irq_control,1 ); - pc->parent_realize (dev, err); + dc_parent->realize (dev, err); }static Property pit_properties[] = {
@@ -348,11 +342,9 @@ static Property pit_properties[] = {static void pit_class_initfn (ObjectClass *klass,void *data) { -PITClass *pc =PIT_CLASS (klass);PITCommonClass *k =PIT_COMMON_CLASS (klass);DeviceClass *dc =DEVICE_CLASS (klass); - pc->parent_realize = dc->realize; dc->realize = pit_realizefn; k->set_channel_gate = pit_set_channel_gate; k->get_channel_info = pit_get_channel_info_common;
@@ -366,7 +358,6 @@ static const TypeInfo pit_info = { .parent = TYPE_PIT_COMMON, .instance_size = sizeof(PITCommonState), .class_init = pit_class_initfn, - .class_size = sizeof(PITClass), };static void pit_register_types (void )
Signature · 1 line
1.8.3.rc1.44.gb387c77.dirty