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:
Daniel Henrique Barboza 2024-11-06 10:34:06 -03:00 committed by Alistair Francis
parent 01c1caa9d1
commit 9afd26715e
6 changed files with 82 additions and 2 deletions

View file

@ -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),