Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion arch/riscv/op_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,10 @@ static inline target_ulong get_counter_enabled_mask(CPUState *env)
case PRV_S:
return env->mcounteren;
case PRV_U:
return riscv_has_ext(env, RISCV_FEATURE_RVS) ? env->scounteren : env->mcounteren;
if(riscv_has_ext(env, RISCV_FEATURE_RVS)) {
return env->mcounteren & env->scounteren;
}
return env->mcounteren;
default:
tlib_abortf("Invalid privilege level: %d", env->priv);
return 0;
Expand Down Expand Up @@ -187,11 +190,17 @@ void helper_raise_illegal_instruction(CPUState *env)

static inline uint64_t get_minstret_current(CPUState *env)
{
if(env->privilege_architecture >= RISCV_PRIV1_11 && (env->mcountinhibit & 0x4)) {
return env->minstret_snapshot_offset > 0 ? env->minstret_snapshot_offset - 1 : 0;
}
return cpu_riscv_read_instret(env) - env->minstret_snapshot + env->minstret_snapshot_offset;
}

static inline uint64_t get_mcycles_current(CPUState *env)
{
if(env->privilege_architecture >= RISCV_PRIV1_11 && (env->mcountinhibit & 0x1)) {
return env->mcycle_snapshot_offset > 0 ? env->mcycle_snapshot_offset - 1 : 0;
}
uint64_t instructions = cpu_riscv_read_instret(env) - env->mcycle_snapshot + env->mcycle_snapshot_offset;
return instructions_to_cycles(env, instructions);
}
Expand Down Expand Up @@ -516,7 +525,16 @@ inline void csr_write_helper(CPUState *env, target_ulong val_to_write, target_ul
if(env->privilege_architecture == RISCV_PRIV1_09) {
env->mucounteren = val_to_write;
} else if(env->privilege_architecture >= RISCV_PRIV1_11) {
uint64_t current_mcycle = get_mcycles_current(env);
uint64_t current_minstret = get_minstret_current(env);
uint64_t current_instret = cpu_riscv_read_instret(env);

env->mcountinhibit = val_to_write;

env->mcycle_snapshot_offset = current_mcycle;
env->mcycle_snapshot = current_instret;
env->minstret_snapshot_offset = current_minstret;
env->minstret_snapshot = current_instret;
}
break;
case CSR_MSCOUNTEREN:
Expand Down