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); + } + } + qdev_init_gpio_in(dev, avec_irq_handler, NR_VECTORS * s->num_cpu); + 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 */ -- 2.34.1