Decode itrigger privilege enables directly from the mode bits and only advertise itrigger activity while an instruction-count trigger still has a non-zero count.
This removes a looser check in the debug helper paths and keeps the exposed itrigger state aligned with the conditions under which the trigger can actually fire. Signed-off-by: Chao Liu <[email protected]> --- target/riscv/debug.c | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/target/riscv/debug.c b/target/riscv/debug.c index 00fd75f15f..f3d6eaeb1e 100644 --- a/target/riscv/debug.c +++ b/target/riscv/debug.c @@ -795,30 +795,37 @@ itrigger_set_count(CPURISCVState *env, int index, int value) static bool check_itrigger_priv(CPURISCVState *env, int index) { target_ulong tdata1 = env->tdata1[index]; + if (env->virt_enabled) { - /* check VU/VS bit against current privilege level */ - return (get_field(tdata1, ITRIGGER_VS) == env->priv) || - (get_field(tdata1, ITRIGGER_VU) == env->priv); - } else { - /* check U/S/M bit against current privilege level */ - return (get_field(tdata1, ITRIGGER_M) == env->priv) || - (get_field(tdata1, ITRIGGER_S) == env->priv) || - (get_field(tdata1, ITRIGGER_U) == env->priv); + switch (env->priv) { + case PRV_S: + return !!(tdata1 & ITRIGGER_VS); + case PRV_U: + return !!(tdata1 & ITRIGGER_VU); + default: + return false; + } + } + + switch (env->priv) { + case PRV_M: + return !!(tdata1 & ITRIGGER_M); + case PRV_S: + return !!(tdata1 & ITRIGGER_S); + case PRV_U: + return !!(tdata1 & ITRIGGER_U); + default: + return false; } } bool riscv_itrigger_enabled(CPURISCVState *env) { - int count; for (int i = 0; i < RV_MAX_TRIGGERS; i++) { if (get_trigger_type(env, i) != TRIGGER_TYPE_INST_CNT) { continue; } - if (check_itrigger_priv(env, i)) { - continue; - } - count = itrigger_get_count(env, i); - if (!count) { + if (!itrigger_get_count(env, i)) { continue; } return true; -- 2.53.0
