aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAtul Khare <atulkhare@rivosinc.com>2023-05-16 15:11:44 -0700
committerAtul Khare <atulkhare@rivosinc.com>2023-05-17 13:04:14 -0700
commit7a2ff14bff461f2c7adfbf407e11527f55d920db (patch)
tree27100973d65ac99e8d76b20413c513156cef455c
parentbb631e660fcb5ad4836b1f7c33db5c0a903272c1 (diff)
downloadriscv-isa-sim-7a2ff14bff461f2c7adfbf407e11527f55d920db.zip
riscv-isa-sim-7a2ff14bff461f2c7adfbf407e11527f55d920db.tar.gz
riscv-isa-sim-7a2ff14bff461f2c7adfbf407e11527f55d920db.tar.bz2
triggers: Fix etrigger match on exceptions
The etrigger match on exceptions doesn't work properly in cases like the following: 1) M-mode delegates ECALLs to S-mode 2) A CPU hardware point mechanism is used to place a breakpoint on the Umode instruction that executes the ECALL from Umode to Smode. In effect, this creates a breakpoint etrigger based on Umode. In the above, the expectation is that #2 will first cause an exit to the Smode handler (stvec), and the hardware breakpoint exception will be triggered following an entry into the handler. However, since etrigger currently checks the current privilege mode, we will never get a match on conditions like #2. The patch attempts to address the issue by using the stashed version of the previous privilege mode for the etrigger match. cc: YenHaoChen <howard25336284@gmail.com> Signed-off-by: Atul Khare <atulkhare@rivosinc.com>
-rw-r--r--riscv/triggers.cc9
-rw-r--r--riscv/triggers.h2
2 files changed, 7 insertions, 4 deletions
diff --git a/riscv/triggers.cc b/riscv/triggers.cc
index 51dcf18..bb2a815 100644
--- a/riscv/triggers.cc
+++ b/riscv/triggers.cc
@@ -55,9 +55,11 @@ 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 {
+bool trigger_t::common_match(processor_t * const proc, bool use_last_inst_priv) const noexcept {
auto state = proc->get_state();
- return mode_match(state->prv, state->v) && textra_match(proc);
+ auto prv = use_last_inst_priv ? state->last_inst_priv : state->prv;
+ auto v = use_last_inst_priv ? state->last_v : state->v;
+ return mode_match(prv, v) && textra_match(proc);
}
bool trigger_t::mode_match(reg_t prv, bool v) const noexcept
@@ -398,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();
diff --git a/riscv/triggers.h b/riscv/triggers.h
index 94e7e5c..c3cbc65 100644
--- a/riscv/triggers.h
+++ b/riscv/triggers.h
@@ -90,7 +90,7 @@ public:
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_last_inst_priv = false) const noexcept;
bool allow_action(const state_t * const state) const;
reg_t tdata2;