mirror of
https://github.com/riscv-software-src/opensbi.git
synced 2025-12-07 08:51:37 +00:00
lib: sbi_pmu: Fix xINH bits configuring
Before this patch sbi_pmu_ctr_start() ignores flags received in
sbi_pmu_ctr_cfg_match() including inhibit ones. To prevent it,
save flags together with event_data and use them both in
sbi_pmu_ctr_start().
Fixes: 1db95da299 ("lib: sbi: sbi_pmu: fixed hw counters start for hart")
Signed-off-by: Shifrin Dmitry <dmitry.shifrin@syntacore.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20251110113140.80561-1-dmitry.shifrin@syntacore.com
Signed-off-by: Anup Patel <anup@brainfault.org>
This commit is contained in:
committed by
Anup Patel
parent
da05980de6
commit
c9f856e23f
@@ -291,6 +291,15 @@ struct sbi_pmu_event_info {
|
||||
#define SBI_PMU_CFG_FLAG_SET_UINH (1 << 5)
|
||||
#define SBI_PMU_CFG_FLAG_SET_SINH (1 << 6)
|
||||
#define SBI_PMU_CFG_FLAG_SET_MINH (1 << 7)
|
||||
/* Event configuration mask */
|
||||
#define SBI_PMU_CFG_EVENT_MASK \
|
||||
( \
|
||||
SBI_PMU_CFG_FLAG_SET_VUINH | \
|
||||
SBI_PMU_CFG_FLAG_SET_VSINH | \
|
||||
SBI_PMU_CFG_FLAG_SET_UINH | \
|
||||
SBI_PMU_CFG_FLAG_SET_SINH | \
|
||||
SBI_PMU_CFG_FLAG_SET_MINH \
|
||||
)
|
||||
|
||||
/* Flags defined for counter start function */
|
||||
#define SBI_PMU_START_FLAG_SET_INIT_VALUE (1 << 0)
|
||||
|
||||
@@ -56,6 +56,14 @@ union sbi_pmu_ctr_info {
|
||||
#error "Can't handle firmware counters beyond BITS_PER_LONG"
|
||||
#endif
|
||||
|
||||
/** HW event configuration parameters */
|
||||
struct sbi_pmu_hw_event_config {
|
||||
/* event_data value from sbi_pmu_ctr_cfg_match() */
|
||||
uint64_t event_data;
|
||||
/* HW events flags from sbi_pmu_ctr_cfg_match() */
|
||||
uint64_t flags;
|
||||
};
|
||||
|
||||
/** Per-HART state of the PMU counters */
|
||||
struct sbi_pmu_hart_state {
|
||||
/* HART to which this state belongs */
|
||||
@@ -72,11 +80,12 @@ struct sbi_pmu_hart_state {
|
||||
* and hence can optimally share the same memory.
|
||||
*/
|
||||
uint64_t fw_counters_data[SBI_PMU_FW_CTR_MAX];
|
||||
/* Data values from sbi_pmu_ctr_cfg_match() command which
|
||||
* is used for restoring RAW hardware events after
|
||||
/* HW events configuration parameters from
|
||||
* sbi_pmu_ctr_cfg_match() command which are
|
||||
* used for restoring RAW hardware events after
|
||||
* cpu suspending.
|
||||
*/
|
||||
uint64_t hw_counters_data[SBI_PMU_HW_CTR_MAX];
|
||||
struct sbi_pmu_hw_event_config hw_counters_cfg[SBI_PMU_HW_CTR_MAX];
|
||||
};
|
||||
|
||||
/** Offset of pointer to PMU HART state in scratch space */
|
||||
@@ -561,9 +570,13 @@ int sbi_pmu_ctr_start(unsigned long cbase, unsigned long cmask,
|
||||
ival, bUpdate);
|
||||
} else {
|
||||
if (cidx >= 3) {
|
||||
struct sbi_pmu_hw_event_config *ev_cfg =
|
||||
&phs->hw_counters_cfg[cidx];
|
||||
|
||||
ret = pmu_update_hw_mhpmevent(&hw_event_map[cidx], cidx,
|
||||
0, phs->active_events[cidx],
|
||||
phs->hw_counters_data[cidx]);
|
||||
ev_cfg->flags,
|
||||
phs->active_events[cidx],
|
||||
ev_cfg->event_data);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
@@ -892,8 +905,14 @@ int sbi_pmu_ctr_cfg_match(unsigned long cidx_base, unsigned long cidx_mask,
|
||||
} else {
|
||||
ctr_idx = pmu_ctr_find_hw(phs, cidx_base, cidx_mask, flags,
|
||||
event_idx, event_data);
|
||||
if (ctr_idx >= 0)
|
||||
phs->hw_counters_data[ctr_idx] = event_data;
|
||||
if (ctr_idx >= 0) {
|
||||
struct sbi_pmu_hw_event_config *ev_cfg =
|
||||
&phs->hw_counters_cfg[ctr_idx];
|
||||
|
||||
ev_cfg->event_data = event_data;
|
||||
/* Remove flags that are used in match call only */
|
||||
ev_cfg->flags = flags & SBI_PMU_CFG_EVENT_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctr_idx < 0)
|
||||
|
||||
Reference in New Issue
Block a user