the AVEC controller use 2ff00000-2fffffff Memory.

Signed-off-by: Song Gao <gaos...@loongson.cn>
---
 hw/intc/loongarch_avec.c         | 25 ++++++++++++++++++++
 hw/loongarch/virt.c              | 39 +++++++++++++++++++++++++++++++-
 include/hw/intc/loongarch_avec.h |  1 +
 include/hw/loongarch/virt.h      |  1 +
 4 files changed, 65 insertions(+), 1 deletion(-)

diff --git a/hw/intc/loongarch_avec.c b/hw/intc/loongarch_avec.c
index 5a3e7ecc03..50956e7e4e 100644
--- a/hw/intc/loongarch_avec.c
+++ b/hw/intc/loongarch_avec.c
@@ -17,6 +17,24 @@
 #include "trace.h"
 #include "hw/qdev-properties.h"
 
+static uint64_t loongarch_avec_mem_read(void *opaque,
+                                        hwaddr addr, unsigned size)
+{
+    return 0;
+}
+
+static void loongarch_avec_mem_write(void *opaque, hwaddr addr,
+                                     uint64_t val, unsigned size)
+{
+    return;
+}
+
+
+static const MemoryRegionOps loongarch_avec_ops = {
+    .read = loongarch_avec_mem_read,
+    .write = loongarch_avec_mem_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
 
 static void loongarch_avec_realize(DeviceState *dev, Error **errp)
 {
@@ -39,6 +57,13 @@ static void loongarch_avec_unrealize(DeviceState *dev)
 
 static void loongarch_avec_init(Object *obj)
 {
+    LoongArchAVECState *s = LOONGARCH_AVEC(obj);
+    SysBusDevice *shd = SYS_BUS_DEVICE(obj);
+    memory_region_init_io(&s->avec_mmio, OBJECT(s), &loongarch_avec_ops,
+                          s, TYPE_LOONGARCH_AVEC, 0x100000);
+    sysbus_init_mmio(shd, &s->avec_mmio);
+    msi_nonbroken = true;
+
     return;
 }
 
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 35643a4e0b..272355da2d 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_avec.h"
 #include "hw/pci-host/ls7a.h"
 #include "hw/pci-host/gpex.h"
 #include "hw/misc/unimp.h"
@@ -365,7 +366,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, *avec;
     SysBusDevice *d;
     int i, start, num;
 
@@ -411,6 +412,33 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
      *    +--------+ +---------+ +---------+
      *    | UARTs  | | Devices | | Devices |
      *    +--------+ +---------+ +---------+
+     *
+     *
+     *  Advanced Extended IRQ model
+     *
+     *  +-----+     +-----------------------+     +-------+
+     *  | IPI | --> |        CPUINTC        | <-- | Timer |
+     *  +-----+     +-----------------------+     +-------+
+     *               ^          ^          ^
+     *               |          |          |
+     *        +---------+ +----------+ +---------+     +-------+
+     *        | EIOINTC | | AVECINTC | | LIOINTC | <-- | UARTs |
+     *        +---------+ +----------+ +---------+     +-------+
+     *             ^            ^
+     *             |            |
+     *        +---------+  +---------+
+     *        | PCH-PIC |  | PCH-MSI |
+     *        +---------+  +---------+
+     *          ^     ^           ^
+     *          |     |           |
+     *  +---------+ +---------+ +---------+
+     *  | Devices | | PCH-LPC | | Devices |
+     *  +---------+ +---------+ +---------+
+     *                  ^
+     *                  |
+     *             +---------+
+     *             | Devices |
+     *             +---------+
      */
 
     /* Create IPI device */
@@ -424,6 +452,15 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
     memory_region_add_subregion(&lvms->system_iocsr, MAIL_SEND_ADDR,
                    sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 1));
 
+    /* Create AVEC device*/
+    if (virt_is_avecintc_enabled(lvms)) {
+        avec = qdev_new(TYPE_LOONGARCH_AVEC);
+        lvms->avec = avec;
+        sysbus_realize_and_unref(SYS_BUS_DEVICE(avec), &error_fatal);
+        memory_region_add_subregion(get_system_memory(), VIRT_PCH_MSI_ADDR_LOW,
+                        sysbus_mmio_get_region(SYS_BUS_DEVICE(avec), 0));
+    }
+
     /* Create EXTIOI device */
     extioi = qdev_new(TYPE_LOONGARCH_EXTIOI);
     lvms->extioi = extioi;
diff --git a/include/hw/intc/loongarch_avec.h b/include/hw/intc/loongarch_avec.h
index 3c68593a7c..274b284641 100644
--- a/include/hw/intc/loongarch_avec.h
+++ b/include/hw/intc/loongarch_avec.h
@@ -23,6 +23,7 @@ typedef struct AVECCore {
 
 struct LoongArchAVECState {
     SysBusDevice parent_obj;
+    MemoryRegion avec_mmio;
     AVECCore *cpu;
     uint32_t num_cpu;
 };
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
index 3a81f048e8..172f40711d 100644
--- a/include/hw/loongarch/virt.h
+++ b/include/hw/loongarch/virt.h
@@ -64,6 +64,7 @@ struct LoongArchVirtMachineState {
     struct loongarch_boot_info bootinfo;
     DeviceState *ipi;
     DeviceState *extioi;
+    DeviceState *avec;
 };
 
 #define TYPE_LOONGARCH_VIRT_MACHINE  MACHINE_TYPE_NAME("virt")
-- 
2.34.1


Reply via email to