Skip to content

Commit

Permalink
Merge pull request #1350 from rivosinc/etrigger_fix_exception_match
Browse files Browse the repository at this point in the history
triggers: Fix etrigger match on exceptions
  • Loading branch information
aswaterman committed May 24, 2023
2 parents 23bc4cd + d9e30bb commit fa79c20
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 22 deletions.
26 changes: 13 additions & 13 deletions riscv/processor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,8 @@ void state_t::reset(processor_t* const proc, reg_t max_isa)
// mstatus_csr_t::unlogged_write()):
auto xlen = proc->get_isa().get_max_xlen();

prv = PRV_M;
v = false;
prv = prev_prv = PRV_M;
v = prev_v = false;
csrmap[CSR_MISA] = misa = std::make_shared<misa_csr_t>(proc, CSR_MISA, max_isa);
mstatus = std::make_shared<mstatus_csr_t>(proc, CSR_MSTATUS);

Expand Down Expand Up @@ -717,6 +717,7 @@ reg_t processor_t::legalize_privilege(reg_t prv)
void processor_t::set_privilege(reg_t prv)
{
mmu->flush_tlb();
state.prev_prv = state.prv;
state.prv = legalize_privilege(prv);
}

Expand Down Expand Up @@ -747,17 +748,16 @@ void processor_t::set_virt(bool virt)
if (state.prv == PRV_M)
return;

if (state.v != virt) {
/*
* Ideally, we should flush TLB here but we don't need it because
* set_virt() is always used in conjucter with set_privilege() and
* set_privilege() will flush TLB unconditionally.
*
* The virtualized sstatus register also relies on this TLB flush,
* since changing V might change sstatus.MXR and sstatus.SUM.
*/
state.v = virt;
}
/*
* Ideally, we should flush TLB here but we don't need it because
* set_virt() is always used in conjucter with set_privilege() and
* set_privilege() will flush TLB unconditionally.
*
* The virtualized sstatus register also relies on this TLB flush,
* since changing V might change sstatus.MXR and sstatus.SUM.
*/
state.prev_v = state.v;
state.v = virt;
}

void processor_t::enter_debug_mode(uint8_t cause)
Expand Down
2 changes: 2 additions & 0 deletions riscv/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@ struct state_t
// control and status registers
std::unordered_map<reg_t, csr_t_p> csrmap;
reg_t prv; // TODO: Can this be an enum instead?
reg_t prev_prv;
bool v;
bool prev_v;
misa_csr_t_p misa;
mstatus_csr_t_p mstatus;
csr_t_p mstatush;
Expand Down
18 changes: 11 additions & 7 deletions riscv/triggers.cc
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,19 @@ void trigger_t::tdata3_write(processor_t * const proc, const reg_t val) noexcept
sselect = (sselect_t)((proc->extension_enabled_const('S') && get_field(val, CSR_TEXTRA_SSELECT(xlen)) <= SSELECT_MAXVAL) ? get_field(val, CSR_TEXTRA_SSELECT(xlen)) : SSELECT_IGNORE);
}

bool trigger_t::common_match(processor_t * const proc) const noexcept {
return mode_match(proc->get_state()) && textra_match(proc);
bool trigger_t::common_match(processor_t * const proc, bool use_prev_prv) const noexcept {
auto state = proc->get_state();
auto prv = use_prev_prv ? state->prev_prv : state->prv;
auto v = use_prev_prv ? state->prev_v : state->v;
return mode_match(prv, v) && textra_match(proc);
}

bool trigger_t::mode_match(state_t * const state) const noexcept
bool trigger_t::mode_match(reg_t prv, bool v) const noexcept
{
switch (state->prv) {
switch (prv) {
case PRV_M: return m;
case PRV_S: return state->v ? vs : s;
case PRV_U: return state->v ? vu : u;
case PRV_S: return v ? vs : s;
case PRV_U: return v ? vu : u;
default: assert(false);
}
}
Expand Down Expand Up @@ -397,7 +400,8 @@ void itrigger_t::tdata1_write(processor_t * const proc, const reg_t val, const b

std::optional<match_result_t> trap_common_t::detect_trap_match(processor_t * const proc, const trap_t& t) noexcept
{
if (!common_match(proc))
// Use the previous privilege for matching
if (!common_match(proc, true))
return std::nullopt;

auto xlen = proc->get_xlen();
Expand Down
4 changes: 2 additions & 2 deletions riscv/triggers.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class trigger_t {

protected:
static action_t legalize_action(reg_t val, reg_t action_mask, reg_t dmode_mask) noexcept;
bool common_match(processor_t * const proc) const noexcept;
bool common_match(processor_t * const proc, bool use_prev_prv = false) const noexcept;
bool allow_action(const state_t * const state) const;
reg_t tdata2;

Expand All @@ -102,7 +102,7 @@ class trigger_t {

private:
unsigned legalize_mhselect(bool h_enabled) const noexcept;
bool mode_match(state_t * const state) const noexcept;
bool mode_match(reg_t prv, bool v) const noexcept;
bool textra_match(processor_t * const proc) const noexcept;

struct mhselect_interpretation {
Expand Down

0 comments on commit fa79c20

Please sign in to comment.