mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-11 03:24:58 -06:00
hw/intc/riscv_aplic: add kvm_msicfgaddr for split mode aplic-imsic
The last step to enable KVM AIA aplic-imsic with irqchip in split mode is to deal with how MSIs are going to be sent. In our current design we don't allow an APLIC controller to send MSIs unless it's on m-mode. And we also do not allow Supervisor MSI address configuration via the 'smsiaddrcfg' and 'smsiaddrcfgh' registers unless it's also a m-mode APLIC controller. Add a new RISCVACPLICState attribute called 'kvm_msicfgaddr'. This attribute represents the base configuration address for MSIs, in our case the base addr of the IMSIC controller. This attribute is being set only when running irqchip_split() mode with aia=aplic-imsic. During riscv_aplic_msi_send() we'll check if the attribute was set to skip the check for a m-mode APLIC controller and to change the resulting MSI addr by adding kvm_msicfgaddr right before address_space_stl_le(). Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> Acked-by: Alistair Francis <alistair.francis@wdc.com> Message-ID: <20241119191706.718860-7-dbarboza@ventanamicro.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
parent
b319ef15b8
commit
e0c87e3067
3 changed files with 44 additions and 10 deletions
|
@ -177,6 +177,16 @@ bool riscv_use_emulated_aplic(bool msimode)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void riscv_aplic_set_kvm_msicfgaddr(RISCVAPLICState *aplic, hwaddr addr)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_KVM
|
||||||
|
if (riscv_use_emulated_aplic(aplic->msimode)) {
|
||||||
|
aplic->kvm_msicfgaddr = extract64(addr, 0, 32);
|
||||||
|
aplic->kvm_msicfgaddrH = extract64(addr, 32, 32);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static bool riscv_aplic_irq_rectified_val(RISCVAPLICState *aplic,
|
static bool riscv_aplic_irq_rectified_val(RISCVAPLICState *aplic,
|
||||||
uint32_t irq)
|
uint32_t irq)
|
||||||
{
|
{
|
||||||
|
@ -381,6 +391,8 @@ static void riscv_aplic_msi_send(RISCVAPLICState *aplic,
|
||||||
uint32_t lhxs, lhxw, hhxs, hhxw, group_idx, msicfgaddr, msicfgaddrH;
|
uint32_t lhxs, lhxw, hhxs, hhxw, group_idx, msicfgaddr, msicfgaddrH;
|
||||||
|
|
||||||
aplic_m = aplic;
|
aplic_m = aplic;
|
||||||
|
|
||||||
|
if (!aplic->kvm_splitmode) {
|
||||||
while (aplic_m && !aplic_m->mmode) {
|
while (aplic_m && !aplic_m->mmode) {
|
||||||
aplic_m = aplic_m->parent;
|
aplic_m = aplic_m->parent;
|
||||||
}
|
}
|
||||||
|
@ -389,6 +401,7 @@ static void riscv_aplic_msi_send(RISCVAPLICState *aplic,
|
||||||
__func__);
|
__func__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (aplic->mmode) {
|
if (aplic->mmode) {
|
||||||
msicfgaddr = aplic_m->mmsicfgaddr;
|
msicfgaddr = aplic_m->mmsicfgaddr;
|
||||||
|
@ -419,6 +432,11 @@ static void riscv_aplic_msi_send(RISCVAPLICState *aplic,
|
||||||
addr |= (uint64_t)(guest_idx & APLIC_xMSICFGADDR_PPN_HART(lhxs));
|
addr |= (uint64_t)(guest_idx & APLIC_xMSICFGADDR_PPN_HART(lhxs));
|
||||||
addr <<= APLIC_xMSICFGADDR_PPN_SHIFT;
|
addr <<= APLIC_xMSICFGADDR_PPN_SHIFT;
|
||||||
|
|
||||||
|
if (aplic->kvm_splitmode) {
|
||||||
|
addr |= aplic->kvm_msicfgaddr;
|
||||||
|
addr |= ((uint64_t)aplic->kvm_msicfgaddrH << 32);
|
||||||
|
}
|
||||||
|
|
||||||
address_space_stl_le(&address_space_memory, addr,
|
address_space_stl_le(&address_space_memory, addr,
|
||||||
eiid, MEMTXATTRS_UNSPECIFIED, &result);
|
eiid, MEMTXATTRS_UNSPECIFIED, &result);
|
||||||
if (result != MEMTX_OK) {
|
if (result != MEMTX_OK) {
|
||||||
|
@ -892,6 +910,10 @@ static void riscv_aplic_realize(DeviceState *dev, Error **errp)
|
||||||
memory_region_init_io(&aplic->mmio, OBJECT(dev), &riscv_aplic_ops,
|
memory_region_init_io(&aplic->mmio, OBJECT(dev), &riscv_aplic_ops,
|
||||||
aplic, TYPE_RISCV_APLIC, aplic->aperture_size);
|
aplic, TYPE_RISCV_APLIC, aplic->aperture_size);
|
||||||
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &aplic->mmio);
|
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &aplic->mmio);
|
||||||
|
|
||||||
|
if (kvm_enabled()) {
|
||||||
|
aplic->kvm_splitmode = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -939,8 +961,8 @@ static const Property riscv_aplic_properties[] = {
|
||||||
|
|
||||||
static const VMStateDescription vmstate_riscv_aplic = {
|
static const VMStateDescription vmstate_riscv_aplic = {
|
||||||
.name = "riscv_aplic",
|
.name = "riscv_aplic",
|
||||||
.version_id = 1,
|
.version_id = 2,
|
||||||
.minimum_version_id = 1,
|
.minimum_version_id = 2,
|
||||||
.fields = (const VMStateField[]) {
|
.fields = (const VMStateField[]) {
|
||||||
VMSTATE_UINT32(domaincfg, RISCVAPLICState),
|
VMSTATE_UINT32(domaincfg, RISCVAPLICState),
|
||||||
VMSTATE_UINT32(mmsicfgaddr, RISCVAPLICState),
|
VMSTATE_UINT32(mmsicfgaddr, RISCVAPLICState),
|
||||||
|
@ -948,6 +970,8 @@ static const VMStateDescription vmstate_riscv_aplic = {
|
||||||
VMSTATE_UINT32(smsicfgaddr, RISCVAPLICState),
|
VMSTATE_UINT32(smsicfgaddr, RISCVAPLICState),
|
||||||
VMSTATE_UINT32(smsicfgaddrH, RISCVAPLICState),
|
VMSTATE_UINT32(smsicfgaddrH, RISCVAPLICState),
|
||||||
VMSTATE_UINT32(genmsi, RISCVAPLICState),
|
VMSTATE_UINT32(genmsi, RISCVAPLICState),
|
||||||
|
VMSTATE_UINT32(kvm_msicfgaddr, RISCVAPLICState),
|
||||||
|
VMSTATE_UINT32(kvm_msicfgaddrH, RISCVAPLICState),
|
||||||
VMSTATE_VARRAY_UINT32(sourcecfg, RISCVAPLICState,
|
VMSTATE_VARRAY_UINT32(sourcecfg, RISCVAPLICState,
|
||||||
num_irqs, 0,
|
num_irqs, 0,
|
||||||
vmstate_info_uint32, uint32_t),
|
vmstate_info_uint32, uint32_t),
|
||||||
|
|
|
@ -1300,7 +1300,7 @@ static DeviceState *virt_create_aia(RISCVVirtAIAType aia_type, int aia_guests,
|
||||||
int base_hartid, int hart_count)
|
int base_hartid, int hart_count)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
hwaddr addr;
|
hwaddr addr = 0;
|
||||||
uint32_t guest_bits;
|
uint32_t guest_bits;
|
||||||
DeviceState *aplic_s = NULL;
|
DeviceState *aplic_s = NULL;
|
||||||
DeviceState *aplic_m = NULL;
|
DeviceState *aplic_m = NULL;
|
||||||
|
@ -1350,6 +1350,10 @@ static DeviceState *virt_create_aia(RISCVVirtAIAType aia_type, int aia_guests,
|
||||||
VIRT_IRQCHIP_NUM_PRIO_BITS,
|
VIRT_IRQCHIP_NUM_PRIO_BITS,
|
||||||
msimode, false, aplic_m);
|
msimode, false, aplic_m);
|
||||||
|
|
||||||
|
if (kvm_enabled() && msimode) {
|
||||||
|
riscv_aplic_set_kvm_msicfgaddr(RISCV_APLIC(aplic_s), addr);
|
||||||
|
}
|
||||||
|
|
||||||
return kvm_enabled() ? aplic_s : aplic_m;
|
return kvm_enabled() ? aplic_s : aplic_m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,11 +68,17 @@ struct RISCVAPLICState {
|
||||||
uint32_t num_irqs;
|
uint32_t num_irqs;
|
||||||
bool msimode;
|
bool msimode;
|
||||||
bool mmode;
|
bool mmode;
|
||||||
|
|
||||||
|
/* To support KVM aia=aplic-imsic with irqchip split mode */
|
||||||
|
bool kvm_splitmode;
|
||||||
|
uint32_t kvm_msicfgaddr;
|
||||||
|
uint32_t kvm_msicfgaddrH;
|
||||||
};
|
};
|
||||||
|
|
||||||
void riscv_aplic_add_child(DeviceState *parent, DeviceState *child);
|
void riscv_aplic_add_child(DeviceState *parent, DeviceState *child);
|
||||||
bool riscv_is_kvm_aia_aplic_imsic(bool msimode);
|
bool riscv_is_kvm_aia_aplic_imsic(bool msimode);
|
||||||
bool riscv_use_emulated_aplic(bool msimode);
|
bool riscv_use_emulated_aplic(bool msimode);
|
||||||
|
void riscv_aplic_set_kvm_msicfgaddr(RISCVAPLICState *aplic, hwaddr addr);
|
||||||
|
|
||||||
DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size,
|
DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size,
|
||||||
uint32_t hartid_base, uint32_t num_harts, uint32_t num_sources,
|
uint32_t hartid_base, uint32_t num_harts, uint32_t num_sources,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue