aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2020-11-29 16:06:32 -0800
committerGitHub <noreply@github.com>2020-11-29 16:06:32 -0800
commit4b04d715298c7c0542badf30828f65d1f02e1c1d (patch)
tree59d990f39ad60943bcc8a0a6f0d4192ab2407f2e
parentd6cf0d23635a53e5229e4ed317f1bcc58323b21a (diff)
parentd0d923ebdef92deb26ac0f02fb15e61e328c602a (diff)
downloadspike-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.cc30
-rw-r--r--riscv/mmu.h8
-rw-r--r--riscv/processor.cc2
-rw-r--r--riscv/trap.h24
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