From 3b1d07b6279defa40bf9903f420d8ddcf839794d Mon Sep 17 00:00:00 2001 From: Tomasz Jeznach Date: Mon, 24 Feb 2025 16:08:24 -0300 Subject: [PATCH] hw/riscv/riscv-iommu.c: add RISCV_IOMMU_CAP_HPM cap Now that we have every piece in place we can advertise CAP_HTM to software, allowing any HPM aware driver to make use of the counters. HPM is enabled/disabled via the 'hpm-counters' attribute. Default value is 31, max value is also 31. Setting it to zero will disable HPM support. Signed-off-by: Tomasz Jeznach Signed-off-by: Daniel Henrique Barboza Acked-by: Alistair Francis Message-ID: <20250224190826.1858473-10-dbarboza@ventanamicro.com> Signed-off-by: Alistair Francis --- hw/riscv/riscv-iommu.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c index cdbb848181..d46beb2d64 100644 --- a/hw/riscv/riscv-iommu.c +++ b/hw/riscv/riscv-iommu.c @@ -2357,6 +2357,15 @@ static void riscv_iommu_realize(DeviceState *dev, Error **errp) RISCV_IOMMU_CAP_SV48X4 | RISCV_IOMMU_CAP_SV57X4; } + if (s->hpm_cntrs > 0) { + /* Clip number of HPM counters to maximum supported (31). */ + if (s->hpm_cntrs > RISCV_IOMMU_IOCOUNT_NUM) { + s->hpm_cntrs = RISCV_IOMMU_IOCOUNT_NUM; + } + /* Enable hardware performance monitor interface */ + s->cap |= RISCV_IOMMU_CAP_HPM; + } + /* Out-of-reset translation mode: OFF (DMA disabled) BARE (passthrough) */ s->ddtp = set_field(0, RISCV_IOMMU_DDTP_MODE, s->enable_off ? RISCV_IOMMU_DDTP_MODE_OFF : RISCV_IOMMU_DDTP_MODE_BARE); @@ -2404,6 +2413,18 @@ static void riscv_iommu_realize(DeviceState *dev, Error **errp) RISCV_IOMMU_TR_REQ_CTL_GO_BUSY); } + /* If HPM registers are enabled. */ + if (s->cap & RISCV_IOMMU_CAP_HPM) { + /* +1 for cycle counter bit. */ + stl_le_p(&s->regs_ro[RISCV_IOMMU_REG_IOCOUNTINH], + ~((2 << s->hpm_cntrs) - 1)); + stq_le_p(&s->regs_ro[RISCV_IOMMU_REG_IOHPMCYCLES], 0); + memset(&s->regs_ro[RISCV_IOMMU_REG_IOHPMCTR_BASE], + 0x00, s->hpm_cntrs * 8); + memset(&s->regs_ro[RISCV_IOMMU_REG_IOHPMEVT_BASE], + 0x00, s->hpm_cntrs * 8); + } + /* Memory region for downstream access, if specified. */ if (s->target_mr) { s->target_as = g_new0(AddressSpace, 1); -- 2.30.2