[PULL 06/11] hw/loongarch: DINTC add a MemoryRegion

Song Gao posted 11 patches 3 days, 9 hours ago
Maintainers: Paolo Bonzini <pbonzini@redhat.com>, Song Gao <gaosong@loongson.cn>, Bibo Mao <maobibo@loongson.cn>, Jiaxun Yang <jiaxun.yang@flygoat.com>
There is a newer version of this series
[PULL 06/11] hw/loongarch: DINTC add a MemoryRegion
Posted by Song Gao 3 days, 9 hours ago
the DINTC use [2fe00000-2ff00000) Memory.

Signed-off-by: Song Gao <gaosong@loongson.cn>
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
Message-ID: <20250916122109.749813-7-gaosong@loongson.cn>
---
 hw/intc/loongarch_dintc.c         | 24 +++++++++++++++++++
 hw/loongarch/virt.c               | 38 ++++++++++++++++++++++++++++++-
 include/hw/intc/loongarch_dintc.h |  1 +
 include/hw/loongarch/virt.h       |  1 +
 include/hw/pci-host/ls7a.h        |  2 ++
 5 files changed, 65 insertions(+), 1 deletion(-)

diff --git a/hw/intc/loongarch_dintc.c b/hw/intc/loongarch_dintc.c
index b2465cb022..7173a6aa29 100644
--- a/hw/intc/loongarch_dintc.c
+++ b/hw/intc/loongarch_dintc.c
@@ -17,6 +17,24 @@
 #include "trace.h"
 #include "hw/qdev-properties.h"
 
+static uint64_t loongarch_dintc_mem_read(void *opaque,
+                                        hwaddr addr, unsigned size)
+{
+    return 0;
+}
+
+static void loongarch_dintc_mem_write(void *opaque, hwaddr addr,
+                                     uint64_t val, unsigned size)
+{
+    return;
+}
+
+
+static const MemoryRegionOps loongarch_dintc_ops = {
+    .read = loongarch_dintc_mem_read,
+    .write = loongarch_dintc_mem_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
 
 static void loongarch_dintc_realize(DeviceState *dev, Error **errp)
 {
@@ -39,6 +57,12 @@ static void loongarch_dintc_unrealize(DeviceState *dev)
 
 static void loongarch_dintc_init(Object *obj)
 {
+    LoongArchDINTCState *s = LOONGARCH_DINTC(obj);
+    SysBusDevice *shd = SYS_BUS_DEVICE(obj);
+    memory_region_init_io(&s->dintc_mmio, OBJECT(s), &loongarch_dintc_ops,
+                          s, TYPE_LOONGARCH_DINTC, VIRT_DINTC_SIZE);
+    sysbus_init_mmio(shd, &s->dintc_mmio);
+    msi_nonbroken = true;
     return;
 }
 
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 4ec50f6bd9..ccd94f5328 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -28,6 +28,7 @@
 #include "hw/intc/loongarch_extioi.h"
 #include "hw/intc/loongarch_pch_pic.h"
 #include "hw/intc/loongarch_pch_msi.h"
+#include "hw/intc/loongarch_dintc.h"
 #include "hw/pci-host/ls7a.h"
 #include "hw/pci-host/gpex.h"
 #include "hw/misc/unimp.h"
@@ -386,7 +387,7 @@ static void virt_cpu_irq_init(LoongArchVirtMachineState *lvms)
 static void virt_irq_init(LoongArchVirtMachineState *lvms)
 {
     DeviceState *pch_pic, *pch_msi;
-    DeviceState *ipi, *extioi;
+    DeviceState *ipi, *extioi, *dintc;
     SysBusDevice *d;
     int i, start, num;
 
@@ -432,6 +433,33 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
      *    +--------+ +---------+ +---------+
      *    | UARTs  | | Devices | | Devices |
      *    +--------+ +---------+ +---------+
+     *
+     *
+     *  Advanced Extended IRQ model
+     *
+     *  +-----+     +---------------------------------+     +-------+
+     *  | IPI | --> |        CPUINTC                  | <-- | Timer |
+     *  +-----+     +---------------------------------+     +-------+
+     *                      ^            ^          ^
+     *                      |            |          |
+     *             +-------------+ +----------+ +---------+     +-------+
+     *             |   EIOINTC   | |   DINTC  | | LIOINTC | <-- | UARTs |
+     *             +-------------+ +----------+ +---------+     +-------+
+     *             ^            ^       ^
+     *             |            |       |
+     *        +---------+  +---------+  |
+     *        | PCH-PIC |  | PCH-MSI |  |
+     *        +---------+  +---------+  |
+     *          ^     ^           ^     |
+     *          |     |           |     |
+     *  +---------+ +---------+ +---------+
+     *  | Devices | | PCH-LPC | | Devices |
+     *  +---------+ +---------+ +---------+
+     *                  ^
+     *                  |
+     *             +---------+
+     *             | Devices |
+     *             +---------+
      */
 
     /* Create IPI device */
@@ -439,6 +467,14 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
     lvms->ipi = ipi;
     sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), &error_fatal);
 
+    /* Create DINTC device*/
+    if (virt_has_dmsi(lvms)) {
+        dintc = qdev_new(TYPE_LOONGARCH_DINTC);
+        lvms->dintc = dintc;
+        sysbus_realize_and_unref(SYS_BUS_DEVICE(dintc), &error_fatal);
+        sysbus_mmio_map(SYS_BUS_DEVICE(dintc), 0, VIRT_DINTC_BASE);
+    }
+
     /* Create EXTIOI device */
     extioi = qdev_new(TYPE_LOONGARCH_EXTIOI);
     lvms->extioi = extioi;
diff --git a/include/hw/intc/loongarch_dintc.h b/include/hw/intc/loongarch_dintc.h
index aa94cd1003..0b0b5347b2 100644
--- a/include/hw/intc/loongarch_dintc.h
+++ b/include/hw/intc/loongarch_dintc.h
@@ -23,6 +23,7 @@ typedef struct DINTCCore {
 
 struct LoongArchDINTCState {
     SysBusDevice parent_obj;
+    MemoryRegion dintc_mmio;
     DINTCCore *cpu;
     uint32_t num_cpu;
 };
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
index 98e9bf0737..cd97bdfb8d 100644
--- a/include/hw/loongarch/virt.h
+++ b/include/hw/loongarch/virt.h
@@ -89,6 +89,7 @@ struct LoongArchVirtMachineState {
     unsigned int memmap_entries;
     uint64_t misc_feature;
     uint64_t misc_status;
+    DeviceState *dintc;
 };
 
 #define TYPE_LOONGARCH_VIRT_MACHINE  MACHINE_TYPE_NAME("virt")
diff --git a/include/hw/pci-host/ls7a.h b/include/hw/pci-host/ls7a.h
index 79d4ea8501..bfdbfe3614 100644
--- a/include/hw/pci-host/ls7a.h
+++ b/include/hw/pci-host/ls7a.h
@@ -24,6 +24,8 @@
 #define VIRT_PCH_REG_BASE        0x10000000UL
 #define VIRT_IOAPIC_REG_BASE     (VIRT_PCH_REG_BASE)
 #define VIRT_PCH_MSI_ADDR_LOW    0x2FF00000UL
+#define VIRT_DINTC_SIZE          0x100000UL
+#define VIRT_DINTC_BASE          0x2FE00000UL
 #define VIRT_PCH_REG_SIZE        0x400
 #define VIRT_PCH_MSI_SIZE        0x8
 
-- 
2.47.0