Skip to content

Commit 56f30bb

Browse files
committed
riscv: add fallible functions to mcountinhibit
Adds fallible access functions for `Mcountinhibit` HPM fields.
1 parent 66fa6a4 commit 56f30bb

File tree

2 files changed

+86
-2
lines changed

2 files changed

+86
-2
lines changed

riscv/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1919
- Add `riscv::register::mcountinhibit` module for `mcountinhibit` CSR
2020
- Add `Mcounteren` in-memory update functions
2121
- Add `Mstatus` vector extension support
22+
- Add fallible counterparts to all functions that `panic`
2223

2324
### Fixed
2425

riscv/src/register/mcountinhibit.rs

+85-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! `mcountinhibit` register
22
33
use crate::bits::{bf_extract, bf_insert};
4+
use crate::result::{Error, Result};
45

56
/// `mcountinhibit` register
67
#[derive(Clone, Copy, Debug)]
@@ -44,6 +45,22 @@ impl Mcountinhibit {
4445
bf_extract(self.bits, index, 1) != 0
4546
}
4647

48+
/// Machine "hpm\[x\]" Disable (bits 3-31)
49+
///
50+
/// Attempts to read the "hpm\[x\]" value, and returns an error if the index is invalid.
51+
#[inline]
52+
pub fn try_hpm(&self, index: usize) -> Result<bool> {
53+
if (3..32).contains(&index) {
54+
Ok(bf_extract(self.bits, index, 1) != 0)
55+
} else {
56+
Err(Error::IndexOutOfBounds {
57+
index,
58+
min: 3,
59+
max: 31,
60+
})
61+
}
62+
}
63+
4764
/// Sets whether to inhibit the "hpm\[X\]" counter.
4865
///
4966
/// Only updates the in-memory value, does not modify the `mcountinhibit` register.
@@ -52,6 +69,25 @@ impl Mcountinhibit {
5269
assert!((3..32).contains(&index));
5370
self.bits = bf_insert(self.bits, index, 1, hpm as usize);
5471
}
72+
73+
/// Sets whether to inhibit the "hpm\[X\]" counter.
74+
///
75+
/// Only updates the in-memory value, does not modify the `mcountinhibit` register.
76+
///
77+
/// Attempts to update the "hpm\[x\]" value, and returns an error if the index is invalid.
78+
#[inline]
79+
pub fn try_set_hpm(&mut self, index: usize, hpm: bool) -> Result<()> {
80+
if (3..32).contains(&index) {
81+
self.bits = bf_insert(self.bits, index, 1, hpm as usize);
82+
Ok(())
83+
} else {
84+
Err(Error::IndexOutOfBounds {
85+
index,
86+
min: 3,
87+
max: 31,
88+
})
89+
}
90+
}
5591
}
5692

5793
read_csr_as!(Mcountinhibit, 0x320);
@@ -73,12 +109,38 @@ pub unsafe fn set_hpm(index: usize) {
73109
_set(1 << index);
74110
}
75111

112+
#[inline]
113+
pub unsafe fn try_set_hpm(index: usize) -> Result<()> {
114+
if (3..32).contains(&index) {
115+
_try_set(1 << index)
116+
} else {
117+
Err(Error::IndexOutOfBounds {
118+
index,
119+
min: 3,
120+
max: 31,
121+
})
122+
}
123+
}
124+
76125
#[inline]
77126
pub unsafe fn clear_hpm(index: usize) {
78127
assert!((3..32).contains(&index));
79128
_clear(1 << index);
80129
}
81130

131+
#[inline]
132+
pub unsafe fn try_clear_hpm(index: usize) -> Result<()> {
133+
if (3..32).contains(&index) {
134+
_try_clear(1 << index)
135+
} else {
136+
Err(Error::IndexOutOfBounds {
137+
index,
138+
min: 3,
139+
max: 31,
140+
})
141+
}
142+
}
143+
82144
#[cfg(test)]
83145
mod tests {
84146
use super::*;
@@ -105,12 +167,33 @@ mod tests {
105167

106168
(3..32).for_each(|i| {
107169
assert!(!m.hpm(i));
170+
assert_eq!(m.try_hpm(i), Ok(false));
108171

109172
m.set_hpm(i, true);
110173
assert!(m.hpm(i));
174+
assert_eq!(m.try_hpm(i), Ok(true));
111175

112-
m.set_hpm(i, false);
113-
assert!(!m.hpm(i));
176+
assert_eq!(m.try_set_hpm(i, false), Ok(()));
177+
assert_eq!(m.try_hpm(i), Ok(false));
178+
});
179+
180+
(0..2).chain(32..64).for_each(|index| {
181+
assert_eq!(
182+
m.try_hpm(index),
183+
Err(Error::IndexOutOfBounds {
184+
index,
185+
min: 3,
186+
max: 31
187+
})
188+
);
189+
assert_eq!(
190+
m.try_set_hpm(index, false),
191+
Err(Error::IndexOutOfBounds {
192+
index,
193+
min: 3,
194+
max: 31
195+
})
196+
);
114197
});
115198
}
116199
}

0 commit comments

Comments
 (0)