Skip to content

Commit b343fbe

Browse files
committed
riscv: define mtvec CSR with macro helpers
Uses the CSR macro helpers to define the `mtvec` CSR register. Authored-by: rmsyn <[email protected]> Reviewed-by: romancardenas <[email protected]>
1 parent 6e91134 commit b343fbe

File tree

1 file changed

+48
-33
lines changed

1 file changed

+48
-33
lines changed

riscv/src/register/mtvec.rs

Lines changed: 48 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,65 @@
11
//! mtvec register
22
3-
/// mtvec register
4-
#[derive(Clone, Copy, Debug)]
5-
pub struct Mtvec {
6-
bits: usize,
3+
use crate::result::{Error, Result};
4+
5+
const MASK: usize = usize::MAX;
6+
const TRAP_MASK: usize = 0b11;
7+
8+
read_write_csr! {
9+
/// mtvec register
10+
Mtvec: 0x305,
11+
mask: MASK,
12+
}
13+
14+
csr_field_enum! {
15+
/// Trap mode
16+
TrapMode {
17+
default: Direct,
18+
Direct = 0,
19+
Vectored = 1,
20+
}
721
}
822

9-
/// Trap mode
10-
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
11-
pub enum TrapMode {
12-
Direct = 0,
13-
Vectored = 1,
23+
read_write_csr_field! {
24+
Mtvec,
25+
/// Accesses the trap-vector mode.
26+
trap_mode,
27+
TrapMode: [0:1],
1428
}
1529

1630
impl Mtvec {
17-
/// Returns the contents of the register as raw bits
31+
/// Returns the trap-vector base-address
1832
#[inline]
19-
pub fn bits(&self) -> usize {
20-
self.bits
33+
pub const fn address(&self) -> usize {
34+
self.bits & !TRAP_MASK
2135
}
2236

23-
/// Returns the trap-vector base-address
37+
/// Sets the trap-vector base-address.
38+
///
39+
/// # Note
40+
///
41+
/// Panics if the address is not aligned to 4-bytes.
2442
#[inline]
25-
pub fn address(&self) -> usize {
26-
self.bits - (self.bits & 0b11)
43+
pub fn set_address(&mut self, address: usize) {
44+
self.try_set_address(address).unwrap();
2745
}
2846

29-
/// Returns the trap-vector mode
47+
/// Attempts to set the trap-vector base-address.
48+
///
49+
/// # Note
50+
///
51+
/// Returns an error if the address is not aligned to 4-bytes.
3052
#[inline]
31-
pub fn trap_mode(&self) -> Option<TrapMode> {
32-
let mode = self.bits & 0b11;
33-
match mode {
34-
0 => Some(TrapMode::Direct),
35-
1 => Some(TrapMode::Vectored),
36-
_ => None,
53+
pub fn try_set_address(&mut self, address: usize) -> Result<()> {
54+
// check for four-byte alignment
55+
if (address & TRAP_MASK) != 0 {
56+
Err(Error::InvalidFieldVariant {
57+
field: "mtvec::address",
58+
value: address,
59+
})
60+
} else {
61+
self.bits = address | (self.bits & TRAP_MASK);
62+
Ok(())
3763
}
3864
}
3965
}
40-
41-
read_csr_as!(Mtvec, 0x305);
42-
43-
write_csr!(0x305);
44-
45-
/// Writes the CSR
46-
#[inline]
47-
pub unsafe fn write(addr: usize, mode: TrapMode) {
48-
let bits = addr + mode as usize;
49-
_write(bits);
50-
}

0 commit comments

Comments
 (0)