Skip to contentSkip to conversation

QOM Super class access

PATCH New [email protected] 1 participant 5 messages Jul 15, 2013

lore
Share & tools
lore
#0 lore raw

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
#1 lore raw

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
index be26acc..c2e1800 100644
@@ -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
#2 lore raw

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
index 48ba605..afc569e 100644
@@ -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
index c2e1800..933e6b1 100644
@@ -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
#3 lore raw

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
index ec2b989..b02f036 100644
@@ -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
index dce1c7e..a938ba8 100644
@@ -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
#4 lore raw

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
index c1f4094..f92c241 100644
@@ -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
index cd52140..e74cc50 100644
@@ -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