Skip to content

Commit 451a7dc

Browse files
committed
triggers: Move allow_action() into common_match()
They are always called together, and now we get the previous privilege behavior in both.
1 parent 4abd669 commit 451a7dc

File tree

2 files changed

+28
-23
lines changed

2 files changed

+28
-23
lines changed

riscv/triggers.cc

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,30 @@ 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);
70-
return (prv < PRV_M || m_enabled) && mode_match(prv, v) && textra_match(proc);
69+
70+
if (!mode_match(prv, v))
71+
return false;
72+
73+
if (!textra_match(proc))
74+
return false;
75+
76+
if (get_action() == ACTION_DEBUG_EXCEPTION) {
77+
const bool mstatus_mie = state->mstatus->read() & MSTATUS_MIE;
78+
if (prv == PRV_M && !mstatus_mie)
79+
return false;
80+
81+
const bool sstatus_sie = state->sstatus->read() & MSTATUS_SIE;
82+
const bool medeleg_breakpoint = (state->medeleg->read() >> CAUSE_BREAKPOINT) & 1;
83+
if (prv == PRV_S && !v && medeleg_breakpoint && !sstatus_sie)
84+
return false;
85+
86+
const bool vsstatus_sie = state->vsstatus->read() & MSTATUS_SIE;
87+
const bool hedeleg_breakpoint = (state->hedeleg->read() >> CAUSE_BREAKPOINT) & 1;
88+
if (prv == PRV_S && v && medeleg_breakpoint && hedeleg_breakpoint && !vsstatus_sie)
89+
return false;
90+
}
91+
92+
return true;
7193
}
7294

7395
bool trigger_t::mode_match(reg_t prv, bool v) const noexcept
@@ -117,22 +139,6 @@ bool trigger_t::textra_match(processor_t * const proc) const noexcept
117139
return true;
118140
}
119141

120-
bool trigger_t::allow_action(processor_t * const proc) const
121-
{
122-
const state_t *state = proc->get_state();
123-
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);
132-
}
133-
return true;
134-
}
135-
136142
reg_t disabled_trigger_t::tdata1_read(const processor_t * const proc) const noexcept
137143
{
138144
auto xlen = proc->get_xlen();
@@ -243,7 +249,7 @@ std::optional<match_result_t> mcontrol_common_t::detect_memory_access_match(proc
243249
value &= 0xffffffff;
244250
}
245251

246-
if (simple_match(xlen, value) && allow_action(proc)) {
252+
if (simple_match(xlen, value)) {
247253
/* This is OK because this function is only called if the trigger was not
248254
* inhibited by the previous trigger in the chain. */
249255
set_hit(timing ? HIT_IMMEDIATELY_AFTER : HIT_BEFORE);
@@ -332,7 +338,7 @@ void mcontrol6_t::tdata1_write(processor_t * const proc, const reg_t val, const
332338

333339
std::optional<match_result_t> icount_t::detect_icount_fire(processor_t * const proc) noexcept
334340
{
335-
if (!common_match(proc) || !allow_action(proc))
341+
if (!common_match(proc))
336342
return std::nullopt;
337343

338344
std::optional<match_result_t> ret = std::nullopt;
@@ -347,7 +353,7 @@ std::optional<match_result_t> icount_t::detect_icount_fire(processor_t * const p
347353

348354
void icount_t::detect_icount_decrement(processor_t * const proc) noexcept
349355
{
350-
if (!common_match(proc) || !allow_action(proc))
356+
if (!common_match(proc))
351357
return;
352358

353359
if (count >= 1) {
@@ -439,7 +445,7 @@ std::optional<match_result_t> trap_common_t::detect_trap_match(processor_t * con
439445
bool interrupt = (t.cause() & ((reg_t)1 << (xlen - 1))) != 0;
440446
reg_t bit = t.cause() & ~((reg_t)1 << (xlen - 1));
441447
assert(bit < xlen);
442-
if (simple_match(interrupt, bit) && allow_action(proc)) {
448+
if (simple_match(interrupt, bit)) {
443449
hit = true;
444450
return match_result_t(TIMING_AFTER, action);
445451
}

riscv/triggers.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,6 @@ class trigger_t {
9999
protected:
100100
static action_t legalize_action(reg_t val, reg_t action_mask, reg_t dmode_mask) noexcept;
101101
bool common_match(processor_t * const proc, bool use_prev_prv = false) const noexcept;
102-
bool allow_action(processor_t * const proc) const;
103102
reg_t tdata2;
104103

105104
bool vs = false;

0 commit comments

Comments
 (0)