diff options
author | Daniel Lustig <dlustig@nvidia.com> | 2021-07-20 13:30:16 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-20 10:30:16 -0700 |
commit | cb8f09a4d6fed30527fdd832b885c898b4591a5f (patch) | |
tree | d29859362cdb20f83e57899bacdfad628756c92d /riscv | |
parent | ec6f7b08ff59929313de1cff90973f34c5747ea9 (diff) | |
download | spike-cb8f09a4d6fed30527fdd832b885c898b4591a5f.zip spike-cb8f09a4d6fed30527fdd832b885c898b4591a5f.tar.gz spike-cb8f09a4d6fed30527fdd832b885c898b4591a5f.tar.bz2 |
Priv virtual memory updates (#750)
* Priv virtual memory updates
* Priv 1.12 requires page faults when the address translation process
reaches a PTE with any reserved bit set
* Svpbmt uses two PTE bits, but otherwise has no effect on Spike (since
Spike is sequentially consistent and does not model PMAs)
* Add Svinval instructions
Even though I updated riscv-opcodes separately, I merged the new
defines into riscv/encoding.h manually, because riscv-opcodes seems
to be a step ahead of riscv-isa-sim for a few vector opcodes, causing
conflicts when regenerating encoding.h...
If that gets fixed, and encoding.h gets regenerated automatically, I can
remove it from this PR to avoid conflicts.
* Svinval: use #include rather than copying code
..for the Svinval functions that are implemented in ways that just
mimic SFENCE/HFENCE instructions
Thanks to @aswaterman for the suggestion
Diffstat (limited to 'riscv')
-rw-r--r-- | riscv/encoding.h | 18 | ||||
-rw-r--r-- | riscv/insns/hinval_gvma.h | 1 | ||||
-rw-r--r-- | riscv/insns/hinval_vvma.h | 1 | ||||
-rw-r--r-- | riscv/insns/sfence_inval_ir.h | 2 | ||||
-rw-r--r-- | riscv/insns/sfence_w_inval.h | 2 | ||||
-rw-r--r-- | riscv/insns/sinval_vma.h | 1 | ||||
-rw-r--r-- | riscv/mmu.cc | 12 | ||||
-rw-r--r-- | riscv/riscv.mk.in | 7 |
8 files changed, 40 insertions, 4 deletions
diff --git a/riscv/encoding.h b/riscv/encoding.h index dfc3b75..bde53a4 100644 --- a/riscv/encoding.h +++ b/riscv/encoding.h @@ -221,7 +221,10 @@ #define PTE_A 0x040 /* Accessed */ #define PTE_D 0x080 /* Dirty */ #define PTE_SOFT 0x300 /* Reserved for Software */ +#define PTE_RSVD 0x1FC0000000000000 /* Reserved for future standard use */ +#define PTE_PBMT 0x6000000000000000 /* Svpbmt: Page-based memory types */ #define PTE_N 0x8000000000000000 /* Svnapot: NAPOT translation contiguity */ +#define PTE_ATTR 0xFFC0000000000000 /* All attributes and reserved bits */ #define PTE_PPN_SHIFT 10 @@ -1020,6 +1023,16 @@ #define MASK_CSRRSI 0x707f #define MATCH_CSRRCI 0x7073 #define MASK_CSRRCI 0x707f +#define MATCH_SINVAL_VMA 0x16000073 +#define MASK_SINVAL_VMA 0xfe007fff +#define MATCH_SFENCE_W_INVAL 0x18000073 +#define MASK_SFENCE_W_INVAL 0xfff07fff +#define MATCH_SFENCE_INVAL_IR 0x18100073 +#define MASK_SFENCE_INVAL_IR 0xfff07fff +#define MATCH_HINVAL_VVMA 0x36000073 +#define MASK_HINVAL_VVMA 0xfe007fff +#define MATCH_HINVAL_GVMA 0x76000073 +#define MASK_HINVAL_GVMA 0xfe007fff #define MATCH_FADD_H 0x4000053 #define MASK_FADD_H 0xfe00007f #define MATCH_FSUB_H 0xc000053 @@ -3475,6 +3488,11 @@ DECLARE_INSN(csrrc, MATCH_CSRRC, MASK_CSRRC) DECLARE_INSN(csrrwi, MATCH_CSRRWI, MASK_CSRRWI) DECLARE_INSN(csrrsi, MATCH_CSRRSI, MASK_CSRRSI) DECLARE_INSN(csrrci, MATCH_CSRRCI, MASK_CSRRCI) +DECLARE_INSN(sinval_vma, MATCH_SINVAL_VMA, MASK_SINVAL_VMA) +DECLARE_INSN(sfence_w_inval, MATCH_SFENCE_W_INVAL, MASK_SFENCE_W_INVAL) +DECLARE_INSN(sfence_inval_ir, MATCH_SFENCE_INVAL_IR, MASK_SFENCE_INVAL_IR) +DECLARE_INSN(hinval_vvma, MATCH_HINVAL_VVMA, MASK_HINVAL_VVMA) +DECLARE_INSN(hinval_gvma, MATCH_HINVAL_GVMA, MASK_HINVAL_GVMA) DECLARE_INSN(fadd_h, MATCH_FADD_H, MASK_FADD_H) DECLARE_INSN(fsub_h, MATCH_FSUB_H, MASK_FSUB_H) DECLARE_INSN(fmul_h, MATCH_FMUL_H, MASK_FMUL_H) diff --git a/riscv/insns/hinval_gvma.h b/riscv/insns/hinval_gvma.h new file mode 100644 index 0000000..d8fd29d --- /dev/null +++ b/riscv/insns/hinval_gvma.h @@ -0,0 +1 @@ +#include "hfence_gvma.h" diff --git a/riscv/insns/hinval_vvma.h b/riscv/insns/hinval_vvma.h new file mode 100644 index 0000000..9206037 --- /dev/null +++ b/riscv/insns/hinval_vvma.h @@ -0,0 +1 @@ +#include "hfence_vvma.h" diff --git a/riscv/insns/sfence_inval_ir.h b/riscv/insns/sfence_inval_ir.h new file mode 100644 index 0000000..10d8dd6 --- /dev/null +++ b/riscv/insns/sfence_inval_ir.h @@ -0,0 +1,2 @@ +require_extension('S'); +require_impl(IMPL_MMU); diff --git a/riscv/insns/sfence_w_inval.h b/riscv/insns/sfence_w_inval.h new file mode 100644 index 0000000..10d8dd6 --- /dev/null +++ b/riscv/insns/sfence_w_inval.h @@ -0,0 +1,2 @@ +require_extension('S'); +require_impl(IMPL_MMU); diff --git a/riscv/insns/sinval_vma.h b/riscv/insns/sinval_vma.h new file mode 100644 index 0000000..385b2de --- /dev/null +++ b/riscv/insns/sinval_vma.h @@ -0,0 +1 @@ +#include "sfence_vma.h" diff --git a/riscv/mmu.cc b/riscv/mmu.cc index 39c2a15..bc2dcc8 100644 --- a/riscv/mmu.cc +++ b/riscv/mmu.cc @@ -328,9 +328,11 @@ reg_t mmu_t::s2xlate(reg_t gva, reg_t gpa, access_type type, access_type trap_ty } 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; + reg_t ppn = (pte & ~reg_t(PTE_ATTR)) >> PTE_PPN_SHIFT; - if (PTE_TABLE(pte)) { // next level of page table + if (pte & PTE_RSVD) { + break; + } else if (PTE_TABLE(pte)) { // next level of page table base = ppn << PGSHIFT; } else if (!(pte & PTE_V) || (!(pte & PTE_R) && (pte & PTE_W))) { break; @@ -408,9 +410,11 @@ reg_t mmu_t::walk(reg_t addr, access_type type, reg_t mode, bool virt, bool mxr) 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; + reg_t ppn = (pte & ~reg_t(PTE_ATTR)) >> PTE_PPN_SHIFT; - if (PTE_TABLE(pte)) { // next level of page table + if (pte & PTE_RSVD) { + break; + } else if (PTE_TABLE(pte)) { // next level of page table base = ppn << PGSHIFT; } else if ((pte & PTE_U) ? s_mode && (type == FETCH || !sum) : !s_mode) { break; diff --git a/riscv/riscv.mk.in b/riscv/riscv.mk.in index dffbd58..bb7b374 100644 --- a/riscv/riscv.mk.in +++ b/riscv/riscv.mk.in @@ -1262,6 +1262,12 @@ riscv_insn_priv = \ sret \ wfi \ +riscv_insn_svinval = \ + sfence_w_inval \ + sfence_inval_ir \ + sinval_vma \ + hinval_vvma \ + hinval_gvma \ riscv_insn_list = \ $(riscv_insn_ext_a) \ @@ -1278,6 +1284,7 @@ riscv_insn_list = \ $(riscv_insn_ext_h) \ $(riscv_insn_ext_p) \ $(riscv_insn_priv) \ + $(riscv_insn_svinval) \ riscv_gen_srcs = \ $(addsuffix .cc,$(riscv_insn_list)) |