On 2025/9/4 下午8:18, Song Gao wrote:
> the AVEC controller supports 256*256 irqs input, all the irqs connect CPU INT_AVEC irq
>
> Signed-off-by: Song Gao <gaosong@loongson.cn>
> ---
> hw/intc/loongarch_avec.c | 20 ++++++++++++++++++++
> hw/loongarch/virt.c | 10 +++++++++-
> target/loongarch/cpu.h | 3 ++-
> 3 files changed, 31 insertions(+), 2 deletions(-)
>
> diff --git a/hw/intc/loongarch_avec.c b/hw/intc/loongarch_avec.c
> index 253bab5461..1f9f376898 100644
> --- a/hw/intc/loongarch_avec.c
> +++ b/hw/intc/loongarch_avec.c
> @@ -38,7 +38,12 @@ static const MemoryRegionOps loongarch_avec_ops = {
>
> 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;
>
> Error *local_err = NULL;
> lac->parent_realize(dev, &local_err);
> @@ -47,6 +52,21 @@ 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);
> + qdev_init_gpio_out(dev, &s->cpu[i].parent_irq, 1);
> + }
> +
> return;
> }
>
> diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
> index 1b390fb876..a3f8f4c854 100644
> --- a/hw/loongarch/virt.c
> +++ b/hw/loongarch/virt.c
> @@ -383,9 +383,11 @@ static void virt_cpu_irq_init(LoongArchVirtMachineState *lvms)
> static void virt_irq_init(LoongArchVirtMachineState *lvms)
> {
> DeviceState *pch_pic, *pch_msi;
> - DeviceState *ipi, *extioi, *avec;
> + DeviceState *ipi, *extioi, *avec, *cpudev;
> SysBusDevice *d;
> int i, start, num;
> + CPUState *cpu_state;
> + MachineState *ms;
>
> /*
> * Extended IRQ model.
> @@ -470,6 +472,12 @@ 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_AVEC_BASE,
> sysbus_mmio_get_region(SYS_BUS_DEVICE(avec), 0));
> + ms = MACHINE(lvms);
> + 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));
> + }
I think it can be moved to hotplug interface of avec.
Regards
Bibo Mao
> }
>
> /* Create EXTIOI device */
> diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
> index f083c31bb4..55a5dc33f2 100644
> --- a/target/loongarch/cpu.h
> +++ b/target/loongarch/cpu.h
> @@ -217,9 +217,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 */
>