mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 08:13:54 -06:00
target/riscv: update APLIC and IMSIC to support KVM AIA
KVM AIA can't emulate APLIC only. When "aia=aplic" parameter is passed, APLIC devices is emulated by QEMU. For "aia=aplic-imsic", remove the mmio operations of APLIC when using KVM AIA and send wired interrupt signal via KVM_IRQ_LINE API. After KVM AIA enabled, MSI messages are delivered by KVM_SIGNAL_MSI API when the IMSICs receive mmio write requests. Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com> Reviewed-by: Jim Shu <jim.shu@sifive.com> Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> Reviewed-by: Andrew Jones <ajones@ventanamicro.com> Message-ID: <20230727102439.22554-5-yongxuan.wang@sifive.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
parent
9634ef7eda
commit
95a97b3fd2
2 changed files with 61 additions and 20 deletions
|
@ -32,6 +32,7 @@
|
|||
#include "target/riscv/cpu.h"
|
||||
#include "target/riscv/cpu_bits.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "sysemu/kvm.h"
|
||||
#include "migration/vmstate.h"
|
||||
|
||||
#define IMSIC_MMIO_PAGE_LE 0x00
|
||||
|
@ -283,6 +284,20 @@ static void riscv_imsic_write(void *opaque, hwaddr addr, uint64_t value,
|
|||
goto err;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_KVM)
|
||||
if (kvm_irqchip_in_kernel()) {
|
||||
struct kvm_msi msi;
|
||||
|
||||
msi.address_lo = extract64(imsic->mmio.addr + addr, 0, 32);
|
||||
msi.address_hi = extract64(imsic->mmio.addr + addr, 32, 32);
|
||||
msi.data = le32_to_cpu(value);
|
||||
|
||||
kvm_vm_ioctl(kvm_state, KVM_SIGNAL_MSI, &msi);
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Writes only supported for MSI little-endian registers */
|
||||
page = addr >> IMSIC_MMIO_PAGE_SHIFT;
|
||||
if ((addr & (IMSIC_MMIO_PAGE_SZ - 1)) == IMSIC_MMIO_PAGE_LE) {
|
||||
|
@ -320,10 +335,12 @@ static void riscv_imsic_realize(DeviceState *dev, Error **errp)
|
|||
CPUState *cpu = cpu_by_arch_id(imsic->hartid);
|
||||
CPURISCVState *env = cpu ? cpu->env_ptr : NULL;
|
||||
|
||||
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);
|
||||
imsic->eistate = g_new0(uint32_t, imsic->num_eistate);
|
||||
if (!kvm_irqchip_in_kernel()) {
|
||||
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);
|
||||
imsic->eistate = g_new0(uint32_t, imsic->num_eistate);
|
||||
}
|
||||
|
||||
memory_region_init_io(&imsic->mmio, OBJECT(dev), &riscv_imsic_ops,
|
||||
imsic, TYPE_RISCV_IMSIC,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue