@@ -110,17 +110,29 @@ bool trigger_t::textra_match(processor_t * const proc) const noexcept
110
110
return true ;
111
111
}
112
112
113
- bool trigger_t::allow_action (const state_t * const state ) const
113
+ bool trigger_t::allow_action (processor_t * const proc ) const
114
114
{
115
+ const state_t *state = proc->get_state ();
115
116
if (get_action () == ACTION_DEBUG_EXCEPTION) {
116
- const bool mstatus_mie = state->mstatus ->read () & MSTATUS_MIE;
117
- const bool sstatus_sie = state->sstatus ->read () & MSTATUS_SIE;
118
- const bool vsstatus_sie = state->vsstatus ->read () & MSTATUS_SIE;
119
- const bool medeleg_breakpoint = (state->medeleg ->read () >> CAUSE_BREAKPOINT) & 1 ;
120
- const bool hedeleg_breakpoint = (state->hedeleg ->read () >> CAUSE_BREAKPOINT) & 1 ;
121
- return (state->prv != PRV_M || mstatus_mie) &&
122
- (state->prv != PRV_S || state->v || !medeleg_breakpoint || sstatus_sie) &&
123
- (state->prv != PRV_S || !state->v || !medeleg_breakpoint || !hedeleg_breakpoint || vsstatus_sie);
117
+ if (proc->extension_enabled (' S' )) {
118
+ // The hardware prevents triggers with action=0 from matching or firing
119
+ // while in M-mode and while MIE in mstatus is 0. If medeleg [3]=1 then it
120
+ // prevents triggers with action=0 from matching or firing while in S-mode
121
+ // and while SIE in sstatus is 0. If medeleg [3]=1 and hedeleg [3]=1 then
122
+ // it prevents triggers with action=0 from matching or firing while in
123
+ // VS-mode and while SIE in vstatus is 0.
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);
132
+ } else {
133
+ // mte and mpte in tcontrol is implemented. medeleg [3] is hard-wired to 0.
134
+ return (state->prv != PRV_M) || (state->tcontrol ->read () & CSR_TCONTROL_MTE);
135
+ }
124
136
}
125
137
return true ;
126
138
}
@@ -235,7 +247,7 @@ std::optional<match_result_t> mcontrol_common_t::detect_memory_access_match(proc
235
247
value &= 0xffffffff ;
236
248
}
237
249
238
- if (simple_match (xlen, value) && allow_action (proc-> get_state () )) {
250
+ if (simple_match (xlen, value) && allow_action (proc)) {
239
251
/* This is OK because this function is only called if the trigger was not
240
252
* inhibited by the previous trigger in the chain. */
241
253
set_hit (timing ? HIT_IMMEDIATELY_AFTER : HIT_BEFORE);
@@ -324,7 +336,7 @@ void mcontrol6_t::tdata1_write(processor_t * const proc, const reg_t val, const
324
336
325
337
std::optional<match_result_t > icount_t::detect_icount_fire (processor_t * const proc) noexcept
326
338
{
327
- if (!common_match (proc) || !allow_action (proc-> get_state () ))
339
+ if (!common_match (proc) || !allow_action (proc))
328
340
return std::nullopt;
329
341
330
342
std::optional<match_result_t > ret = std::nullopt;
@@ -339,7 +351,7 @@ std::optional<match_result_t> icount_t::detect_icount_fire(processor_t * const p
339
351
340
352
void icount_t::detect_icount_decrement (processor_t * const proc) noexcept
341
353
{
342
- if (!common_match (proc) || !allow_action (proc-> get_state () ))
354
+ if (!common_match (proc) || !allow_action (proc))
343
355
return ;
344
356
345
357
if (count >= 1 ) {
@@ -431,7 +443,7 @@ std::optional<match_result_t> trap_common_t::detect_trap_match(processor_t * con
431
443
bool interrupt = (t.cause () & ((reg_t )1 << (xlen - 1 ))) != 0 ;
432
444
reg_t bit = t.cause () & ~((reg_t )1 << (xlen - 1 ));
433
445
assert (bit < xlen);
434
- if (simple_match (interrupt, bit) && allow_action (proc-> get_state () )) {
446
+ if (simple_match (interrupt, bit) && allow_action (proc)) {
435
447
hit = true ;
436
448
return match_result_t (TIMING_AFTER, action);
437
449
}
0 commit comments