@@ -4,290 +4,174 @@ use bit_field::BitField;
4
4
/// Permission enum contains all possible permission modes for pmp registers
5
5
#[ derive( Clone , Copy , Debug ) ]
6
6
pub enum Permission {
7
- NONE = 0b_000 ,
8
- R = 0b_001 ,
9
- W = 0b_010 ,
10
- RW = 0b_011 ,
11
- X = 0b_100 ,
12
- RX = 0b_101 ,
13
- WX = 0b_110 ,
14
- RWX = 0b_111 ,
7
+ NONE = 0b000 ,
8
+ R = 0b001 ,
9
+ W = 0b010 ,
10
+ RW = 0b011 ,
11
+ X = 0b100 ,
12
+ RX = 0b101 ,
13
+ WX = 0b110 ,
14
+ RWX = 0b111 ,
15
15
}
16
16
17
17
/// Range enum contains all possible addressing modes for pmp registers
18
18
#[ derive( Clone , Copy , Debug ) ]
19
19
pub enum Range {
20
- OFF = 0b_00 ,
21
- TOR = 0b_01 ,
22
- NA4 = 0b_10 ,
23
- NAPOT = 0b_11 ,
20
+ OFF = 0b00 ,
21
+ TOR = 0b01 ,
22
+ NA4 = 0b10 ,
23
+ NAPOT = 0b11 ,
24
24
}
25
25
26
+ /// RV64 Pmpcfg holds the entire register (8 Pmp configurations)
26
27
#[ derive( Clone , Copy , Debug ) ]
27
- pub struct Pmpcfg {
28
- pub bits : usize ,
28
+ pub struct Pmp {
29
+ /// raw bits
30
+ pub byte : u8 ,
31
+ /// Current PMP Permission
32
+ pub permission : Permission ,
33
+ /// Current PMP Range
34
+ pub range : Range ,
35
+ /// Is PMP locked?
36
+ pub locked : bool ,
29
37
}
30
38
31
- /// PmpByte holds the a single pmp configuration
32
- #[ derive( Clone , Copy , Debug ) ]
33
- pub struct PmpEntry {
34
- pub byte : usize ,
35
- pub index : usize ,
36
- pub permission : Option < Permission > ,
37
- pub range : Option < Range > ,
38
- pub locked : bool ,
39
+ pub struct Pmpcsr {
40
+ /// Holds the raw contents of the PMP CSR
41
+ pub bits : usize ,
39
42
}
40
43
41
- impl Pmpcfg {
44
+ impl Pmpcsr {
45
+ /// Take the register contents and translate into configurations held in a Pmpcfg struct
46
+ /// Takes `self` as a parameter and destroys the current Pmpcsr struct
42
47
#[ inline]
43
- pub fn get_config ( & self , index : usize ) -> PmpEntry {
48
+ pub fn into_config ( & self , index : usize ) -> Pmp {
44
49
#[ cfg( riscv32) ]
45
50
assert ! ( index < 4 ) ;
46
51
47
52
#[ cfg( riscv64) ]
48
53
assert ! ( index < 8 ) ;
49
54
50
- PmpEntry {
51
- byte : self . get_byte ( index) ,
52
- index,
53
- permission : self . get_permission ( index) ,
54
- range : self . get_range ( index) ,
55
- locked : self . is_locked ( index) ,
56
- }
57
- }
58
-
59
- /// PmpByte methods to get a pmp configuration attributes
60
- pub fn get_byte ( & self , index : usize ) -> usize {
61
- self . bits . get_bits ( 8 * index..=( 8 * index) + 7 ) as usize
62
- }
63
-
64
- #[ inline]
65
- pub fn is_locked ( & self , index : usize ) -> bool {
66
- self . bits . get_bit ( 7 + 8 * index)
67
- }
68
-
69
- #[ inline]
70
- pub fn get_permission ( & self , index : usize ) -> Option < Permission > {
71
- match self . bits . get_bits ( 8 * index..=8 * index + 2 ) {
72
- 0 => Some ( Permission :: NONE ) ,
73
- 1 => Some ( Permission :: R ) ,
74
- 2 => Some ( Permission :: W ) ,
75
- 3 => Some ( Permission :: RW ) ,
76
- 4 => Some ( Permission :: X ) ,
77
- 5 => Some ( Permission :: RX ) ,
78
- 6 => Some ( Permission :: WX ) ,
79
- 7 => Some ( Permission :: RWX ) ,
80
- _ => unreachable ! ( ) ,
81
- }
82
- }
83
-
84
- #[ inline]
85
- pub fn get_range ( & self , index : usize ) -> Option < Range > {
86
- match self . bits . get_bits ( 8 * index + 3 ..=8 * index + 4 ) {
87
- 0 => Some ( Range :: OFF ) ,
88
- 1 => Some ( Range :: TOR ) ,
89
- 2 => Some ( Range :: NA4 ) ,
90
- 3 => Some ( Range :: NAPOT ) ,
91
- _ => unreachable ! ( ) ,
55
+ let byte = self . bits . get_bits ( 8 * index..=8 * index + 7 ) as u8 ;
56
+ Pmp {
57
+ byte,
58
+ permission : match byte. get_bits ( 0 ..=2 ) {
59
+ 0 => Permission :: NONE ,
60
+ 1 => Permission :: R ,
61
+ 2 => Permission :: W ,
62
+ 3 => Permission :: RW ,
63
+ 4 => Permission :: X ,
64
+ 5 => Permission :: RX ,
65
+ 6 => Permission :: WX ,
66
+ 7 => Permission :: RWX ,
67
+ _ => unreachable ! ( ) ,
68
+ } ,
69
+ range : match byte. get_bits ( 3 ..=4 ) {
70
+ 0 => Range :: OFF ,
71
+ 1 => Range :: TOR ,
72
+ 2 => Range :: NA4 ,
73
+ 3 => Range :: NAPOT ,
74
+ _ => unreachable ! ( ) ,
75
+ } ,
76
+ locked : byte. get_bit ( 7 ) as bool ,
92
77
}
93
78
}
94
79
}
80
+
95
81
/// Physical memory protection configuration
96
- /// Pmpcfg0 struct contains pmp0cfg - pmp3cfg for RV32, or pmp0cfg - pmp7cfg for RV64
97
- /// get_byte() method retrieves a single pmp<x>cfg held in a PmpByte struct
98
- pub mod pmpcfg0 {
99
- use super :: { Permission , Pmpcfg , Range } ;
82
+ /// pmpcfg0 struct contains pmp0cfg - pmp3cfg for RV32, and pmp0cfg - pmp7cfg for RV64
83
+ mod pmpcfg0 {
84
+ use super :: { Permission , Pmpcsr , Range } ;
100
85
use bit_field:: BitField ;
101
86
102
- read_csr_as ! ( Pmpcfg , 0x3A0 , __read_pmpcfg0) ;
103
- write_csr ! ( 0x3A0 , __write_pmpcfg0) ;
87
+ read_csr_as ! ( Pmpcsr , 0x3A0 , __read_pmpcfg0) ;
88
+ write_csr_as_usize ! ( 0x3A0 , __write_pmpcfg0) ;
104
89
set ! ( 0x3A0 , __set_pmpcfg0) ;
105
90
clear ! ( 0x3A0 , __clear_pmpcfg0) ;
106
91
107
- #[ inline]
108
- pub unsafe fn set_permissions ( permission : Permission , index : usize ) {
109
- #[ cfg( riscv32) ]
110
- assert ! ( index < 4 ) ;
111
-
112
- #[ cfg( riscv64) ]
113
- assert ! ( index < 8 ) ;
114
-
115
- let mut value = _read ( ) ;
116
- value. set_bits ( 8 * index..=8 * index + 2 , permission as usize ) ;
117
- _write ( value) ;
118
- }
119
-
120
- #[ inline]
121
- pub unsafe fn set_range ( range : Range , index : usize ) {
92
+ /// set the configuration for pmp(x)
93
+ pub unsafe fn set_pmp ( index : usize , range : Range , permission : Permission , locked : bool ) {
122
94
#[ cfg( riscv32) ]
123
95
assert ! ( index < 4 ) ;
124
96
125
97
#[ cfg( riscv64) ]
126
98
assert ! ( index < 8 ) ;
127
99
128
100
let mut value = _read ( ) ;
129
- value. set_bits ( 8 * index + 3 ..=8 * index + 4 , range as usize ) ;
130
- _write ( value) ;
131
- }
132
-
133
- #[ inline]
134
- pub unsafe fn set_lock ( index : usize ) {
135
- #[ cfg( riscv32) ]
136
- assert ! ( index < 4 ) ;
137
-
138
- #[ cfg( riscv64) ]
139
- assert ! ( index < 8 ) ;
140
-
141
- _set ( 1 << ( 7 + index * 8 ) ) ;
101
+ let byte = ( locked as usize ) << 7 | ( range as usize ) << 3 | ( permission as usize ) ;
102
+ value. set_bits ( 8 * index..=8 * index + 7 , byte) ;
103
+ _set ( value)
142
104
}
143
105
}
144
106
145
107
/// Physical memory protection configuration
146
- /// Pmpcfg1 struct contains pmp4cfg - pmp7cfg for RV32 only
147
- /// get_byte() method retrieves a single pmp<x>cfg held in a PmpByte struct
148
- pub mod pmpcfg1 {
149
- use super :: { Permission , Pmpcfg , Range } ;
108
+ /// pmpcfg1 struct contains pmp4cfg - pmp7cfg for RV32 only
109
+ # [ cfg ( riscv32 ) ]
110
+ mod pmpcfg1 {
111
+ use super :: { Permission , Pmpcsr , Range } ;
150
112
use bit_field:: BitField ;
151
113
152
- read_csr_as ! ( Pmpcfg , 0x3A1 , __read_pmpcfg1) ;
153
- write_csr ! ( 0x3A1 , __write_pmpcfg1) ;
114
+ read_csr_as ! ( Pmpcsr , 0x3A1 , __read_pmpcfg1) ;
115
+ write_csr_as_usize_rv32 ! ( 0x3A1 , __write_pmpcfg1) ;
154
116
set ! ( 0x3A1 , __set_pmpcfg1) ;
155
117
clear ! ( 0x3A1 , __clear_pmpcfg1) ;
156
118
157
- #[ inline]
158
- pub unsafe fn set_permissions ( permission : Permission , index : usize ) {
159
- #[ cfg( riscv32) ]
119
+ /// set the configuration for pmp(x)
120
+ pub unsafe fn set_pmp ( index : usize , range : Range , permission : Permission , locked : bool ) {
160
121
assert ! ( index < 4 ) ;
161
122
162
- #[ cfg( riscv64) ]
163
- assert ! ( index < 8 ) ;
164
-
165
- let mut value = _read ( ) ;
166
- value. set_bits ( 8 * index..=8 * index + 2 , permission as usize ) ;
167
- _write ( value) ;
168
- }
169
-
170
- #[ inline]
171
- pub unsafe fn set_range ( range : Range , index : usize ) {
172
- #[ cfg( riscv32) ]
173
- assert ! ( index < 4 ) ;
174
-
175
- #[ cfg( riscv64) ]
176
- assert ! ( index < 8 ) ;
177
-
178
123
let mut value = _read ( ) ;
179
- value. set_bits ( 8 * index + 3 ..=8 * index + 4 , range as usize ) ;
180
- _write ( value) ;
181
- }
182
-
183
- #[ inline]
184
- pub unsafe fn set_lock ( index : usize ) {
185
- #[ cfg( riscv32) ]
186
- assert ! ( index < 4 ) ;
187
-
188
- #[ cfg( riscv64) ]
189
- assert ! ( index < 8 ) ;
190
-
191
- _set ( 1 << ( 7 + index * 8 ) ) ;
124
+ let byte = ( locked as usize ) << 7 | ( range as usize ) << 3 | ( permission as usize ) ;
125
+ value. set_bits ( 8 * index..=8 * index + 7 , byte) ;
126
+ _set ( value)
192
127
}
193
128
}
194
129
195
130
/// Physical memory protection configuration
196
- /// Pmpcfg0 struct contains pmp8cfg - pmp11cfg for RV32, or pmp8cfg - pmp15cfg for RV64
197
- /// get_byte() method retrieves a single pmp<x>cfg held in a PmpByte struct
131
+ /// pmpcfg2 struct contains pmp8cfg - pmp11cfg for RV32, or pmp8cfg - pmp15cfg for RV64
198
132
pub mod pmpcfg2 {
199
- use super :: { Permission , Pmpcfg , Range } ;
133
+ use super :: { Permission , Pmpcsr , Range } ;
200
134
use bit_field:: BitField ;
201
135
202
- read_csr_as ! ( Pmpcfg , 0x3A2 , __read_pmpcfg2) ;
203
- write_csr ! ( 0x3A2 , __write_pmpcfg2) ;
136
+ read_csr_as ! ( Pmpcsr , 0x3A2 , __read_pmpcfg2) ;
137
+ write_csr_as_usize ! ( 0x3A2 , __write_pmpcfg2) ;
204
138
set ! ( 0x3A2 , __set_pmpcfg2) ;
205
139
clear ! ( 0x3A2 , __clear_pmpcfg2) ;
206
140
207
- # [ inline ]
208
- pub unsafe fn set_permissions ( permission : Permission , index : usize ) {
141
+ /// set the configuration for pmp(x)
142
+ pub unsafe fn set_pmp ( index : usize , range : Range , permission : Permission , locked : bool ) {
209
143
#[ cfg( riscv32) ]
210
144
assert ! ( index < 4 ) ;
211
145
212
146
#[ cfg( riscv64) ]
213
147
assert ! ( index < 8 ) ;
214
148
215
149
let mut value = _read ( ) ;
216
- value. set_bits ( 8 * index..=8 * index + 2 , permission as usize ) ;
217
- _write ( value) ;
218
- }
219
-
220
- #[ inline]
221
- pub unsafe fn set_range ( range : Range , index : usize ) {
222
- #[ cfg( riscv32) ]
223
- assert ! ( index < 4 ) ;
224
-
225
- #[ cfg( riscv64) ]
226
- assert ! ( index < 8 ) ;
227
-
228
- let mut value = _read ( ) ;
229
- value. set_bits ( 8 * index + 3 ..=8 * index + 4 , range as usize ) ;
230
- _write ( value) ;
231
- }
232
-
233
- #[ inline]
234
- pub unsafe fn set_lock ( index : usize ) {
235
- #[ cfg( riscv32) ]
236
- assert ! ( index < 4 ) ;
237
-
238
- #[ cfg( riscv64) ]
239
- assert ! ( index < 8 ) ;
240
-
241
- _set ( 1 << ( 7 + index * 8 ) ) ;
150
+ let byte = ( locked as usize ) << 7 | ( range as usize ) << 3 | ( permission as usize ) ;
151
+ value. set_bits ( 8 * index..=8 * index + 7 , byte) ;
152
+ _set ( value)
242
153
}
243
154
}
244
155
245
156
/// Physical memory protection configuration
246
- /// Pmpcfg0 struct contains pmp12cfg - pmp15cfg for RV32 only
247
- /// get_byte() method retrieves a single pmp<x>cfg held in a PmpByte struct
157
+ /// pmpcfg3 struct contains pmp12cfg - pmp15cfg for RV32 only
158
+ # [ cfg ( riscv32 ) ]
248
159
pub mod pmpcfg3 {
249
- use super :: { Permission , Pmpcfg , Range } ;
160
+ use super :: { Permission , Pmpcsr , Range } ;
250
161
use bit_field:: BitField ;
251
162
252
- read_csr_as ! ( Pmpcfg , 0x3A3 , __read_pmpcfg3) ;
253
- write_csr ! ( 0x3A3 , __write_pmpcfg3 ) ;
163
+ read_csr_as ! ( Pmpcsr , 0x3A3 , __read_pmpcfg3) ;
164
+ write_csr_as_usize_rv32 ! ( 0x3A3 , __read_pmpcfg3 ) ;
254
165
set ! ( 0x3A3 , __set_pmpcfg3) ;
255
166
clear ! ( 0x3A3 , __clear_pmpcfg3) ;
256
167
257
- #[ inline]
258
- pub unsafe fn set_permissions ( permission : Permission , index : usize ) {
259
- #[ cfg( riscv32) ]
260
- assert ! ( index < 4 ) ;
261
-
262
- #[ cfg( riscv64) ]
263
- assert ! ( index < 8 ) ;
264
-
265
- let mut value = _read ( ) ;
266
- value. set_bits ( 8 * index..=8 * index + 2 , permission as usize ) ;
267
- _write ( value) ;
268
- }
269
-
270
- #[ inline]
271
- pub unsafe fn set_range ( range : Range , index : usize ) {
272
- #[ cfg( riscv32) ]
168
+ /// set the configuration for pmp(x)
169
+ pub unsafe fn set_pmp ( index : usize , range : Range , permission : Permission , locked : bool ) {
273
170
assert ! ( index < 4 ) ;
274
171
275
- #[ cfg( riscv64) ]
276
- assert ! ( index < 8 ) ;
277
-
278
172
let mut value = _read ( ) ;
279
- value. set_bits ( 8 * index + 3 ..=8 * index + 4 , range as usize ) ;
280
- _write ( value) ;
281
- }
282
-
283
- #[ inline]
284
- pub unsafe fn set_lock ( index : usize ) {
285
- #[ cfg( riscv32) ]
286
- assert ! ( index < 4 ) ;
287
-
288
- #[ cfg( riscv64) ]
289
- assert ! ( index < 8 ) ;
290
-
291
- _set ( 1 << ( 7 + index * 8 ) ) ;
173
+ let byte = ( locked as usize ) << 7 | ( range as usize ) << 3 | ( permission as usize ) ;
174
+ value. set_bits ( 8 * index..=8 * index + 7 , byte) ;
175
+ _set ( value)
292
176
}
293
177
}
0 commit comments