Trait rustsbi::Pmu

source ·
pub trait Pmu: Send + Sync {
    // Required methods
    fn num_counters(&self) -> usize;
    fn counter_get_info(&self, counter_idx: usize) -> SbiRet;
    fn counter_config_matching(
        &self,
        counter_idx_base: usize,
        counter_idx_mask: usize,
        config_flags: usize,
        event_idx: usize,
        event_data: u64
    ) -> SbiRet;
    fn counter_start(
        &self,
        counter_idx_base: usize,
        counter_idx_mask: usize,
        start_flags: usize,
        initial_value: u64
    ) -> SbiRet;
    fn counter_stop(
        &self,
        counter_idx_base: usize,
        counter_idx_mask: usize,
        stop_flags: usize
    ) -> SbiRet;
    fn counter_fw_read(&self, counter_idx: usize) -> SbiRet;
}
Expand description

Performance Monitoring Unit Extension

The RISC-V hardware performance counters such as mcycle, minstret, and mhpmcounterX CSRs are accessible as read-only from supervisor-mode using cycle, instret, and hpmcounterX CSRs. The SBI performance monitoring unit (PMU) extension is an interface for supervisor-mode to configure and use the RISC-V hardware performance counters with assistance from the machine-mode (or hypervisor-mode). These hardware performance counters can only be started, stopped, or configured from machine-mode using mcountinhibit and mhpmeventX CSRs. Due to this, a machine-mode SBI implementation may choose to disallow SBI PMU extension if mcountinhibit CSR is not implemented by the RISC-V platform.

A RISC-V platform generally supports monitoring of various hardware events using a limited number of hardware performance counters which are up to 64 bits wide. In addition, a SBI implementation can also provide firmware performance counters which can monitor firmware events such as number of misaligned load/store instructions, number of RFENCEs, number of IPIs, etc. The firmware counters are always 64 bits wide.

The SBI PMU extension provides:

  1. An interface for supervisor-mode software to discover and configure per-HART hardware/firmware counters
  2. A typical perf compatible interface for hardware/firmware performance counters and events
  3. Full access to microarchitecture’s raw event encodings

To define SBI PMU extension calls, we first define important entities counter_idx, event_idx, and event_data. The counter_idx is a logical number assigned to each hardware/firmware counter. The event_idx represents a hardware (or firmware) event whereas the event_data is 64 bits wide and represents additional configuration (or parameters) for a hardware (or firmware) event.

The event_idx is a 20 bits wide number encoded as follows:

event_idx[19:16] = type;
event_idx[15:0] = code;

Required Methods§

source

fn num_counters(&self) -> usize

Returns the number of counters (both hardware and firmware).

The value is returned in SbiRet.value; this call always returns SbiRet::success().

source

fn counter_get_info(&self, counter_idx: usize) -> SbiRet

Get details about the specified counter such as underlying CSR number, width of the counter, type of counter hardware/firmware, etc.

The counter_info returned by this SBI call is encoded as follows:

counter_info[11:0] = CSR; // (12bit CSR number)
counter_info[17:12] = Width; // (One less than number of bits in CSR)
counter_info[XLEN-2:18] = Reserved; // Reserved for future use
counter_info[XLEN-1] = Type; // (0 = hardware and 1 = firmware)

If counter_info.type == 1 then counter_info.csr and counter_info.width should be ignored.

Return value

Returns the counter_info described above in SbiRet.value.

The possible return error codes returned in SbiRet.error are shown in the table below:

Return codeDescription
SbiRet::success()counter_info read successfully.
SbiRet::invalid_param()counter_idx points to an invalid counter.
source

fn counter_config_matching( &self, counter_idx_base: usize, counter_idx_mask: usize, config_flags: usize, event_idx: usize, event_data: u64 ) -> SbiRet

Find and configure a counter from a set of counters which is not started (or enabled) and can monitor the specified event.

Parameters

The counter_idx_base and counter_idx_mask parameters represent the set of counters, whereas the event_idx represents the event to be monitored and event_data represents any additional event configuration.

The config_flags parameter represents additional counter configuration and filter flags. The bit definitions of the config_flags parameter are shown in the table below:

