1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
//! mcause register
pub use crate::interrupt::Trap;
read_only_csr! {
/// `mcause` register
Mcause: 0x342,
mask: usize::MAX,
}
#[cfg(target_arch = "riscv32")]
read_only_csr_field! {
Mcause,
/// Returns the `code` field.
code: [0:30],
}
#[cfg(not(target_arch = "riscv32"))]
read_only_csr_field! {
Mcause,
/// Returns the `code` field.
code: [0:62],
}
#[cfg(target_arch = "riscv32")]
read_only_csr_field! {
Mcause,
/// Is the trap cause an interrupt.
is_interrupt: 31,
}
#[cfg(not(target_arch = "riscv32"))]
read_only_csr_field! {
Mcause,
/// Is the trap cause an interrupt.
is_interrupt: 63,
}
impl Mcause {
/// Returns the trap cause represented by this register.
///
/// # Note
///
/// This method returns a **raw trap cause**, which means that values are represented as `usize`.
/// To get a target-specific trap cause, use [`Trap::try_into`] with your target-specific M-Mode trap cause types.
#[inline]
pub fn cause(&self) -> Trap<usize, usize> {
if self.is_interrupt() {
Trap::Interrupt(self.code())
} else {
Trap::Exception(self.code())
}
}
/// Is trap cause an exception.
#[inline]
pub fn is_exception(&self) -> bool {
!self.is_interrupt()
}
}