aboutsummaryrefslogtreecommitdiff
path: root/riscv/mmu.cc
diff options
context:
space:
mode:
authorVed Shanbhogue <ved@rivosinc.com>2023-08-27 14:15:39 -0500
committerVed Shanbhogue <ved@rivosinc.com>2023-08-27 14:15:39 -0500
commitfd410c6f6f8ef7510d943d802ba2f885dc3f4778 (patch)
tree4e7b9ea207b1b0a24b004e0e51f96fb562ac38a7 /riscv/mmu.cc
parentae9888e50806837a3b6a39293c1014d9c7c37c56 (diff)
downloadriscv-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/mmu.cc')
-rw-r--r--riscv/mmu.cc24
1 files changed, 16 insertions, 8 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;
}
}