[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v7 09/11] target/riscv: Start counters from both mhpmcounter and
From: |
Atish Patra |
Subject: |
[PATCH v7 09/11] target/riscv: Start counters from both mhpmcounter and mcountinhibit |
Date: |
Wed, 26 Jun 2024 16:57:29 -0700 |
From: Rajnesh Kanwal <rkanwal@rivosinc.com>
Currently we start timer counter from write_mhpmcounter path only
without checking for mcountinhibit bit. This changes adds mcountinhibit
check and also programs the counter from write_mcountinhibit as well.
When a counter is stopped using mcountinhibit we simply update
the value of the counter based on current host ticks and save
it for future reads.
We don't need to disable running timer as pmu_timer_trigger_irq
will discard the interrupt if the counter has been inhibited.
Signed-off-by: Rajnesh Kanwal <rkanwal@rivosinc.com>
---
target/riscv/csr.c | 75 ++++++++++++++++++++++++++++++++++++++----------------
target/riscv/pmu.c | 3 +--
2 files changed, 54 insertions(+), 24 deletions(-)
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 6c1a884eec82..150e02f080ec 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1008,8 +1008,9 @@ static RISCVException write_mhpmcounter(CPURISCVState
*env, int csrno,
uint64_t mhpmctr_val = val;
counter->mhpmcounter_val = val;
- if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
- riscv_pmu_ctr_monitor_instructions(env, ctr_idx)) {
+ if (!get_field(env->mcountinhibit, BIT(ctr_idx)) &&
+ (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
+ riscv_pmu_ctr_monitor_instructions(env, ctr_idx))) {
counter->mhpmcounter_prev = riscv_pmu_ctr_get_fixed_counters_val(env,
ctr_idx,
false);
if (ctr_idx > 2) {
@@ -1037,8 +1038,9 @@ static RISCVException write_mhpmcounterh(CPURISCVState
*env, int csrno,
counter->mhpmcounterh_val = val;
mhpmctr_val = mhpmctr_val | (mhpmctrh_val << 32);
- if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
- riscv_pmu_ctr_monitor_instructions(env, ctr_idx)) {
+ if (!get_field(env->mcountinhibit, BIT(ctr_idx)) &&
+ (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
+ riscv_pmu_ctr_monitor_instructions(env, ctr_idx))) {
counter->mhpmcounterh_prev = riscv_pmu_ctr_get_fixed_counters_val(env,
ctr_idx,
true);
if (ctr_idx > 2) {
@@ -2101,31 +2103,60 @@ static RISCVException write_mcountinhibit(CPURISCVState
*env, int csrno,
int cidx;
PMUCTRState *counter;
RISCVCPU *cpu = env_archcpu(env);
+ uint32_t present_ctrs = cpu->pmu_avail_ctrs | COUNTEREN_CY | COUNTEREN_IR;
+ target_ulong updated_ctrs = (env->mcountinhibit ^ val) & present_ctrs;
+ uint64_t mhpmctr_val, prev_count, curr_count;
/* WARL register - disable unavailable counters; TM bit is always 0 */
- env->mcountinhibit =
- val & (cpu->pmu_avail_ctrs | COUNTEREN_CY | COUNTEREN_IR);
+ env->mcountinhibit = val & present_ctrs;
/* Check if any other counter is also monitoring cycles/instructions */
for (cidx = 0; cidx < RV_MAX_MHPMCOUNTERS; cidx++) {
- counter = &env->pmu_ctrs[cidx];
- if (get_field(env->mcountinhibit, BIT(cidx)) && (val & BIT(cidx))) {
- /*
- * Update the counter value for cycle/instret as we can't stop the
- * host ticks. But we should show the current value at this moment.
- */
- if (riscv_pmu_ctr_monitor_cycles(env, cidx) ||
- riscv_pmu_ctr_monitor_instructions(env, cidx)) {
- counter->mhpmcounter_val =
- riscv_pmu_ctr_get_fixed_counters_val(env, cidx, false) -
- counter->mhpmcounter_prev +
- counter->mhpmcounter_val;
+ if (!(updated_ctrs & BIT(cidx)) ||
+ (!riscv_pmu_ctr_monitor_cycles(env, cidx) &&
+ !riscv_pmu_ctr_monitor_instructions(env, cidx))) {
+ continue;
+ }
+
+ counter = &env->pmu_ctrs[cidx];
+
+ if (!get_field(env->mcountinhibit, BIT(cidx))) {
+ counter->mhpmcounter_prev =
+ riscv_pmu_ctr_get_fixed_counters_val(env, cidx, false);
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
+ counter->mhpmcounterh_prev =
+ riscv_pmu_ctr_get_fixed_counters_val(env, cidx, true);
+ }
+
+ if (cidx > 2) {
+ mhpmctr_val = counter->mhpmcounter_val;
if (riscv_cpu_mxl(env) == MXL_RV32) {
- counter->mhpmcounterh_val =
- riscv_pmu_ctr_get_fixed_counters_val(env, cidx, true) -
- counter->mhpmcounterh_prev +
- counter->mhpmcounterh_val;
+ mhpmctr_val = mhpmctr_val |
+ ((uint64_t)counter->mhpmcounterh_val << 32);
}
+ riscv_pmu_setup_timer(env, mhpmctr_val, cidx);
+ }
+ } else {
+ curr_count = riscv_pmu_ctr_get_fixed_counters_val(env, cidx,
false);
+
+ mhpmctr_val = counter->mhpmcounter_val;
+ prev_count = counter->mhpmcounter_prev;
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
+ uint64_t tmp =
+ riscv_pmu_ctr_get_fixed_counters_val(env, cidx, true);
+
+ curr_count = curr_count | (tmp << 32);
+ mhpmctr_val = mhpmctr_val |
+ ((uint64_t)counter->mhpmcounterh_val << 32);
+ prev_count = prev_count |
+ ((uint64_t)counter->mhpmcounterh_prev << 32);
+ }
+
+ /* Adjust the counter for later reads. */
+ mhpmctr_val = curr_count - prev_count + mhpmctr_val;
+ counter->mhpmcounter_val = mhpmctr_val;
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
+ counter->mhpmcounterh_val = mhpmctr_val >> 32;
}
}
}
diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c
index ac648cff8d7c..63420d9f3679 100644
--- a/target/riscv/pmu.c
+++ b/target/riscv/pmu.c
@@ -285,8 +285,7 @@ int riscv_pmu_incr_ctr(RISCVCPU *cpu, enum
riscv_pmu_event_idx event_idx)
}
ctr_idx = GPOINTER_TO_UINT(value);
- if (!riscv_pmu_counter_enabled(cpu, ctr_idx) ||
- get_field(env->mcountinhibit, BIT(ctr_idx))) {
+ if (!riscv_pmu_counter_enabled(cpu, ctr_idx)) {
return -1;
}
--
2.34.1
- [PATCH v7 00/11] Add RISC-V ISA extension smcntrpmf support, Atish Patra, 2024/06/26
- [PATCH v7 01/11] target/riscv: Combine set_mode and set_virt functions., Atish Patra, 2024/06/26
- [PATCH v7 02/11] target/riscv: Fix the predicate functions for mhpmeventhX CSRs, Atish Patra, 2024/06/26
- [PATCH v7 04/11] target/riscv: Add cycle & instret privilege mode filtering definitions, Atish Patra, 2024/06/26
- [PATCH v7 05/11] target/riscv: Add cycle & instret privilege mode filtering support, Atish Patra, 2024/06/26
- [PATCH v7 03/11] target/riscv: Add cycle & instret privilege mode filtering properties, Atish Patra, 2024/06/26
- [PATCH v7 07/11] target/riscv: Save counter values during countinhibit update, Atish Patra, 2024/06/26
- [PATCH v7 06/11] target/riscv: Implement privilege mode filtering for cycle/instret, Atish Patra, 2024/06/26
- [PATCH v7 09/11] target/riscv: Start counters from both mhpmcounter and mcountinhibit,
Atish Patra <=
- [PATCH v7 08/11] target/riscv: Enforce WARL behavior for scounteren/hcounteren, Atish Patra, 2024/06/26
- [PATCH v7 10/11] target/riscv: More accurately model priv mode filtering., Atish Patra, 2024/06/26
- [PATCH v7 11/11] target/riscv: Do not setup pmu timer if OF is disabled, Atish Patra, 2024/06/26