Skip to content

Commit c044fe8

Browse files
Merge pull request #302 from rust-embedded/rvp-hart0
`riscv-peripheral`: const methods for HART 0
2 parents 025e42b + a57eb3e commit c044fe8

File tree

6 files changed

+61
-3
lines changed

6 files changed

+61
-3
lines changed

riscv-peripheral/CHANGELOG.md

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

88
## [Unreleased]
99

10+
### Added
11+
12+
- Constant methods to access to PLIC and ACLINT registers for HART 0.
13+
These new methods are especially convenient for single-HART targets.
14+
1015
## [v0.3.0] - 2025-06-10
1116

1217
### Changed

riscv-peripheral/src/aclint.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ pub(crate) mod test {
130130
assert_eq!(mtime.get_ptr() as usize, 0x0200_bff8);
131131

132132
assert_eq!(clint.mtimecmp0(), mtimer.mtimecmp(HartId::H0));
133+
assert_eq!(clint.mtimecmp0(), mtimer.mtimecmp0());
133134
assert_eq!(clint.mtimecmp1(), mtimer.mtimecmp(HartId::H1));
134135
assert_eq!(clint.mtimecmp2(), mtimer.mtimecmp(HartId::H2));
135136

riscv-peripheral/src/aclint/mswi.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,19 @@ impl<M: Mswi> MSWI<M> {
8181
unsafe { MSIP::new(self.as_ptr().add(hart_id.number()) as _) }
8282
}
8383

84+
/// Returns the `MSIP` register for HART 0.
85+
///
86+
/// # Note
87+
///
88+
/// According to the RISC-V specification, HART 0 is mandatory.
89+
/// Thus, this function is specially useful in single-HART mode, where HART 0 is the only HART available.
90+
/// In multi-HART mode, it is recommended to use [`MSWI::msip`] or [`MSWI::msip_mhartid`] instead.
91+
#[inline]
92+
pub const fn msip0(self) -> MSIP {
93+
// SAFETY: HART 0 is mandatory
94+
unsafe { MSIP::new(M::BASE) }
95+
}
96+
8497
/// Returns the `MSIP` register for the current HART.
8598
///
8699
/// # Note

riscv-peripheral/src/aclint/mtimer.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,19 @@ impl<M: Mtimer> MTIMER<M> {
105105
unsafe { MTIMECMP::new(self.mtimecmp_as_ptr().add(hart_id.number()) as _) }
106106
}
107107

108+
/// Returns the `MTIMECMP` register for HART 0.
109+
///
110+
/// # Note
111+
///
112+
/// According to the RISC-V specification, HART 0 is mandatory.
113+
/// Thus, this function is specially useful in single-HART mode, where HART 0 is the only HART available.
114+
/// In multi-HART mode, it is recommended to use [`MTIMER::mtimecmp`] or [`MTIMER::mtimecmp_mhartid`] instead.
115+
#[inline]
116+
pub const fn mtimecmp0(self) -> MTIMECMP {
117+
// SAFETY: HART 0 is mandatory
118+
unsafe { MTIMECMP::new(M::MTIMECMP_BASE) }
119+
}
120+
108121
/// Returns the `MTIMECMP` register for the current HART.
109122
///
110123
/// # Note

riscv-peripheral/src/aclint/sswi.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,19 @@ impl<S: Sswi> SSWI<S> {
7171
// SAFETY: `hart_id` is valid for the target
7272
unsafe { SETSSIP::new(self.as_ptr().add(hart_id.number()) as _) }
7373
}
74+
75+
/// Returns the `SETSSIP` register for HART 0.
76+
///
77+
/// # Note
78+
///
79+
/// According to the RISC-V specification, HART 0 is mandatory.
80+
/// Thus, this function is specially useful in single-HART mode, where HART 0 is the only HART available.
81+
/// In multi-HART mode, it is recommended to use [`SSWI::setssip`] instead.
82+
#[inline]
83+
pub const fn setssip0(self) -> SETSSIP {
84+
// SAFETY: HART 0 is mandatory
85+
unsafe { SETSSIP::new(S::BASE) }
86+
}
7487
}
7588

7689
unsafe_peripheral!(SETSSIP, u32, RW);

riscv-peripheral/src/plic.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,19 @@ impl<P: Plic> PLIC<P> {
108108
unsafe { CTX::new(hart_id.number() as _) }
109109
}
110110

111+
/// Returns the PLIC HART context for HART 0.
112+
///
113+
/// # Note
114+
///
115+
/// According to the RISC-V specification, HART 0 is mandatory.
116+
/// Thus, this function is specially useful in single-HART mode, where HART 0 is the only HART available.
117+
/// In multi-HART mode, it is recommended to use [`PLIC::ctx`] or [`PLIC::ctx_mhartid`] instead.
118+
#[inline]
119+
pub const fn ctx0(self) -> CTX<P> {
120+
// SAFETY: HART 0 is mandatory
121+
unsafe { CTX::new(0) }
122+
}
123+
111124
/// Returns the PLIC HART context for the current HART.
112125
///
113126
/// # Note
@@ -146,7 +159,7 @@ impl<P: Plic> CTX<P> {
146159
///
147160
/// The context number must be valid for the target device.
148161
#[inline]
149-
pub(crate) unsafe fn new(context: u16) -> Self {
162+
const unsafe fn new(context: u16) -> Self {
150163
Self {
151164
context: context as _,
152165
_marker: core::marker::PhantomData,
@@ -195,8 +208,8 @@ pub(crate) mod test {
195208
crate::plic_codegen!(
196209
PLIC,
197210
base 0x0C00_0000,
198-
harts [HartId::H0 => 0, HartId::H1 => 1, HartId::H2 => 2]
199-
);
211+
harts [HartId::H1 => 1, HartId::H2 => 2]
212+
); // We skip HART 0 to get advantage of const ctx0 method
200213

201214
let plic = PLIC::new();
202215
let priorities = plic.priorities();

0 commit comments

Comments
 (0)