diff options
Diffstat (limited to 'hw/intc/loongarch_extioi.c')
| -rw-r--r-- | hw/intc/loongarch_extioi.c | 112 |
1 files changed, 37 insertions, 75 deletions
diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c index dd91f89361..4a1a7c357c 100644 --- a/hw/intc/loongarch_extioi.c +++ b/hw/intc/loongarch_extioi.c @@ -10,16 +10,13 @@ #include "qemu/log.h" #include "qapi/error.h" #include "hw/irq.h" -#include "hw/sysbus.h" #include "hw/loongarch/virt.h" -#include "hw/qdev-properties.h" #include "exec/address-spaces.h" #include "hw/intc/loongarch_extioi.h" -#include "migration/vmstate.h" #include "trace.h" -static void extioi_update_irq(LoongArchExtIOI *s, int irq, int level) +static void extioi_update_irq(LoongArchExtIOICommonState *s, int irq, int level) { int ipnum, cpu, found, irq_index, irq_mask; @@ -54,7 +51,7 @@ static void extioi_update_irq(LoongArchExtIOI *s, int irq, int level) static void extioi_setirq(void *opaque, int irq, int level) { - LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque); + LoongArchExtIOICommonState *s = LOONGARCH_EXTIOI_COMMON(opaque); trace_loongarch_extioi_setirq(irq, level); if (level) { set_bit32(irq, s->isr); @@ -67,7 +64,7 @@ static void extioi_setirq(void *opaque, int irq, int level) static MemTxResult extioi_readw(void *opaque, hwaddr addr, uint64_t *data, unsigned size, MemTxAttrs attrs) { - LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque); + LoongArchExtIOICommonState *s = LOONGARCH_EXTIOI_COMMON(opaque); unsigned long offset = addr & 0xffff; uint32_t index, cpu; @@ -106,7 +103,7 @@ static MemTxResult extioi_readw(void *opaque, hwaddr addr, uint64_t *data, return MEMTX_OK; } -static inline void extioi_enable_irq(LoongArchExtIOI *s, int index,\ +static inline void extioi_enable_irq(LoongArchExtIOICommonState *s, int index,\ uint32_t mask, int level) { uint32_t val; @@ -125,8 +122,8 @@ static inline void extioi_enable_irq(LoongArchExtIOI *s, int index,\ } } -static inline void extioi_update_sw_coremap(LoongArchExtIOI *s, int irq, - uint64_t val, bool notify) +static inline void extioi_update_sw_coremap(LoongArchExtIOICommonState *s, + int irq, uint64_t val, bool notify) { int i, cpu; @@ -162,8 +159,8 @@ static inline void extioi_update_sw_coremap(LoongArchExtIOI *s, int irq, } } -static inline void extioi_update_sw_ipmap(LoongArchExtIOI *s, int index, - uint64_t val) +static inline void extioi_update_sw_ipmap(LoongArchExtIOICommonState *s, + int index, uint64_t val) { int i; uint8_t ipnum; @@ -186,7 +183,7 @@ static MemTxResult extioi_writew(void *opaque, hwaddr addr, uint64_t val, unsigned size, MemTxAttrs attrs) { - LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque); + LoongArchExtIOICommonState *s = LOONGARCH_EXTIOI_COMMON(opaque); int cpu, index, old_data, irq; uint32_t offset; @@ -266,7 +263,7 @@ static const MemoryRegionOps extioi_ops = { static MemTxResult extioi_virt_readw(void *opaque, hwaddr addr, uint64_t *data, unsigned size, MemTxAttrs attrs) { - LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque); + LoongArchExtIOICommonState *s = LOONGARCH_EXTIOI_COMMON(opaque); switch (addr) { case EXTIOI_VIRT_FEATURES: @@ -286,7 +283,7 @@ static MemTxResult extioi_virt_writew(void *opaque, hwaddr addr, uint64_t val, unsigned size, MemTxAttrs attrs) { - LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque); + LoongArchExtIOICommonState *s = LOONGARCH_EXTIOI_COMMON(opaque); switch (addr) { case EXTIOI_VIRT_FEATURES: @@ -320,12 +317,15 @@ static const MemoryRegionOps extioi_virt_ops = { static void loongarch_extioi_realize(DeviceState *dev, Error **errp) { - LoongArchExtIOI *s = LOONGARCH_EXTIOI(dev); + LoongArchExtIOICommonState *s = LOONGARCH_EXTIOI_COMMON(dev); + LoongArchExtIOIClass *lec = LOONGARCH_EXTIOI_GET_CLASS(dev); SysBusDevice *sbd = SYS_BUS_DEVICE(dev); + Error *local_err = NULL; int i, pin; - if (s->num_cpu == 0) { - error_setg(errp, "num-cpu must be at least 1"); + lec->parent_realize(dev, &local_err); + if (local_err) { + error_propagate(errp, local_err); return; } @@ -360,23 +360,23 @@ static void loongarch_extioi_realize(DeviceState *dev, Error **errp) } } -static void loongarch_extioi_finalize(Object *obj) +static void loongarch_extioi_unrealize(DeviceState *dev) { - LoongArchExtIOI *s = LOONGARCH_EXTIOI(obj); + LoongArchExtIOICommonState *s = LOONGARCH_EXTIOI_COMMON(dev); g_free(s->cpu); } static void loongarch_extioi_reset(DeviceState *d) { - LoongArchExtIOI *s = LOONGARCH_EXTIOI(d); + LoongArchExtIOICommonState *s = LOONGARCH_EXTIOI_COMMON(d); s->status = 0; } static int vmstate_extioi_post_load(void *opaque, int version_id) { - LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque); + LoongArchExtIOICommonState *s = LOONGARCH_EXTIOI_COMMON(opaque); int i, start_irq; for (i = 0; i < (EXTIOI_IRQS / 4); i++) { @@ -391,66 +391,28 @@ static int vmstate_extioi_post_load(void *opaque, int version_id) return 0; } -static const VMStateDescription vmstate_extioi_core = { - .name = "extioi-core", - .version_id = 1, - .minimum_version_id = 1, - .fields = (const VMStateField[]) { - VMSTATE_UINT32_ARRAY(coreisr, ExtIOICore, EXTIOI_IRQS_GROUP_COUNT), - VMSTATE_END_OF_LIST() - } -}; - -static const VMStateDescription vmstate_loongarch_extioi = { - .name = TYPE_LOONGARCH_EXTIOI, - .version_id = 3, - .minimum_version_id = 3, - .post_load = vmstate_extioi_post_load, - .fields = (const VMStateField[]) { - VMSTATE_UINT32_ARRAY(bounce, LoongArchExtIOI, EXTIOI_IRQS_GROUP_COUNT), - VMSTATE_UINT32_ARRAY(nodetype, LoongArchExtIOI, - EXTIOI_IRQS_NODETYPE_COUNT / 2), - VMSTATE_UINT32_ARRAY(enable, LoongArchExtIOI, EXTIOI_IRQS / 32), - VMSTATE_UINT32_ARRAY(isr, LoongArchExtIOI, EXTIOI_IRQS / 32), - VMSTATE_UINT32_ARRAY(ipmap, LoongArchExtIOI, EXTIOI_IRQS_IPMAP_SIZE / 4), - VMSTATE_UINT32_ARRAY(coremap, LoongArchExtIOI, EXTIOI_IRQS / 4), - - VMSTATE_STRUCT_VARRAY_POINTER_UINT32(cpu, LoongArchExtIOI, num_cpu, - vmstate_extioi_core, ExtIOICore), - VMSTATE_UINT32(features, LoongArchExtIOI), - VMSTATE_UINT32(status, LoongArchExtIOI), - VMSTATE_END_OF_LIST() - } -}; - -static const Property extioi_properties[] = { - DEFINE_PROP_UINT32("num-cpu", LoongArchExtIOI, num_cpu, 1), - DEFINE_PROP_BIT("has-virtualization-extension", LoongArchExtIOI, features, - EXTIOI_HAS_VIRT_EXTENSION, 0), - DEFINE_PROP_END_OF_LIST(), -}; - static void loongarch_extioi_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + LoongArchExtIOIClass *lec = LOONGARCH_EXTIOI_CLASS(klass); + LoongArchExtIOICommonClass *lecc = LOONGARCH_EXTIOI_COMMON_CLASS(klass); - dc->realize = loongarch_extioi_realize; + device_class_set_parent_realize(dc, loongarch_extioi_realize, + &lec->parent_realize); + device_class_set_parent_unrealize(dc, loongarch_extioi_unrealize, + &lec->parent_unrealize); device_class_set_legacy_reset(dc, loongarch_extioi_reset); - device_class_set_props(dc, extioi_properties); - dc->vmsd = &vmstate_loongarch_extioi; + lecc->post_load = vmstate_extioi_post_load; } -static const TypeInfo loongarch_extioi_info = { - .name = TYPE_LOONGARCH_EXTIOI, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(struct LoongArchExtIOI), - .class_init = loongarch_extioi_class_init, - .instance_finalize = loongarch_extioi_finalize, +static const TypeInfo loongarch_extioi_types[] = { + { + .name = TYPE_LOONGARCH_EXTIOI, + .parent = TYPE_LOONGARCH_EXTIOI_COMMON, + .instance_size = sizeof(LoongArchExtIOIState), + .class_size = sizeof(LoongArchExtIOIClass), + .class_init = loongarch_extioi_class_init, + } }; -static void loongarch_extioi_register_types(void) -{ - type_register_static(&loongarch_extioi_info); -} - -type_init(loongarch_extioi_register_types) +DEFINE_TYPES(loongarch_extioi_types) |