diff options
author | Ved Shanbhogue <ved@rivosinc.com> | 2023-08-27 14:15:39 -0500 |
---|---|---|
committer | Ved Shanbhogue <ved@rivosinc.com> | 2023-08-27 14:15:39 -0500 |
commit | fd410c6f6f8ef7510d943d802ba2f885dc3f4778 (patch) | |
tree | 4e7b9ea207b1b0a24b004e0e51f96fb562ac38a7 /riscv | |
parent | ae9888e50806837a3b6a39293c1014d9c7c37c56 (diff) | |
download | riscv-isa-sim-fd410c6f6f8ef7510d943d802ba2f885dc3f4778.zip riscv-isa-sim-fd410c6f6f8ef7510d943d802ba2f885dc3f4778.tar.gz riscv-isa-sim-fd410c6f6f8ef7510d943d802ba2f885dc3f4778.tar.bz2 |
report right pseudo-inst for guest PF caused for VS-stage addr trans
Diffstat (limited to 'riscv')
-rw-r--r-- | riscv/mmu.cc | 24 | ||||
-rw-r--r-- | riscv/mmu.h | 2 |
2 files changed, 17 insertions, 9 deletions
diff --git a/riscv/mmu.cc b/riscv/mmu.cc index 1473e89..165be53 100644 --- a/riscv/mmu.cc +++ b/riscv/mmu.cc @@ -387,7 +387,7 @@ reg_t mmu_t::pmp_homogeneous(reg_t addr, reg_t len) return true; } -reg_t mmu_t::s2xlate(reg_t gva, reg_t gpa, access_type type, access_type trap_type, bool virt, bool hlvx) +reg_t mmu_t::s2xlate(reg_t gva, reg_t gpa, access_type type, access_type trap_type, bool virt, bool hlvx, bool is_for_vs_pt_addr) { if (!virt) return gpa; @@ -400,6 +400,14 @@ reg_t mmu_t::s2xlate(reg_t gva, reg_t gpa, access_type type, access_type trap_ty reg_t maxgpa = (1ULL << maxgpabits) - 1; bool mxr = proc->state.sstatus->readvirt(false) & MSTATUS_MXR; + // tinst is set to 0x3000/0x3020 - for RV64 read/write respectively for + // VS-stage address translation (for spike HSXLEN == VSXLEN always) else + // tinst is set to 0x2000/0x2020 - for RV32 read/write respectively for + // VS-stage address translation else set to 0 + int tinst = 0; + tinst |= (is_for_vs_pt_addr == true) ? 0x2000 : 0; + tinst |= ((proc->get_const_xlen() == 64) && (is_for_vs_pt_addr == true)) ? 0x1000 : 0; + tinst |= ((type == STORE) && (is_for_vs_pt_addr == true)) ? 0x0020 : 0; reg_t base = vm.ptbase; if ((gpa & ~maxgpa) == 0) { @@ -466,9 +474,9 @@ reg_t mmu_t::s2xlate(reg_t gva, reg_t gpa, access_type type, access_type trap_ty } switch (trap_type) { - case FETCH: throw trap_instruction_guest_page_fault(gva, gpa >> 2, 0); - case LOAD: throw trap_load_guest_page_fault(gva, gpa >> 2, 0); - case STORE: throw trap_store_guest_page_fault(gva, gpa >> 2, 0); + case FETCH: throw trap_instruction_guest_page_fault(gva, gpa >> 2, tinst); + case LOAD: throw trap_load_guest_page_fault(gva, gpa >> 2, tinst); + case STORE: throw trap_store_guest_page_fault(gva, gpa >> 2, tinst); default: abort(); } } @@ -484,7 +492,7 @@ reg_t mmu_t::walk(mem_access_info_t access_info) reg_t satp = proc->get_state()->satp->readvirt(virt); vm_info vm = decode_vm_info(proc->get_const_xlen(), false, mode, satp); if (vm.levels == 0) - return s2xlate(addr, addr & ((reg_t(2) << (proc->xlen-1))-1), type, type, virt, hlvx) & ~page_mask; // zero-extend from xlen + return s2xlate(addr, addr & ((reg_t(2) << (proc->xlen-1))-1), type, type, virt, hlvx, false) & ~page_mask; // zero-extend from xlen bool s_mode = mode == PRV_S; bool sum = proc->state.sstatus->readvirt(virt) & MSTATUS_SUM; @@ -503,7 +511,7 @@ reg_t mmu_t::walk(mem_access_info_t access_info) reg_t idx = (addr >> (PGSHIFT + ptshift)) & ((1 << vm.idxbits) - 1); // check that physical address of PTE is legal - auto pte_paddr = s2xlate(addr, base + idx * vm.ptesize, LOAD, type, virt, false); + auto pte_paddr = s2xlate(addr, base + idx * vm.ptesize, LOAD, type, virt, false, true); reg_t pte = pte_load(pte_paddr, addr, virt, type, vm.ptesize); reg_t ppn = (pte & ~reg_t(PTE_ATTR)) >> PTE_PPN_SHIFT; bool pbmte = virt ? (proc->get_state()->henvcfg->read() & HENVCFG_PBMTE) : (proc->get_state()->menvcfg->read() & MENVCFG_PBMTE); @@ -538,7 +546,7 @@ reg_t mmu_t::walk(mem_access_info_t access_info) if (hade) { // Check for write permission to the first-stage PT in second-stage // PTE and set the D bit in the second-stage PTE if needed - s2xlate(addr, base + idx * vm.ptesize, STORE, type, virt, false); + s2xlate(addr, base + idx * vm.ptesize, STORE, type, virt, false, true); // set accessed and possibly dirty bits. pte_store(pte_paddr, pte | ad, addr, virt, type, vm.ptesize); } else { @@ -558,7 +566,7 @@ reg_t mmu_t::walk(mem_access_info_t access_info) | (vpn & ((reg_t(1) << napot_bits) - 1)) | (vpn & ((reg_t(1) << ptshift) - 1))) << PGSHIFT; reg_t phys = page_base | (addr & page_mask); - return s2xlate(addr, phys, type, type, virt, hlvx) & ~page_mask; + return s2xlate(addr, phys, type, type, virt, hlvx, false) & ~page_mask; } } diff --git a/riscv/mmu.h b/riscv/mmu.h index ce50527..a163fe4 100644 --- a/riscv/mmu.h +++ b/riscv/mmu.h @@ -391,7 +391,7 @@ private: const char* fill_from_mmio(reg_t vaddr, reg_t paddr); // perform a stage2 translation for a given guest address - reg_t s2xlate(reg_t gva, reg_t gpa, access_type type, access_type trap_type, bool virt, bool hlvx); + reg_t s2xlate(reg_t gva, reg_t gpa, access_type type, access_type trap_type, bool virt, bool hlvx, bool is_for_vs_pt_addr); // perform a page table walk for a given VA; set referenced/dirty bits reg_t walk(mem_access_info_t access_info); |