diff options
author | Tim Newsome <tim@sifive.com> | 2022-03-18 10:55:25 -0700 |
---|---|---|
committer | Tim Newsome <tim@sifive.com> | 2022-04-05 10:10:03 -0700 |
commit | da4afeac5812a8d0751301a1b566bc3abaea2bda (patch) | |
tree | d66d98e3f5ecf8c7c1996f6c9a90bf3e25110cf8 /riscv | |
parent | f2646bf1fb2a40d9a723f8c32078d971a17dba7b (diff) | |
download | spike-da4afeac5812a8d0751301a1b566bc3abaea2bda.zip spike-da4afeac5812a8d0751301a1b566bc3abaea2bda.tar.gz spike-da4afeac5812a8d0751301a1b566bc3abaea2bda.tar.bz2 |
Move mcontrol match logic into mcontrol_t.
Diffstat (limited to 'riscv')
-rw-r--r-- | riscv/triggers.cc | 115 | ||||
-rw-r--r-- | riscv/triggers.h | 8 |
2 files changed, 62 insertions, 61 deletions
diff --git a/riscv/triggers.cc b/riscv/triggers.cc index 59c7bf8..092dbbd 100644 --- a/riscv/triggers.cc +++ b/riscv/triggers.cc @@ -81,6 +81,57 @@ bool mcontrol_t::tdata2_write(processor_t *proc, const reg_t val) noexcept { return true; } +bool mcontrol_t::memory_access_match(processor_t *proc, operation_t operation, reg_t address, reg_t data) { + state_t *state = proc->get_state(); + if ((operation == triggers::OPERATION_EXECUTE && !execute) || + (operation == triggers::OPERATION_STORE && !store) || + (operation == triggers::OPERATION_LOAD && !load) || + (state->prv == PRV_M && !m) || + (state->prv == PRV_S && !s) || + (state->prv == PRV_U && !u)) { + return false; + } + + reg_t value; + if (select) { + value = data; + } else { + value = address; + } + + // We need this because in 32-bit mode sometimes the PC bits get sign + // extended. + auto xlen = proc->get_xlen(); + if (xlen == 32) { + value &= 0xffffffff; + } + + switch (match) { + case triggers::mcontrol_t::MATCH_EQUAL: + return value == tdata2; + case triggers::mcontrol_t::MATCH_NAPOT: + { + reg_t mask = ~((1 << (cto(tdata2)+1)) - 1); + return (value & mask) == (tdata2 & mask); + } + case triggers::mcontrol_t::MATCH_GE: + return value >= tdata2; + case triggers::mcontrol_t::MATCH_LT: + return value < tdata2; + case triggers::mcontrol_t::MATCH_MASK_LOW: + { + reg_t mask = tdata2 >> (xlen/2); + return (value & mask) == (tdata2 & mask); + } + case triggers::mcontrol_t::MATCH_MASK_HIGH: + { + reg_t mask = tdata2 >> (xlen/2); + return ((value >> (xlen/2)) & mask) == (tdata2 & mask); + } + } + assert(0); +} + module_t::module_t(unsigned count) : triggers(count) { for (unsigned i = 0; i < count; i++) { triggers[i] = new mcontrol_t(); @@ -95,7 +146,6 @@ int module_t::trigger_match(triggers::operation_t operation, reg_t address, reg_ return -1; bool chain_ok = true; - auto xlen = proc->get_xlen(); for (unsigned int i = 0; i < triggers.size(); i++) { if (!chain_ok) { @@ -103,68 +153,11 @@ int module_t::trigger_match(triggers::operation_t operation, reg_t address, reg_ continue; } - if ((operation == triggers::OPERATION_EXECUTE && !triggers[i]->execute) || - (operation == triggers::OPERATION_STORE && !triggers[i]->store) || - (operation == triggers::OPERATION_LOAD && !triggers[i]->load) || - (state->prv == PRV_M && !triggers[i]->m) || - (state->prv == PRV_S && !triggers[i]->s) || - (state->prv == PRV_U && !triggers[i]->u)) { - continue; - } - - reg_t value; - if (triggers[i]->select) { - value = data; - } else { - value = address; - } - - // We need this because in 32-bit mode sometimes the PC bits get sign - // extended. - if (xlen == 32) { - value &= 0xffffffff; - } - - auto tdata2 = triggers[i]->tdata2; - switch (triggers[i]->match) { - case triggers::mcontrol_t::MATCH_EQUAL: - if (value != tdata2) - continue; - break; - case triggers::mcontrol_t::MATCH_NAPOT: - { - reg_t mask = ~((1 << (cto(tdata2)+1)) - 1); - if ((value & mask) != (tdata2 & mask)) - continue; - } - break; - case triggers::mcontrol_t::MATCH_GE: - if (value < tdata2) - continue; - break; - case triggers::mcontrol_t::MATCH_LT: - if (value >= tdata2) - continue; - break; - case triggers::mcontrol_t::MATCH_MASK_LOW: - { - reg_t mask = tdata2 >> (xlen/2); - if ((value & mask) != (tdata2 & mask)) - continue; - } - break; - case triggers::mcontrol_t::MATCH_MASK_HIGH: - { - reg_t mask = tdata2 >> (xlen/2); - if (((value >> (xlen/2)) & mask) != (tdata2 & mask)) - continue; - } - break; - } - - if (!triggers[i]->chain) { + if (triggers[i]->memory_access_match(proc, operation, address, data) && + !triggers[i]->chain) { return i; } + chain_ok = true; } return -1; diff --git a/riscv/triggers.h b/riscv/triggers.h index dea4fdb..555706e 100644 --- a/riscv/triggers.h +++ b/riscv/triggers.h @@ -37,6 +37,10 @@ class matched_t class trigger_t { public: + virtual bool memory_access_match(processor_t *proc, + operation_t operation, reg_t address, reg_t data) = 0; + +public: bool dmode; action_t action; @@ -57,11 +61,15 @@ public: } match_t; mcontrol_t(); + reg_t tdata1_read(const processor_t *proc) const noexcept; bool tdata1_write(processor_t *proc, const reg_t val) noexcept; reg_t tdata2_read(const processor_t *proc) const noexcept; bool tdata2_write(processor_t *proc, const reg_t val) noexcept; + virtual bool memory_access_match(processor_t *proc, + operation_t operation, reg_t address, reg_t data) override; + uint8_t type; uint8_t maskmax; bool select; |