The check_itrigger_priv() did not check privilege bits properly. Move all priv checks into functions and have the icount check follow the same form as the others.
Signed-off-by: Nicholas Piggin <[email protected]> --- target/riscv/debug.c | 82 ++++++++++++++++++++------------------------ 1 file changed, 37 insertions(+), 45 deletions(-) diff --git a/target/riscv/debug.c b/target/riscv/debug.c index c92bd9860e..2effbb49af 100644 --- a/target/riscv/debug.c +++ b/target/riscv/debug.c @@ -306,48 +306,50 @@ static void do_trigger_action(CPURISCVState *env, target_ulong trigger_index) * Check the privilege level of specific trigger matches CPU's current privilege * level. */ +static bool type2_priv_match(CPURISCVState *env, target_ulong tdata1) +{ + /* type 2 trigger cannot be fired in VU/VS mode */ + if (env->virt_enabled) { + return false; + } + /* check U/S/M bit against current privilege level */ + return (((tdata1 >> 3) & 0b1011) & BIT(env->priv)); +} + +static bool type6_priv_match(CPURISCVState *env, target_ulong tdata1) +{ + if (env->virt_enabled) { + /* check VU/VS bit against current privilege level */ + return (((tdata1 >> 23) & 0b11) & BIT(env->priv)); + } else { + /* check U/S/M bit against current privilege level */ + return (((tdata1 >> 3) & 0b1011) & BIT(env->priv)); + } +} + +static bool icount_priv_match(CPURISCVState *env, target_ulong tdata1) +{ + if (env->virt_enabled) { + /* check VU/VS bit against current privilege level */ + return (((tdata1 >> 25) & 0b11) & BIT(env->priv)); + } else { + /* check U/S/M bit against current privilege level */ + return (((tdata1 >> 6) & 0b1011) & BIT(env->priv)); + } +} + static bool trigger_priv_match(CPURISCVState *env, trigger_type_t type, int trigger_index) { - target_ulong ctrl = env->tdata1[trigger_index]; + target_ulong tdata1 = env->tdata1[trigger_index]; switch (type) { case TRIGGER_TYPE_AD_MATCH: - /* type 2 trigger cannot be fired in VU/VS mode */ - if (env->virt_enabled) { - return false; - } - /* check U/S/M bit against current privilege level */ - if ((ctrl >> 3) & BIT(env->priv)) { - return true; - } - break; + return type2_priv_match(env, tdata1); case TRIGGER_TYPE_AD_MATCH6: - if (env->virt_enabled) { - /* check VU/VS bit against current privilege level */ - if ((ctrl >> 23) & BIT(env->priv)) { - return true; - } - } else { - /* check U/S/M bit against current privilege level */ - if ((ctrl >> 3) & BIT(env->priv)) { - return true; - } - } - break; + return type6_priv_match(env, tdata1); case TRIGGER_TYPE_INST_CNT: - if (env->virt_enabled) { - /* check VU/VS bit against current privilege level */ - if ((ctrl >> 25) & BIT(env->priv)) { - return true; - } - } else { - /* check U/S/M bit against current privilege level */ - if ((ctrl >> 6) & BIT(env->priv)) { - return true; - } - } - break; + return icount_priv_match(env, tdata1); case TRIGGER_TYPE_INT: case TRIGGER_TYPE_EXCP: case TRIGGER_TYPE_EXT_SRC: @@ -665,17 +667,7 @@ 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); - } + return icount_priv_match(env, index); } bool riscv_itrigger_enabled(CPURISCVState *env) -- 2.51.0
