diff options
author | Tim Newsome <tim@sifive.com> | 2016-04-24 08:54:19 -0700 |
---|---|---|
committer | Tim Newsome <tim@sifive.com> | 2016-05-23 12:12:11 -0700 |
commit | d999dfc0d41a119730ff8944d37dbee88bf99723 (patch) | |
tree | 2268c9d7d5f122fb81253d10bd05901eaff0ff62 /riscv/mmu.cc | |
parent | 191671a2015136c429394fd3051e4a9c1ff45352 (diff) | |
download | spike-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.cc | 36 |
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; } } |