aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomasz Jeznach <tjeznach@rivosinc.com>2025-02-24 16:08:24 -0300
committerAlistair Francis <alistair.francis@wdc.com>2025-03-04 15:42:54 +1000
commit3b1d07b6279defa40bf9903f420d8ddcf839794d (patch)
tree8432607ec4496536f003a2c2eccd6e3ae1dac62c
parent4faa3e6f906c832f4c5382fbd618e368525ad2dc (diff)
downloadqemu-3b1d07b6279defa40bf9903f420d8ddcf839794d.zip
qemu-3b1d07b6279defa40bf9903f420d8ddcf839794d.tar.gz
qemu-3b1d07b6279defa40bf9903f420d8ddcf839794d.tar.bz2
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 <tjeznach@rivosinc.com> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> Acked-by: Alistair Francis <alistair.francis@wdc.com> Message-ID: <20250224190826.1858473-10-dbarboza@ventanamicro.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
-rw-r--r--hw/riscv/riscv-iommu.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
index cdbb848..d46beb2 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);