diff options
Diffstat (limited to 'hw/intc')
-rw-r--r-- | hw/intc/riscv_imsic.c | 47 |
1 files changed, 26 insertions, 21 deletions
diff --git a/hw/intc/riscv_imsic.c b/hw/intc/riscv_imsic.c index dc8162c..241b12f 100644 --- a/hw/intc/riscv_imsic.c +++ b/hw/intc/riscv_imsic.c @@ -349,7 +349,19 @@ static void riscv_imsic_realize(DeviceState *dev, Error **errp) CPUState *cpu = cpu_by_arch_id(imsic->hartid); CPURISCVState *env = cpu ? cpu_env(cpu) : NULL; + /* Claim the CPU interrupt to be triggered by this IMSIC */ + if (riscv_cpu_claim_interrupts(rcpu, + (imsic->mmode) ? MIP_MEIP : MIP_SEIP) < 0) { + error_setg(errp, "%s already claimed", + (imsic->mmode) ? "MEIP" : "SEIP"); + return; + } + if (!kvm_irqchip_in_kernel()) { + /* Create output IRQ lines */ + imsic->external_irqs = g_malloc(sizeof(qemu_irq) * imsic->num_pages); + qdev_init_gpio_out(dev, imsic->external_irqs, imsic->num_pages); + imsic->num_eistate = imsic->num_pages * imsic->num_irqs; imsic->eidelivery = g_new0(uint32_t, imsic->num_pages); imsic->eithreshold = g_new0(uint32_t, imsic->num_pages); @@ -361,18 +373,6 @@ static void riscv_imsic_realize(DeviceState *dev, Error **errp) IMSIC_MMIO_SIZE(imsic->num_pages)); sysbus_init_mmio(SYS_BUS_DEVICE(dev), &imsic->mmio); - /* Claim the CPU interrupt to be triggered by this IMSIC */ - if (riscv_cpu_claim_interrupts(rcpu, - (imsic->mmode) ? MIP_MEIP : MIP_SEIP) < 0) { - error_setg(errp, "%s already claimed", - (imsic->mmode) ? "MEIP" : "SEIP"); - return; - } - - /* Create output IRQ lines */ - imsic->external_irqs = g_malloc(sizeof(qemu_irq) * imsic->num_pages); - qdev_init_gpio_out(dev, imsic->external_irqs, imsic->num_pages); - /* Force select AIA feature and setup CSR read-modify-write callback */ if (env) { if (!imsic->mmode) { @@ -381,8 +381,11 @@ static void riscv_imsic_realize(DeviceState *dev, Error **errp) } else { rcpu->cfg.ext_smaia = true; } - riscv_cpu_set_aia_ireg_rmw_fn(env, (imsic->mmode) ? PRV_M : PRV_S, - riscv_imsic_rmw, imsic); + + if (!kvm_irqchip_in_kernel()) { + riscv_cpu_set_aia_ireg_rmw_fn(env, (imsic->mmode) ? PRV_M : PRV_S, + riscv_imsic_rmw, imsic); + } } msi_nonbroken = true; @@ -464,15 +467,17 @@ DeviceState *riscv_imsic_create(hwaddr addr, uint32_t hartid, bool mmode, sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr); - for (i = 0; i < num_pages; i++) { - if (!i) { - qdev_connect_gpio_out_named(dev, NULL, i, - qdev_get_gpio_in(DEVICE(cpu), + if (!kvm_irqchip_in_kernel()) { + for (i = 0; i < num_pages; i++) { + if (!i) { + qdev_connect_gpio_out_named(dev, NULL, i, + qdev_get_gpio_in(DEVICE(cpu), (mmode) ? IRQ_M_EXT : IRQ_S_EXT)); - } else { - qdev_connect_gpio_out_named(dev, NULL, i, - qdev_get_gpio_in(DEVICE(cpu), + } else { + qdev_connect_gpio_out_named(dev, NULL, i, + qdev_get_gpio_in(DEVICE(cpu), IRQ_LOCAL_MAX + i - 1)); + } } } |