On Wed, Nov 6, 2024 at 11:35 PM Daniel Henrique Barboza <dbarb...@ventanamicro.com> wrote: > > 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 <dbarb...@ventanamicro.com>
Acked-by: Alistair Francis <alistair.fran...@wdc.com> Alistair > --- > hw/riscv/riscv-iommu-pci.c | 20 ++++++++++++++++++++ > hw/riscv/riscv-iommu-sys.c | 20 ++++++++++++++++++++ > hw/riscv/riscv-iommu.c | 35 +++++++++++++++++++++++++++++++++++ > hw/riscv/riscv-iommu.h | 1 + > hw/riscv/trace-events | 2 ++ > include/hw/riscv/iommu.h | 6 ++++-- > 6 files changed, 82 insertions(+), 2 deletions(-) > > diff --git a/hw/riscv/riscv-iommu-pci.c b/hw/riscv/riscv-iommu-pci.c > index 4ce9bf6b78..51226c4877 100644 > --- a/hw/riscv/riscv-iommu-pci.c > +++ b/hw/riscv/riscv-iommu-pci.c > @@ -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 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; > diff --git a/hw/riscv/riscv-iommu-sys.c b/hw/riscv/riscv-iommu-sys.c > index a0ef67a20b..605979a0ac 100644 > --- a/hw/riscv/riscv-iommu-sys.c > +++ b/hw/riscv/riscv-iommu-sys.c > @@ -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); > diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c > index 239f83f5bd..cf2019d6aa 100644 > --- a/hw/riscv/riscv-iommu.c > +++ b/hw/riscv/riscv-iommu.c > @@ -2228,6 +2228,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 Property riscv_iommu_properties[] = { > DEFINE_PROP_UINT32("version", RISCVIOMMUState, version, > RISCV_IOMMU_SPEC_DOT_VER), > diff --git a/hw/riscv/riscv-iommu.h b/hw/riscv/riscv-iommu.h > index f9f2827808..9424989df4 100644 > --- a/hw/riscv/riscv-iommu.h > +++ b/hw/riscv/riscv-iommu.h > @@ -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 */ > > diff --git a/hw/riscv/trace-events b/hw/riscv/trace-events > index 94facbb8b1..aaa2c0eb94 100644 > --- a/hw/riscv/trace-events > +++ b/hw/riscv/trace-events > @@ -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%lx 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" > diff --git a/include/hw/riscv/iommu.h b/include/hw/riscv/iommu.h > index 8a8acfc3f0..b03339d75c 100644 > --- a/include/hw/riscv/iommu.h > +++ b/include/hw/riscv/iommu.h > @@ -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 > > -- > 2.45.2 > >