[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 08/39] hw/riscv/riscv-iommu: implement reset protocol
From: |
Alistair Francis |
Subject: |
[PULL 08/39] hw/riscv/riscv-iommu: implement reset protocol |
Date: |
Thu, 19 Dec 2024 08:29:38 +1000 |
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
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>
---
hw/riscv/riscv-iommu.h | 1 +
include/hw/riscv/iommu.h | 6 ++++--
hw/riscv/riscv-iommu-pci.c | 20 ++++++++++++++++++++
hw/riscv/riscv-iommu-sys.c | 20 ++++++++++++++++++++
hw/riscv/riscv-iommu.c | 35 +++++++++++++++++++++++++++++++++++
hw/riscv/trace-events | 2 ++
6 files changed, 82 insertions(+), 2 deletions(-)
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/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
diff --git a/hw/riscv/riscv-iommu-pci.c b/hw/riscv/riscv-iommu-pci.c
index a95d0f74c8..2c1ae72461 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 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;
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 9137217cb7..72e607c9eb 100644
--- a/hw/riscv/riscv-iommu.c
+++ b/hw/riscv/riscv-iommu.c
@@ -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),
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"
--
2.47.1
- [PULL 02/39] hw/intc/riscv_aplic: Fix APLIC in_clrip and clripnum write emulation, (continued)
- [PULL 02/39] hw/intc/riscv_aplic: Fix APLIC in_clrip and clripnum write emulation, Alistair Francis, 2024/12/18
- [PULL 03/39] hw/riscv/riscv-iommu.c: add riscv_iommu_instance_init(), Alistair Francis, 2024/12/18
- [PULL 04/39] hw/riscv/riscv-iommu: parametrize CAP.IGS, Alistair Francis, 2024/12/18
- [PULL 07/39] hw/riscv/virt.c, riscv-iommu-sys.c: add MSIx support, Alistair Francis, 2024/12/18
- [PULL 05/39] hw/riscv: add riscv-iommu-sys platform device, Alistair Francis, 2024/12/18
- [PULL 06/39] hw/riscv/virt: Add IOMMU as platform device if the option is set, Alistair Francis, 2024/12/18
- [PULL 11/39] hw/intc/riscv_aplic: rename is_kvm_aia(), Alistair Francis, 2024/12/18
- [PULL 09/39] docs/specs: add riscv-iommu-sys information, Alistair Francis, 2024/12/18
- [PULL 12/39] hw/riscv/virt.c: reduce virt_use_kvm_aia() usage, Alistair Francis, 2024/12/18
- [PULL 10/39] target/riscv: Add Tenstorrent Ascalon CPU, Alistair Francis, 2024/12/18
- [PULL 08/39] hw/riscv/riscv-iommu: implement reset protocol,
Alistair Francis <=
- [PULL 13/39] hw/riscv/virt.c: rename helper to virt_use_kvm_aia_aplic_imsic(), Alistair Francis, 2024/12/18
- [PULL 15/39] hw/riscv/virt.c, riscv_aplic.c: add 'emulated_aplic' helpers, Alistair Francis, 2024/12/18
- [PULL 16/39] hw/intc/riscv_aplic: add kvm_msicfgaddr for split mode aplic-imsic, Alistair Francis, 2024/12/18
- [PULL 14/39] target/riscv/kvm: consider irqchip_split() in aia_create(), Alistair Francis, 2024/12/18
- [PULL 21/39] hw/acpi: Upgrade ACPI SPCR table to support SPCR table revision 4 format, Alistair Francis, 2024/12/18
- [PULL 24/39] hw/char/riscv_htif: Explicit little-endian implementation, Alistair Francis, 2024/12/18
- [PULL 32/39] target/riscv: Check memory access to meet svukte rule, Alistair Francis, 2024/12/18
- [PULL 19/39] hw/riscv: Add Microblaze V generic board, Alistair Francis, 2024/12/18
- [PULL 22/39] tests/qtest/bios-tables-test: Update virt SPCR golden reference for RISC-V, Alistair Francis, 2024/12/18
- [PULL 26/39] hw/riscv: Support to load DTB after 3GB memory on 64-bit system., Alistair Francis, 2024/12/18