diff options
author | Tim Newsome <tim@sifive.com> | 2022-03-16 10:51:27 -0700 |
---|---|---|
committer | Tim Newsome <tim@sifive.com> | 2022-04-05 10:10:03 -0700 |
commit | 354f977848c17ba80681de60c05d46966e1ffc1a (patch) | |
tree | b9630d0a16fde153ac1b595248b8bf86940b88f0 /riscv | |
parent | 894f77677d2d6bb84cf57ddec68e87857df357a1 (diff) | |
download | spike-354f977848c17ba80681de60c05d46966e1ffc1a.zip spike-354f977848c17ba80681de60c05d46966e1ffc1a.tar.gz spike-354f977848c17ba80681de60c05d46966e1ffc1a.tar.bz2 |
Move trigger_match() into triggers.
Diffstat (limited to 'riscv')
-rw-r--r-- | riscv/mmu.h | 4 | ||||
-rw-r--r-- | riscv/processor.h | 81 | ||||
-rw-r--r-- | riscv/triggers.cc | 84 | ||||
-rw-r--r-- | riscv/triggers.h | 3 |
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; }; |