[kvm-unit-tests PATCH 2/4] lib: riscv: Add SBI PMU support
James Raphael Tiovalen
jamestiotio at gmail.com
Sat Dec 13 07:08:46 PST 2025
Add support for all of the SBI PMU functions, which will be used by the
SBI tests.
Signed-off-by: James Raphael Tiovalen <jamestiotio at gmail.com>
---
lib/riscv/asm/sbi.h | 22 ++++++++++++++
lib/riscv/sbi.c | 73 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 95 insertions(+)
diff --git a/lib/riscv/asm/sbi.h b/lib/riscv/asm/sbi.h
index 35dbf508..8794c126 100644
--- a/lib/riscv/asm/sbi.h
+++ b/lib/riscv/asm/sbi.h
@@ -390,5 +390,27 @@ struct sbiret sbi_fwft_set(uint32_t feature, unsigned long value, unsigned long
struct sbiret sbi_fwft_get_raw(unsigned long feature);
struct sbiret sbi_fwft_get(uint32_t feature);
+struct sbiret sbi_pmu_num_counters(void);
+struct sbiret sbi_pmu_counter_get_info(unsigned long counter_idx);
+struct sbiret sbi_pmu_counter_config_matching(unsigned long counter_idx_base,
+ unsigned long counter_idx_mask,
+ unsigned long config_flags,
+ unsigned long event_idx,
+ unsigned long event_data);
+struct sbiret sbi_pmu_counter_start(unsigned long counter_idx_base, unsigned long counter_idx_mask,
+ unsigned long start_flags, unsigned long initial_value);
+struct sbiret sbi_pmu_counter_stop(unsigned long counter_idx_base, unsigned long counter_idx_mask,
+ unsigned long stop_flags);
+struct sbiret sbi_pmu_counter_fw_read(unsigned long counter_idx);
+struct sbiret sbi_pmu_counter_fw_read_hi(unsigned long counter_idx);
+struct sbiret sbi_pmu_snapshot_set_shmem_raw(unsigned long shmem_phys_lo,
+ unsigned long shmem_phys_hi,
+ unsigned long flags);
+struct sbiret sbi_pmu_snapshot_set_shmem(unsigned long *shmem, unsigned long flags);
+struct sbiret sbi_pmu_event_get_info_raw(unsigned long shmem_phys_lo, unsigned long shmem_phys_hi,
+ unsigned long num_entries, unsigned long flags);
+struct sbiret sbi_pmu_event_get_info(unsigned long *shmem, unsigned long num_entries,
+ unsigned long flags);
+
#endif /* !__ASSEMBLER__ */
#endif /* _ASMRISCV_SBI_H_ */
diff --git a/lib/riscv/sbi.c b/lib/riscv/sbi.c
index 39f6138f..ca8f3d33 100644
--- a/lib/riscv/sbi.c
+++ b/lib/riscv/sbi.c
@@ -32,6 +32,79 @@ struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0,
return ret;
}
+struct sbiret sbi_pmu_num_counters(void)
+{
+ return sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_NUM_COUNTERS, 0, 0, 0, 0, 0, 0);
+}
+
+struct sbiret sbi_pmu_counter_get_info(unsigned long counter_idx)
+{
+ return sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_GET_INFO, counter_idx, 0, 0, 0, 0, 0);
+}
+
+struct sbiret sbi_pmu_counter_config_matching(unsigned long counter_idx_base,
+ unsigned long counter_idx_mask,
+ unsigned long config_flags,
+ unsigned long event_idx,
+ unsigned long event_data)
+{
+ return sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_CONFIG_MATCHING, counter_idx_base,
+ counter_idx_mask, config_flags, event_idx, event_data, 0);
+}
+
+struct sbiret sbi_pmu_counter_start(unsigned long counter_idx_base, unsigned long counter_idx_mask,
+ unsigned long start_flags, unsigned long initial_value)
+{
+ return sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_START, counter_idx_base,
+ counter_idx_mask, start_flags, initial_value, 0, 0);
+}
+
+struct sbiret sbi_pmu_counter_stop(unsigned long counter_idx_base, unsigned long counter_idx_mask,
+ unsigned long stop_flags)
+{
+ return sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_STOP, counter_idx_base,
+ counter_idx_mask, stop_flags, 0, 0, 0);
+}
+
+struct sbiret sbi_pmu_counter_fw_read(unsigned long counter_idx)
+{
+ return sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_FW_READ, counter_idx, 0, 0, 0, 0, 0);
+}
+
+struct sbiret sbi_pmu_counter_fw_read_hi(unsigned long counter_idx)
+{
+ return sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_FW_READ_HI, counter_idx, 0, 0, 0, 0, 0);
+}
+
+struct sbiret sbi_pmu_snapshot_set_shmem_raw(unsigned long shmem_phys_lo, unsigned long shmem_phys_hi,
+ unsigned long flags)
+{
+ return sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_SNAPSHOT_SET_SHMEM, shmem_phys_lo,
+ shmem_phys_hi, flags, 0, 0, 0);
+}
+
+struct sbiret sbi_pmu_snapshot_set_shmem(unsigned long *shmem, unsigned long flags)
+{
+ phys_addr_t p = virt_to_phys(shmem);
+
+ return sbi_pmu_snapshot_set_shmem_raw(lower_32_bits(p), upper_32_bits(p), flags);
+}
+
+struct sbiret sbi_pmu_event_get_info_raw(unsigned long shmem_phys_lo, unsigned long shmem_phys_hi,
+ unsigned long num_entries, unsigned long flags)
+{
+ return sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_EVENT_GET_INFO, shmem_phys_lo,
+ shmem_phys_hi, num_entries, flags, 0, 0);
+}
+
+struct sbiret sbi_pmu_event_get_info(unsigned long *shmem, unsigned long num_entries,
+ unsigned long flags)
+{
+ phys_addr_t p = virt_to_phys(shmem);
+
+ return sbi_pmu_event_get_info_raw(lower_32_bits(p), upper_32_bits(p), num_entries, flags);
+}
+
struct sbiret sbi_sse_read_attrs_raw(unsigned long event_id, unsigned long base_attr_id,
unsigned long attr_count, unsigned long phys_lo,
unsigned long phys_hi)
--
2.43.0
More information about the kvm-riscv
mailing list