|
@@ -28,6 +28,16 @@
|
|
|
|
|
|
#define TYPE_KVM_ARM_ITS "arm-its-kvm"
|
|
#define TYPE_KVM_ARM_ITS "arm-its-kvm"
|
|
#define KVM_ARM_ITS(obj) OBJECT_CHECK(GICv3ITSState, (obj), TYPE_KVM_ARM_ITS)
|
|
#define KVM_ARM_ITS(obj) OBJECT_CHECK(GICv3ITSState, (obj), TYPE_KVM_ARM_ITS)
|
|
|
|
+#define KVM_ARM_ITS_CLASS(klass) \
|
|
|
|
+ OBJECT_CLASS_CHECK(KVMARMITSClass, (klass), TYPE_KVM_ARM_ITS)
|
|
|
|
+#define KVM_ARM_ITS_GET_CLASS(obj) \
|
|
|
|
+ OBJECT_GET_CLASS(KVMARMITSClass, (obj), TYPE_KVM_ARM_ITS)
|
|
|
|
+
|
|
|
|
+typedef struct KVMARMITSClass {
|
|
|
|
+ GICv3ITSCommonClass parent_class;
|
|
|
|
+ void (*parent_reset)(DeviceState *dev);
|
|
|
|
+} KVMARMITSClass;
|
|
|
|
+
|
|
|
|
|
|
static int kvm_its_send_msi(GICv3ITSState *s, uint32_t value, uint16_t devid)
|
|
static int kvm_its_send_msi(GICv3ITSState *s, uint32_t value, uint16_t devid)
|
|
{
|
|
{
|
|
@@ -186,6 +196,34 @@ static void kvm_arm_its_post_load(GICv3ITSState *s)
|
|
GITS_CTLR, &s->ctlr, true, &error_abort);
|
|
GITS_CTLR, &s->ctlr, true, &error_abort);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void kvm_arm_its_reset(DeviceState *dev)
|
|
|
|
+{
|
|
|
|
+ GICv3ITSState *s = ARM_GICV3_ITS_COMMON(dev);
|
|
|
|
+ KVMARMITSClass *c = KVM_ARM_ITS_GET_CLASS(s);
|
|
|
|
+ int i;
|
|
|
|
+
|
|
|
|
+ c->parent_reset(dev);
|
|
|
|
+
|
|
|
|
+ error_report("ITS KVM: full reset is not supported by QEMU");
|
|
|
|
+
|
|
|
|
+ if (!kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
|
|
|
|
+ GITS_CTLR)) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
|
|
|
|
+ GITS_CTLR, &s->ctlr, true, &error_abort);
|
|
|
|
+
|
|
|
|
+ kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
|
|
|
|
+ GITS_CBASER, &s->cbaser, true, &error_abort);
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < 8; i++) {
|
|
|
|
+ kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
|
|
|
|
+ GITS_BASER + i * 8, &s->baser[i], true,
|
|
|
|
+ &error_abort);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
static Property kvm_arm_its_props[] = {
|
|
static Property kvm_arm_its_props[] = {
|
|
DEFINE_PROP_LINK("parent-gicv3", GICv3ITSState, gicv3, "kvm-arm-gicv3",
|
|
DEFINE_PROP_LINK("parent-gicv3", GICv3ITSState, gicv3, "kvm-arm-gicv3",
|
|
GICv3State *),
|
|
GICv3State *),
|
|
@@ -196,12 +234,15 @@ static void kvm_arm_its_class_init(ObjectClass *klass, void *data)
|
|
{
|
|
{
|
|
DeviceClass *dc = DEVICE_CLASS(klass);
|
|
DeviceClass *dc = DEVICE_CLASS(klass);
|
|
GICv3ITSCommonClass *icc = ARM_GICV3_ITS_COMMON_CLASS(klass);
|
|
GICv3ITSCommonClass *icc = ARM_GICV3_ITS_COMMON_CLASS(klass);
|
|
|
|
+ KVMARMITSClass *ic = KVM_ARM_ITS_CLASS(klass);
|
|
|
|
|
|
dc->realize = kvm_arm_its_realize;
|
|
dc->realize = kvm_arm_its_realize;
|
|
dc->props = kvm_arm_its_props;
|
|
dc->props = kvm_arm_its_props;
|
|
|
|
+ ic->parent_reset = dc->reset;
|
|
icc->send_msi = kvm_its_send_msi;
|
|
icc->send_msi = kvm_its_send_msi;
|
|
icc->pre_save = kvm_arm_its_pre_save;
|
|
icc->pre_save = kvm_arm_its_pre_save;
|
|
icc->post_load = kvm_arm_its_post_load;
|
|
icc->post_load = kvm_arm_its_post_load;
|
|
|
|
+ dc->reset = kvm_arm_its_reset;
|
|
}
|
|
}
|
|
|
|
|
|
static const TypeInfo kvm_arm_its_info = {
|
|
static const TypeInfo kvm_arm_its_info = {
|
|
@@ -209,6 +250,7 @@ static const TypeInfo kvm_arm_its_info = {
|
|
.parent = TYPE_ARM_GICV3_ITS_COMMON,
|
|
.parent = TYPE_ARM_GICV3_ITS_COMMON,
|
|
.instance_size = sizeof(GICv3ITSState),
|
|
.instance_size = sizeof(GICv3ITSState),
|
|
.class_init = kvm_arm_its_class_init,
|
|
.class_init = kvm_arm_its_class_init,
|
|
|
|
+ .class_size = sizeof(KVMARMITSClass),
|
|
};
|
|
};
|
|
|
|
|
|
static void kvm_arm_its_register_types(void)
|
|
static void kvm_arm_its_register_types(void)
|