diff options
author | Andrew Waterman <andrew@sifive.com> | 2020-11-29 16:06:32 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-29 16:06:32 -0800 |
commit | 4b04d715298c7c0542badf30828f65d1f02e1c1d (patch) | |
tree | 59d990f39ad60943bcc8a0a6f0d4192ab2407f2e | |
parent | d6cf0d23635a53e5229e4ed317f1bcc58323b21a (diff) | |
parent | d0d923ebdef92deb26ac0f02fb15e61e328c602a (diff) | |
download | spike-4b04d715298c7c0542badf30828f65d1f02e1c1d.zip spike-4b04d715298c7c0542badf30828f65d1f02e1c1d.tar.gz spike-4b04d715298c7c0542badf30828f65d1f02e1c1d.tar.bz2 |
Merge pull request #605 from avpatel/riscv_gva_fix_v1
Fix hstatus.GVA and mstatus.GVA updation
-rw-r--r-- | riscv/mmu.cc | 30 | ||||
-rw-r--r-- | riscv/mmu.h | 8 | ||||
-rw-r--r-- | riscv/processor.cc | 2 | ||||
-rw-r--r-- | riscv/trap.h | 24 |
4 files changed, 38 insertions, 26 deletions
diff --git a/riscv/mmu.cc b/riscv/mmu.cc index 8e32dfe..23f132e 100644 --- a/riscv/mmu.cc +++ b/riscv/mmu.cc @@ -38,12 +38,12 @@ void mmu_t::flush_tlb() flush_icache(); } -static void throw_access_exception(reg_t addr, access_type type) +static void throw_access_exception(bool virt, reg_t addr, access_type type) { switch (type) { - case FETCH: throw trap_instruction_access_fault(addr, 0, 0); - case LOAD: throw trap_load_access_fault(addr, 0, 0); - case STORE: throw trap_store_access_fault(addr, 0, 0); + case FETCH: throw trap_instruction_access_fault(virt, addr, 0, 0); + case LOAD: throw trap_load_access_fault(virt, addr, 0, 0); + case STORE: throw trap_store_access_fault(virt, addr, 0, 0); default: abort(); } } @@ -73,7 +73,7 @@ reg_t mmu_t::translate(reg_t addr, reg_t len, access_type type, uint32_t xlate_f reg_t paddr = walk(addr, type, mode, virt, mxr) | (addr & (PGSIZE-1)); if (!pmp_ok(paddr, len, type, mode)) - throw_access_exception(addr, type); + throw_access_exception(virt, addr, type); return paddr; } @@ -85,7 +85,7 @@ tlb_entry_t mmu_t::fetch_slow_path(reg_t vaddr) return refill_tlb(vaddr, paddr, host_addr, FETCH); } else { if (!mmio_load(paddr, sizeof fetch_temp, (uint8_t*)&fetch_temp)) - throw trap_instruction_access_fault(vaddr, 0, 0); + throw trap_instruction_access_fault(proc->state.v, vaddr, 0, 0); tlb_entry_t entry = {(char*)&fetch_temp - vaddr, paddr - vaddr}; return entry; } @@ -153,7 +153,7 @@ void mmu_t::load_slow_path(reg_t addr, reg_t len, uint8_t* bytes, uint32_t xlate else refill_tlb(addr, paddr, host_addr, LOAD); } else if (!mmio_load(paddr, len, bytes)) { - throw trap_load_access_fault(addr, 0, 0); + throw trap_load_access_fault(proc->state.v, addr, 0, 0); } if (!matched_trigger) { @@ -182,7 +182,7 @@ void mmu_t::store_slow_path(reg_t addr, reg_t len, const uint8_t* bytes, uint32_ else refill_tlb(addr, paddr, host_addr, STORE); } else if (!mmio_store(paddr, len, bytes)) { - throw trap_store_access_fault(addr, 0, 0); + throw trap_store_access_fault(proc->state.v, addr, 0, 0); } } @@ -320,7 +320,7 @@ reg_t mmu_t::s2xlate(reg_t gva, reg_t gpa, access_type type, access_type trap_ty auto pte_paddr = base + idx * vm.ptesize; auto ppte = sim->addr_to_mem(pte_paddr); if (!ppte || !pmp_ok(pte_paddr, vm.ptesize, LOAD, PRV_S)) { - throw_access_exception(gva, trap_type); + throw_access_exception(virt, gva, trap_type); } reg_t pte = vm.ptesize == 4 ? from_target(*(target_endian<uint32_t>*)ppte) : from_target(*(target_endian<uint64_t>*)ppte); @@ -344,7 +344,7 @@ reg_t mmu_t::s2xlate(reg_t gva, reg_t gpa, access_type type, access_type trap_ty // set accessed and possibly dirty bits. if ((pte & ad) != ad) { if (!pmp_ok(pte_paddr, vm.ptesize, STORE, PRV_S)) - throw_access_exception(gva, trap_type); + throw_access_exception(virt, gva, trap_type); *(target_endian<uint32_t>*)ppte |= to_target((uint32_t)ad); } #else @@ -401,7 +401,7 @@ reg_t mmu_t::walk(reg_t addr, access_type type, reg_t mode, bool virt, bool mxr) auto pte_paddr = s2xlate(addr, base + idx * vm.ptesize, LOAD, type, virt, false); auto ppte = sim->addr_to_mem(pte_paddr); if (!ppte || !pmp_ok(pte_paddr, vm.ptesize, LOAD, PRV_S)) - throw_access_exception(addr, type); + throw_access_exception(virt, addr, type); reg_t pte = vm.ptesize == 4 ? from_target(*(target_endian<uint32_t>*)ppte) : from_target(*(target_endian<uint64_t>*)ppte); reg_t ppn = (pte & ~reg_t(PTE_N)) >> PTE_PPN_SHIFT; @@ -424,7 +424,7 @@ reg_t mmu_t::walk(reg_t addr, access_type type, reg_t mode, bool virt, bool mxr) // set accessed and possibly dirty bits. if ((pte & ad) != ad) { if (!pmp_ok(pte_paddr, vm.ptesize, STORE, PRV_S)) - throw_access_exception(addr, type); + throw_access_exception(virt, addr, type); *(target_endian<uint32_t>*)ppte |= to_target((uint32_t)ad); } #else @@ -448,9 +448,9 @@ reg_t mmu_t::walk(reg_t addr, access_type type, reg_t mode, bool virt, bool mxr) } switch (type) { - case FETCH: throw trap_instruction_page_fault(addr, 0, 0); - case LOAD: throw trap_load_page_fault(addr, 0, 0); - case STORE: throw trap_store_page_fault(addr, 0, 0); + case FETCH: throw trap_instruction_page_fault(virt, addr, 0, 0); + case LOAD: throw trap_load_page_fault(virt, addr, 0, 0); + case STORE: throw trap_store_page_fault(virt, addr, 0, 0); default: abort(); } } diff --git a/riscv/mmu.h b/riscv/mmu.h index 4bba5b0..ada20fb 100644 --- a/riscv/mmu.h +++ b/riscv/mmu.h @@ -200,10 +200,10 @@ public: throw trap_store_address_misaligned(t.get_tval(), t.get_tval2(), t.get_tinst()); \ } catch (trap_load_page_fault& t) { \ /* AMO faults should be reported as store faults */ \ - throw trap_store_page_fault(t.get_tval(), t.get_tval2(), t.get_tinst()); \ + throw trap_store_page_fault(t.has_gva(), t.get_tval(), t.get_tval2(), t.get_tinst()); \ } catch (trap_load_access_fault& t) { \ /* AMO faults should be reported as store faults */ \ - throw trap_store_access_fault(t.get_tval(), t.get_tval2(), t.get_tinst()); \ + throw trap_store_access_fault(t.has_gva(), t.get_tval(), t.get_tval2(), t.get_tinst()); \ } \ } @@ -253,7 +253,7 @@ public: if (auto host_addr = sim->addr_to_mem(paddr)) load_reservation_address = refill_tlb(vaddr, paddr, host_addr, LOAD).target_offset + vaddr; else - throw trap_load_access_fault(vaddr, 0, 0); // disallow LR to I/O space + throw trap_load_access_fault(proc->state.v, vaddr, 0, 0); // disallow LR to I/O space } inline bool check_load_reservation(reg_t vaddr, size_t size) @@ -265,7 +265,7 @@ public: if (auto host_addr = sim->addr_to_mem(paddr)) return load_reservation_address == refill_tlb(vaddr, paddr, host_addr, STORE).target_offset + vaddr; else - throw trap_store_access_fault(vaddr, 0, 0); // disallow SC to I/O space + throw trap_store_access_fault(proc->state.v, vaddr, 0, 0); // disallow SC to I/O space } static const reg_t ICACHE_ENTRIES = 1024; diff --git a/riscv/processor.cc b/riscv/processor.cc index e01e196..9cfd4ad 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -1142,7 +1142,7 @@ void processor_t::set_csr(int which, reg_t val) /* Ignore */ break; case CSR_HTVAL: - state.htinst = val; + state.htval = val; break; case CSR_HIP: { reg_t mask = MIP_VSSIP; diff --git a/riscv/trap.h b/riscv/trap.h index 4431d8a..46114ec 100644 --- a/riscv/trap.h +++ b/riscv/trap.h @@ -68,16 +68,28 @@ class mem_trap_t : public trap_t #define DECLARE_MEM_TRAP(n, x) class trap_##x : public mem_trap_t { \ public: \ + trap_##x(bool gva, reg_t tval, reg_t tval2, reg_t tinst) : mem_trap_t(n, gva, tval, tval2, tinst) {} \ + const char* name() { return "trap_"#x; } \ +}; + +#define DECLARE_MEM_NOGVA_TRAP(n, x) class trap_##x : public mem_trap_t { \ + public: \ + trap_##x(reg_t tval, reg_t tval2, reg_t tinst) : mem_trap_t(n, false, tval, tval2, tinst) {} \ + const char* name() { return "trap_"#x; } \ +}; + +#define DECLARE_MEM_GVA_TRAP(n, x) class trap_##x : public mem_trap_t { \ + public: \ trap_##x(reg_t tval, reg_t tval2, reg_t tinst) : mem_trap_t(n, true, tval, tval2, tinst) {} \ const char* name() { return "trap_"#x; } \ }; -DECLARE_MEM_TRAP(CAUSE_MISALIGNED_FETCH, instruction_address_misaligned) +DECLARE_MEM_NOGVA_TRAP(CAUSE_MISALIGNED_FETCH, instruction_address_misaligned) DECLARE_MEM_TRAP(CAUSE_FETCH_ACCESS, instruction_access_fault) DECLARE_INST_TRAP(CAUSE_ILLEGAL_INSTRUCTION, illegal_instruction) DECLARE_INST_TRAP(CAUSE_BREAKPOINT, breakpoint) -DECLARE_MEM_TRAP(CAUSE_MISALIGNED_LOAD, load_address_misaligned) -DECLARE_MEM_TRAP(CAUSE_MISALIGNED_STORE, store_address_misaligned) +DECLARE_MEM_NOGVA_TRAP(CAUSE_MISALIGNED_LOAD, load_address_misaligned) +DECLARE_MEM_NOGVA_TRAP(CAUSE_MISALIGNED_STORE, store_address_misaligned) DECLARE_MEM_TRAP(CAUSE_LOAD_ACCESS, load_access_fault) DECLARE_MEM_TRAP(CAUSE_STORE_ACCESS, store_access_fault) DECLARE_TRAP(CAUSE_USER_ECALL, user_ecall) @@ -87,9 +99,9 @@ DECLARE_TRAP(CAUSE_MACHINE_ECALL, machine_ecall) DECLARE_MEM_TRAP(CAUSE_FETCH_PAGE_FAULT, instruction_page_fault) DECLARE_MEM_TRAP(CAUSE_LOAD_PAGE_FAULT, load_page_fault) DECLARE_MEM_TRAP(CAUSE_STORE_PAGE_FAULT, store_page_fault) -DECLARE_MEM_TRAP(CAUSE_FETCH_GUEST_PAGE_FAULT, instruction_guest_page_fault) -DECLARE_MEM_TRAP(CAUSE_LOAD_GUEST_PAGE_FAULT, load_guest_page_fault) +DECLARE_MEM_GVA_TRAP(CAUSE_FETCH_GUEST_PAGE_FAULT, instruction_guest_page_fault) +DECLARE_MEM_GVA_TRAP(CAUSE_LOAD_GUEST_PAGE_FAULT, load_guest_page_fault) DECLARE_INST_TRAP(CAUSE_VIRTUAL_INSTRUCTION, virtual_instruction) -DECLARE_MEM_TRAP(CAUSE_STORE_GUEST_PAGE_FAULT, store_guest_page_fault) +DECLARE_MEM_GVA_TRAP(CAUSE_STORE_GUEST_PAGE_FAULT, store_guest_page_fault) #endif |