On 2025/6/9 下午6:48, Song Gao wrote:
the AVEC controller supports 256*256 irqs, all the irqs connect CPU INT_AVEC irq

Signed-off-by: Song Gao <gaos...@loongson.cn>
---
  hw/intc/loongarch_avec.c | 28 ++++++++++++++++++++++++++++
  hw/loongarch/virt.c      | 11 +++++++++--
  target/loongarch/cpu.h   |  3 ++-
  3 files changed, 39 insertions(+), 3 deletions(-)

diff --git a/hw/intc/loongarch_avec.c b/hw/intc/loongarch_avec.c
index 50956e7e4e..c692fef43c 100644
--- a/hw/intc/loongarch_avec.c
+++ b/hw/intc/loongarch_avec.c
@@ -36,9 +36,19 @@ static const MemoryRegionOps loongarch_avec_ops = {
      .endianness = DEVICE_LITTLE_ENDIAN,
  };
+static void avec_irq_handler(void *opaque, int irq, int level)
+{
+    return;
+}
+
  static void loongarch_avec_realize(DeviceState *dev, Error **errp)
  {
+    LoongArchAVECState *s = LOONGARCH_AVEC(dev);
      LoongArchAVECClass *lac = LOONGARCH_AVEC_GET_CLASS(dev);
+    MachineState *machine = MACHINE(qdev_get_machine());
+    MachineClass *mc = MACHINE_GET_CLASS(machine);
+    const CPUArchIdList  *id_list;
+    int i, irq;
Error *local_err = NULL;
      lac->parent_realize(dev, &local_err);
@@ -47,6 +57,24 @@ static void loongarch_avec_realize(DeviceState *dev, Error 
**errp)
          return;
      }
+ assert(mc->possible_cpu_arch_ids);
+    id_list = mc->possible_cpu_arch_ids(machine);
+    s->num_cpu = id_list->len;
+    s->cpu = g_new(AVECCore, s->num_cpu);
+    if (s->cpu == NULL) {
+        error_setg(errp, "Memory allocation for AVECCore fail");
+        return;
+    }
+
+    for (i = 0; i < s->num_cpu; i++) {
+        s->cpu[i].arch_id = id_list->cpus[i].arch_id;
+        s->cpu[i].cpu = CPU(id_list->cpus[i].cpu);
+        for (irq = 0; irq < NR_VECTORS; irq++) {
+            qdev_init_gpio_out(dev, &s->cpu[i].parent_irq[irq], 1);
+        }
One parent irqline for per-cpu is ok, so the total number of parent irqline is s->num_cpu, the number of possible cpu.

+    }
+    qdev_init_gpio_in(dev, avec_irq_handler, NR_VECTORS * s->num_cpu);
avec_irq_handler() can be removed here.

Regards
Bibo Mao
+
      return;
  }
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 272355da2d..718b5b4f92 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -363,7 +363,7 @@ static void virt_cpu_irq_init(LoongArchVirtMachineState 
*lvms)
      }
  }
-static void virt_irq_init(LoongArchVirtMachineState *lvms)
+static void virt_irq_init(LoongArchVirtMachineState *lvms, MachineState *ms)
  {
      DeviceState *pch_pic, *pch_msi;
      DeviceState *ipi, *extioi, *avec;
@@ -459,6 +459,13 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
          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));
+        CPUState *cpu_state;
+        DeviceState *cpudev;
+        for (int cpu = 0; cpu < ms->smp.cpus; cpu++) {
+            cpu_state = qemu_get_cpu(cpu);
+            cpudev = DEVICE(cpu_state);
+            qdev_connect_gpio_out(avec, cpu, qdev_get_gpio_in(cpudev, 
INT_AVEC));
+        }
      }
/* Create EXTIOI device */
@@ -799,7 +806,7 @@ static void virt_init(MachineState *machine)
      }
/* Initialize the IO interrupt subsystem */
-    virt_irq_init(lvms);
+    virt_irq_init(lvms, machine);
      lvms->machine_done.notify = virt_done;
      qemu_add_machine_init_done_notifier(&lvms->machine_done);
       /* connect powerdown request */
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index a1918a85da..b96df1cb2a 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -240,9 +240,10 @@ FIELD(CSR_CRMD, WE, 9, 1)
  extern const char * const regnames[32];
  extern const char * const fregnames[32];
-#define N_IRQS 13
+#define N_IRQS      15
  #define IRQ_TIMER   11
  #define IRQ_IPI     12
+#define INT_AVEC    14
#define LOONGARCH_STLB 2048 /* 2048 STLB */
  #define LOONGARCH_MTLB         64   /* 64 MTLB */



Reply via email to