@@ -66,7 +66,12 @@ bool trigger_t::common_match(processor_t * const proc, bool use_prev_prv) const
6666 auto state = proc->get_state ();
6767 auto prv = use_prev_prv ? state->prev_prv : state->prv ;
6868 auto v = use_prev_prv ? state->prev_v : state->v ;
69- auto m_enabled = get_action () != 0 || (tcontrol_value (state) & CSR_TCONTROL_MTE);
69+ bool m_enabled = get_action () != 0 ;
70+ if (!m_enabled && proc->extension_enabled (' S' )) {
71+ m_enabled |= tcontrol_value (state) & CSR_TCONTROL_MTE;
72+ } else {
73+ m_enabled |= state->mstatus ->read () & MSTATUS_MIE;
74+ }
7075 return (prv < PRV_M || m_enabled) && mode_match (prv, v) && textra_match (proc);
7176}
7277
@@ -121,14 +126,25 @@ bool trigger_t::allow_action(processor_t * const proc) const
121126{
122127 const state_t *state = proc->get_state ();
123128 if (get_action () == ACTION_DEBUG_EXCEPTION) {
124- const bool mstatus_mie = state->mstatus ->read () & MSTATUS_MIE;
125- const bool sstatus_sie = state->sstatus ->read () & MSTATUS_SIE;
126- const bool vsstatus_sie = state->vsstatus ->read () & MSTATUS_SIE;
127- const bool medeleg_breakpoint = (state->medeleg ->read () >> CAUSE_BREAKPOINT) & 1 ;
128- const bool hedeleg_breakpoint = (state->hedeleg ->read () >> CAUSE_BREAKPOINT) & 1 ;
129- return (state->prv != PRV_M || mstatus_mie) &&
130- (state->prv != PRV_S || state->v || !medeleg_breakpoint || sstatus_sie) &&
131- (state->prv != PRV_S || !state->v || !medeleg_breakpoint || !hedeleg_breakpoint || vsstatus_sie);
129+ if (proc->extension_enabled (' S' )) {
130+ // The hardware prevents triggers with action=0 from matching or firing
131+ // while in M-mode and while MIE in mstatus is 0. If medeleg [3]=1 then it
132+ // prevents triggers with action=0 from matching or firing while in S-mode
133+ // and while SIE in sstatus is 0. If medeleg [3]=1 and hedeleg [3]=1 then
134+ // it prevents triggers with action=0 from matching or firing while in
135+ // VS-mode and while SIE in vstatus is 0.
136+ const bool mstatus_mie = state->mstatus ->read () & MSTATUS_MIE;
137+ const bool sstatus_sie = state->sstatus ->read () & MSTATUS_SIE;
138+ const bool vsstatus_sie = state->vsstatus ->read () & MSTATUS_SIE;
139+ const bool medeleg_breakpoint = (state->medeleg ->read () >> CAUSE_BREAKPOINT) & 1 ;
140+ const bool hedeleg_breakpoint = (state->hedeleg ->read () >> CAUSE_BREAKPOINT) & 1 ;
141+ return (state->prv != PRV_M || mstatus_mie) &&
142+ (state->prv != PRV_S || state->v || !medeleg_breakpoint || sstatus_sie) &&
143+ (state->prv != PRV_S || !state->v || !medeleg_breakpoint || !hedeleg_breakpoint || vsstatus_sie);
144+ } else {
145+ // mte and mpte in tcontrol is implemented. medeleg [3] is hard-wired to 0.
146+ return (state->prv != PRV_M) || (tcontrol_value (state) & CSR_TCONTROL_MTE);
147+ }
132148 }
133149 return true ;
134150}
0 commit comments