aboutsummaryrefslogtreecommitdiff
path: root/riscv/mmu.cc
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2016-08-22 09:49:20 -0700
committerTim Newsome <tim@sifive.com>2016-08-22 09:49:20 -0700
commitd6dae451821656d7676fec3ec515691d4c66e065 (patch)
treeab8d1a8129710b380147cefc44e97c4dad28425b /riscv/mmu.cc
parent5e1d0059353a4756740df709f85c35ee86138ad6 (diff)
downloadspike-d6dae451821656d7676fec3ec515691d4c66e065.zip
spike-d6dae451821656d7676fec3ec515691d4c66e065.tar.gz
spike-d6dae451821656d7676fec3ec515691d4c66e065.tar.bz2
Implement address and data triggers.
So far I only have testcases for instruction and data address. Not implemented is the mechanism that lets the debugger prevent a user program from using triggers at all. I'll be adding that soonish. The critical path is unchanged, but my experimenting shows the simulation is slowed down about 8% by this code. Reducing the size of trigger_match() (which is never called during my benchmark) fixes that, but making it not be inlined has no effect. I suspect the slowdown comes from cache alignment or something similar, and on a different CPU or after more code changes the speed will come back.
Diffstat (limited to 'riscv/mmu.cc')
-rw-r--r--riscv/mmu.cc20
1 files changed, 16 insertions, 4 deletions
diff --git a/riscv/mmu.cc b/riscv/mmu.cc
index 4b7166f..0b60713 100644
--- a/riscv/mmu.cc
+++ b/riscv/mmu.cc
@@ -5,7 +5,11 @@
#include "processor.h"
mmu_t::mmu_t(sim_t* sim, processor_t* proc)
- : sim(sim), proc(proc)
+ : sim(sim), proc(proc),
+ check_triggers_fetch(false),
+ check_triggers_load(false),
+ check_triggers_store(false),
+ matched_trigger(NULL)
{
flush_tlb();
}
@@ -102,9 +106,17 @@ void mmu_t::refill_tlb(reg_t vaddr, reg_t paddr, access_type type)
reg_t idx = (vaddr >> PGSHIFT) % TLB_ENTRIES;
reg_t expected_tag = vaddr >> PGSHIFT;
- if (tlb_load_tag[idx] != expected_tag) tlb_load_tag[idx] = -1;
- if (tlb_store_tag[idx] != expected_tag) tlb_store_tag[idx] = -1;
- if (tlb_insn_tag[idx] != expected_tag) tlb_insn_tag[idx] = -1;
+ if ((tlb_load_tag[idx] & ~TLB_CHECK_TRIGGERS) != expected_tag)
+ tlb_load_tag[idx] = -1;
+ if ((tlb_store_tag[idx] & ~TLB_CHECK_TRIGGERS) != expected_tag)
+ tlb_store_tag[idx] = -1;
+ if ((tlb_insn_tag[idx] & ~TLB_CHECK_TRIGGERS) != expected_tag)
+ tlb_insn_tag[idx] = -1;
+
+ if ((check_triggers_fetch && type == FETCH) ||
+ (check_triggers_load && type == LOAD) ||
+ (check_triggers_store && type == STORE))
+ expected_tag |= TLB_CHECK_TRIGGERS;
if (type == FETCH) tlb_insn_tag[idx] = expected_tag;
else if (type == STORE) tlb_store_tag[idx] = expected_tag;