aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Johnson <scott.johnson@arilinc.com>2023-01-13 11:38:43 -0800
committerGitHub <noreply@github.com>2023-01-13 11:38:43 -0800
commit23718cb9b1ef2447b765e0b8cafb2ad15b469135 (patch)
treef23c53da3cc6d794172e0b39aebc4f610c0dbafe
parent35e229ccfa08d4858f286f1354c8f6abc0f25812 (diff)
parente3efb15eca0b020ecc0c6db4e5c6ad48501a8708 (diff)
downloadspike-23718cb9b1ef2447b765e0b8cafb2ad15b469135.zip
spike-23718cb9b1ef2447b765e0b8cafb2ad15b469135.tar.gz
spike-23718cb9b1ef2447b765e0b8cafb2ad15b469135.tar.bz2
Merge pull request #1214 from YenHaoChen/pr-legalize-timing
Add legalize_timing() for tdata1.timing
-rw-r--r--riscv/triggers.cc33
-rw-r--r--riscv/triggers.h5
2 files changed, 22 insertions, 16 deletions
diff --git a/riscv/triggers.cc b/riscv/triggers.cc
index f451f05..64de725 100644
--- a/riscv/triggers.cc
+++ b/riscv/triggers.cc
@@ -25,8 +25,9 @@ void trigger_t::tdata2_write(processor_t UNUSED * const proc, const reg_t UNUSED
tdata2 = val;
}
-action_t trigger_t::legalize_action(reg_t val) const noexcept {
- return (val > ACTION_MAXVAL || (val == ACTION_DEBUG_MODE && get_dmode() == 0)) ? ACTION_DEBUG_EXCEPTION : (action_t)val;
+action_t trigger_t::legalize_action(reg_t val, reg_t action_mask, reg_t dmode_mask) noexcept {
+ reg_t act = get_field(val, action_mask);
+ return (act > ACTION_MAXVAL || (act == ACTION_DEBUG_MODE && get_field(val, dmode_mask) == 0)) ? ACTION_DEBUG_EXCEPTION : (action_t)act;
}
unsigned trigger_t::legalize_mhselect(bool h_enabled) const noexcept {
@@ -148,8 +149,8 @@ void mcontrol_t::tdata1_write(processor_t * const proc, const reg_t val, const b
dmode = get_field(val, CSR_MCONTROL_DMODE(xlen));
hit = get_field(val, CSR_MCONTROL_HIT);
select = get_field(val, MCONTROL_SELECT);
- timing = get_field(val, MCONTROL_TIMING);
- action = legalize_action(get_field(val, MCONTROL_ACTION));
+ timing = legalize_timing(val, MCONTROL_TIMING, MCONTROL_SELECT, MCONTROL_EXECUTE, MCONTROL_LOAD);
+ action = legalize_action(val, MCONTROL_ACTION, CSR_MCONTROL_DMODE(xlen));
chain = allow_chain ? get_field(val, MCONTROL_CHAIN) : 0;
match = legalize_match(get_field(val, MCONTROL_MATCH));
m = get_field(val, MCONTROL_M);
@@ -158,9 +159,6 @@ void mcontrol_t::tdata1_write(processor_t * const proc, const reg_t val, const b
execute = get_field(val, MCONTROL_EXECUTE);
store = get_field(val, MCONTROL_STORE);
load = get_field(val, MCONTROL_LOAD);
- // Assume we're here because of csrw.
- if (execute)
- timing = 0;
}
bool mcontrol_common_t::simple_match(unsigned xlen, reg_t value) const {
@@ -223,7 +221,7 @@ std::optional<match_result_t> mcontrol_common_t::detect_memory_access_match(proc
return std::nullopt;
}
-mcontrol_common_t::match_t mcontrol_common_t::legalize_match(reg_t val) const noexcept
+mcontrol_common_t::match_t mcontrol_common_t::legalize_match(reg_t val) noexcept
{
switch (val) {
case MATCH_EQUAL:
@@ -238,6 +236,15 @@ mcontrol_common_t::match_t mcontrol_common_t::legalize_match(reg_t val) const no
}
}
+bool mcontrol_common_t::legalize_timing(reg_t val, reg_t timing_mask, reg_t select_mask, reg_t execute_mask, reg_t load_mask) noexcept {
+ // For load data triggers, force timing=after to avoid debugger having to repeat loads which may have side effects.
+ if (get_field(val, select_mask) && get_field(val, load_mask))
+ return TIMING_AFTER;
+ if (get_field(val, execute_mask))
+ return TIMING_BEFORE;
+ return get_field(val, timing_mask);
+}
+
reg_t mcontrol6_t::tdata1_read(const processor_t * const proc) const noexcept {
unsigned xlen = proc->get_const_xlen();
reg_t tdata1 = 0;
@@ -268,8 +275,8 @@ void mcontrol6_t::tdata1_write(processor_t * const proc, const reg_t val, const
vu = get_field(val, CSR_MCONTROL6_VU);
hit = get_field(val, CSR_MCONTROL6_HIT);
select = get_field(val, CSR_MCONTROL6_SELECT);
- timing = get_field(val, CSR_MCONTROL6_TIMING);
- action = legalize_action(get_field(val, CSR_MCONTROL6_ACTION));
+ timing = legalize_timing(val, CSR_MCONTROL6_TIMING, CSR_MCONTROL6_SELECT, CSR_MCONTROL6_EXECUTE, CSR_MCONTROL6_LOAD);
+ action = legalize_action(val, CSR_MCONTROL6_ACTION, CSR_MCONTROL6_DMODE(xlen));
chain = allow_chain ? get_field(val, CSR_MCONTROL6_CHAIN) : 0;
match = legalize_match(get_field(val, CSR_MCONTROL6_MATCH));
m = get_field(val, CSR_MCONTROL6_M);
@@ -278,8 +285,6 @@ void mcontrol6_t::tdata1_write(processor_t * const proc, const reg_t val, const
execute = get_field(val, CSR_MCONTROL6_EXECUTE);
store = get_field(val, CSR_MCONTROL6_STORE);
load = get_field(val, CSR_MCONTROL6_LOAD);
- if (execute)
- timing = 0;
}
reg_t itrigger_t::tdata1_read(const processor_t * const proc) const noexcept
@@ -311,7 +316,7 @@ void itrigger_t::tdata1_write(processor_t * const proc, const reg_t val, const b
m = get_field(val, CSR_ITRIGGER_M);
s = proc->extension_enabled_const('S') ? get_field(val, CSR_ITRIGGER_S) : 0;
u = proc->extension_enabled_const('U') ? get_field(val, CSR_ITRIGGER_U) : 0;
- action = legalize_action(get_field(val, CSR_ITRIGGER_ACTION));
+ action = legalize_action(val, CSR_ITRIGGER_ACTION, CSR_ITRIGGER_DMODE(xlen));
}
std::optional<match_result_t> trap_common_t::detect_trap_match(processor_t * const proc, const trap_t& t) noexcept
@@ -362,7 +367,7 @@ void etrigger_t::tdata1_write(processor_t * const proc, const reg_t val, const b
m = get_field(val, CSR_ETRIGGER_M);
s = proc->extension_enabled_const('S') ? get_field(val, CSR_ETRIGGER_S) : 0;
u = proc->extension_enabled_const('U') ? get_field(val, CSR_ETRIGGER_U) : 0;
- action = legalize_action(get_field(val, CSR_ETRIGGER_ACTION));
+ action = legalize_action(val, CSR_ETRIGGER_ACTION, CSR_ETRIGGER_DMODE(xlen));
}
bool etrigger_t::simple_match(bool interrupt, reg_t bit) const
diff --git a/riscv/triggers.h b/riscv/triggers.h
index 31c5b30..bc64c4d 100644
--- a/riscv/triggers.h
+++ b/riscv/triggers.h
@@ -85,7 +85,7 @@ public:
virtual std::optional<match_result_t> detect_trap_match(processor_t UNUSED * const proc, const trap_t UNUSED & t) noexcept { return std::nullopt; }
protected:
- action_t legalize_action(reg_t val) const noexcept;
+ 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;
reg_t tdata2;
@@ -207,7 +207,8 @@ private:
bool simple_match(unsigned xlen, reg_t value) const;
protected:
- match_t legalize_match(reg_t val) const noexcept;
+ static match_t legalize_match(reg_t val) noexcept;
+ static bool legalize_timing(reg_t val, reg_t timing_mask, reg_t select_mask, reg_t execute_mask, reg_t load_mask) noexcept;
bool dmode = false;
action_t action = ACTION_DEBUG_EXCEPTION;
bool hit = false;