Skip to content

Commit 2fc23fe

Browse files
Merge pull request #213 from rmsyn/register/mcountinhibit
riscv: add `mcountinhibit` module
2 parents 6de6e53 + 93c6d40 commit 2fc23fe

File tree

6 files changed

+125
-3
lines changed

6 files changed

+125
-3
lines changed

riscv-peripheral/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## [Unreleased]
99

10+
### Fixed
11+
12+
- `clippy` fixes
13+
1014
## [v0.1.0] - 2024-02-15
1115

1216
### Added

riscv-peripheral/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
//! ## Features
44
//!
55
//! - `aclint-hal-async`: enables the [`hal_async::delay::DelayNs`] implementation for the ACLINT peripheral.
6-
//! This feature relies on external functions that must be provided by the user. See [`hal_async::aclint`] for more information.
6+
//! This feature relies on external functions that must be provided by the user. See [`hal_async::aclint`] for more information.
77
88
#![deny(missing_docs)]
99
#![no_std]

riscv/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1616
- Add `Mstatus::update_*` helpers to manipulate Mstatus values without touching
1717
the CSR
1818
- Export `riscv::register::macros` module macros for external use
19+
- Add `riscv::register::mcountinhibit` module for `mcountinhibit` CSR
1920

2021
### Fixed
2122

riscv/src/interrupt.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ pub mod machine {
6262
/// - Do not call this function inside a critical section.
6363
/// - This method is assumed to be called within an interrupt handler.
6464
/// - Make sure to clear the interrupt flag that caused the interrupt before calling
65-
/// this method. Otherwise, the interrupt will be re-triggered before executing `f`.
65+
/// this method. Otherwise, the interrupt will be re-triggered before executing `f`.
6666
#[inline]
6767
pub unsafe fn nested<F, R>(f: F) -> R
6868
where
@@ -151,7 +151,7 @@ pub mod supervisor {
151151
/// - Do not call this function inside a critical section.
152152
/// - This method is assumed to be called within an interrupt handler.
153153
/// - Make sure to clear the interrupt flag that caused the interrupt before calling
154-
/// this method. Otherwise, the interrupt will be re-triggered before executing `f`.
154+
/// this method. Otherwise, the interrupt will be re-triggered before executing `f`.
155155
#[inline]
156156
pub unsafe fn nested<F, R>(f: F) -> R
157157
where

riscv/src/register.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ mod pmpaddrx;
9595
pub use self::pmpaddrx::*;
9696

9797
// Machine Counter/Timers
98+
pub mod mcountinhibit;
9899
pub mod mcycle;
99100
pub mod mcycleh;
100101
mod mhpmcounterx;

riscv/src/register/mcountinhibit.rs

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
//! `mcountinhibit` register
2+
3+
use crate::bits::{bf_extract, bf_insert};
4+
5+
/// `mcountinhibit` register
6+
#[derive(Clone, Copy, Debug)]
7+
pub struct Mcountinhibit {
8+
bits: usize,
9+
}
10+
11+
impl Mcountinhibit {
12+
/// Machine "cycle\[h\]" Disable
13+
#[inline]
14+
pub fn cy(&self) -> bool {
15+
bf_extract(self.bits, 0, 1) != 0
16+
}
17+
18+
/// Sets whether to inhibit the "cycle\[h\]" counter.
19+
///
20+
/// Only updates the in-memory value, does not modify the `mcountinhibit` register.
21+
#[inline]
22+
pub fn set_cy(&mut self, cy: bool) {
23+
self.bits = bf_insert(self.bits, 0, 1, cy as usize);
24+
}
25+
26+
/// Machine "instret\[h\]" Disable
27+
#[inline]
28+
pub fn ir(&self) -> bool {
29+
bf_extract(self.bits, 2, 1) != 0
30+
}
31+
32+
/// Sets whether to inhibit the "instret\[h\]" counter.
33+
///
34+
/// Only updates the in-memory value, does not modify the `mcountinhibit` register.
35+
#[inline]
36+
pub fn set_ir(&mut self, ir: bool) {
37+
self.bits = bf_insert(self.bits, 2, 1, ir as usize);
38+
}
39+
40+
/// Machine "hpm\[x\]" Disable (bits 3-31)
41+
#[inline]
42+
pub fn hpm(&self, index: usize) -> bool {
43+
assert!((3..32).contains(&index));
44+
bf_extract(self.bits, index, 1) != 0
45+
}
46+
47+
/// Sets whether to inhibit the "hpm\[X\]" counter.
48+
///
49+
/// Only updates the in-memory value, does not modify the `mcountinhibit` register.
50+
#[inline]
51+
pub fn set_hpm(&mut self, index: usize, hpm: bool) {
52+
assert!((3..32).contains(&index));
53+
self.bits = bf_insert(self.bits, index, 1, hpm as usize);
54+
}
55+
}
56+
57+
read_csr_as!(Mcountinhibit, 0x320);
58+
write_csr_as!(Mcountinhibit, 0x320);
59+
set!(0x320);
60+
clear!(0x320);
61+
62+
set_clear_csr!(
63+
/// Machine cycle Disable
64+
, set_cy, clear_cy, 1 << 0);
65+
66+
set_clear_csr!(
67+
/// Machine instret Disable
68+
, set_ir, clear_ir, 1 << 2);
69+
70+
#[inline]
71+
pub unsafe fn set_hpm(index: usize) {
72+
assert!((3..32).contains(&index));
73+
_set(1 << index);
74+
}
75+
76+
#[inline]
77+
pub unsafe fn clear_hpm(index: usize) {
78+
assert!((3..32).contains(&index));
79+
_clear(1 << index);
80+
}
81+
82+
#[cfg(test)]
83+
mod tests {
84+
use super::*;
85+
86+
#[test]
87+
fn test_mcountinhibit() {
88+
let mut m = Mcountinhibit { bits: 0 };
89+
90+
assert!(!m.cy());
91+
92+
m.set_cy(true);
93+
assert!(m.cy());
94+
95+
m.set_cy(false);
96+
assert!(!m.cy());
97+
98+
assert!(!m.ir());
99+
100+
m.set_ir(true);
101+
assert!(m.ir());
102+
103+
m.set_ir(false);
104+
assert!(!m.ir());
105+
106+
(3..32).for_each(|i| {
107+
assert!(!m.hpm(i));
108+
109+
m.set_hpm(i, true);
110+
assert!(m.hpm(i));
111+
112+
m.set_hpm(i, false);
113+
assert!(!m.hpm(i));
114+
});
115+
}
116+
}

0 commit comments

Comments
 (0)