aboutsummaryrefslogtreecommitdiff
path: root/riscv/mmu.cc
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2022-10-06 14:31:07 -0700
committerAndrew Waterman <andrew@sifive.com>2022-10-06 19:30:40 -0700
commit14410156b2d796dad0e439b9535057f1e4c5a13c (patch)
tree7b5c3ec0cde00a43b26f876848393b90414d3233 /riscv/mmu.cc
parent6311f7513aa150797f69ecac906978bb9e9fecbd (diff)
downloadspike-14410156b2d796dad0e439b9535057f1e4c5a13c.zip
spike-14410156b2d796dad0e439b9535057f1e4c5a13c.tar.gz
spike-14410156b2d796dad0e439b9535057f1e4c5a13c.tar.bz2
Move uncommon-case fetch functionality into fetch_slow_path
Diffstat (limited to 'riscv/mmu.cc')
-rw-r--r--riscv/mmu.cc32
1 files changed, 24 insertions, 8 deletions
diff --git a/riscv/mmu.cc b/riscv/mmu.cc
index 9c9a6c5..5a5f5c0 100644
--- a/riscv/mmu.cc
+++ b/riscv/mmu.cc
@@ -76,16 +76,32 @@ reg_t mmu_t::translate(reg_t addr, reg_t len, access_type type, uint32_t xlate_f
tlb_entry_t mmu_t::fetch_slow_path(reg_t vaddr)
{
- reg_t paddr = translate(vaddr, sizeof(fetch_temp), FETCH, 0);
-
- if (auto host_addr = sim->addr_to_mem(paddr)) {
- return refill_tlb(vaddr, paddr, host_addr, FETCH);
+ triggers::action_t action;
+ auto match = proc->TM.memory_access_match(&action, triggers::OPERATION_EXECUTE, vaddr, false);
+ if (match != triggers::MATCH_NONE)
+ throw triggers::matched_t(triggers::OPERATION_EXECUTE, vaddr, 0, action);
+
+ tlb_entry_t result;
+ reg_t vpn = vaddr >> PGSHIFT;
+ if (unlikely(tlb_insn_tag[vpn % TLB_ENTRIES] != (vpn | TLB_CHECK_TRIGGERS))) {
+ reg_t paddr = translate(vaddr, sizeof(fetch_temp), FETCH, 0);
+ if (auto host_addr = sim->addr_to_mem(paddr)) {
+ result = refill_tlb(vaddr, paddr, host_addr, FETCH);
+ } else {
+ if (!mmio_load(paddr, sizeof fetch_temp, (uint8_t*)&fetch_temp))
+ throw trap_instruction_access_fault(proc->state.v, vaddr, 0, 0);
+ result = {(char*)&fetch_temp - vaddr, paddr - vaddr};
+ }
} else {
- if (!mmio_load(paddr, sizeof fetch_temp, (uint8_t*)&fetch_temp))
- throw trap_instruction_access_fault(proc->state.v, vaddr, 0, 0);
- tlb_entry_t entry = {(char*)&fetch_temp - vaddr, paddr - vaddr};
- return entry;
+ result = tlb_data[vpn % TLB_ENTRIES];
}
+
+ target_endian<uint16_t>* ptr = (target_endian<uint16_t>*)(result.host_offset + vaddr);
+ match = proc->TM.memory_access_match(&action, triggers::OPERATION_EXECUTE, vaddr, true, from_target(*ptr));
+ if (match != triggers::MATCH_NONE)
+ throw triggers::matched_t(triggers::OPERATION_EXECUTE, vaddr, from_target(*ptr), action);
+
+ return result;
}
reg_t reg_from_bytes(size_t len, const uint8_t* bytes)