On 2025/9/4 下午8:18, Song Gao wrote:
the AVEC controller use [2fe00000-2ff000000) Memory.

Signed-off-by: Song Gao <gaos...@loongson.cn>
---
  hw/intc/loongarch_avec.c         | 24 ++++++++++++++++++++
  hw/loongarch/virt.c              | 39 +++++++++++++++++++++++++++++++-
  include/hw/intc/loongarch_avec.h |  1 +
  include/hw/loongarch/virt.h      |  1 +
  include/hw/pci-host/ls7a.h       |  2 ++
  5 files changed, 66 insertions(+), 1 deletion(-)

diff --git a/hw/intc/loongarch_avec.c b/hw/intc/loongarch_avec.c
index 5a3e7ecc03..253bab5461 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,12 @@ 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, VIRT_AVEC_MSG_OFFSET);
+    sysbus_init_mmio(shd, &s->avec_mmio);
+    msi_nonbroken = true;
      return;
  }
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 124f96af03..1b390fb876 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"
@@ -382,7 +383,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;
@@ -428,6 +429,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 */
@@ -435,6 +463,15 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
      lvms->ipi = ipi;
      sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), &error_fatal);
+ /* Create AVEC device*/
+    if (virt_has_avecintc(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_AVEC_BASE,
+                        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 92e2ca9590..3e8cf7d2c1 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 68b8e92e99..bc3cee705d 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;Reviewed-by: Bibo Mao <maob...@loongson.cn>
      uint64_t misc_status;
+    DeviceState *avec;
  };
#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..199f47ecc0 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_AVEC_MSG_OFFSET     0x1000000UL
+#define VIRT_AVEC_BASE           (VIRT_PCH_MSI_ADDR_LOW - VIRT_AVEC_MSG_OFFSET)
  #define VIRT_PCH_REG_SIZE        0x400
  #define VIRT_PCH_MSI_SIZE        0x8
Reviewed-by: Bibo Mao <maob...@loongson.cn>


Reply via email to