Skip to content

Commit 1aef881

Browse files
Merge pull request #409 from KushalMeghani1644/fix-408
Add atomic topei read-clear operations
2 parents 85da9b0 + 2aff4cd commit 1aef881

5 files changed

Lines changed: 51 additions & 1 deletion

File tree

riscv/CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
99

1010
### Added
1111

12-
- Add `mireg` and `sireg` CSRs
12+
13+
- Add atomic topei read-clear operations
14+
- Add `mireg` CSR
1315
- Add `stopei` and `vstopei` CSRs (AIA supervisor/virtual-supervisor top external
1416
interrupt), completing the `*topei` set alongside `mtopei`.
1517
- Auto-generate `<FIELD>_SHIFT`, `<FIELD>_WIDTH`, and `<FIELD>_MASK` associated

riscv/src/register/macros.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,48 @@ macro_rules! read_csr_as_rv32 {
104104
};
105105
}
106106

107+
/// Convenience macro to atomically read and clear a CSR as a `register` type.
108+
///
109+
/// This macro should generally not be called directly.
110+
#[macro_export]
111+
macro_rules! read_clear_csr_as {
112+
($register:ident, $csr_number:literal) => {
113+
$crate::read_clear_csr_as!($register, $csr_number, any(target_arch = "riscv32", target_arch = "riscv64"));
114+
};
115+
($register:ident, $csr_number:literal, $($cfg:meta),*) => {
116+
/// Atomically reads and clears the CSR.
117+
///
118+
/// # Safety
119+
///
120+
/// Clearing this CSR may have side effects.
121+
#[inline]
122+
pub unsafe fn read_clear() -> $register {
123+
try_read_clear().unwrap()
124+
}
125+
126+
/// Attempts to atomically read and clear the CSR.
127+
///
128+
/// # Safety
129+
///
130+
/// Clearing this CSR may have side effects.
131+
#[inline]
132+
#[cfg_attr(not($($cfg),*), allow(unused_variables))]
133+
pub unsafe fn try_read_clear() -> $crate::result::Result<$register> {
134+
match () {
135+
#[cfg($($cfg),*)]
136+
() => {
137+
let bits: usize;
138+
core::arch::asm!(concat!("csrrw {0}, ", stringify!($csr_number), ", x0"), out(reg) bits);
139+
Ok($register { bits })
140+
}
141+
#[cfg(not($($cfg),*))]
142+
() => Err($crate::result::Error::Unimplemented),
143+
}
144+
}
145+
146+
};
147+
}
148+
107149
/// Convenience macro to read a CSR register value as a [`usize`].
108150
#[macro_export]
109151
macro_rules! read_csr_as_usize {

riscv/src/register/mtopei.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ read_write_csr! {
1010
mask: 0x07FF_07FF,
1111
}
1212

13+
read_clear_csr_as!(Mtopei, 0x35C);
14+
1315
read_write_csr_field! {
1416
Mtopei,
1517
/// Interrupt ID (bits 16..26)

riscv/src/register/stopei.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ read_write_csr! {
1010
mask: 0x07FF_07FF,
1111
}
1212

13+
read_clear_csr_as!(Stopei, 0x15C);
14+
1315
read_write_csr_field! {
1416
Stopei,
1517
/// Interrupt ID (bits 16..26)

riscv/src/register/vstopei.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ read_write_csr! {
1010
mask: 0x07FF_07FF,
1111
}
1212

13+
read_clear_csr_as!(Vstopei, 0x25C);
14+
1315
read_write_csr_field! {
1416
Vstopei,
1517
/// Interrupt ID (bits 16..26)

0 commit comments

Comments
 (0)