From: bibo mao <maobibo@loongson.cn>
Add pch pic common driver, so that it can be shared with KVM and
TCG driver, put vmstate and property, vmstate load and store interface
in this pic common driver.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
hw/intc/loongarch_pic_common.c | 97 ++++++++++++++++++++++++++
include/hw/intc/loongarch_pic_common.h | 82 ++++++++++++++++++++++
2 files changed, 179 insertions(+)
create mode 100644 hw/intc/loongarch_pic_common.c
create mode 100644 include/hw/intc/loongarch_pic_common.h
diff --git a/hw/intc/loongarch_pic_common.c b/hw/intc/loongarch_pic_common.c
new file mode 100644
index 0000000000..a74b6c7b44
--- /dev/null
+++ b/hw/intc/loongarch_pic_common.c
@@ -0,0 +1,97 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * QEMU Loongson 7A1000 I/O interrupt controller.
+ * Copyright (C) 2024 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/intc/loongarch_pic_common.h"
+#include "hw/qdev-properties.h"
+#include "migration/vmstate.h"
+
+static int loongarch_pic_pre_save(void *opaque)
+{
+ LoongArchPICCommonState *s = (LoongArchPICCommonState *)opaque;
+ LoongArchPICCommonClass *lpcc = LOONGARCH_PIC_COMMON_GET_CLASS(s);
+
+ if (lpcc->pre_save) {
+ return lpcc->pre_save(s);
+ }
+
+ return 0;
+}
+
+static int loongarch_pic_post_load(void *opaque, int version_id)
+{
+ LoongArchPICCommonState *s = (LoongArchPICCommonState *)opaque;
+ LoongArchPICCommonClass *lpcc = LOONGARCH_PIC_COMMON_GET_CLASS(s);
+
+ if (lpcc->post_load) {
+ return lpcc->post_load(s, version_id);
+ }
+
+ return 0;
+}
+
+static void loongarch_pic_common_realize(DeviceState *dev, Error **errp)
+{
+ LoongArchPICCommonState *s = LOONGARCH_PIC_COMMON(dev);
+
+ if (!s->irq_num || s->irq_num > VIRT_PCH_PIC_IRQ_NUM) {
+ error_setg(errp, "Invalid 'pic_irq_num'");
+ return;
+ }
+}
+
+static Property loongarch_pic_common_properties[] = {
+ DEFINE_PROP_UINT32("pch_pic_irq_num", LoongArchPICCommonState, irq_num, 0),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static const VMStateDescription vmstate_loongarch_pic_common = {
+ .name = "loongarch_pch_pic",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .pre_save = loongarch_pic_pre_save,
+ .post_load = loongarch_pic_post_load,
+ .fields = (const VMStateField[]) {
+ VMSTATE_UINT64(int_mask, LoongArchPICCommonState),
+ VMSTATE_UINT64(htmsi_en, LoongArchPICCommonState),
+ VMSTATE_UINT64(intedge, LoongArchPICCommonState),
+ VMSTATE_UINT64(intclr, LoongArchPICCommonState),
+ VMSTATE_UINT64(auto_crtl0, LoongArchPICCommonState),
+ VMSTATE_UINT64(auto_crtl1, LoongArchPICCommonState),
+ VMSTATE_UINT8_ARRAY(route_entry, LoongArchPICCommonState, 64),
+ VMSTATE_UINT8_ARRAY(htmsi_vector, LoongArchPICCommonState, 64),
+ VMSTATE_UINT64(last_intirr, LoongArchPICCommonState),
+ VMSTATE_UINT64(intirr, LoongArchPICCommonState),
+ VMSTATE_UINT64(intisr, LoongArchPICCommonState),
+ VMSTATE_UINT64(int_polarity, LoongArchPICCommonState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static void loongarch_pic_common_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ LoongArchPICCommonClass *lpcc = LOONGARCH_PIC_COMMON_CLASS(klass);
+
+ device_class_set_parent_realize(dc, loongarch_pic_common_realize,
+ &lpcc->parent_realize);
+ device_class_set_props(dc, loongarch_pic_common_properties);
+ dc->vmsd = &vmstate_loongarch_pic_common;
+}
+
+static const TypeInfo loongarch_pic_common_types[] = {
+ {
+ .name = TYPE_LOONGARCH_PIC_COMMON,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(LoongArchPICCommonState),
+ .class_size = sizeof(LoongArchPICCommonClass),
+ .class_init = loongarch_pic_common_class_init,
+ .abstract = true,
+ }
+};
+
+DEFINE_TYPES(loongarch_pic_common_types)
diff --git a/include/hw/intc/loongarch_pic_common.h b/include/hw/intc/loongarch_pic_common.h
new file mode 100644
index 0000000000..2bb15b571e
--- /dev/null
+++ b/include/hw/intc/loongarch_pic_common.h
@@ -0,0 +1,82 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * LoongArch 7A1000 I/O interrupt controller definitions
+ * Copyright (c) 2024 Loongson Technology Corporation Limited
+ */
+
+#ifndef HW_LOONGARCH_PIC_COMMON_H
+#define HW_LOONGARCH_PIC_COMMON_H
+
+#include "hw/pci-host/ls7a.h"
+#include "hw/sysbus.h"
+
+#define PCH_PIC_INT_ID_VAL 0x7000000UL
+#define PCH_PIC_INT_ID_VER 0x1UL
+#define PCH_PIC_INT_ID_LO 0x00
+#define PCH_PIC_INT_ID_HI 0x04
+#define PCH_PIC_INT_MASK_LO 0x20
+#define PCH_PIC_INT_MASK_HI 0x24
+#define PCH_PIC_HTMSI_EN_LO 0x40
+#define PCH_PIC_HTMSI_EN_HI 0x44
+#define PCH_PIC_INT_EDGE_LO 0x60
+#define PCH_PIC_INT_EDGE_HI 0x64
+#define PCH_PIC_INT_CLEAR_LO 0x80
+#define PCH_PIC_INT_CLEAR_HI 0x84
+#define PCH_PIC_AUTO_CTRL0_LO 0xc0
+#define PCH_PIC_AUTO_CTRL0_HI 0xc4
+#define PCH_PIC_AUTO_CTRL1_LO 0xe0
+#define PCH_PIC_AUTO_CTRL1_HI 0xe4
+#define PCH_PIC_ROUTE_ENTRY_OFFSET 0x100
+#define PCH_PIC_ROUTE_ENTRY_END 0x13f
+#define PCH_PIC_HTMSI_VEC_OFFSET 0x200
+#define PCH_PIC_HTMSI_VEC_END 0x23f
+#define PCH_PIC_INT_STATUS_LO 0x3a0
+#define PCH_PIC_INT_STATUS_HI 0x3a4
+#define PCH_PIC_INT_POL_LO 0x3e0
+#define PCH_PIC_INT_POL_HI 0x3e4
+
+#define STATUS_LO_START 0
+#define STATUS_HI_START 0x4
+#define POL_LO_START 0x40
+#define POL_HI_START 0x44
+
+#define TYPE_LOONGARCH_PIC_COMMON "loongarch_pic_common"
+OBJECT_DECLARE_TYPE(LoongArchPICCommonState,
+ LoongArchPICCommonClass, LOONGARCH_PIC_COMMON)
+
+struct LoongArchPICCommonState {
+ SysBusDevice parent_obj;
+
+ qemu_irq parent_irq[64];
+ uint64_t int_mask; /* 0x020 interrupt mask register */
+ uint64_t htmsi_en; /* 0x040 1=msi */
+ uint64_t intedge; /* 0x060 edge=1 level=0 */
+ uint64_t intclr; /* 0x080 clean edge int, set 1 clean, 0 noused */
+ uint64_t auto_crtl0; /* 0x0c0 */
+ uint64_t auto_crtl1; /* 0x0e0 */
+ uint64_t last_intirr; /* edge detection */
+ uint64_t intirr; /* 0x380 interrupt request register */
+ uint64_t intisr; /* 0x3a0 interrupt service register */
+ /*
+ * 0x3e0 interrupt level polarity selection
+ * register 0 for high level trigger
+ */
+ uint64_t int_polarity;
+
+ uint8_t route_entry[64]; /*0x100 - 0x138*/
+ uint8_t htmsi_vector[64]; /*0x200 - 0x238*/
+
+ MemoryRegion iomem32_low;
+ MemoryRegion iomem32_high;
+ MemoryRegion iomem8;
+ unsigned int irq_num;
+};
+
+struct LoongArchPICCommonClass {
+ SysBusDeviceClass parent_class;
+
+ DeviceRealize parent_realize;
+ int (*pre_save)(LoongArchPICCommonState *s);
+ int (*post_load)(LoongArchPICCommonState *s, int version_id);
+};
+#endif /* HW_LOONGARCH_PIC_COMMON_H */
--
2.39.3
© 2016 - 2024 Red Hat, Inc.