Browse Source

Move mcontrol match logic into mcontrol_t.

pull/944/head
Tim Newsome 4 years ago
parent
commit
da4afeac58
  1. 93
      riscv/triggers.cc
  2. 8
      riscv/triggers.h

93
riscv/triggers.cc

@ -81,39 +81,19 @@ bool mcontrol_t::tdata2_write(processor_t *proc, const reg_t val) noexcept {
return true; return true;
} }
module_t::module_t(unsigned count) : triggers(count) { bool mcontrol_t::memory_access_match(processor_t *proc, operation_t operation, reg_t address, reg_t data) {
for (unsigned i = 0; i < count; i++) {
triggers[i] = new mcontrol_t();
}
}
// Return the index of a trigger that matched, or -1.
int module_t::trigger_match(triggers::operation_t operation, reg_t address, reg_t data)
{
state_t *state = proc->get_state(); state_t *state = proc->get_state();
if (state->debug_mode) if ((operation == triggers::OPERATION_EXECUTE && !execute) ||
return -1; (operation == triggers::OPERATION_STORE && !store) ||
(operation == triggers::OPERATION_LOAD && !load) ||
bool chain_ok = true; (state->prv == PRV_M && !m) ||
auto xlen = proc->get_xlen(); (state->prv == PRV_S && !s) ||
(state->prv == PRV_U && !u)) {
for (unsigned int i = 0; i < triggers.size(); i++) { return false;
if (!chain_ok) {
chain_ok |= !triggers[i]->chain;
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; reg_t value;
if (triggers[i]->select) { if (select) {
value = data; value = data;
} else { } else {
value = address; value = address;
@ -121,50 +101,63 @@ int module_t::trigger_match(triggers::operation_t operation, reg_t address, reg_
// We need this because in 32-bit mode sometimes the PC bits get sign // We need this because in 32-bit mode sometimes the PC bits get sign
// extended. // extended.
auto xlen = proc->get_xlen();
if (xlen == 32) { if (xlen == 32) {
value &= 0xffffffff; value &= 0xffffffff;
} }
auto tdata2 = triggers[i]->tdata2; switch (match) {
switch (triggers[i]->match) {
case triggers::mcontrol_t::MATCH_EQUAL: case triggers::mcontrol_t::MATCH_EQUAL:
if (value != tdata2) return value == tdata2;
continue;
break;
case triggers::mcontrol_t::MATCH_NAPOT: case triggers::mcontrol_t::MATCH_NAPOT:
{ {
reg_t mask = ~((1 << (cto(tdata2)+1)) - 1); reg_t mask = ~((1 << (cto(tdata2)+1)) - 1);
if ((value & mask) != (tdata2 & mask)) return (value & mask) == (tdata2 & mask);
continue;
} }
break;
case triggers::mcontrol_t::MATCH_GE: case triggers::mcontrol_t::MATCH_GE:
if (value < tdata2) return value >= tdata2;
continue;
break;
case triggers::mcontrol_t::MATCH_LT: case triggers::mcontrol_t::MATCH_LT:
if (value >= tdata2) return value < tdata2;
continue;
break;
case triggers::mcontrol_t::MATCH_MASK_LOW: case triggers::mcontrol_t::MATCH_MASK_LOW:
{ {
reg_t mask = tdata2 >> (xlen/2); reg_t mask = tdata2 >> (xlen/2);
if ((value & mask) != (tdata2 & mask)) return (value & mask) == (tdata2 & mask);
continue;
} }
break;
case triggers::mcontrol_t::MATCH_MASK_HIGH: case triggers::mcontrol_t::MATCH_MASK_HIGH:
{ {
reg_t mask = tdata2 >> (xlen/2); reg_t mask = tdata2 >> (xlen/2);
if (((value >> (xlen/2)) & mask) != (tdata2 & mask)) return ((value >> (xlen/2)) & mask) == (tdata2 & mask);
continue;
} }
break; }
assert(0);
} }
if (!triggers[i]->chain) { module_t::module_t(unsigned count) : triggers(count) {
for (unsigned i = 0; i < count; i++) {
triggers[i] = new mcontrol_t();
}
}
// Return the index of a trigger that matched, or -1.
int module_t::trigger_match(triggers::operation_t operation, reg_t address, reg_t data)
{
state_t *state = proc->get_state();
if (state->debug_mode)
return -1;
bool chain_ok = true;
for (unsigned int i = 0; i < triggers.size(); i++) {
if (!chain_ok) {
chain_ok |= !triggers[i]->chain;
continue;
}
if (triggers[i]->memory_access_match(proc, operation, address, data) &&
!triggers[i]->chain) {
return i; return i;
} }
chain_ok = true; chain_ok = true;
} }
return -1; return -1;

8
riscv/triggers.h

@ -36,6 +36,10 @@ class matched_t
}; };
class trigger_t { class trigger_t {
public:
virtual bool memory_access_match(processor_t *proc,
operation_t operation, reg_t address, reg_t data) = 0;
public: public:
bool dmode; bool dmode;
action_t action; action_t action;
@ -57,11 +61,15 @@ public:
} match_t; } match_t;
mcontrol_t(); mcontrol_t();
reg_t tdata1_read(const processor_t *proc) const noexcept; reg_t tdata1_read(const processor_t *proc) const noexcept;
bool tdata1_write(processor_t *proc, const reg_t val) noexcept; bool tdata1_write(processor_t *proc, const reg_t val) noexcept;
reg_t tdata2_read(const processor_t *proc) const noexcept; reg_t tdata2_read(const processor_t *proc) const noexcept;
bool tdata2_write(processor_t *proc, const reg_t val) 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 type;
uint8_t maskmax; uint8_t maskmax;
bool select; bool select;

Loading…
Cancel
Save