19
19
20
20
type pte_flags_bits = bits(8)
21
21
22
- // For PTW extensions (non-standard)
23
- type extPte = bits(64)
24
-
25
- // PRIVATE: extract msbs of PTE above the PPN
26
- function msbs_of_PTE(sv_params : SV_Params, pte : bits(64)) -> bits(64) = {
27
- let mask : bits(64) = zero_extend(ones(sv_params.pte_msbs_size_bits));
28
- (pte >> sv_params.pte_msbs_lsb_index) & mask
29
- }
30
-
31
- // PRIVATE: extract PPNs of PTE
32
- function PPNs_of_PTE(sv_params : SV_Params, pte : bits(64)) -> bits(64) = {
33
- let mask : bits(64) = zero_extend(ones(sv_params.pte_PPNs_size_bits));
34
- (pte >> sv_params.pte_PPNs_lsb_index) & mask
35
- }
36
-
37
22
// PRIVATE: 8 LSBs of PTEs in Sv32, Sv39, Sv48 and Sv57
38
23
bitfield PTE_Flags : pte_flags_bits = {
39
24
D : 7, // dirty
@@ -46,21 +31,50 @@ bitfield PTE_Flags : pte_flags_bits = {
46
31
V : 0 // Valid
47
32
}
48
33
34
+ /* Reserved PTE bits could be used by extensions on RV64. There are
35
+ * no such available bits on RV32, so these bits will be zeros on RV32.
36
+ */
37
+ type pte_ext_bits = bits(10)
38
+
39
+ bitfield PTE_Ext : pte_ext_bits = {
40
+ N : 9, /* NAPOT page table entry */
41
+ PBMT : 8 .. 7, /* Page based memory types */
42
+ reserved : 6 .. 0,
43
+ }
44
+
45
+ // PRIVATE: extract msbs of PTE above the PPN
46
+ function ext_bits_of_PTE(sv_params : SV_Params, pte : bits(64)) -> PTE_Ext = {
47
+ Mk_PTE_Ext(if sv_params.log_pte_size_bytes == 3 then pte[63 .. 54] else zeros())
48
+ }
49
+
50
+ // PRIVATE: extract PPNs of PTE
51
+ function PPNs_of_PTE(sv_params : SV_Params, pte : bits(64)) -> bits(64) = {
52
+ let mask : bits(64) = zero_extend(ones(sv_params.pte_PPNs_size_bits));
53
+ (pte >> sv_params.pte_PPNs_lsb_index) & mask
54
+ }
55
+
49
56
// PRIVATE: check if a PTE is a pointer to next level (non-leaf)
50
57
function pte_is_ptr(pte_flags : PTE_Flags) -> bool = (pte_flags[X] == 0b0)
51
58
& (pte_flags[W] == 0b0)
52
59
& (pte_flags[R] == 0b0)
53
60
54
61
// PRIVATE: check if a PTE is valid
55
- function pte_is_invalid(pte_flags : PTE_Flags) -> bool = (pte_flags[V] == 0b0)
56
- | ((pte_flags[W] == 0b1)
57
- & (pte_flags[R] == 0b0))
62
+ function pte_is_invalid(pte_flags : PTE_Flags, pte_ext : PTE_Ext) -> bool =
63
+ pte_flags[V] == 0b0
64
+ | (pte_flags[W] == 0b1 & pte_flags[R] == 0b0)
65
+ // Since version 1.12 of the spec, reserved bits must be zero.
66
+ | extensionEnabled(Ext_Sx1p12) & (
67
+ // If this is a non-leaf page, A/D/U bits are reserved
68
+ pte_is_ptr(pte_flags) & (pte_flags[A] @ pte_flags[D] @ pte_flags[U] != zeros())
69
+ // `pte_ext` contains bits for Svnapot and Svpbmt but these are not implemented yet.
70
+ | pte_ext.bits != zeros()
71
+ )
58
72
59
73
// ----------------
60
74
// Check access permissions in PTE
61
75
62
76
// For (non-standard) extensions: this function gets the extension-available bits
63
- // of the PTE in extPte , and the accumulated information of the page-table-walk
77
+ // of the PTE in PTE_Ext , and the accumulated information of the page-table-walk
64
78
// in ext_ptw. It should return the updated ext_ptw in both success and failure cases.
65
79
66
80
union PTE_Check = {
@@ -74,7 +88,7 @@ function check_PTE_permission(ac : AccessType(ext_access_type),
74
88
mxr : bool,
75
89
do_sum : bool,
76
90
pte_flags : PTE_Flags,
77
- ext : extPte ,
91
+ ext : PTE_Ext ,
78
92
ext_ptw : ext_ptw) -> PTE_Check = {
79
93
let pte_U = pte_flags[U];
80
94
let pte_R = pte_flags[R];
0 commit comments