Skip to content

Commit 206c690

Browse files
committed
riscv: define sstatus CSR with macro helpers
Uses CSR macro helpers to define the `sstatus` CSR register.
1 parent f463f22 commit 206c690

File tree

2 files changed

+78
-71
lines changed

2 files changed

+78
-71
lines changed

riscv/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
3737
- Use CSR helper macros to define `sie` register
3838
- Use CSR helper macros to define `scounteren` field types
3939
- Use CSR helper macros to define `sip` register
40+
- Use CSR helper macros to define `sstatus` field types
4041

4142
## [v0.12.1] - 2024-10-20
4243

riscv/src/register/sstatus.rs

Lines changed: 77 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,105 +1,111 @@
11
//! sstatus register
22
33
pub use super::misa::XLEN;
4-
pub use super::mstatus::FS;
4+
pub use super::mstatus::{FS, XS};
55

6-
/// Supervisor Status Register
7-
#[derive(Clone, Copy, Debug)]
8-
pub struct Sstatus {
9-
bits: usize,
6+
#[cfg(target_arch = "riscv32")]
7+
const MASK: usize = 0x800d_e122;
8+
#[cfg(not(target_arch = "riscv32"))]
9+
const MASK: usize = 0x8000_0003_000d_e122;
10+
11+
read_write_csr! {
12+
/// Supervisor Status Register
13+
Sstatus: 0x100,
14+
mask: MASK,
1015
}
1116

12-
/// Supervisor Previous Privilege Mode
13-
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
14-
pub enum SPP {
15-
Supervisor = 1,
16-
User = 0,
17+
csr_field_enum! {
18+
/// Supervisor Previous Privilege Mode
19+
SPP {
20+
default: User,
21+
/// Previous privilege mode is User mode.
22+
User = 0,
23+
/// Previous privilege mode is Supervisor mode.
24+
Supervisor = 1,
25+
}
1726
}
1827

19-
impl Sstatus {
28+
read_write_csr_field! {
29+
Sstatus,
2030
/// Supervisor Interrupt Enable
21-
#[inline]
22-
pub fn sie(&self) -> bool {
23-
self.bits & (1 << 1) != 0
24-
}
31+
sie: 1,
32+
}
2533

34+
read_write_csr_field! {
35+
Sstatus,
2636
/// Supervisor Previous Interrupt Enable
27-
#[inline]
28-
pub fn spie(&self) -> bool {
29-
self.bits & (1 << 5) != 0
30-
}
37+
spie: 5,
38+
}
3139

40+
read_write_csr_field! {
41+
Sstatus,
3242
/// Supervisor Previous Privilege Mode
33-
#[inline]
34-
pub fn spp(&self) -> SPP {
35-
match self.bits & (1 << 8) != 0 {
36-
true => SPP::Supervisor,
37-
false => SPP::User,
38-
}
39-
}
43+
spp,
44+
SPP: [8:8],
45+
}
4046

47+
read_write_csr_field! {
48+
Sstatus,
4149
/// The status of the floating-point unit
42-
#[inline]
43-
pub fn fs(&self) -> FS {
44-
let fs = (self.bits >> 13) & 0x3; // bits 13-14
45-
match fs {
46-
0 => FS::Off,
47-
1 => FS::Initial,
48-
2 => FS::Clean,
49-
3 => FS::Dirty,
50-
_ => unreachable!(),
51-
}
52-
}
50+
fs,
51+
FS: [13:14],
52+
}
5353

54+
read_only_csr_field! {
55+
Sstatus,
5456
/// The status of additional user-mode extensions
5557
/// and associated state
56-
#[inline]
57-
pub fn xs(&self) -> FS {
58-
let xs = (self.bits >> 15) & 0x3; // bits 15-16
59-
match xs {
60-
0 => FS::Off,
61-
1 => FS::Initial,
62-
2 => FS::Clean,
63-
3 => FS::Dirty,
64-
_ => unreachable!(),
65-
}
66-
}
58+
xs,
59+
XS: [15:16],
60+
}
6761

62+
read_write_csr_field! {
63+
Sstatus,
6864
/// Permit Supervisor User Memory access
69-
#[inline]
70-
pub fn sum(&self) -> bool {
71-
self.bits & (1 << 18) != 0
72-
}
65+
sum: 18,
66+
}
7367

68+
read_write_csr_field! {
69+
Sstatus,
7470
/// Make eXecutable Readable
75-
#[inline]
76-
pub fn mxr(&self) -> bool {
77-
self.bits & (1 << 19) != 0
78-
}
71+
mxr: 19,
72+
}
7973

74+
#[cfg(not(target_arch = "riscv32"))]
75+
read_write_csr_field! {
76+
Sstatus,
8077
/// Effective xlen in U-mode (i.e., `UXLEN`).
81-
///
82-
/// In RISCV-32, UXL does not exist, and `UXLEN` is always [`XLEN::XLEN32`].
83-
#[inline]
84-
pub fn uxl(&self) -> XLEN {
85-
match () {
86-
#[cfg(riscv32)]
87-
() => XLEN::XLEN32,
88-
#[cfg(not(riscv32))]
89-
() => XLEN::try_from((self.bits >> 32) & 0x3).unwrap_or_default(),
90-
}
91-
}
78+
uxl,
79+
XLEN: [32:33],
80+
}
9281

82+
#[cfg(target_arch = "riscv32")]
83+
read_write_csr_field! {
84+
Sstatus,
9385
/// Whether either the FS field or XS field
9486
/// signals the presence of some dirty state
87+
sd: 31,
88+
}
89+
90+
#[cfg(not(target_arch = "riscv32"))]
91+
read_write_csr_field! {
92+
Sstatus,
93+
/// Whether either the FS field or XS field
94+
/// signals the presence of some dirty state
95+
sd: 63,
96+
}
97+
98+
impl Sstatus {
99+
/// Effective xlen in U-mode (i.e., `UXLEN`).
100+
///
101+
/// In RISCV-32, UXL does not exist, and `UXLEN` is always [`XLEN::XLEN32`].
95102
#[inline]
96-
pub fn sd(&self) -> bool {
97-
self.bits & (1 << (usize::BITS as usize - 1)) != 0
103+
#[cfg(target_arch = "riscv32")]
104+
pub fn uxl(&self) -> XLEN {
105+
XLEN::XLEN32
98106
}
99107
}
100108

101-
read_csr_as!(Sstatus, 0x100);
102-
write_csr!(0x100);
103109
set!(0x100);
104110
clear!(0x100);
105111

0 commit comments

Comments
 (0)