Skip to content

Commit 60afe03

Browse files
committed
riscv: add fallible functions to mcounteren
Adds fallible access functions for `Mcounteren` HPM fields.
1 parent 2f86d05 commit 60afe03

File tree

1 file changed

+121
-9
lines changed

1 file changed

+121
-9
lines changed

riscv/src/register/mcounteren.rs

Lines changed: 121 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! mcounteren register
22
33
use crate::bits::{bf_extract, bf_insert};
4+
use crate::result::{Error, Result};
45

56
/// mcounteren register
67
#[derive(Clone, Copy, Debug)]
@@ -52,19 +53,62 @@ impl Mcounteren {
5253
}
5354

5455
/// Supervisor "hpm\[x\]" Enable (bits 3-31)
56+
///
57+
/// **WARNING**: panics on:
58+
///
59+
/// - non-`riscv` targets
60+
/// - `index` out-of-bounds
5561
#[inline]
5662
pub fn hpm(&self, index: usize) -> bool {
57-
assert!((3..32).contains(&index));
58-
bf_extract(self.bits, index, 1) != 0
63+
self.try_hpm(index).unwrap()
64+
}
65+
66+
/// Fallible Supervisor "hpm\[x\]" Enable (bits 3-31).
67+
///
68+
/// Attempts to read the "hpm\[x\]" value, and returns an error if the `index` is invalid.
69+
#[inline]
70+
pub fn try_hpm(&self, index: usize) -> Result<bool> {
71+
if (3..32).contains(&index) {
72+
Ok(bf_extract(self.bits, index, 1) != 0)
73+
} else {
74+
Err(Error::IndexOutOfBounds {
75+
index,
76+
min: 3,
77+
max: 31,
78+
})
79+
}
5980
}
6081

6182
/// Sets whether to enable the "hpm\[X\]" counter.
6283
///
6384
/// Only updates the in-memory value, does not modify the `mcounteren` register.
85+
///
86+
/// **WARNING**: panics on:
87+
///
88+
/// - non-`riscv` targets
89+
/// - `index` out-of-bounds
6490
#[inline]
6591
pub fn set_hpm(&mut self, index: usize, hpm: bool) {
66-
assert!((3..32).contains(&index));
67-
self.bits = bf_insert(self.bits, index, 1, hpm as usize);
92+
self.try_set_hpm(index, hpm).unwrap()
93+
}
94+
95+
/// Sets whether to enable the "hpm\[X\]" counter.
96+
///
97+
/// Only updates the in-memory value, does not modify the `mcounteren` register.
98+
///
99+
/// Attempts to update the "hpm\[x\]" value, and returns an error if the `index` is invalid.
100+
#[inline]
101+
pub fn try_set_hpm(&mut self, index: usize, hpm: bool) -> Result<()> {
102+
if (3..32).contains(&index) {
103+
self.bits = bf_insert(self.bits, index, 1, hpm as usize);
104+
Ok(())
105+
} else {
106+
Err(Error::IndexOutOfBounds {
107+
index,
108+
min: 3,
109+
max: 31,
110+
})
111+
}
68112
}
69113
}
70114

@@ -85,16 +129,62 @@ set_clear_csr!(
85129
/// Supervisor instret Enable
86130
, set_ir, clear_ir, 1 << 2);
87131

132+
/// Enables the "hpm\[X\]" counter.
133+
///
134+
/// Updates the `mcounteren` register.
135+
///
136+
/// **WARNING**: panics on:
137+
///
138+
/// - non-`riscv` targets
139+
/// - `index` out-of-bounds
88140
#[inline]
89141
pub unsafe fn set_hpm(index: usize) {
90-
assert!((3..32).contains(&index));
91-
_set(1 << index);
142+
try_set_hpm(index).unwrap();
143+
}
144+
145+
/// Attempts to enable the "hpm\[X\]" counter.
146+
///
147+
/// Updates the `mcounteren` register.
148+
#[inline]
149+
pub unsafe fn try_set_hpm(index: usize) -> Result<()> {
150+
if (3..32).contains(&index) {
151+
_try_set(1 << index)
152+
} else {
153+
Err(Error::IndexOutOfBounds {
154+
index,
155+
min: 3,
156+
max: 31,
157+
})
158+
}
92159
}
93160

161+
/// Disables the "hpm\[X\]" counter.
162+
///
163+
/// Updates the `mcounteren` register.
164+
///
165+
/// **WARNING**: panics on:
166+
///
167+
/// - non-`riscv` targets
168+
/// - `index` out-of-bounds
94169
#[inline]
95170
pub unsafe fn clear_hpm(index: usize) {
96-
assert!((3..32).contains(&index));
97-
_clear(1 << index);
171+
try_clear_hpm(index).unwrap();
172+
}
173+
174+
/// Attempts to disable the "hpm\[X\]" counter.
175+
///
176+
/// Updates the `mcounteren` register.
177+
#[inline]
178+
pub unsafe fn try_clear_hpm(index: usize) -> Result<()> {
179+
if (3..32).contains(&index) {
180+
_try_clear(1 << index)
181+
} else {
182+
Err(Error::IndexOutOfBounds {
183+
index,
184+
min: 3,
185+
max: 31,
186+
})
187+
}
98188
}
99189

100190
#[cfg(test)]
@@ -131,12 +221,34 @@ mod tests {
131221

132222
(3..32).for_each(|i| {
133223
assert!(!m.hpm(i));
224+
assert_eq!(m.try_hpm(i), Ok(false));
134225

135226
m.set_hpm(i, true);
136227
assert!(m.hpm(i));
137228

138-
m.set_hpm(i, false);
229+
assert_eq!(m.try_set_hpm(i, false), Ok(()));
230+
assert_eq!(m.try_hpm(i), Ok(false));
231+
139232
assert!(!m.hpm(i));
140233
});
234+
235+
(0..3).chain(32..64).for_each(|index| {
236+
assert_eq!(
237+
m.try_hpm(index),
238+
Err(Error::IndexOutOfBounds {
239+
index,
240+
min: 3,
241+
max: 31
242+
})
243+
);
244+
assert_eq!(
245+
m.try_set_hpm(index, false),
246+
Err(Error::IndexOutOfBounds {
247+
index,
248+
min: 3,
249+
max: 31
250+
})
251+
);
252+
})
141253
}
142254
}

0 commit comments

Comments
 (0)