Add support for all of the SBI PMU functions, which will be used by the SBI tests. Signed-off-by: James Raphael Tiovalen --- 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