hw/intc/loongarch_extioi: Inherit from loongarch_extioi_common

Set TYPE_LOONGARCH_EXTIOI inherit from TYPE_LOONGARCH_EXTIOI_COMMON
object, it shares vmsate and property of TYPE_LOONGARCH_EXTIOI_COMMON,
and has its own realize() function.

Signed-off-by: Bibo Mao <maobibo@loongson.cn>
Reviewed-by: Song Gao <gaosong@loongson.cn>
This commit is contained in:
Bibo Mao 2024-12-13 15:32:39 +08:00
parent 6b69f77817
commit 272c467a48
5 changed files with 85 additions and 24 deletions

View file

@ -318,17 +318,15 @@ static const MemoryRegionOps extioi_virt_ops = {
.endianness = DEVICE_LITTLE_ENDIAN, .endianness = DEVICE_LITTLE_ENDIAN,
}; };
static int vmstate_extioi_post_load(void *opaque, int version_id);
#include "loongarch_extioi_common.c"
static void loongarch_extioi_realize(DeviceState *dev, Error **errp) 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); SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
Error *local_err = NULL; Error *local_err = NULL;
int i, pin; int i, pin;
loongarch_extioi_common_realize(dev, &local_err); lec->parent_realize(dev, &local_err);
if (local_err) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
return; return;
@ -399,24 +397,25 @@ static int vmstate_extioi_post_load(void *opaque, int version_id)
static void loongarch_extioi_class_init(ObjectClass *klass, void *data) static void loongarch_extioi_class_init(ObjectClass *klass, void *data)
{ {
DeviceClass *dc = DEVICE_CLASS(klass); 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,
dc->unrealize = loongarch_extioi_unrealize; &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_legacy_reset(dc, loongarch_extioi_reset);
device_class_set_props(dc, extioi_properties); lecc->post_load = vmstate_extioi_post_load;
dc->vmsd = &vmstate_loongarch_extioi;
} }
static const TypeInfo loongarch_extioi_info = { static const TypeInfo loongarch_extioi_types[] = {
.name = TYPE_LOONGARCH_EXTIOI, {
.parent = TYPE_SYS_BUS_DEVICE, .name = TYPE_LOONGARCH_EXTIOI,
.instance_size = sizeof(struct LoongArchExtIOI), .parent = TYPE_LOONGARCH_EXTIOI_COMMON,
.class_init = loongarch_extioi_class_init, .instance_size = sizeof(LoongArchExtIOIState),
.class_size = sizeof(LoongArchExtIOIClass),
.class_init = loongarch_extioi_class_init,
}
}; };
static void loongarch_extioi_register_types(void) DEFINE_TYPES(loongarch_extioi_types)
{
type_register_static(&loongarch_extioi_info);
}
type_init(loongarch_extioi_register_types)

View file

@ -3,6 +3,12 @@
* Loongson extioi interrupt controller emulation * Loongson extioi interrupt controller emulation
* Copyright (C) 2024 Loongson Technology Corporation Limited * Copyright (C) 2024 Loongson Technology Corporation Limited
*/ */
#include "qemu/osdep.h"
#include "qemu/module.h"
#include "qapi/error.h"
#include "hw/qdev-properties.h"
#include "hw/intc/loongarch_extioi_common.h"
#include "migration/vmstate.h"
static void loongarch_extioi_common_realize(DeviceState *dev, Error **errp) static void loongarch_extioi_common_realize(DeviceState *dev, Error **errp)
{ {
@ -16,7 +22,14 @@ static void loongarch_extioi_common_realize(DeviceState *dev, Error **errp)
static int loongarch_extioi_common_post_load(void *opaque, int version_id) static int loongarch_extioi_common_post_load(void *opaque, int version_id)
{ {
return vmstate_extioi_post_load(opaque, version_id); LoongArchExtIOICommonState *s = (LoongArchExtIOICommonState *)opaque;
LoongArchExtIOICommonClass *lecc = LOONGARCH_EXTIOI_COMMON_GET_CLASS(s);
if (lecc->post_load) {
return lecc->post_load(s, version_id);
}
return 0;
} }
static const VMStateDescription vmstate_extioi_core = { static const VMStateDescription vmstate_extioi_core = {
@ -61,3 +74,27 @@ static const Property extioi_properties[] = {
features, EXTIOI_HAS_VIRT_EXTENSION, 0), features, EXTIOI_HAS_VIRT_EXTENSION, 0),
DEFINE_PROP_END_OF_LIST(), DEFINE_PROP_END_OF_LIST(),
}; };
static void loongarch_extioi_common_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
LoongArchExtIOICommonClass *lecc = LOONGARCH_EXTIOI_COMMON_CLASS(klass);
device_class_set_parent_realize(dc, loongarch_extioi_common_realize,
&lecc->parent_realize);
device_class_set_props(dc, extioi_properties);
dc->vmsd = &vmstate_loongarch_extioi;
}
static const TypeInfo loongarch_extioi_common_types[] = {
{
.name = TYPE_LOONGARCH_EXTIOI_COMMON,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(LoongArchExtIOICommonState),
.class_size = sizeof(LoongArchExtIOICommonClass),
.class_init = loongarch_extioi_common_class_init,
.abstract = true,
}
};
DEFINE_TYPES(loongarch_extioi_common_types)

