Skip to content

Commit

Permalink
riscv: define stvec CSR with macro helpers
Browse files Browse the repository at this point in the history
Uses CSR macro helpers to define the `stvec` CSR register.
  • Loading branch information
rmsyn committed Feb 12, 2025
1 parent f463f22 commit 0856abb
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 26 deletions.
1 change: 1 addition & 0 deletions riscv/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Use CSR helper macros to define `sie` register
- Use CSR helper macros to define `scounteren` field types
- Use CSR helper macros to define `sip` register
- Use CSR helper macros to define `stvec` field types

## [v0.12.1] - 2024-10-20

Expand Down
65 changes: 39 additions & 26 deletions riscv/src/register/stvec.rs
Original file line number Diff line number Diff line change
@@ -1,43 +1,56 @@
//! stvec register
pub use crate::register::mtvec::TrapMode;
use crate::result::{Error, Result};

/// stvec register
#[derive(Clone, Copy, Debug)]
pub struct Stvec {
bits: usize,
const TRAP_MASK: usize = 0b11;

read_write_csr! {
/// stvec register
Stvec: 0x105,
mask: usize::MAX,
}

read_write_csr_field! {
Stvec,
/// Returns the trap-vector mode
trap_mode,
TrapMode: [0:1],
}

impl Stvec {
/// Returns the contents of the register as raw bits
/// Returns the trap-vector base-address
#[inline]
pub fn bits(&self) -> usize {
self.bits
pub const fn address(&self) -> usize {
self.bits & !TRAP_MASK
}

/// Returns the trap-vector base-address
/// Sets the trap-vector base-address.
///
/// # Note
///
/// Panics if the address is not aligned to 4-bytes.
#[inline]
pub fn address(&self) -> usize {
self.bits - (self.bits & 0b11)
pub fn set_address(&mut self, address: usize) {
self.try_set_address(address).unwrap();
}

/// Returns the trap-vector mode
/// Attempts to set the trap-vector base-address.
///
/// # Note
///
/// Returns an error if the address is not aligned to 4-bytes.
#[inline]
pub fn trap_mode(&self) -> Option<TrapMode> {
let mode = self.bits & 0b11;
match mode {
0 => Some(TrapMode::Direct),
1 => Some(TrapMode::Vectored),
_ => None,
pub fn try_set_address(&mut self, address: usize) -> Result<()> {
// check for four-byte alignment
if (address & TRAP_MASK) != 0 {
Err(Error::InvalidFieldVariant {
field: "stvec::address",
value: address,
})
} else {
self.bits = address | (self.bits & TRAP_MASK);
Ok(())
}
}
}

read_csr_as!(Stvec, 0x105);
write_csr!(0x105);

/// Writes the CSR
#[inline]
pub unsafe fn write(addr: usize, mode: TrapMode) {
_write(addr + mode as usize);
}

0 comments on commit 0856abb

Please sign in to comment.