aboutsummaryrefslogtreecommitdiff
path: root/riscv/mmu.h
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2017-02-08 14:16:08 -0800
committerAndrew Waterman <andrew@sifive.com>2017-02-08 14:16:08 -0800
commita30f1583002563aaae6a0e83c43300eaf81e646e (patch)
tree268f03b6d3fb941a15b9398abe84d10f65c49875 /riscv/mmu.h
parentdaaf28f7296c0a5f5c90fe6646a4f8a73a720af5 (diff)
downloadspike-a30f1583002563aaae6a0e83c43300eaf81e646e.zip
spike-a30f1583002563aaae6a0e83c43300eaf81e646e.tar.gz
spike-a30f1583002563aaae6a0e83c43300eaf81e646e.tar.bz2
Encode VM type in sptbr, not mstatus
https://github.com/riscv/riscv-isa-manual/issues/4 Also, refactor gdbserver code to not duplicate VM decoding logic.
Diffstat (limited to 'riscv/mmu.h')
-rw-r--r--riscv/mmu.h31
1 files changed, 31 insertions, 0 deletions
diff --git a/riscv/mmu.h b/riscv/mmu.h
index 34bcf99..9365457 100644
--- a/riscv/mmu.h
+++ b/riscv/mmu.h
@@ -260,4 +260,35 @@ private:
friend class processor_t;
};
+struct vm_info {
+ int levels;
+ int idxbits;
+ int ptesize;
+ reg_t ptbase;
+};
+
+inline vm_info decode_vm_info(int xlen, reg_t prv, reg_t sptbr)
+{
+ if (prv == PRV_M) {
+ return {0, 0, 0, 0};
+ } else if (prv <= PRV_S && xlen == 32) {
+ switch (get_field(sptbr, SPTBR32_MODE)) {
+ case SPTBR_MODE_OFF: return {0, 0, 0, 0};
+ case SPTBR_MODE_SV32: return {2, 10, 4, (sptbr & SPTBR32_PPN) << PGSHIFT};
+ default: abort();
+ }
+ } else if (prv <= PRV_S && xlen == 64) {
+ switch (get_field(sptbr, SPTBR64_MODE)) {
+ case SPTBR_MODE_OFF: return {0, 0, 0, 0};
+ case SPTBR_MODE_SV39: return {3, 9, 8, (sptbr & SPTBR64_PPN) << PGSHIFT};
+ case SPTBR_MODE_SV48: return {4, 9, 8, (sptbr & SPTBR64_PPN) << PGSHIFT};
+ case SPTBR_MODE_SV57: return {5, 9, 8, (sptbr & SPTBR64_PPN) << PGSHIFT};
+ case SPTBR_MODE_SV64: return {6, 9, 8, (sptbr & SPTBR64_PPN) << PGSHIFT};
+ default: abort();
+ }
+ } else {
+ abort();
+ }
+}
+
#endif