diff options
author | Tim Newsome <tim@sifive.com> | 2022-04-28 10:27:42 -0700 |
---|---|---|
committer | Tim Newsome <tim@sifive.com> | 2022-05-02 13:15:13 -0700 |
commit | 85fbd75d44c369ccb358d70bb4adc3a82a23c495 (patch) | |
tree | 067efdf80197b3f7fbb9aaf4bf17ea7006113e1b | |
parent | f2f6037fea9313f43f7e94872304ab18ead0181d (diff) | |
download | riscv-isa-sim-85fbd75d44c369ccb358d70bb4adc3a82a23c495.zip riscv-isa-sim-85fbd75d44c369ccb358d70bb4adc3a82a23c495.tar.gz riscv-isa-sim-85fbd75d44c369ccb358d70bb4adc3a82a23c495.tar.bz2 |
Implement mcontrol trigger hit bit.
-rw-r--r-- | riscv/triggers.cc | 12 | ||||
-rw-r--r-- | riscv/triggers.h | 3 |
2 files changed, 14 insertions, 1 deletions
diff --git a/riscv/triggers.cc b/riscv/triggers.cc index 7f6be44..ed9105e 100644 --- a/riscv/triggers.cc +++ b/riscv/triggers.cc @@ -1,3 +1,4 @@ +#include "debug_defines.h" #include "processor.h" #include "triggers.h" @@ -16,6 +17,7 @@ reg_t mcontrol_t::tdata1_read(const processor_t * const proc) const noexcept { v = set_field(v, MCONTROL_TYPE(xlen), 2); v = set_field(v, MCONTROL_DMODE(xlen), dmode); v = set_field(v, MCONTROL_MASKMAX(xlen), 0); + v = set_field(v, CSR_MCONTROL_HIT, hit); v = set_field(v, MCONTROL_SELECT, select); v = set_field(v, MCONTROL_TIMING, timing); v = set_field(v, MCONTROL_ACTION, action); @@ -36,6 +38,7 @@ bool mcontrol_t::tdata1_write(processor_t * const proc, const reg_t val) noexcep } auto xlen = proc->get_xlen(); dmode = get_field(val, MCONTROL_DMODE(xlen)); + hit = get_field(val, CSR_MCONTROL_HIT); select = get_field(val, MCONTROL_SELECT); timing = get_field(val, MCONTROL_TIMING); action = (triggers::action_t) get_field(val, MCONTROL_ACTION); @@ -131,6 +134,9 @@ match_result_t mcontrol_t::memory_access_match(processor_t * const proc, operati } if (simple_match(xlen, value)) { + /* This is OK because this function is only called if the trigger was not + * inhibited by the previous trigger in the chain. */ + hit = true; if (timing) return MATCH_FIRE_AFTER; else @@ -165,6 +171,12 @@ match_result_t module_t::memory_access_match(action_t * const action, operation_ continue; } + /* Note: We call memory_access_match for each trigger in a chain as long as + * the triggers are matching. This results in "temperature coding" so that + * `hit` is set on each of the consecutive triggers that matched, even if the + * entire chain did not match. This is allowed by the spec, because the final + * trigger in the chain will never get `hit` set unless the entire chain + * matches. */ match_result_t result = triggers[i]->memory_access_match(proc, operation, address, data); if (result != MATCH_NONE && !triggers[i]->chain()) { *action = triggers[i]->action; diff --git a/riscv/triggers.h b/riscv/triggers.h index 75ee405..19fa437 100644 --- a/riscv/triggers.h +++ b/riscv/triggers.h @@ -58,11 +58,12 @@ public: public: bool dmode; action_t action; + bool hit; virtual ~trigger_t() {}; protected: - trigger_t() : dmode(false), action(ACTION_DEBUG_EXCEPTION) {}; + trigger_t() : dmode(false), action(ACTION_DEBUG_EXCEPTION), hit(false) {}; }; class mcontrol_t : public trigger_t { |