49
}
50
}
51
52
+static bool riscv_pmu_counter_filtered(CPURISCVState *env, uint64_t cfg)
53
+{
54
+ bool virt_on = env->virt_enabled;
55
+
56
+ return (env->priv == PRV_M && (cfg & MHPMEVENT_BIT_MINH)) ||
57
+ (env->priv == PRV_S && virt_on &&
58
+ (cfg & MHPMEVENT_BIT_VSINH)) ||
59
+ (env->priv == PRV_U && virt_on &&
60
+ (cfg & MHPMEVENT_BIT_VUINH)) ||
61
+ (env->priv == PRV_S && !virt_on &&
62
+ (cfg & MHPMEVENT_BIT_SINH)) ||
63
+ (env->priv == PRV_U && !virt_on &&
64
+ (cfg & MHPMEVENT_BIT_UINH));
65
+}
66
+
67
/*
68
* Information needed to update counters:
69
* new_priv, new_virt: To correctly save starting snapshot for the newly
162
riscv_pmu_icount_update_priv(env, newpriv, new_virt);
163
}
164
165
+void riscv_pmu_decr_instret(CPURISCVState *env)
166
+{
167
+ if (!icount_enabled() ||
168
+ (env->mcountinhibit & COUNTEREN_IR) ||
169
+ riscv_pmu_counter_filtered(env, env->minstretcfg)) {
170
+ return;
171
+ }
172
+
173
+ /*
174
+ * minstret is derived from icount, which includes the current
175
+ * instruction. Move the baseline forward to exclude an instruction
176
+ * that raises an exception and therefore does not retire.
177
+ */
178
+ env->pmu_ctrs[2].mhpmcounter_prev++;
179
+}
180
+
181
int riscv_pmu_incr_ctr(RISCVCPU *cpu, enum riscv_pmu_event_idx event_idx)
182
{
183
uint32_t ctr_idx;
184
CPURISCVState *env = &cpu->env;
185
uint64_t max_val = UINT64_MAX;
155
- bool virt_on = env->virt_enabled;
186
PMUCTRState *counter;
187
gpointer value;
188
200
return -1;
201
}
202
173
- /* Privilege mode filtering */
174
- if ((env->priv == PRV_M &&
175
- (env->mhpmevent_val[ctr_idx] & MHPMEVENT_BIT_MINH)) ||
176
- (env->priv == PRV_S && virt_on &&
177
- (env->mhpmevent_val[ctr_idx] & MHPMEVENT_BIT_VSINH)) ||
178
- (env->priv == PRV_U && virt_on &&
179
- (env->mhpmevent_val[ctr_idx] & MHPMEVENT_BIT_VUINH)) ||
180
- (env->priv == PRV_S && !virt_on &&
181
- (env->mhpmevent_val[ctr_idx] & MHPMEVENT_BIT_SINH)) ||
182
- (env->priv == PRV_U && !virt_on &&
183
- (env->mhpmevent_val[ctr_idx] & MHPMEVENT_BIT_UINH))) {
203
+ if (riscv_pmu_counter_filtered(env, env->mhpmevent_val[ctr_idx])) {
204
return 0;
205
}
206