@@ -72,6 +72,15 @@ impl From<bool> for Endianness {
72
72
}
73
73
74
74
impl Mstatus {
75
+ /// Helper to insert a bitfield into Mstatus
76
+ #[inline]
77
+ fn bf_insert(&self, bit: usize, width: usize, val: usize) -> Self {
78
+ let mask = (1 << width) - 1;
79
+ Self {
80
+ bits: self.bits & !(mask << bit) | (val & mask << bit),
81
+ }
82
+ }
83
+
75
84
/// Returns the contents of the register as raw bits
76
85
#[inline]
77
86
pub fn bits(&self) -> usize {
@@ -84,30 +93,60 @@ impl Mstatus {
84
93
self.bits & (1 << 1) != 0
85
94
}
86
95
96
+ /// Set Supervisor Interrupt Enable
97
+ #[inline]
98
+ pub fn set_sie(&self, sie: bool) -> Self {
99
+ self.bf_insert(1, 1, sie as usize)
100
+ }
101
+
87
102
/// Machine Interrupt Enable
88
103
#[inline]
89
104
pub fn mie(&self) -> bool {
90
105
self.bits & (1 << 3) != 0
91
106
}
92
107
108
+ /// Set Machine Interrupt Enable
109
+ #[inline]
110
+ pub fn set_mie(&self, mie: bool) -> Self {
111
+ self.bf_insert(3, 1, mie as usize)
112
+ }
113
+
93
114
/// Supervisor Previous Interrupt Enable
94
115
#[inline]
95
116
pub fn spie(&self) -> bool {
96
117
self.bits & (1 << 5) != 0
97
118
}
98
119
120
+ /// Supervisor Previous Interrupt Enable
121
+ #[inline]
122
+ pub fn set_spie(&self, spie: bool) -> Self {
123
+ self.bf_insert(5, 1, spie as usize)
124
+ }
125
+
99
126
/// U-mode non-instruction-fetch memory endianness
100
127
#[inline]
101
128
pub fn ube(&self) -> Endianness {
102
129
Endianness::from(self.bits & (1 << 6) != 0)
103
130
}
104
131
132
+ /// Set U-mode non-instruction-fetch memory endianness
133
+ #[inline]
134
+ pub fn set_ube(&self, endianness: Endianness) -> Self {
135
+ self.bf_insert(6, 1, endianness as usize)
136
+ }
137
+
105
138
/// Machine Previous Interrupt Enable
106
139
#[inline]
107
140
pub fn mpie(&self) -> bool {
108
141
self.bits & (1 << 7) != 0
109
142
}
110
143
144
+ /// Set Machine Previous Interrupt Enable
145
+ #[inline]
146
+ pub fn set_mpie(&self, mpie: bool) -> Self {
147
+ self.bf_insert(7, 1, mpie as usize)
148
+ }
149
+
111
150
/// Supervisor Previous Privilege Mode
112
151
#[inline]
113
152
pub fn spp(&self) -> SPP {
@@ -117,6 +156,12 @@ impl Mstatus {
117
156
}
118
157
}
119
158
159
+ /// Set Supervisor Previous Privilege Mode
160
+ #[inline]
161
+ pub fn set_spp(&self, spp: SPP) -> Self {
162
+ self.bf_insert(8, 1, spp as usize)
163
+ }
164
+
120
165
/// Machine Previous Privilege Mode
121
166
#[inline]
122
167
pub fn mpp(&self) -> MPP {
@@ -129,6 +174,12 @@ impl Mstatus {
129
174
}
130
175
}
131
176
177
+ /// Set Machine Previous Privilege Mode
178
+ #[inline]
179
+ pub fn set_mpp(&self, mpp: MPP) -> Self {
180
+ self.bf_insert(11, 2, mpp as usize)
181
+ }
182
+
132
183
/// Floating-point extension state
133
184
///
134
185
/// Encodes the status of the floating-point unit,
@@ -145,6 +196,12 @@ impl Mstatus {
145
196
}
146
197
}
147
198
199
+ /// Set Floating-point extension state
200
+ #[inline]
201
+ pub fn set_fs(&self, fs: FS) -> Self {
202
+ self.bf_insert(13, 2, fs as usize)
203
+ }
204
+
148
205
/// Additional extension state
149
206
///
150
207
/// Encodes the status of additional user-mode extensions and associated state.
@@ -160,24 +217,48 @@ impl Mstatus {
160
217
}
161
218
}
162
219
220
+ /// Set Additional extension state
221
+ #[inline]
222
+ pub fn set_xs(&self, xs: XS) -> Self {
223
+ self.bf_insert(15, 2, xs as usize)
224
+ }
225
+
163
226
/// Modify Memory PRiVilege
164
227
#[inline]
165
228
pub fn mprv(&self) -> bool {
166
229
self.bits & (1 << 17) != 0
167
230
}
168
231
232
+ /// Set Modify Memory PRiVilege
233
+ #[inline]
234
+ pub fn set_mprv(&self, mprv: bool) -> Self {
235
+ self.bf_insert(17, 1, mprv as usize)
236
+ }
237
+
169
238
/// Permit Supervisor User Memory access
170
239
#[inline]
171
240
pub fn sum(&self) -> bool {
172
241
self.bits & (1 << 18) != 0
173
242
}
174
243
244
+ /// Set Permit Supervisor User Memory access
245
+ #[inline]
246
+ pub fn set_sum(&self, sum: bool) -> Self {
247
+ self.bf_insert(18, 1, sum as usize)
248
+ }
249
+
175
250
/// Make eXecutable Readable
176
251
#[inline]
177
252
pub fn mxr(&self) -> bool {
178
253
self.bits & (1 << 19) != 0
179
254
}
180
255
256
+ /// Set Make eXecutable Readable
257
+ #[inline]
258
+ pub fn set_mxr(&self, mxr: bool) -> Self {
259
+ self.bf_insert(19, 1, mxr as usize)
260
+ }
261
+
181
262
/// Trap Virtual Memory
182
263
///
183
264
/// If this bit is set, reads or writes to `satp` CSR or execute `sfence.vma`
@@ -189,6 +270,12 @@ impl Mstatus {
189
270
self.bits & (1 << 20) != 0
190
271
}
191
272
273
+ /// Set Trap Virtual Memory
274
+ #[inline]
275
+ pub fn set_tvm(&self, tvm: bool) -> Self {
276
+ self.bf_insert(20, 1, tvm as usize)
277
+ }
278
+
192
279
/// Timeout Wait
193
280
///
194
281
/// Indicates that if WFI instruction should be intercepted.
@@ -203,6 +290,12 @@ impl Mstatus {
203
290
self.bits & (1 << 21) != 0
204
291
}
205
292
293
+ /// Set Timeout Wait
294
+ #[inline]
295
+ pub fn set_tw(&self, tw: bool) -> Self {
296
+ self.bf_insert(21, 1, tw as usize)
297
+ }
298
+
206
299
/// Trap SRET
207
300
///
208
301
/// Indicates that if SRET instruction should be trapped to raise illegal
@@ -214,6 +307,12 @@ impl Mstatus {
214
307
self.bits & (1 << 22) != 0
215
308
}
216
309
310
+ /// Set Trap SRET
311
+ #[inline]
312
+ pub fn set_tsr(&self, tsr: bool) -> Self {
313
+ self.bf_insert(22, 1, tsr as usize)
314
+ }
315
+
217
316
/// Effective xlen in U-mode (i.e., `UXLEN`).
218
317
///
219
318
/// In RISCV-32, UXL does not exist, and `UXLEN` is always [`XLEN::XLEN32`].
@@ -227,6 +326,17 @@ impl Mstatus {
227
326
}
228
327
}
229
328
329
+ /// Set Effective xlen in U-mode (i.e., `UXLEN`).
330
+ #[inline]
331
+ pub fn set_uxl(&self, uxl: XLEN) -> Self {
332
+ #[cfg(riscv32)]
333
+ {
334
+ *self
335
+ }
336
+ #[cfg(not(riscv32))]
337
+ self.bf_insert(32, 2, uxl as usize)
338
+ }
339
+
230
340
/// Effective xlen in S-mode (i.e., `SXLEN`).
231
341
///
232
342
/// In RISCV-32, SXL does not exist, and SXLEN is always [`XLEN::XLEN32`].
@@ -240,6 +350,17 @@ impl Mstatus {
240
350
}
241
351
}
242
352
353
+ /// Set Effective xlen in S-mode (i.e., `SXLEN`).
354
+ #[inline]
355
+ pub fn set_sxl(&self, sxl: XLEN) -> Self {
356
+ #[cfg(riscv32)]
357
+ {
358
+ *self
359
+ }
360
+ #[cfg(not(riscv32))]
361
+ self.bf_insert(34, 2, sxl as usize)
362
+ }
363
+
243
364
/// S-mode non-instruction-fetch memory endianness.
244
365
///
245
366
/// In RISCV-32, this field is read from the [`crate::register::mstatush`] register.
@@ -252,6 +373,17 @@ impl Mstatus {
252
373
}
253
374
}
254
375
376
+ /// Set S-mode non-instruction-fetch memory endianness
377
+ #[inline]
378
+ pub fn set_sbe(&self, endianness: Endianness) -> Self {
379
+ #[cfg(riscv32)]
380
+ {
381
+ *self
382
+ }
383
+ #[cfg(not(riscv32))]
384
+ self.bf_insert(36, 1, endianness as usize)
385
+ }
386
+
255
387
/// M-mode non-instruction-fetch memory endianness
256
388
///
257
389
/// In RISCV-32, this field is read from the [`crate::register::mstatush`] register
@@ -264,11 +396,27 @@ impl Mstatus {
264
396
}
265
397
}
266
398
399
+ /// Set M-mode non-instruction-fetch memory endianness
400
+ pub fn set_mbe(&self, endianness: Endianness) -> Self {
401
+ #[cfg(riscv32)]
402
+ {
403
+ *self
404
+ }
405
+ #[cfg(not(riscv32))]
406
+ self.bf_insert(37, 1, endianness as usize)
407
+ }
408
+
267
409
/// Whether either the FS field or XS field signals the presence of some dirty state
268
410
#[inline]
269
411
pub fn sd(&self) -> bool {
270
412
self.bits & (1 << (usize::BITS as usize - 1)) != 0
271
413
}
414
+
415
+ /// Set whether either the FS field or XS field signals the presence of some dirty state
416
+ #[inline]
417
+ pub fn set_sd(&self, sd: bool) -> Self {
418
+ self.bf_insert(usize::BITS as usize - 1, 1, sd as usize)
419
+ }
272
420
}
273
421
274
422
read_csr_as!(Mstatus, 0x300);
0 commit comments