diff --git a/riscv/CHANGELOG.md b/riscv/CHANGELOG.md index e8a64fb8..a662702f 100644 --- a/riscv/CHANGELOG.md +++ b/riscv/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +### Added + +- CSR helper macro to check for platform implementation + +### Changed + +- Use CSR helper macros to define `marchid` register + ## [v0.12.1] - 2024-10-20 ### Changed diff --git a/riscv/src/register/macros.rs b/riscv/src/register/macros.rs index 1aeb082d..46bf84ec 100644 --- a/riscv/src/register/macros.rs +++ b/riscv/src/register/macros.rs @@ -92,6 +92,27 @@ macro_rules! read_csr_as { }) } }; + + ($register:ident, $csr_number:literal, $sentinel:tt) => { + $crate::read_csr!($csr_number); + + /// Reads the CSR. + /// + /// **WARNING**: panics on targets not implementing this CSR. + #[inline] + pub fn read() -> $register { + try_read().unwrap() + } + + /// Attempts to reads the CSR. + #[inline] + pub fn try_read() -> $crate::result::Result<$register> { + match unsafe { _try_read()? } { + $sentinel => Err($crate::result::Error::Unimplemented), + bits => Ok($register { bits }), + } + } + }; } /// `RV32`: Convenience macro to read a CSR register value as a `register` type. @@ -732,6 +753,16 @@ macro_rules! read_only_csr { $crate::read_csr_as!($ty, $csr); }; + + ($(#[$doc:meta])+ + $ty:ident: $csr:tt, + mask: $mask:tt, + sentinel: $sentinel:tt$(,)?, + ) => { + $crate::csr! { $(#[$doc])+ $ty, $mask } + + $crate::read_csr_as!($ty, $csr, $sentinel); + }; } /// Helper macro to create a read-only CSR type. diff --git a/riscv/src/register/marchid.rs b/riscv/src/register/marchid.rs index feca296a..fd03d763 100644 --- a/riscv/src/register/marchid.rs +++ b/riscv/src/register/marchid.rs @@ -1,28 +1,8 @@ //! marchid register -use core::num::NonZeroUsize; - -/// marchid register -#[derive(Clone, Copy, Debug)] -pub struct Marchid { - bits: NonZeroUsize, -} - -impl Marchid { - /// Returns the contents of the register as raw bits - #[inline] - pub fn bits(&self) -> usize { - self.bits.get() - } -} - -read_csr!(0xF12); - -/// Reads the CSR -#[inline] -pub fn read() -> Option { - let r = unsafe { _read() }; - // When marchid is hardwired to zero it means that the marchid - // csr isn't implemented. - NonZeroUsize::new(r).map(|bits| Marchid { bits }) +read_only_csr! { + /// `marchid` register + Marchid: 0xF12, + mask: 0xffff_ffff, + sentinel: 0, }