Browse Source

Move mcontrol match logic into mcontrol_t.

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

115
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;

8
riscv/triggers.h

@ -36,6 +36,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;

Loading…
Cancel
Save