mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 08:13:54 -06:00
hw/riscv/riscv-iommu: implement reset protocol
Add a riscv_iommu_reset() helper in the base emulation code that implements the expected reset behavior as defined by the riscv-iommu spec. Devices can then use this helper in their own reset callbacks. Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> Acked-by: Alistair Francis <alistair.francis@wdc.com> Message-ID: <20241106133407.604587-7-dbarboza@ventanamicro.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
parent
01c1caa9d1
commit
9afd26715e
6 changed files with 82 additions and 2 deletions
|
@ -31,6 +31,7 @@
|
|||
#include "cpu_bits.h"
|
||||
#include "riscv-iommu.h"
|
||||
#include "riscv-iommu-bits.h"
|
||||
#include "trace.h"
|
||||
|
||||
/* RISC-V IOMMU PCI Device Emulation */
|
||||
#define RISCV_PCI_CLASS_SYSTEM_IOMMU 0x0806
|
||||
|
@ -66,6 +67,12 @@ typedef struct RISCVIOMMUStatePci {
|
|||
RISCVIOMMUState iommu; /* common IOMMU state */
|
||||
} RISCVIOMMUStatePci;
|
||||
|
||||
struct RISCVIOMMUPciClass {
|
||||
/*< public >*/
|
||||
DeviceRealize parent_realize;
|
||||
ResettablePhases parent_phases;
|
||||
};
|
||||
|
||||
/* interrupt delivery callback */
|
||||
static void riscv_iommu_pci_notify(RISCVIOMMUState *iommu, unsigned vector)
|
||||
{
|
||||
|
@ -167,10 +174,23 @@ static const Property riscv_iommu_pci_properties[] = {
|
|||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
static void riscv_iommu_pci_reset_hold(Object *obj, ResetType type)
|
||||
{
|
||||
RISCVIOMMUStatePci *pci = RISCV_IOMMU_PCI(obj);
|
||||
RISCVIOMMUState *iommu = &pci->iommu;
|
||||
|
||||
riscv_iommu_reset(iommu);
|
||||
|
||||
trace_riscv_iommu_pci_reset_hold(type);
|
||||
}
|
||||
|
||||
static void riscv_iommu_pci_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
|
||||
ResettableClass *rc = RESETTABLE_CLASS(klass);
|
||||
|
||||
rc->phases.hold = riscv_iommu_pci_reset_hold;
|
||||
|
||||
k->realize = riscv_iommu_pci_realize;
|
||||
k->exit = riscv_iommu_pci_exit;
|
||||
|
|
|
@ -54,6 +54,12 @@ struct RISCVIOMMUStateSys {
|
|||
uint8_t *msix_pba;
|
||||
};
|
||||
|
||||
struct RISCVIOMMUSysClass {
|
||||
/*< public >*/
|
||||
DeviceRealize parent_realize;
|
||||
ResettablePhases parent_phases;
|
||||
};
|
||||
|
||||
static uint64_t msix_table_mmio_read(void *opaque, hwaddr addr,
|
||||
unsigned size)
|
||||
{
|
||||
|
@ -212,9 +218,23 @@ static Property riscv_iommu_sys_properties[] = {
|
|||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
static void riscv_iommu_sys_reset_hold(Object *obj, ResetType type)
|
||||
{
|
||||
RISCVIOMMUStateSys *sys = RISCV_IOMMU_SYS(obj);
|
||||
RISCVIOMMUState *iommu = &sys->iommu;
|
||||
|
||||
riscv_iommu_reset(iommu);
|
||||
|
||||
trace_riscv_iommu_sys_reset_hold(type);
|
||||
}
|
||||
|
||||
static void riscv_iommu_sys_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
ResettableClass *rc = RESETTABLE_CLASS(klass);
|
||||
|
||||
rc->phases.hold = riscv_iommu_sys_reset_hold;
|
||||
|
||||
dc->realize = riscv_iommu_sys_realize;
|
||||
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
|
||||
device_class_set_props(dc, riscv_iommu_sys_properties);
|
||||
|
|
|
@ -2262,6 +2262,41 @@ static void riscv_iommu_unrealize(DeviceState *dev)
|
|||
g_hash_table_unref(s->ctx_cache);
|
||||
}
|
||||
|
||||
void riscv_iommu_reset(RISCVIOMMUState *s)
|
||||
{
|
||||
uint32_t reg_clr;
|
||||
int ddtp_mode;
|
||||
|
||||
/*
|
||||
* Clear DDTP while setting DDTP_mode back to user
|
||||
* initial setting.
|
||||
*/
|
||||
ddtp_mode = s->enable_off ?
|
||||
RISCV_IOMMU_DDTP_MODE_OFF : RISCV_IOMMU_DDTP_MODE_BARE;
|
||||
s->ddtp = set_field(0, RISCV_IOMMU_DDTP_MODE, ddtp_mode);
|
||||
riscv_iommu_reg_set64(s, RISCV_IOMMU_REG_DDTP, s->ddtp);
|
||||
|
||||
reg_clr = RISCV_IOMMU_CQCSR_CQEN | RISCV_IOMMU_CQCSR_CIE |
|
||||
RISCV_IOMMU_CQCSR_CQON | RISCV_IOMMU_CQCSR_BUSY;
|
||||
riscv_iommu_reg_mod32(s, RISCV_IOMMU_REG_CQCSR, 0, reg_clr);
|
||||
|
||||
reg_clr = RISCV_IOMMU_FQCSR_FQEN | RISCV_IOMMU_FQCSR_FIE |
|
||||
RISCV_IOMMU_FQCSR_FQON | RISCV_IOMMU_FQCSR_BUSY;
|
||||
riscv_iommu_reg_mod32(s, RISCV_IOMMU_REG_FQCSR, 0, reg_clr);
|
||||
|
||||
reg_clr = RISCV_IOMMU_PQCSR_PQEN | RISCV_IOMMU_PQCSR_PIE |
|
||||
RISCV_IOMMU_PQCSR_PQON | RISCV_IOMMU_PQCSR_BUSY;
|
||||
riscv_iommu_reg_mod32(s, RISCV_IOMMU_REG_PQCSR, 0, reg_clr);
|
||||
|
||||
riscv_iommu_reg_mod64(s, RISCV_IOMMU_REG_TR_REQ_CTL, 0,
|
||||
RISCV_IOMMU_TR_REQ_CTL_GO_BUSY);
|
||||
|
||||
riscv_iommu_reg_set32(s, RISCV_IOMMU_REG_IPSR, 0);
|
||||
|
||||
g_hash_table_remove_all(s->ctx_cache);
|
||||
g_hash_table_remove_all(s->iot_cache);
|
||||
}
|
||||
|
||||
static const Property riscv_iommu_properties[] = {
|
||||
DEFINE_PROP_UINT32("version", RISCVIOMMUState, version,
|
||||
RISCV_IOMMU_SPEC_DOT_VER),
|
||||
|
|
|
@ -89,6 +89,7 @@ struct RISCVIOMMUState {
|
|||
void riscv_iommu_pci_setup_iommu(RISCVIOMMUState *iommu, PCIBus *bus,
|
||||
Error **errp);
|
||||
void riscv_iommu_set_cap_igs(RISCVIOMMUState *s, riscv_iommu_igs_mode mode);
|
||||
void riscv_iommu_reset(RISCVIOMMUState *s);
|
||||
|
||||
/* private helpers */
|
||||
|
||||
|
|
|
@ -17,3 +17,5 @@ riscv_iommu_ats_inval(const char *id) "%s: dev-iotlb invalidate"
|
|||
riscv_iommu_ats_prgr(const char *id) "%s: dev-iotlb page request group response"
|
||||
riscv_iommu_sys_irq_sent(uint32_t vector) "IRQ sent to vector %u"
|
||||
riscv_iommu_sys_msi_sent(uint32_t vector, uint64_t msi_addr, uint32_t msi_data, uint32_t result) "MSI sent to vector %u msi_addr 0x%"PRIx64" msi_data 0x%x result %u"
|
||||
riscv_iommu_sys_reset_hold(int reset_type) "reset type %d"
|
||||
riscv_iommu_pci_reset_hold(int reset_type) "reset type %d"
|
||||
|
|
|
@ -30,12 +30,14 @@ typedef struct RISCVIOMMUState RISCVIOMMUState;
|
|||
typedef struct RISCVIOMMUSpace RISCVIOMMUSpace;
|
||||
|
||||
#define TYPE_RISCV_IOMMU_PCI "riscv-iommu-pci"
|
||||
OBJECT_DECLARE_SIMPLE_TYPE(RISCVIOMMUStatePci, RISCV_IOMMU_PCI)
|
||||
OBJECT_DECLARE_TYPE(RISCVIOMMUStatePci, RISCVIOMMUPciClass, RISCV_IOMMU_PCI)
|
||||
typedef struct RISCVIOMMUStatePci RISCVIOMMUStatePci;
|
||||
typedef struct RISCVIOMMUPciClass RISCVIOMMUPciClass;
|
||||
|
||||
#define TYPE_RISCV_IOMMU_SYS "riscv-iommu-device"
|
||||
OBJECT_DECLARE_SIMPLE_TYPE(RISCVIOMMUStateSys, RISCV_IOMMU_SYS)
|
||||
OBJECT_DECLARE_TYPE(RISCVIOMMUStateSys, RISCVIOMMUSysClass, RISCV_IOMMU_SYS)
|
||||
typedef struct RISCVIOMMUStateSys RISCVIOMMUStateSys;
|
||||
typedef struct RISCVIOMMUSysClass RISCVIOMMUSysClass;
|
||||
|
||||
#define FDT_IRQ_TYPE_EDGE_LOW 1
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue