aboutsummaryrefslogtreecommitdiff
path: root/riscv/mmu.cc
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2016-04-24 08:54:19 -0700
committerTim Newsome <tim@sifive.com>2016-05-23 12:12:11 -0700
commitd999dfc0d41a119730ff8944d37dbee88bf99723 (patch)
tree2268c9d7d5f122fb81253d10bd05901eaff0ff62 /riscv/mmu.cc
parent191671a2015136c429394fd3051e4a9c1ff45352 (diff)
downloadspike-d999dfc0d41a119730ff8944d37dbee88bf99723.zip
spike-d999dfc0d41a119730ff8944d37dbee88bf99723.tar.gz
spike-d999dfc0d41a119730ff8944d37dbee88bf99723.tar.bz2
Add debug_module bus device.
This should replace the ROM hack I implemented earlier, but for now both exist together. Back to the point where gdb connects, core jumps to ROM->RAM->ROM.
Diffstat (limited to 'riscv/mmu.cc')
-rw-r--r--riscv/mmu.cc36
1 files changed, 32 insertions, 4 deletions
diff --git a/riscv/mmu.cc b/riscv/mmu.cc
index 5fb72bf..514547c 100644
--- a/riscv/mmu.cc
+++ b/riscv/mmu.cc
@@ -51,16 +51,44 @@ reg_t mmu_t::translate(reg_t addr, access_type type)
return walk(addr, type, mode > PRV_U, pum) | (addr & (PGSIZE-1));
}
-const uint16_t* mmu_t::fetch_slow_path(reg_t addr)
+const char* mmu_t::fill_from_mmio(reg_t vaddr, reg_t paddr)
{
- reg_t paddr = translate(addr, FETCH);
+ reg_t rv_start = paddr & PGMASK;
+ char* spike_start = proc->sim->mmio_page(rv_start);
+
+ if (!spike_start)
+ return NULL;
+
+ // TODO: refactor with refill_tlb()
+ 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;
+
+ tlb_insn_tag[idx] = expected_tag;
+ tlb_data[idx] = spike_start - DEBUG_START;
+
+ return spike_start + (paddr & ~PGMASK);
+}
+
+const uint16_t* mmu_t::fetch_slow_path(reg_t vaddr)
+{
+ reg_t paddr = translate(vaddr, FETCH);
+
+ // mmu_t::walk() returns -1 if it can't find a match. Of course -1 could also
+ // be a valid address.
+ if (paddr == ~(reg_t) 0 && vaddr != ~(reg_t) 0) {
+ throw trap_instruction_access_fault(vaddr);
+ }
if (sim->addr_is_mem(paddr)) {
- refill_tlb(addr, paddr, FETCH);
+ refill_tlb(vaddr, paddr, FETCH);
return (const uint16_t*)sim->addr_to_mem(paddr);
} else {
if (!sim->mmio_load(paddr, sizeof fetch_temp, (uint8_t*)&fetch_temp))
- throw trap_instruction_access_fault(addr);
+ throw trap_instruction_access_fault(vaddr);
return &fetch_temp;
}
}