Browse Source

triggers: add etrigger_t

pull/1128/head
YenHaoChen 3 years ago
parent
commit
8da8a8c89a
  1. 2
      README.md
  2. 61
      riscv/triggers.cc
  3. 21
      riscv/triggers.h

2
README.md

@ -38,7 +38,7 @@ Spike supports the following RISC-V ISA features:
- Svpbmt extension, v1.0
- Svinval extension, v1.0
- Debug v0.14
- 4 triggers support type=2 (mcontrol), type=4 (itrigger), and type=15 (disabled)
- 4 triggers support type=2 (mcontrol), type=4 (itrigger), type=5 (etrigger), and type=15 (disabled)
- Smepmp extension v1.0
- Smstateen extension, v1.0
- Sscofpmf v0.5.2

61
riscv/triggers.cc

@ -204,6 +204,60 @@ match_result_t itrigger_t::detect_trap_match(processor_t * const proc, const tra
return match_result_t(false);
}
reg_t etrigger_t::tdata1_read(const processor_t * const proc) const noexcept
{
auto xlen = proc->get_xlen();
reg_t tdata1 = 0;
tdata1 = set_field(tdata1, CSR_ETRIGGER_TYPE(xlen), CSR_TDATA1_TYPE_ETRIGGER);
tdata1 = set_field(tdata1, CSR_ETRIGGER_DMODE(xlen), dmode);
tdata1 = set_field(tdata1, CSR_ETRIGGER_HIT(xlen), hit);
tdata1 = set_field(tdata1, CSR_ETRIGGER_VS, proc->extension_enabled('H') ? vs : 0);
tdata1 = set_field(tdata1, CSR_ETRIGGER_VU, proc->extension_enabled('H') ? vu : 0);
tdata1 = set_field(tdata1, CSR_ETRIGGER_M, m);
tdata1 = set_field(tdata1, CSR_ETRIGGER_S, s);
tdata1 = set_field(tdata1, CSR_ETRIGGER_U, u);
tdata1 = set_field(tdata1, CSR_ETRIGGER_ACTION, action);
return tdata1;
}
void etrigger_t::tdata1_write(processor_t * const proc, const reg_t val, const bool UNUSED allow_chain) noexcept
{
auto xlen = proc->get_xlen();
assert(get_field(val, CSR_ETRIGGER_TYPE(xlen)) == CSR_TDATA1_TYPE_ETRIGGER);
dmode = get_field(val, CSR_ETRIGGER_DMODE(xlen));
hit = get_field(val, CSR_ETRIGGER_HIT(xlen));
vs = get_field(val, CSR_ETRIGGER_VS);
vu = get_field(val, CSR_ETRIGGER_VU);
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 = (action_t)get_field(val, CSR_ETRIGGER_ACTION);
if (action > ACTION_MAXVAL || (action==ACTION_DEBUG_MODE && dmode==0))
action = ACTION_DEBUG_EXCEPTION;
}
match_result_t etrigger_t::detect_trap_match(processor_t * const proc, const trap_t& t)
{
state_t * const state = proc->get_state();
if ((state->prv == PRV_M && !m) ||
(!state->v && state->prv == PRV_S && !s) ||
(!state->v && state->prv == PRV_U && !u) ||
(state->v && state->prv == PRV_S && !vs) ||
(state->v && state->prv == PRV_U && !vu)) {
return match_result_t(false);
}
auto xlen = proc->get_xlen();
bool interrupt = (t.cause() & ((reg_t)1 << (xlen - 1))) != 0;
reg_t bit = t.cause() & ~((reg_t)1 << (xlen - 1));
assert(bit < xlen);
if (!interrupt && ((tdata2 >> bit) & 1)) {
hit = true;
return match_result_t(true, TIMING_AFTER, action);
}
return match_result_t(false);
}
module_t::module_t(unsigned count) : triggers(count) {
for (unsigned i = 0; i < count; i++) {
triggers[i] = new disabled_trigger_t();
@ -244,6 +298,7 @@ bool module_t::tdata1_write(processor_t * const proc, unsigned index, const reg_
if (!proc->get_state()->debug_mode) {
assert(CSR_TDATA1_DMODE(xlen) == CSR_MCONTROL_DMODE(xlen));
assert(CSR_TDATA1_DMODE(xlen) == CSR_ITRIGGER_DMODE(xlen));
assert(CSR_TDATA1_DMODE(xlen) == CSR_ETRIGGER_DMODE(xlen));
tdata1 = set_field(tdata1, CSR_TDATA1_DMODE(xlen), 0);
}
@ -251,6 +306,7 @@ bool module_t::tdata1_write(processor_t * const proc, unsigned index, const reg_
switch (type) {
case CSR_TDATA1_TYPE_MCONTROL: triggers[index] = new mcontrol_t(); break;
case CSR_TDATA1_TYPE_ITRIGGER: triggers[index] = new itrigger_t(); break;
case CSR_TDATA1_TYPE_ETRIGGER: triggers[index] = new etrigger_t(); break;
default: triggers[index] = new disabled_trigger_t(); break;
}
@ -321,7 +377,10 @@ match_result_t module_t::detect_trap_match(const trap_t& t)
reg_t module_t::tinfo_read(UNUSED const processor_t * const proc, unsigned UNUSED index) const noexcept
{
/* In spike, every trigger supports the same types. */
return (1 << CSR_TDATA1_TYPE_MCONTROL) | (1 << CSR_TDATA1_TYPE_ITRIGGER) | (1 << CSR_TDATA1_TYPE_DISABLED);
return (1 << CSR_TDATA1_TYPE_MCONTROL) |
(1 << CSR_TDATA1_TYPE_ITRIGGER) |
(1 << CSR_TDATA1_TYPE_ETRIGGER) |
(1 << CSR_TDATA1_TYPE_DISABLED);
}
};

21
riscv/triggers.h

@ -114,6 +114,27 @@ private:
action_t action;
};
class etrigger_t : public trigger_with_tdata2_t {
public:
virtual reg_t tdata1_read(const processor_t * const proc) const noexcept override;
virtual void tdata1_write(processor_t * const proc, const reg_t val, const bool allow_chain) noexcept override;
bool get_dmode() const override { return dmode; }
virtual action_t get_action() const override { return action; }
virtual match_result_t detect_trap_match(processor_t * const proc, const trap_t& t) override;
private:
bool dmode;
bool hit;
bool vs;
bool vu;
bool m;
bool s;
bool u;
action_t action;
};
class mcontrol_t : public trigger_with_tdata2_t {
public:
typedef enum

Loading…
Cancel
Save