aboutsummaryrefslogtreecommitdiff
path: root/model/riscv_vmem_common.sail
diff options
context:
space:
mode:
authorPrashanth Mundkur <prashanth.mundkur@gmail.com>2019-02-13 15:14:47 -0800
committerPrashanth Mundkur <prashanth.mundkur@gmail.com>2019-02-13 15:14:47 -0800
commit10c9d1f5529c8972e5898513e297c29b3b10f53b (patch)
tree25e26eed1605b6cd9f8d9afbf0d2e6cbd86035d8 /model/riscv_vmem_common.sail
parent82e1ad350fb49deedb7ac9d79a45bc6185844f78 (diff)
downloadsail-riscv-10c9d1f5529c8972e5898513e297c29b3b10f53b.zip
sail-riscv-10c9d1f5529c8972e5898513e297c29b3b10f53b.tar.gz
sail-riscv-10c9d1f5529c8972e5898513e297c29b3b10f53b.tar.bz2
Attempt to reuse types for Sv39 and Sv48 to the extent possible for simplicity. This might need revisiting for Sv59 and Sv64.
Diffstat (limited to 'model/riscv_vmem_common.sail')
-rw-r--r--model/riscv_vmem_common.sail136
1 files changed, 81 insertions, 55 deletions
diff --git a/model/riscv_vmem_common.sail b/model/riscv_vmem_common.sail
index bf83b23..105cf90 100644
--- a/model/riscv_vmem_common.sail
+++ b/model/riscv_vmem_common.sail
@@ -95,17 +95,41 @@ function translationException(a : AccessType, f : PTW_Error) -> ExceptionType =
}
}
-/* Sv32 parameters and bitfield layouts */
-
-let SV32_LEVEL_BITS = 9
-let SV32_LEVELS = 2
-let PTE32_LOG_SIZE = 2
-let PTE32_SIZE = 4
+/*
+ * Definitions for RV32, which has a single address translation mode: Sv32.
+ */
type vaddr32 = bits(32)
type paddr32 = bits(34)
type pte32 = bits(32)
+/* result of address translation */
+union TR32_Result = {
+ TR32_Address : paddr32,
+ TR32_Failure : PTW_Error
+}
+
+/* asid */
+type asid32 = bits(9)
+
+function curAsid32(satp : bits(32)) -> asid32 = {
+ let s = Mk_Satp32(satp);
+ s.Asid()
+}
+
+/* page table base from satp */
+function curPTB32(satp : bits(32)) -> paddr32 = {
+ let s : Satp32 = Mk_Satp32(satp);
+ shiftl(EXTZ(s.PPN()), PAGESIZE_BITS)
+}
+
+/* Sv32 parameters and bitfield layouts */
+
+let SV32_LEVEL_BITS = 9
+let SV32_LEVELS = 2
+let PTE32_LOG_SIZE = 2
+let PTE32_SIZE = 4
+
bitfield SV32_Vaddr : vaddr32 = {
VPNi : 31 .. 12,
PgOfs : 11 .. 0
@@ -118,61 +142,82 @@ bitfield SV32_Paddr : paddr32 = {
bitfield SV32_PTE : pte32 = {
PPNi : 31 .. 10,
- RSW : 9 .. 8,
- BITS : 7 .. 0
+ RSW : 9 .. 8,
+ BITS : 7 .. 0
}
-/* RV32: ASID */
+/*
+ * Definitions for RV64, which has two defined address translation modes: Sv39 and Sv48.
+ */
-type asid32 = bits(9)
+/* Sv48 and Sv64 are reserved but not defined. The size of the VPN
+ * increases by 9 bits through Sv39, Sv48 and Sv57, but not for Sv64.
+ * Also, the 45-bit size of the VPN for Sv57 exceeds the 44-bit size
+ * of the PPN in satp64. Due to these corner cases, it is unlikely
+ * that definitions can be shared across all four schemes, so separate
+ * definitions might eventually be needed for each translation mode.
+ *
+ * But to keep things simple for now, since Sv39 and Sv48 have the
+ * same PPN size, we share some definitions.
+ */
-function curAsid32(satp : bits(32)) -> asid32 = {
- let s = Mk_Satp32(satp);
+type paddr64 = bits(56)
+type pte64 = bits(64)
+
+/* result of address translation */
+union TR64_Result = {
+ TR64_Address : paddr64,
+ TR64_Failure : PTW_Error
+}
+
+/* asid */
+
+type asid64 = bits(16)
+
+function curAsid64(satp : bits(64)) -> asid64 = {
+ let s = Mk_Satp64(satp);
s.Asid()
}
-/* RV32: Current page table base from satp */
-function curPTB32(satp : bits(32)) -> paddr32 = {
- let s : Satp32 = Mk_Satp32(satp);
+/* page table base from satp */
+function curPTB64(satp : bits(64)) -> paddr64 = {
+ let s = Mk_Satp64(satp);
shiftl(EXTZ(s.PPN()), PAGESIZE_BITS)
}
/* Sv39 parameters and bitfield layouts */
let SV39_LEVEL_BITS = 9
-let SV39_LEVELS = 3
-let PTE39_LOG_SIZE = 3
-let PTE39_SIZE = 8
+let SV39_LEVELS = 3
+let PTE39_LOG_SIZE = 3
+let PTE39_SIZE = 8
type vaddr39 = bits(39)
-type paddr39 = bits(56)
-type pte39 = bits(64)
bitfield SV39_Vaddr : vaddr39 = {
VPNi : 38 .. 12,
PgOfs : 11 .. 0
}
-bitfield SV39_Paddr : paddr39 = {
+bitfield SV39_Paddr : paddr64 = {
PPNi : 55 .. 12,
PgOfs : 11 .. 0
}
-bitfield SV39_PTE : pte39 = {
+bitfield SV39_PTE : pte64 = {
PPNi : 53 .. 10,
- RSW : 9 .. 8,
- BITS : 7 .. 0
+ RSW : 9 .. 8,
+ BITS : 7 .. 0
}
/* Sv48 parameters and bitfield layouts */
let SV48_LEVEL_BITS = 9
-let SV48_LEVELS = 4
-let PTE48_LOG_SIZE = 3
-let PTE48_SIZE = 8
+let SV48_LEVELS = 4
+let PTE48_LOG_SIZE = 3
+let PTE48_SIZE = 8
type vaddr48 = bits(48)
-type paddr48 = bits(56)
type pte48 = bits(64)
bitfield SV48_Vaddr : vaddr48 = {
@@ -180,36 +225,21 @@ bitfield SV48_Vaddr : vaddr48 = {
PgOfs : 11 .. 0
}
-bitfield SV48_Paddr : paddr48 = {
+bitfield SV48_Paddr : paddr64 = {
PPNi : 55 .. 12,
PgOfs : 11 .. 0
}
bitfield SV48_PTE : pte48 = {
PPNi : 53 .. 10,
- RSW : 9 .. 8,
- BITS : 7 .. 0
-}
-
-/* RV64: ASID */
-
-type asid64 = bits(16)
-
-function curAsid64(satp : bits(64)) -> asid64 = {
- let s = Mk_Satp64(satp);
- s.Asid()
-}
-
-/* RV64: Current page table base from satp */
-function curPTB39(satp : bits(64)) -> paddr39 = {
- let s = Mk_Satp64(satp);
- EXTZ(shiftl(s.PPN(), PAGESIZE_BITS))
+ RSW : 9 .. 8,
+ BITS : 7 .. 0
}
/* Result of a page-table walk. */
union PTW_Result = {
- PTW_Success: (paddr39, SV39_PTE, paddr39, nat, bool),
+ PTW_Success: (paddr64, SV39_PTE, paddr64, nat, bool),
PTW_Failure: PTW_Error
}
@@ -219,16 +249,16 @@ struct TLB39_Entry = {
asid : asid64,
global : bool,
vAddr : vaddr39, /* VPN */
- pAddr : paddr39, /* PPN */
+ pAddr : paddr64, /* PPN */
vMatchMask : vaddr39, /* matching mask for superpages */
vAddrMask : vaddr39, /* selection mask for superpages */
pte : SV39_PTE, /* permissions */
- pteAddr : paddr39, /* for dirty writeback */
+ pteAddr : paddr64, /* for dirty writeback */
age : xlenbits
}
/* the rreg effect is an artifact of using the cycle counter to provide the age */
-val make_TLB39_Entry : (asid64, bool, vaddr39, paddr39, SV39_PTE, nat, paddr39) -> TLB39_Entry effect {rreg}
+val make_TLB39_Entry : (asid64, bool, vaddr39, paddr64, SV39_PTE, nat, paddr64) -> TLB39_Entry effect {rreg}
function make_TLB39_Entry(asid, global, vAddr, pAddr, pte, level, pteAddr) = {
let shift : nat = PAGESIZE_BITS + (level * SV39_LEVEL_BITS);
@@ -262,7 +292,7 @@ function lookupTLB39(asid, vaddr) = {
}
}
-val addToTLB39 : (asid64, vaddr39, paddr39, SV39_PTE, paddr39, nat, bool) -> unit effect {wreg, rreg}
+val addToTLB39 : (asid64, vaddr39, paddr64, SV39_PTE, paddr64, nat, bool) -> unit effect {wreg, rreg}
function addToTLB39(asid, vAddr, pAddr, pte, pteAddr, level, global) = {
let ent = make_TLB39_Entry(asid, global, vAddr, pAddr, pte, level, pteAddr);
tlb39 = Some(ent)
@@ -288,7 +318,3 @@ function flushTLB(asid, addr) = {
tlb39 = ent
}
-union TR39_Result = {
- TR39_Address : paddr39,
- TR39_Failure : PTW_Error
-}