View file

@ -73,4 +73,4 @@ specific_ss.add(when: 'CONFIG_LOONGSON_IPI', if_true: files('loongson_ipi.c'))
specific_ss.add(when: 'CONFIG_LOONGARCH_IPI', if_true: files('loongarch_ipi.c')) specific_ss.add(when: 'CONFIG_LOONGARCH_IPI', if_true: files('loongarch_ipi.c'))
specific_ss.add(when: 'CONFIG_LOONGARCH_PCH_PIC', if_true: files('loongarch_pch_pic.c', 'loongarch_pic_common.c')) specific_ss.add(when: 'CONFIG_LOONGARCH_PCH_PIC', if_true: files('loongarch_pch_pic.c', 'loongarch_pic_common.c'))
specific_ss.add(when: 'CONFIG_LOONGARCH_PCH_MSI', if_true: files('loongarch_pch_msi.c')) specific_ss.add(when: 'CONFIG_LOONGARCH_PCH_MSI', if_true: files('loongarch_pch_msi.c'))
specific_ss.add(when: 'CONFIG_LOONGARCH_EXTIOI', if_true: files('loongarch_extioi.c')) specific_ss.add(when: 'CONFIG_LOONGARCH_EXTIOI', if_true: files('loongarch_extioi.c', 'loongarch_extioi_common.c'))

View file

@ -10,7 +10,20 @@
#include "hw/intc/loongarch_extioi_common.h" #include "hw/intc/loongarch_extioi_common.h"
#define LoongArchExtIOI LoongArchExtIOICommonState
#define TYPE_LOONGARCH_EXTIOI "loongarch.extioi" #define TYPE_LOONGARCH_EXTIOI "loongarch.extioi"
OBJECT_DECLARE_SIMPLE_TYPE(LoongArchExtIOI, LOONGARCH_EXTIOI) OBJECT_DECLARE_TYPE(LoongArchExtIOIState, LoongArchExtIOIClass, LOONGARCH_EXTIOI)
struct LoongArchExtIOIState {
LoongArchExtIOICommonState parent_obj;
};
struct LoongArchExtIOIClass {
LoongArchExtIOICommonClass parent_class;
DeviceRealize parent_realize;
DeviceUnrealize parent_unrealize;
};
#define LoongArchExtIOI LoongArchExtIOICommonState
#define LOONGARCH_EXTIOI(obj) ((LoongArchExtIOICommonState *)obj)
#endif /* LOONGARCH_EXTIOI_H */ #endif /* LOONGARCH_EXTIOI_H */

View file

@ -7,6 +7,7 @@
#ifndef LOONGARCH_EXTIOI_COMMON_H #ifndef LOONGARCH_EXTIOI_COMMON_H
#define LOONGARCH_EXTIOI_COMMON_H #define LOONGARCH_EXTIOI_COMMON_H
#include "qom/object.h"
#include "hw/sysbus.h" #include "hw/sysbus.h"
#include "hw/loongarch/virt.h" #include "hw/loongarch/virt.h"
@ -56,6 +57,10 @@
#define EXTIOI_VIRT_COREMAP_START (0x40) #define EXTIOI_VIRT_COREMAP_START (0x40)
#define EXTIOI_VIRT_COREMAP_END (0x240) #define EXTIOI_VIRT_COREMAP_END (0x240)
#define TYPE_LOONGARCH_EXTIOI_COMMON "loongarch_extioi_common"
OBJECT_DECLARE_TYPE(LoongArchExtIOICommonState,
LoongArchExtIOICommonClass, LOONGARCH_EXTIOI_COMMON)
typedef struct ExtIOICore { typedef struct ExtIOICore {
uint32_t coreisr[EXTIOI_IRQS_GROUP_COUNT]; uint32_t coreisr[EXTIOI_IRQS_GROUP_COUNT];
DECLARE_BITMAP(sw_isr[LS3A_INTC_IP], EXTIOI_IRQS); DECLARE_BITMAP(sw_isr[LS3A_INTC_IP], EXTIOI_IRQS);
@ -82,4 +87,11 @@ struct LoongArchExtIOICommonState {
MemoryRegion extioi_system_mem; MemoryRegion extioi_system_mem;
MemoryRegion virt_extend; MemoryRegion virt_extend;
}; };
struct LoongArchExtIOICommonClass {
SysBusDeviceClass parent_class;
DeviceRealize parent_realize;
int (*post_load)(void *s, int version_id);
};
#endif /* LOONGARCH_EXTIOI_H */ #endif /* LOONGARCH_EXTIOI_H */