diff options
author | Anup Patel <anup.patel@wdc.com> | 2020-11-27 11:30:48 +0530 |
---|---|---|
committer | Anup Patel <anup@brainfault.org> | 2020-11-27 11:30:48 +0530 |
commit | 457f628ad78efa305283ae6cc4dc1530fceffbe4 (patch) | |
tree | 59a8895ea1f9f9eb555594ca898ead683980aee1 /riscv | |
parent | d6cf0d23635a53e5229e4ed317f1bcc58323b21a (diff) | |
download | riscv-isa-sim-457f628ad78efa305283ae6cc4dc1530fceffbe4.zip riscv-isa-sim-457f628ad78efa305283ae6cc4dc1530fceffbe4.tar.gz riscv-isa-sim-457f628ad78efa305283ae6cc4dc1530fceffbe4.tar.bz2 |
Fix hstatus.GVA and mstatus.GVA updation
The hstatus.GVA and mstatus.GVA should be set only when guest virtual
address is written to stval or mtval CSRs at time of taking trap.
This patch update access, page fault, and guest page fault trap classes
so that we can pass gva flag correct from source of the trap.
Signed-off-by: Anup Patel <anup.patel@wdc.com>
Diffstat (limited to 'riscv')
-rw-r--r-- | riscv/mmu.cc | 30 | ||||
-rw-r--r-- | riscv/mmu.h | 8 | ||||
-rw-r--r-- | riscv/trap.h | 24 |
3 files changed, 37 insertions, 25 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/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 |