Skip to content

Commit 213181c

Browse files
feat(register): use field enums for DCSR cause and prv
- Add csr_field_enum! { Cause } and wire cause (bits 6..8) to it - Reuse existing Prv enum for prv (bits 0..1) - Remove manual DcsrCause/DcsrPrv enums and conversions - Update convenience methods to use typed fields (try_cause, try_prv) - Adjust unit tests to validate typed field behavior This replaces manual enums with csr_field_enum! as requested.
1 parent 01f127a commit 213181c

File tree

1 file changed

+52
-69
lines changed

1 file changed

+52
-69
lines changed

riscv/src/register/dcsr.rs

Lines changed: 52 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,25 @@ csr_field_enum! {
2121
}
2222
}
2323

24+
csr_field_enum! {
25+
/// Cause for entering debug mode.
26+
Cause {
27+
default: None,
28+
/// No cause.
29+
None = 0,
30+
/// EBREAK instruction.
31+
Ebreak = 1,
32+
/// Trigger module.
33+
Trigger = 2,
34+
/// External halt request.
35+
HaltRequest = 3,
36+
/// Single-step completed.
37+
Step = 4,
38+
/// Reset-halt request.
39+
ResetHaltRequest = 5,
40+
}
41+
}
42+
2443
read_write_csr_field! {
2544
Dcsr,
2645
/// Previous privilege level when entering debug mode (bits 0..1).
@@ -49,7 +68,8 @@ read_write_csr_field! {
4968
read_only_csr_field! {
5069
Dcsr,
5170
/// Cause for entering debug mode (bits 6..8)
52-
cause: [6:8],
71+
cause,
72+
Cause: [6:8],
5373
}
5474

5575
read_write_csr_field! {
@@ -94,70 +114,27 @@ read_only_csr_field! {
94114
xdebugver: [28:31],
95115
}
96116

97-
/// Cause for entering debug mode
98-
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
99-
pub enum DcsrCause {
100-
None = 0,
101-
Ebreak = 1,
102-
Trigger = 2,
103-
HaltRequest = 3,
104-
Step = 4,
105-
ResetHaltRequest = 5,
106-
}
107-
108-
impl DcsrCause {
109-
pub fn from_usize(val: usize) -> Result<Self, usize> {
110-
match val {
111-
0 => Ok(Self::None),
112-
1 => Ok(Self::Ebreak),
113-
2 => Ok(Self::Trigger),
114-
3 => Ok(Self::HaltRequest),
115-
4 => Ok(Self::Step),
116-
5 => Ok(Self::ResetHaltRequest),
117-
other => Err(other),
118-
}
119-
}
120-
}
121-
122-
/// Previous privilege level when entering debug mode
123-
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
124-
pub enum DcsrPrv {
125-
User = 0,
126-
Supervisor = 1,
127-
Machine = 3,
128-
}
129-
130-
impl DcsrPrv {
131-
pub fn from_usize(val: usize) -> Result<Self, usize> {
132-
match val {
133-
0 => Ok(Self::User),
134-
1 => Ok(Self::Supervisor),
135-
3 => Ok(Self::Machine),
136-
other => Err(other),
137-
}
138-
}
139-
}
140-
141117
impl Dcsr {
142118
/// Returns the debug cause as an enum
143-
pub fn debug_cause(&self) -> Result<DcsrCause, usize> {
144-
DcsrCause::from_usize(self.cause())
119+
pub fn debug_cause(&self) -> crate::result::Result<Cause> {
120+
self.try_cause()
145121
}
146122

147123
/// Returns the previous privilege level as an enum
148-
pub fn privilege_level(&self) -> Result<DcsrPrv, usize> {
149-
DcsrPrv::from_usize(self.prv())
124+
pub fn privilege_level(&self) -> crate::result::Result<Prv> {
125+
self.try_prv()
150126
}
151127

152128
/// Sets the previous privilege level
153-
pub fn set_privilege_level(&mut self, level: DcsrPrv) {
154-
self.set_prv(level as usize);
129+
pub fn set_privilege_level(&mut self, level: Prv) {
130+
self.set_prv(level);
155131
}
156132
}
157133

158134
#[cfg(test)]
159135
mod tests {
160136
use super::*;
137+
use crate::result::Error;
161138

162139
#[test]
163140
fn test_dcsr_bitfields() {
@@ -200,29 +177,35 @@ mod tests {
200177

201178
#[test]
202179
fn test_dcsr_enums() {
203-
assert_eq!(DcsrCause::from_usize(0).unwrap(), DcsrCause::None);
204-
assert_eq!(DcsrCause::from_usize(1).unwrap(), DcsrCause::Ebreak);
205-
assert_eq!(DcsrCause::from_usize(2).unwrap(), DcsrCause::Trigger);
206-
assert_eq!(DcsrCause::from_usize(3).unwrap(), DcsrCause::HaltRequest);
207-
assert_eq!(DcsrCause::from_usize(4).unwrap(), DcsrCause::Step);
208-
assert_eq!(
209-
DcsrCause::from_usize(5).unwrap(),
210-
DcsrCause::ResetHaltRequest
211-
);
212-
assert!(DcsrCause::from_usize(6).is_err());
213-
214-
assert_eq!(DcsrPrv::from_usize(0).unwrap(), DcsrPrv::User);
215-
assert_eq!(DcsrPrv::from_usize(1).unwrap(), DcsrPrv::Supervisor);
216-
assert_eq!(DcsrPrv::from_usize(3).unwrap(), DcsrPrv::Machine);
217-
assert!(DcsrPrv::from_usize(2).is_err());
180+
let mut dcsr = Dcsr::from_bits(0);
181+
182+
[
183+
Cause::None,
184+
Cause::Ebreak,
185+
Cause::Trigger,
186+
Cause::HaltRequest,
187+
Cause::Step,
188+
Cause::ResetHaltRequest,
189+
]
190+
.into_iter()
191+
.enumerate()
192+
.for_each(|(val, variant)| {
193+
dcsr = Dcsr::from_bits((val as usize) << 6);
194+
assert_eq!(dcsr.cause(), variant);
195+
assert_eq!(dcsr.debug_cause(), Ok(variant));
196+
});
197+
198+
// invalid variant value 6
199+
dcsr = Dcsr::from_bits(6 << 6);
200+
assert_eq!(dcsr.try_cause(), Err(Error::InvalidVariant(6)));
218201
}
219202

220203
#[test]
221204
fn test_dcsr_convenience_methods() {
222205
let mut dcsr = Dcsr::from_bits(0);
223206

224-
dcsr.set_privilege_level(DcsrPrv::Machine);
225-
assert_eq!(dcsr.privilege_level().unwrap(), DcsrPrv::Machine);
226-
assert_eq!(dcsr.prv(), 3);
207+
dcsr.set_privilege_level(Prv::Machine);
208+
assert_eq!(dcsr.privilege_level().unwrap(), Prv::Machine);
209+
assert_eq!(dcsr.prv(), Prv::Machine);
227210
}
228211
}

0 commit comments

Comments
 (0)