diff options
author | YenHaoChen <howard25336284@gmail.com> | 2022-09-30 11:55:57 +0800 |
---|---|---|
committer | YenHaoChen <howard25336284@gmail.com> | 2022-09-30 12:18:17 +0800 |
commit | a5752cebafa75b8dc539ee327bac8630e3fb84f1 (patch) | |
tree | f17cf2bbd693538e5c2c6b2a7c7fba4f4654ea76 /riscv | |
parent | b724db52f9d7be3e3068e5bf01ac939ece8d032b (diff) | |
download | spike-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.h | 8 |
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); } |