Skip to content

Commit edb3e6c

Browse files
Merge pull request #262 from rmsyn/riscv/scounteren-csr-macro
riscv: define `scounteren` CSR with macro helpers
2 parents 40cb40d + 22dc1b9 commit edb3e6c

File tree

4 files changed

+70
-48
lines changed

4 files changed

+70
-48
lines changed

riscv/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
3535
- Use CSR helper macros to define `pmpcfgx` field types
3636
- Use CSR helper macros to define `scause` field types
3737
- Use CSR helper macros to define `sie` register
38+
- Use CSR helper macros to define `scounteren` field types
3839

3940
## [v0.12.1] - 2024-10-20
4041

riscv/src/register/scounteren.rs

Lines changed: 65 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -2,57 +2,36 @@
22
33
use crate::result::{Error, Result};
44

5-
/// scounteren register
6-
#[derive(Clone, Copy, Debug)]
7-
pub struct Scounteren {
8-
bits: usize,
5+
read_write_csr! {
6+
/// scounteren register
7+
Scounteren: 0x106,
8+
mask: 0xffff_ffff,
99
}
1010

11-
impl Scounteren {
11+
read_write_csr_field! {
12+
Scounteren,
1213
/// User "cycle\[h\]" Enable
13-
#[inline]
14-
pub fn cy(&self) -> bool {
15-
self.bits & (1 << 0) != 0
16-
}
14+
cy: 0,
15+
}
1716

17+
read_write_csr_field! {
18+
Scounteren,
1819
/// User "time\[h\]" Enable
19-
#[inline]
20-
pub fn tm(&self) -> bool {
21-
self.bits & (1 << 1) != 0
22-
}
20+
tm: 1,
21+
}
2322

23+
read_write_csr_field! {
24+
Scounteren,
2425
/// User "instret\[h]\" Enable
25-
#[inline]
26-
pub fn ir(&self) -> bool {
27-
self.bits & (1 << 2) != 0
28-
}
29-
30-
/// User "hpm\[x\]" Enable (bits 3-31)
31-
#[inline]
32-
pub fn hpm(&self, index: usize) -> bool {
33-
assert!((3..32).contains(&index));
34-
self.bits & (1 << index) != 0
35-
}
26+
ir: 2,
27+
}
3628

29+
read_write_csr_field! {
30+
Scounteren,
3731
/// User "hpm\[x\]" Enable (bits 3-31)
38-
///
39-
/// Attempts to read the "hpm\[x\]" value, and returns an error if the index is invalid.
40-
#[inline]
41-
pub fn try_hpm(&self, index: usize) -> Result<bool> {
42-
if (3..32).contains(&index) {
43-
Ok(self.bits & (1 << index) != 0)
44-
} else {
45-
Err(Error::IndexOutOfBounds {
46-
index,
47-
min: 3,
48-
max: 31,
49-
})
50-
}
51-
}
32+
hpm: 3..=31,
5233
}
5334

54-
read_csr_as!(Scounteren, 0x106);
55-
write_csr!(0x106);
5635
set!(0x106);
5736
clear!(0x106);
5837

@@ -68,12 +47,17 @@ set_clear_csr!(
6847
/// User instret Enable
6948
, set_ir, clear_ir, 1 << 2);
7049

50+
/// Sets the "hpm\[x\]" enable (bits 3-31).
51+
///
52+
/// # Note
53+
///
54+
/// Panics if `index` is out-of-bounds.
7155
#[inline]
7256
pub unsafe fn set_hpm(index: usize) {
73-
assert!((3..32).contains(&index));
74-
_set(1 << index);
57+
try_set_hpm(index).unwrap();
7558
}
7659

60+
/// Attempts to set the "hpm\[x\]" enable (bits 3-31).
7761
#[inline]
7862
pub unsafe fn try_set_hpm(index: usize) -> Result<()> {
7963
if (3..32).contains(&index) {
@@ -87,12 +71,17 @@ pub unsafe fn try_set_hpm(index: usize) -> Result<()> {
8771
}
8872
}
8973

74+
/// Clears the "hpm\[x\]" enable (bits 3-31).
75+
///
76+
/// # Note
77+
///
78+
/// Panics if `index` is out-of-bounds.
9079
#[inline]
9180
pub unsafe fn clear_hpm(index: usize) {
92-
assert!((3..32).contains(&index));
93-
_clear(1 << index);
81+
try_clear_hpm(index).unwrap()
9482
}
9583

84+
/// Attempts to clear the "hpm\[x\]" enable (bits 3-31).
9685
#[inline]
9786
pub unsafe fn try_clear_hpm(index: usize) -> Result<()> {
9887
if (3..32).contains(&index) {
@@ -105,3 +94,35 @@ pub unsafe fn try_clear_hpm(index: usize) -> Result<()> {
10594
})
10695
}
10796
}
97+
98+
#[cfg(test)]
99+
mod tests {
100+
use super::*;
101+
102+
#[test]
103+
fn test_scounteren() {
104+
const HPM_MIN: usize = 3;
105+
const HPM_MAX: usize = 31;
106+
107+
let mut scounteren = Scounteren::from_bits(0);
108+
109+
test_csr_field!(scounteren, cy);
110+
test_csr_field!(scounteren, tm);
111+
test_csr_field!(scounteren, ir);
112+
113+
(HPM_MIN..=HPM_MAX).for_each(|index| {
114+
test_csr_field!(scounteren, hpm, index);
115+
});
116+
117+
(0..usize::BITS as usize)
118+
.filter(|&i| !(HPM_MIN..=HPM_MAX).any(|idx| idx == i))
119+
.for_each(|index| {
120+
let err = Error::IndexOutOfBounds {
121+
index,
122+
min: 3,
123+
max: 31,
124+
};
125+
test_csr_field!(scounteren, hpm, index, err)
126+
});
127+
}
128+
}

riscv/src/register/tests/read_write_csr.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,12 @@ pub fn _try_read_csr() -> Result<Mtest> {
5555

5656
#[allow(unused)]
5757
pub fn _write_csr(csr: Mtest) {
58-
write(csr);
58+
unsafe { write(csr) };
5959
}
6060

6161
#[allow(unused)]
6262
pub fn _try_write_csr(csr: Mtest) {
63-
try_write(csr);
63+
unsafe { try_write(csr) };
6464
}
6565

6666
#[test]

riscv/src/register/tests/write_only_csr.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,12 @@ write_only_csr_field! {
4545
// we don't test the `write` function, we are only testing in-memory functions.
4646
#[allow(unused)]
4747
pub fn _write_csr(csr: Mtest) {
48-
write(csr);
48+
unsafe { write(csr) };
4949
}
5050

5151
#[allow(unused)]
5252
pub fn _try_write_csr(csr: Mtest) -> Result<()> {
53-
try_write(csr)
53+
unsafe { try_write(csr) }
5454
}
5555

5656
#[test]

0 commit comments

Comments
 (0)