mirror of
https://github.com/riscv-software-src/opensbi.git
synced 2026-09-08 18:21:29 +01:00
lib: sbi_pmu: Fix counter and event info error codes as per SBI v3.0 spec
Align the PMU extension implementation with the error codes required by the SBI v3.0 specification, chapter 11: - sbi_pmu_counter_start and sbi_pmu_counter_stop (secs 11.9-11.10, tables 39-42): the start_flags/stop_flags bits 2:(XLEN-1) are reserved and must be zero, so return SBI_ERR_INVALID_PARAM when any reserved flag bit is set. Introduce SBI_PMU_START_FLAGS_MASK and SBI_PMU_STOP_FLAGS_MASK for the valid bits of each function. - sbi_pmu_counter_start and sbi_pmu_counter_stop (tables 40 and 42): return SBI_ERR_ALREADY_STARTED / SBI_ERR_ALREADY_STOPPED when the set of counters includes a counter which is already started or stopped, instead of ignoring the error returned for each counter. - sbi_pmu_event_get_info (sec 11.14, table 47): the output word must indicate whether the event is supported, but firmware events were only matched against the hardware event map and were always reported as unsupported. Report a validated firmware event as supported. Signed-off-by: David E. Garcia Porras <david.garcia@aheadcomputing.com> Reviewed-by: Anup Patel <anup@brainfault.org> Link: https://lore.kernel.org/r/20260818210023.466462-4-david.garcia@aheadcomputing.com Signed-off-by: Anup Patel <anup@brainfault.org>
This commit is contained in:
committed by
Anup Patel
parent
d34a39df77
commit
c5077d497d
@@ -306,10 +306,22 @@ struct sbi_pmu_event_info {
|
|||||||
/* Flags defined for counter start function */
|
/* Flags defined for counter start function */
|
||||||
#define SBI_PMU_START_FLAG_SET_INIT_VALUE (1 << 0)
|
#define SBI_PMU_START_FLAG_SET_INIT_VALUE (1 << 0)
|
||||||
#define SBI_PMU_START_FLAG_INIT_FROM_SNAPSHOT (1 << 1)
|
#define SBI_PMU_START_FLAG_INIT_FROM_SNAPSHOT (1 << 1)
|
||||||
|
/* Start flags valid mask */
|
||||||
|
#define SBI_PMU_START_FLAGS_MASK \
|
||||||
|
( \
|
||||||
|
SBI_PMU_START_FLAG_SET_INIT_VALUE | \
|
||||||
|
SBI_PMU_START_FLAG_INIT_FROM_SNAPSHOT \
|
||||||
|
)
|
||||||
|
|
||||||
/* Flags defined for counter stop function */
|
/* Flags defined for counter stop function */
|
||||||
#define SBI_PMU_STOP_FLAG_RESET (1 << 0)
|
#define SBI_PMU_STOP_FLAG_RESET (1 << 0)
|
||||||
#define SBI_PMU_STOP_FLAG_TAKE_SNAPSHOT (1 << 1)
|
#define SBI_PMU_STOP_FLAG_TAKE_SNAPSHOT (1 << 1)
|
||||||
|
/* Stop flags valid mask */
|
||||||
|
#define SBI_PMU_STOP_FLAGS_MASK \
|
||||||
|
( \
|
||||||
|
SBI_PMU_STOP_FLAG_RESET | \
|
||||||
|
SBI_PMU_STOP_FLAG_TAKE_SNAPSHOT \
|
||||||
|
)
|
||||||
|
|
||||||
/* SBI function IDs for DBCN extension */
|
/* SBI function IDs for DBCN extension */
|
||||||
#define SBI_EXT_DBCN_CONSOLE_WRITE 0x0
|
#define SBI_EXT_DBCN_CONSOLE_WRITE 0x0
|
||||||
|
|||||||
@@ -574,6 +574,9 @@ int sbi_pmu_ctr_start(unsigned long cbase, unsigned long cmask,
|
|||||||
if (!pmu_ctr_idx_validate(cbase, cmask))
|
if (!pmu_ctr_idx_validate(cbase, cmask))
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
if (flags & ~SBI_PMU_START_FLAGS_MASK)
|
||||||
|
return SBI_ERR_INVALID_PARAM;
|
||||||
|
|
||||||
if (flags & SBI_PMU_STOP_FLAG_TAKE_SNAPSHOT)
|
if (flags & SBI_PMU_STOP_FLAG_TAKE_SNAPSHOT)
|
||||||
return SBI_ENO_SHMEM;
|
return SBI_ENO_SHMEM;
|
||||||
|
|
||||||
@@ -592,6 +595,8 @@ int sbi_pmu_ctr_start(unsigned long cbase, unsigned long cmask,
|
|||||||
: 0x0;
|
: 0x0;
|
||||||
ret = pmu_ctr_start_fw(phs, cidx, event_code, edata,
|
ret = pmu_ctr_start_fw(phs, cidx, event_code, edata,
|
||||||
ival, bUpdate);
|
ival, bUpdate);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
} else {
|
} else {
|
||||||
if (cidx >= 3) {
|
if (cidx >= 3) {
|
||||||
struct sbi_pmu_hw_event_config *ev_cfg =
|
struct sbi_pmu_hw_event_config *ev_cfg =
|
||||||
@@ -605,6 +610,8 @@ int sbi_pmu_ctr_start(unsigned long cbase, unsigned long cmask,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
ret = pmu_ctr_start_hw(cidx, ival, bUpdate);
|
ret = pmu_ctr_start_hw(cidx, ival, bUpdate);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -693,6 +700,9 @@ int sbi_pmu_ctr_stop(unsigned long cbase, unsigned long cmask,
|
|||||||
if (!pmu_ctr_idx_validate(cbase, cmask))
|
if (!pmu_ctr_idx_validate(cbase, cmask))
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
if (flag & ~SBI_PMU_STOP_FLAGS_MASK)
|
||||||
|
return SBI_ERR_INVALID_PARAM;
|
||||||
|
|
||||||
if (flag & SBI_PMU_STOP_FLAG_TAKE_SNAPSHOT)
|
if (flag & SBI_PMU_STOP_FLAG_TAKE_SNAPSHOT)
|
||||||
return SBI_ENO_SHMEM;
|
return SBI_ENO_SHMEM;
|
||||||
|
|
||||||
@@ -708,6 +718,9 @@ int sbi_pmu_ctr_stop(unsigned long cbase, unsigned long cmask,
|
|||||||
else
|
else
|
||||||
ret = pmu_ctr_stop_hw(cidx);
|
ret = pmu_ctr_stop_hw(cidx);
|
||||||
|
|
||||||
|
if(ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
if (cidx > (CSR_INSTRET - CSR_CYCLE) && flag & SBI_PMU_STOP_FLAG_RESET) {
|
if (cidx > (CSR_INSTRET - CSR_CYCLE) && flag & SBI_PMU_STOP_FLAG_RESET) {
|
||||||
phs->active_events[cidx] = SBI_PMU_EVENT_IDX_INVALID;
|
phs->active_events[cidx] = SBI_PMU_EVENT_IDX_INVALID;
|
||||||
pmu_reset_hw_mhpmevent(cidx);
|
pmu_reset_hw_mhpmevent(cidx);
|
||||||
@@ -1104,6 +1117,8 @@ int sbi_pmu_event_get_info(unsigned long shmem_phys_lo, unsigned long shmem_phys
|
|||||||
event_type = pmu_event_validate(phs, event_idx, einfo[i].event_data);
|
event_type = pmu_event_validate(phs, event_idx, einfo[i].event_data);
|
||||||
if (event_type < 0) {
|
if (event_type < 0) {
|
||||||
einfo[i].output = 0;
|
einfo[i].output = 0;
|
||||||
|
} else if (event_type == SBI_PMU_EVENT_TYPE_FW) {
|
||||||
|
einfo[i].output = 1;
|
||||||
} else {
|
} else {
|
||||||
for (j = 0; j < num_hw_events; j++) {
|
for (j = 0; j < num_hw_events; j++) {
|
||||||
temp = &hw_event_map[j];
|
temp = &hw_event_map[j];
|
||||||
|
|||||||
Reference in New Issue
Block a user