Skip to content

register: add mconfigptr register #290

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/riscv-rt.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 }}
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/riscv-semihosting.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/riscv-target-parser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/riscv.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 }}
Expand Down
2 changes: 2 additions & 0 deletions riscv/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion riscv/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 <[email protected]>"]
categories = ["embedded", "hardware-support", "no-std"]
Expand Down
3 changes: 3 additions & 0 deletions riscv/src/register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ pub mod minstreth;
mod mhpmeventx;
pub use self::mhpmeventx::*;

// Machine configuration
pub mod mconfigptr;

#[cfg(test)]
mod tests;

Expand Down
107 changes: 107 additions & 0 deletions riscv/src/register/mconfigptr.rs
Original file line number Diff line number Diff line change
@@ -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 _);
});
}
}