diff --git a/riscv-peripheral/CHANGELOG.md b/riscv-peripheral/CHANGELOG.md index 91d4b45a..cecd8999 100644 --- a/riscv-peripheral/CHANGELOG.md +++ b/riscv-peripheral/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +### Added + +- Constant methods to access to PLIC and ACLINT registers for HART 0. + These new methods are especially convenient for single-HART targets. + ## [v0.3.0] - 2025-06-10 ### Changed diff --git a/riscv-peripheral/src/aclint.rs b/riscv-peripheral/src/aclint.rs index cbfea295..998edf24 100644 --- a/riscv-peripheral/src/aclint.rs +++ b/riscv-peripheral/src/aclint.rs @@ -130,6 +130,7 @@ pub(crate) mod test { assert_eq!(mtime.get_ptr() as usize, 0x0200_bff8); assert_eq!(clint.mtimecmp0(), mtimer.mtimecmp(HartId::H0)); + assert_eq!(clint.mtimecmp0(), mtimer.mtimecmp0()); assert_eq!(clint.mtimecmp1(), mtimer.mtimecmp(HartId::H1)); assert_eq!(clint.mtimecmp2(), mtimer.mtimecmp(HartId::H2)); diff --git a/riscv-peripheral/src/aclint/mswi.rs b/riscv-peripheral/src/aclint/mswi.rs index afedea3c..c63eab48 100644 --- a/riscv-peripheral/src/aclint/mswi.rs +++ b/riscv-peripheral/src/aclint/mswi.rs @@ -81,6 +81,19 @@ impl MSWI { unsafe { MSIP::new(self.as_ptr().add(hart_id.number()) as _) } } + /// Returns the `MSIP` register for HART 0. + /// + /// # Note + /// + /// According to the RISC-V specification, HART 0 is mandatory. + /// Thus, this function is specially useful in single-HART mode, where HART 0 is the only HART available. + /// In multi-HART mode, it is recommended to use [`MSWI::msip`] or [`MSWI::msip_mhartid`] instead. + #[inline] + pub const fn msip0(self) -> MSIP { + // SAFETY: HART 0 is mandatory + unsafe { MSIP::new(M::BASE) } + } + /// Returns the `MSIP` register for the current HART. /// /// # Note diff --git a/riscv-peripheral/src/aclint/mtimer.rs b/riscv-peripheral/src/aclint/mtimer.rs index 0e2fc834..a22eaefd 100644 --- a/riscv-peripheral/src/aclint/mtimer.rs +++ b/riscv-peripheral/src/aclint/mtimer.rs @@ -105,6 +105,19 @@ impl MTIMER { unsafe { MTIMECMP::new(self.mtimecmp_as_ptr().add(hart_id.number()) as _) } } + /// Returns the `MTIMECMP` register for HART 0. + /// + /// # Note + /// + /// According to the RISC-V specification, HART 0 is mandatory. + /// Thus, this function is specially useful in single-HART mode, where HART 0 is the only HART available. + /// In multi-HART mode, it is recommended to use [`MTIMER::mtimecmp`] or [`MTIMER::mtimecmp_mhartid`] instead. + #[inline] + pub const fn mtimecmp0(self) -> MTIMECMP { + // SAFETY: HART 0 is mandatory + unsafe { MTIMECMP::new(M::MTIMECMP_BASE) } + } + /// Returns the `MTIMECMP` register for the current HART. /// /// # Note diff --git a/riscv-peripheral/src/aclint/sswi.rs b/riscv-peripheral/src/aclint/sswi.rs index b6eed9d1..ad3bfda8 100644 --- a/riscv-peripheral/src/aclint/sswi.rs +++ b/riscv-peripheral/src/aclint/sswi.rs @@ -71,6 +71,19 @@ impl SSWI { // SAFETY: `hart_id` is valid for the target unsafe { SETSSIP::new(self.as_ptr().add(hart_id.number()) as _) } } + + /// Returns the `SETSSIP` register for HART 0. + /// + /// # Note + /// + /// According to the RISC-V specification, HART 0 is mandatory. + /// Thus, this function is specially useful in single-HART mode, where HART 0 is the only HART available. + /// In multi-HART mode, it is recommended to use [`SSWI::setssip`] instead. + #[inline] + pub const fn setssip0(self) -> SETSSIP { + // SAFETY: HART 0 is mandatory + unsafe { SETSSIP::new(S::BASE) } + } } unsafe_peripheral!(SETSSIP, u32, RW); diff --git a/riscv-peripheral/src/plic.rs b/riscv-peripheral/src/plic.rs index 847c89a0..f8f7728a 100644 --- a/riscv-peripheral/src/plic.rs +++ b/riscv-peripheral/src/plic.rs @@ -108,6 +108,19 @@ impl PLIC

{ unsafe { CTX::new(hart_id.number() as _) } } + /// Returns the PLIC HART context for HART 0. + /// + /// # Note + /// + /// According to the RISC-V specification, HART 0 is mandatory. + /// Thus, this function is specially useful in single-HART mode, where HART 0 is the only HART available. + /// In multi-HART mode, it is recommended to use [`PLIC::ctx`] or [`PLIC::ctx_mhartid`] instead. + #[inline] + pub const fn ctx0(self) -> CTX

{ + // SAFETY: HART 0 is mandatory + unsafe { CTX::new(0) } + } + /// Returns the PLIC HART context for the current HART. /// /// # Note @@ -146,7 +159,7 @@ impl CTX

{ /// /// The context number must be valid for the target device. #[inline] - pub(crate) unsafe fn new(context: u16) -> Self { + const unsafe fn new(context: u16) -> Self { Self { context: context as _, _marker: core::marker::PhantomData, @@ -195,8 +208,8 @@ pub(crate) mod test { crate::plic_codegen!( PLIC, base 0x0C00_0000, - harts [HartId::H0 => 0, HartId::H1 => 1, HartId::H2 => 2] - ); + harts [HartId::H1 => 1, HartId::H2 => 2] + ); // We skip HART 0 to get advantage of const ctx0 method let plic = PLIC::new(); let priorities = plic.priorities();