diff --git a/.github/workflows/riscv-rt.yaml b/.github/workflows/riscv-rt.yaml index cf7c52c1..094d25a1 100644 --- a/.github/workflows/riscv-rt.yaml +++ b/.github/workflows/riscv-rt.yaml @@ -10,8 +10,8 @@ jobs: build-riscv: strategy: matrix: - # All generated code should be running on stable now, MRSV is 1.61.0 - toolchain: [ stable, nightly, 1.61.0 ] + # All generated code should be running on stable now, MRSV is 1.67.0 + toolchain: [ stable, nightly, 1.67.0 ] target: - riscv32i-unknown-none-elf - riscv32im-unknown-none-elf @@ -28,9 +28,9 @@ jobs: - toolchain: nightly experimental: true exclude: - - toolchain: 1.61.0 + - toolchain: 1.67.0 target: riscv32im-unknown-none-elf - - toolchain: 1.61.0 + - toolchain: 1.67.0 target: riscv32imafc-unknown-none-elf runs-on: ubuntu-latest continue-on-error: ${{ matrix.experimental || false }} diff --git a/.github/workflows/riscv-semihosting.yaml b/.github/workflows/riscv-semihosting.yaml index 3ba711ec..66e28158 100644 --- a/.github/workflows/riscv-semihosting.yaml +++ b/.github/workflows/riscv-semihosting.yaml @@ -11,8 +11,8 @@ jobs: build-riscv: strategy: matrix: - # All generated code should be running on stable now, MRSV is 1.61.0 - toolchain: [ stable, nightly, 1.61.0 ] + # All generated code should be running on stable now, MRSV is 1.67.0 + toolchain: [ stable, nightly, 1.67.0 ] target: - riscv32i-unknown-none-elf - riscv32imc-unknown-none-elf diff --git a/.github/workflows/riscv-target-parser.yaml b/.github/workflows/riscv-target-parser.yaml index bd04a190..fce646a2 100644 --- a/.github/workflows/riscv-target-parser.yaml +++ b/.github/workflows/riscv-target-parser.yaml @@ -11,7 +11,7 @@ jobs: strategy: matrix: os: [ macos-latest, ubuntu-latest, windows-latest ] - toolchain: [ stable, nightly, 1.61.0 ] + toolchain: [ stable, nightly, 1.67.0 ] include: # Nightly is only for reference and allowed to fail - rust: nightly diff --git a/.github/workflows/riscv.yaml b/.github/workflows/riscv.yaml index 21aac5f9..cf8a1e94 100644 --- a/.github/workflows/riscv.yaml +++ b/.github/workflows/riscv.yaml @@ -11,8 +11,8 @@ jobs: build-riscv: strategy: matrix: - # All generated code should be running on stable now, MRSV is 1.61.0 - toolchain: [ stable, nightly, 1.61.0 ] + # All generated code should be running on stable now, MRSV is 1.67.0 + toolchain: [ stable, nightly, 1.67.0 ] target: - riscv32i-unknown-none-elf - riscv32imc-unknown-none-elf diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index d0979460..2393f742 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -20,8 +20,8 @@ jobs: run-build: strategy: matrix: - # All generated code should be running on stable now, MRSV is 1.61.0 - toolchain: [ stable, nightly, 1.61.0 ] + # All generated code should be running on stable now, MRSV is 1.67.0 + toolchain: [ stable, nightly, 1.67.0 ] target: - riscv32i-unknown-none-elf - riscv32im-unknown-none-elf @@ -37,9 +37,9 @@ jobs: - toolchain: nightly experimental: true exclude: - - toolchain: 1.61.0 + - toolchain: 1.67.0 target: riscv32im-unknown-none-elf - - toolchain: 1.61.0 + - toolchain: 1.67.0 target: riscv32imafc-unknown-none-elf runs-on: ubuntu-latest continue-on-error: ${{ matrix.experimental || false }} diff --git a/riscv/CHANGELOG.md b/riscv/CHANGELOG.md index 0b382665..85e2634e 100644 --- a/riscv/CHANGELOG.md +++ b/riscv/CHANGELOG.md @@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Write utilities for `mcycle`, `minstret` - Add `senvcfg` CSR - Add `scontext` CSR +- Add `mconfigptr` CSR +- Bump MSRV to 1.67.0 for `log` to `ilog` name change ### Changed diff --git a/riscv/Cargo.toml b/riscv/Cargo.toml index a7821462..730b1547 100644 --- a/riscv/Cargo.toml +++ b/riscv/Cargo.toml @@ -2,7 +2,7 @@ name = "riscv" version = "0.13.0" edition = "2021" -rust-version = "1.61" +rust-version = "1.67" repository = "https://github.com/rust-embedded/riscv" authors = ["The RISC-V Team "] categories = ["embedded", "hardware-support", "no-std"] diff --git a/riscv/src/register.rs b/riscv/src/register.rs index 4a56e1e0..817d1745 100644 --- a/riscv/src/register.rs +++ b/riscv/src/register.rs @@ -109,6 +109,9 @@ pub mod minstreth; mod mhpmeventx; pub use self::mhpmeventx::*; +// Machine configuration +pub mod mconfigptr; + #[cfg(test)] mod tests; diff --git a/riscv/src/register/mconfigptr.rs b/riscv/src/register/mconfigptr.rs new file mode 100644 index 00000000..41c7cb47 --- /dev/null +++ b/riscv/src/register/mconfigptr.rs @@ -0,0 +1,107 @@ +//! `mconfigptr` register. + +use crate::result::{Error, Result}; + +const MASK: usize = usize::MAX; + +read_only_csr! { + /// `mconfigptr` register. + Mconfigptr: 0xf15, + mask: MASK, + sentinel: 0, +} + +impl Mconfigptr { + /// Represents the bitshift for a properly aligned configuration pointer. + pub const ALIGN_SHIFT: usize = (usize::BITS / 8).ilog2() as usize; + /// Represents the bitmask for a properly aligned configuration pointer. + pub const ALIGN_MASK: usize = (1usize << Self::ALIGN_SHIFT) - 1; + + /// Gets the pointer to the machine configuration structure. + /// + /// # Panics + /// + /// Panics if: + /// + /// - the value is `0`, indicating no configuration structure + /// - the pointer is not aligned to an MXLEN byte value + pub fn as_ptr(&self) -> *const u8 { + self.try_as_ptr().unwrap() + } + + /// Attempts to get the pointer to the machine configuration structure. + /// + /// # Note + /// + /// Returns an error if: + /// + /// - the value is `0`, indicating no configuration structure + /// - the pointer is not aligned to an MXLEN byte value + pub const fn try_as_ptr(&self) -> Result<*const u8> { + match self.bits() { + 0 => Err(Error::InvalidFieldVariant { + field: "mconfigptr", + value: 0, + }), + p if p & Self::ALIGN_MASK != 0 => Err(Error::InvalidFieldValue { + field: "mconfigptr", + value: p, + bitmask: !Self::ALIGN_MASK, + }), + p => Ok(p as *const _), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_mconfigptr() { + #[cfg(target_arch = "riscv32")] + const EXP_SHIFT: usize = 2; + #[cfg(not(target_arch = "riscv32"))] + const EXP_SHIFT: usize = 3; + + const EXP_MASK: usize = (1usize << EXP_SHIFT) - 1; + + assert_eq!(Mconfigptr::ALIGN_SHIFT, EXP_SHIFT); + assert_eq!(Mconfigptr::ALIGN_MASK, EXP_MASK); + + (1..usize::BITS) + .map(|b| ((1u128 << b) - 1) as usize) + .for_each(|ptr| { + let mconfigptr = Mconfigptr::from_bits(ptr); + assert_eq!(mconfigptr.bits(), ptr); + + match mconfigptr.try_as_ptr() { + Ok(cfg_ptr) => { + assert_eq!(cfg_ptr, ptr as *const _); + assert_eq!(mconfigptr.as_ptr(), ptr as *const _); + } + Err(err) if ptr == 0 => assert_eq!( + err, + Error::InvalidFieldVariant { + field: "mconfigptr", + value: 0 + } + ), + Err(err) => assert_eq!( + err, + Error::InvalidFieldValue { + field: "mconfigptr", + value: ptr, + bitmask: !Mconfigptr::ALIGN_MASK, + } + ), + } + + let aligned_ptr = ptr << Mconfigptr::ALIGN_SHIFT; + let aligned_mconfigptr = Mconfigptr::from_bits(aligned_ptr); + + assert_eq!(aligned_mconfigptr.try_as_ptr(), Ok(aligned_ptr as *const _)); + assert_eq!(aligned_mconfigptr.as_ptr(), aligned_ptr as *const _); + }); + } +}