diff options
author | Tim Newsome <tim@sifive.com> | 2016-08-22 09:49:20 -0700 |
---|---|---|
committer | Tim Newsome <tim@sifive.com> | 2016-08-22 09:49:20 -0700 |
commit | d6dae451821656d7676fec3ec515691d4c66e065 (patch) | |
tree | ab8d1a8129710b380147cefc44e97c4dad28425b /riscv/mmu.cc | |
parent | 5e1d0059353a4756740df709f85c35ee86138ad6 (diff) | |
download | spike-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.cc | 20 |
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; |