aboutsummaryrefslogtreecommitdiff
path: root/riscv
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2022-03-16 10:51:27 -0700
committerTim Newsome <tim@sifive.com>2022-04-05 10:10:03 -0700
commit354f977848c17ba80681de60c05d46966e1ffc1a (patch)
treeb9630d0a16fde153ac1b595248b8bf86940b88f0 /riscv
parent894f77677d2d6bb84cf57ddec68e87857df357a1 (diff)
downloadspike-354f977848c17ba80681de60c05d46966e1ffc1a.zip
spike-354f977848c17ba80681de60c05d46966e1ffc1a.tar.gz
spike-354f977848c17ba80681de60c05d46966e1ffc1a.tar.bz2
Move trigger_match() into triggers.
Diffstat (limited to 'riscv')
-rw-r--r--riscv/mmu.h4
-rw-r--r--riscv/processor.h81
-rw-r--r--riscv/triggers.cc84
-rw-r--r--riscv/triggers.h3
4 files changed, 89 insertions, 83 deletions
diff --git a/riscv/mmu.h b/riscv/mmu.h
index 61fe105..953031a 100644
--- a/riscv/mmu.h
+++ b/riscv/mmu.h
@@ -470,7 +470,7 @@ private:
}
if (unlikely(tlb_insn_tag[vpn % TLB_ENTRIES] == (vpn | TLB_CHECK_TRIGGERS))) {
target_endian<uint16_t>* ptr = (target_endian<uint16_t>*)(tlb_data[vpn % TLB_ENTRIES].host_offset + addr);
- int match = proc->trigger_match(triggers::OPERATION_EXECUTE, addr, from_target(*ptr));
+ int match = proc->TM.trigger_match(proc, triggers::OPERATION_EXECUTE, addr, from_target(*ptr));
if (match >= 0) {
throw trigger_matched_t(match, triggers::OPERATION_EXECUTE, addr, from_target(*ptr));
}
@@ -488,7 +488,7 @@ private:
if (!proc) {
return NULL;
}
- int match = proc->trigger_match(operation, address, data);
+ int match = proc->TM.trigger_match(proc, operation, address, data);
if (match == -1)
return NULL;
if (proc->TM.triggers[match]->timing == 0) {
diff --git a/riscv/processor.h b/riscv/processor.h
index e245e8a..776496c 100644
--- a/riscv/processor.h
+++ b/riscv/processor.h
@@ -316,87 +316,6 @@ public:
HR_GROUP /* Halt requested due to halt group. */
} halt_request;
- // Return the index of a trigger that matched, or -1.
- inline int trigger_match(triggers::operation_t operation, reg_t address, reg_t data)
- {
- if (state.debug_mode)
- return -1;
-
- bool chain_ok = true;
-
- for (unsigned int i = 0; i < state.num_triggers; i++) {
- if (!chain_ok) {
- chain_ok |= !TM.triggers[i]->chain;
- continue;
- }
-
- if ((operation == triggers::OPERATION_EXECUTE && !TM.triggers[i]->execute) ||
- (operation == triggers::OPERATION_STORE && !TM.triggers[i]->store) ||
- (operation == triggers::OPERATION_LOAD && !TM.triggers[i]->load) ||
- (state.prv == PRV_M && !TM.triggers[i]->m) ||
- (state.prv == PRV_S && !TM.triggers[i]->s) ||
- (state.prv == PRV_U && !TM.triggers[i]->u)) {
- continue;
- }
-
- reg_t value;
- if (TM.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 = TM.triggers[i]->tdata2;
- switch (TM.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 (!TM.triggers[i]->chain) {
- return i;
- }
- chain_ok = true;
- }
- return -1;
- }
-
void trigger_updated();
void set_pmp_num(reg_t pmp_num);
diff --git a/riscv/triggers.cc b/riscv/triggers.cc
index f6b6e7d..fc7736a 100644
--- a/riscv/triggers.cc
+++ b/riscv/triggers.cc
@@ -87,4 +87,88 @@ module_t::module_t(unsigned count) : triggers(count) {
}
}
+// Return the index of a trigger that matched, or -1.
+int module_t::trigger_match(processor_t *proc, 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;
+ auto xlen = proc->get_xlen();
+
+ for (unsigned int i = 0; i < triggers.size(); i++) {
+ 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;
+ 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) {
+ return i;
+ }
+ chain_ok = true;
+ }
+ return -1;
+}
+
+
};
diff --git a/riscv/triggers.h b/riscv/triggers.h
index 8dad4f6..a0ff3b5 100644
--- a/riscv/triggers.h
+++ b/riscv/triggers.h
@@ -69,6 +69,9 @@ class module_t {
public:
module_t(unsigned count);
+ // Return the index of a trigger that matched, or -1.
+ int trigger_match(processor_t *proc, triggers::operation_t operation, reg_t address, reg_t data);
+
std::vector<mcontrol_t *> triggers;
};