Flag NameBitsDescription
SBI_PMU_CFG_FLAG_SKIP_MATCH0:0Skip the counter matching
SBI_PMU_CFG_FLAG_CLEAR_VALUE1:1Clear (or zero) the counter value in counter configuration
SBI_PMU_CFG_FLAG_AUTO_START2:2Start the counter after configuring a matching counter
SBI_PMU_CFG_FLAG_SET_VUINH3:3Event counting inhibited in VU-mode
SBI_PMU_CFG_FLAG_SET_VSINH4:4Event counting inhibited in VS-mode
SBI_PMU_CFG_FLAG_SET_UINH5:5Event counting inhibited in U-mode
SBI_PMU_CFG_FLAG_SET_SINH6:6Event counting inhibited in S-mode
SBI_PMU_CFG_FLAG_SET_MINH7:7Event counting inhibited in M-mode
RESERVED8:(XLEN-1)All non-zero values are reserved for future use.

NOTE: When SBI_PMU_CFG_FLAG_SKIP_MATCH is set in config_flags, the SBI implementation will unconditionally select the first counter from the set of counters specified by the counter_idx_base and counter_idx_mask.

NOTE: The SBI_PMU_CFG_FLAG_AUTO_START flag in config_flags has no impact on the counter value.

NOTE: The config_flags[3:7] bits are event filtering hints so these can be ignored or overridden by the SBI implementation for security concerns or due to lack of event filtering support in the underlying RISC-V platform.

Return value

Returns the counter_idx in sbiret.value upon success.

In case of failure, the possible error codes returned in sbiret.error are shown in the table below:

Return codeDescription
SbiRet::success()counter found and configured successfully.
SbiRet::invalid_param()set of counters has at least one invalid counter.
SbiRet::not_supported()none of the counters can monitor the specified event.
source

fn counter_start( &self, counter_idx_base: usize, counter_idx_mask: usize, start_flags: usize, initial_value: u64 ) -> SbiRet

Start or enable a set of counters on the calling HART with the specified initial value.

Parameters

The counter_idx_base and counter_idx_mask parameters represent the set of counters. whereas the initial_value parameter specifies the initial value of the counter.

The bit definitions of the start_flags parameter are shown in the table below:

Flag NameBitsDescription
SBI_PMU_START_SET_INIT_VALUE0:0Set the value of counters based on the initial_value parameter.
RESERVED1:(XLEN-1)All non-zero values are reserved for future use.

NOTE: When SBI_PMU_START_SET_INIT_VALUE is not set in start_flags, the counter value will not be modified and event counting will start from current counter value.

Return value

The possible return error codes returned in SbiRet.error are shown in the table below:

Return codeDescription
SbiRet::success()counter started successfully.
SbiRet::invalid_param()set of counters has at least one invalid counter.
SbiRet::already_started()set of counters includes at least one counter which is already started.
source

fn counter_stop( &self, counter_idx_base: usize, counter_idx_mask: usize, stop_flags: usize ) -> SbiRet

Stop or disable a set of counters on the calling HART.

Parameters

The counter_idx_base and counter_idx_mask parameters represent the set of counters. The bit definitions of the stop_flags parameter are shown in the table below:

Flag NameBitsDescription
SBI_PMU_STOP_FLAG_RESET0:0Reset the counter to event mapping.
RESERVED1:(XLEN-1)All non-zero values are reserved for future use.
Return value

The possible return error codes returned in SbiRet.error are shown in the table below:

Return codeDescription
SbiRet::success()counter stopped successfully.
SbiRet::invalid_param()set of counters has at least one invalid counter.
SbiRet::already_stopped()set of counters includes at least one counter which is already stopped.
source

fn counter_fw_read(&self, counter_idx: usize) -> SbiRet

Provide the current value of a firmware counter in SbiRet.value.

On RV32 systems, the SbiRet.value will only contain the lower 32 bits of the current firmware counter value.

Parameters

This function should be only used to read a firmware counter. It will return an error when user provides a hardware counter in counter_idx parameter.

Return value

The possible return error codes returned in SbiRet.error are shown in the table below:

Return codeDescription
SbiRet::success()firmware counter read successfully.
SbiRet::invalid_param()counter_idx points to a hardware counter or an invalid counter.

Implementations on Foreign Types§

source§

impl<T: Pmu> Pmu for &T

source§

fn num_counters(&self) -> usize

source§

fn counter_get_info(&self, counter_idx: usize) -> SbiRet

source§

fn counter_config_matching( &self, counter_idx_base: usize, counter_idx_mask: usize, config_flags: usize, event_idx: usize, event_data: u64 ) -> SbiRet

source§

fn counter_start( &self, counter_idx_base: usize, counter_idx_mask: usize, start_flags: usize, initial_value: u64 ) -> SbiRet

source§

fn counter_stop( &self, counter_idx_base: usize, counter_idx_mask: usize, stop_flags: usize ) -> SbiRet

source§

fn counter_fw_read(&self, counter_idx: usize) -> SbiRet

source§

impl Pmu for Infallible

Implementors§