aboutsummaryrefslogtreecommitdiff
path: root/riscv
diff options
context:
space:
mode:
authorYenHaoChen <howard25336284@gmail.com>2022-09-30 11:55:57 +0800
committerYenHaoChen <howard25336284@gmail.com>2022-09-30 12:18:17 +0800
commita5752cebafa75b8dc539ee327bac8630e3fb84f1 (patch)
treef17cf2bbd693538e5c2c6b2a7c7fba4f4654ea76 /riscv
parentb724db52f9d7be3e3068e5bf01ac939ece8d032b (diff)
downloadspike-a5752cebafa75b8dc539ee327bac8630e3fb84f1.zip
spike-a5752cebafa75b8dc539ee327bac8630e3fb84f1.tar.gz
spike-a5752cebafa75b8dc539ee327bac8630e3fb84f1.tar.bz2
Fix priority of mcontrol trigger execute address before
The spec defines the mcontrol execute address has a higher priority over page fault (Debug spec, Table 5.2). Thus, the trigger checking should be before the translation. The previous implementation checks the trigger after the translation, resulting in incorrect priority. For instance, when page fault and trigger occur on the same instruction, the previous implementation will choose to raise the page fault, which contradicts the priority requirement. This commit adds an address-only trigger checking before the translation. The trigger will fire on the instruction instead of the page fault in the above case.
Diffstat (limited to 'riscv')
-rw-r--r--riscv/mmu.h8
1 files changed, 6 insertions, 2 deletions
diff --git a/riscv/mmu.h b/riscv/mmu.h
index ebe4f9b..d076aeb 100644
--- a/riscv/mmu.h
+++ b/riscv/mmu.h
@@ -471,6 +471,11 @@ private:
reg_t vpn = addr >> PGSHIFT;
if (likely(tlb_insn_tag[vpn % TLB_ENTRIES] == vpn))
return tlb_data[vpn % TLB_ENTRIES];
+ triggers::action_t action;
+ auto match = proc->TM.memory_access_match(&action, triggers::OPERATION_EXECUTE, addr, false);
+ if (match != triggers::MATCH_NONE) {
+ throw triggers::matched_t(triggers::OPERATION_EXECUTE, addr, 0, action);
+ }
tlb_entry_t result;
if (unlikely(tlb_insn_tag[vpn % TLB_ENTRIES] != (vpn | TLB_CHECK_TRIGGERS))) {
result = fetch_slow_path(addr);
@@ -478,8 +483,7 @@ private:
result = tlb_data[vpn % TLB_ENTRIES];
}
target_endian<uint16_t>* ptr = (target_endian<uint16_t>*)(result.host_offset + addr);
- triggers::action_t action;
- auto match = proc->TM.memory_access_match(&action, triggers::OPERATION_EXECUTE, addr, true, from_target(*ptr));
+ match = proc->TM.memory_access_match(&action, triggers::OPERATION_EXECUTE, addr, true, from_target(*ptr));
if (match != triggers::MATCH_NONE) {
throw triggers::matched_t(triggers::OPERATION_EXECUTE, addr, from_target(*ptr), action);
}