[PATCH v6 06/11] hw/loongarch: AVEC controller add a MemoryRegion

Song Gao posted 11 patches 2 days, 2 hours ago
Maintainers: Paolo Bonzini <pbonzini@redhat.com>, Song Gao <gaosong@loongson.cn>, Bibo Mao <maobibo@loongson.cn>, Jiaxun Yang <jiaxun.yang@flygoat.com>
[PATCH v6 06/11] hw/loongarch: AVEC controller add a MemoryRegion
Posted by Song Gao 2 days, 2 hours ago
the AVEC controller use [2fe00000-2ff000000) Memory.

Signed-off-by: Song Gao <gaosong@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;
     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
 
-- 
2.41.0
Re: [PATCH v6 06/11] hw/loongarch: AVEC controller add a MemoryRegion
Posted by Bibo Mao 1 day, 5 hours ago

On 2025/9/4 下午8:18, Song Gao wrote:
> the AVEC controller use [2fe00000-2ff000000) Memory.
> 
> Signed-off-by: Song Gao <gaosong@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 <maobibo@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 <maobibo@loongson.cn>