Skip to content

Commit 622f6fe

Browse files
authored
Merge pull request #139 from rust-embedded/interrupts-exceptions
Rework of mcause and scause registers
2 parents c884f7e + 6ba456a commit 622f6fe

File tree

4 files changed

+151
-140
lines changed

4 files changed

+151
-140
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
Cargo.lock
22
target/
3+
4+
.vscode/

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,18 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1212
- Add generic implementation of a PLIC peripheral
1313
- Add `asm::fence()`, a wrapper for implementing a `fence` instruction
1414
- Add `asm::fence_i()`, a wrapper for implementing a `fence.i` instruction
15+
- Add `TryFrom` implementation for `mcause::{Interrupt, Exception}` and `scause::{Interrupt, Exception}`
1516

1617
### Changed
1718

1819
- CI actions updated. They now use `checkout@v3` and `dtolnay/rust-toolchain`.
20+
- `mcause::{Interrupt, Exception}` and `scause::{Interrupt, Exception}` now implement `From` trait for `usize`
1921

2022
### Fixed
2123

2224
- Fix `scause::Exception` missing `LoadMisaligned`
25+
- Fix `scause::Exception` missing `SupervisorEnvCall`
26+
- Removed user-level interrupts from `mcause::Interrupt` and `scause::Interrupt`
2327

2428
## [v0.10.1] - 2023-01-18
2529

src/register/mcause.rs

Lines changed: 75 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -15,79 +15,100 @@ pub enum Trap {
1515

1616
/// Interrupt
1717
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
18+
#[repr(usize)]
1819
pub enum Interrupt {
19-
UserSoft,
20-
SupervisorSoft,
21-
MachineSoft,
22-
UserTimer,
23-
SupervisorTimer,
24-
MachineTimer,
25-
UserExternal,
26-
SupervisorExternal,
27-
MachineExternal,
20+
SupervisorSoft = 1,
21+
MachineSoft = 3,
22+
SupervisorTimer = 5,
23+
MachineTimer = 7,
24+
SupervisorExternal = 9,
25+
MachineExternal = 11,
2826
Unknown,
2927
}
3028

3129
/// Exception
3230
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
31+
#[repr(usize)]
3332
pub enum Exception {
34-
InstructionMisaligned,
35-
InstructionFault,
36-
IllegalInstruction,
37-
Breakpoint,
38-
LoadMisaligned,
39-
LoadFault,
40-
StoreMisaligned,
41-
StoreFault,
42-
UserEnvCall,
43-
SupervisorEnvCall,
44-
MachineEnvCall,
45-
InstructionPageFault,
46-
LoadPageFault,
47-
StorePageFault,
33+
InstructionMisaligned = 0,
34+
InstructionFault = 1,
35+
IllegalInstruction = 2,
36+
Breakpoint = 3,
37+
LoadMisaligned = 4,
38+
LoadFault = 5,
39+
StoreMisaligned = 6,
40+
StoreFault = 7,
41+
UserEnvCall = 8,
42+
SupervisorEnvCall = 9,
43+
MachineEnvCall = 11,
44+
InstructionPageFault = 12,
45+
LoadPageFault = 13,
46+
StorePageFault = 15,
4847
Unknown,
4948
}
5049

51-
impl Interrupt {
50+
impl From<usize> for Interrupt {
5251
#[inline]
53-
pub fn from(nr: usize) -> Self {
52+
fn from(nr: usize) -> Self {
5453
match nr {
55-
0 => Interrupt::UserSoft,
56-
1 => Interrupt::SupervisorSoft,
57-
3 => Interrupt::MachineSoft,
58-
4 => Interrupt::UserTimer,
59-
5 => Interrupt::SupervisorTimer,
60-
7 => Interrupt::MachineTimer,
61-
8 => Interrupt::UserExternal,
62-
9 => Interrupt::SupervisorExternal,
63-
11 => Interrupt::MachineExternal,
64-
_ => Interrupt::Unknown,
54+
1 => Self::SupervisorSoft,
55+
3 => Self::MachineSoft,
56+
5 => Self::SupervisorTimer,
57+
7 => Self::MachineTimer,
58+
9 => Self::SupervisorExternal,
59+
11 => Self::MachineExternal,
60+
_ => Self::Unknown,
6561
}
6662
}
6763
}
6864

69-
impl Exception {
65+
impl TryFrom<Interrupt> for usize {
66+
type Error = Interrupt;
67+
68+
#[inline]
69+
fn try_from(value: Interrupt) -> Result<Self, Self::Error> {
70+
match value {
71+
Interrupt::Unknown => Err(Self::Error::Unknown),
72+
_ => Ok(value as Self),
73+
}
74+
}
75+
}
76+
77+
impl From<usize> for Exception {
7078
#[inline]
71-
pub fn from(nr: usize) -> Self {
79+
fn from(nr: usize) -> Self {
7280
match nr {
73-
0 => Exception::InstructionMisaligned,
74-
1 => Exception::InstructionFault,
75-
2 => Exception::IllegalInstruction,
76-
3 => Exception::Breakpoint,
77-
4 => Exception::LoadMisaligned,
78-
5 => Exception::LoadFault,
79-
6 => Exception::StoreMisaligned,
80-
7 => Exception::StoreFault,
81-
8 => Exception::UserEnvCall,
82-
9 => Exception::SupervisorEnvCall,
83-
11 => Exception::MachineEnvCall,
84-
12 => Exception::InstructionPageFault,
85-
13 => Exception::LoadPageFault,
86-
15 => Exception::StorePageFault,
87-
_ => Exception::Unknown,
81+
0 => Self::InstructionMisaligned,
82+
1 => Self::InstructionFault,
83+
2 => Self::IllegalInstruction,
84+
3 => Self::Breakpoint,
85+
4 => Self::LoadMisaligned,
86+
5 => Self::LoadFault,
87+
6 => Self::StoreMisaligned,
88+
7 => Self::StoreFault,
89+
8 => Self::UserEnvCall,
90+
9 => Self::SupervisorEnvCall,
91+
11 => Self::MachineEnvCall,
92+
12 => Self::InstructionPageFault,
93+
13 => Self::LoadPageFault,
94+
15 => Self::StorePageFault,
95+
_ => Self::Unknown,
8896
}
8997
}
9098
}
99+
100+
impl TryFrom<Exception> for usize {
101+
type Error = Exception;
102+
103+
#[inline]
104+
fn try_from(value: Exception) -> Result<Self, Self::Error> {
105+
match value {
106+
Exception::Unknown => Err(Self::Error::Unknown),
107+
_ => Ok(value as Self),
108+
}
109+
}
110+
}
111+
91112
impl Mcause {
92113
/// Returns the contents of the register as raw bits
93114
#[inline]
@@ -98,14 +119,7 @@ impl Mcause {
98119
/// Returns the code field
99120
#[inline]
100121
pub fn code(&self) -> usize {
101-
match () {
102-
#[cfg(target_pointer_width = "32")]
103-
() => self.bits & !(1 << 31),
104-
#[cfg(target_pointer_width = "64")]
105-
() => self.bits & !(1 << 63),
106-
#[cfg(target_pointer_width = "128")]
107-
() => self.bits & !(1 << 127),
108-
}
122+
self.bits & !(1 << (usize::BITS as usize - 1))
109123
}
110124

111125
/// Trap Cause
@@ -121,14 +135,7 @@ impl Mcause {
121135
/// Is trap cause an interrupt.
122136
#[inline]
123137
pub fn is_interrupt(&self) -> bool {
124-
match () {
125-
#[cfg(target_pointer_width = "32")]
126-
() => self.bits & (1 << 31) == 1 << 31,
127-
#[cfg(target_pointer_width = "64")]
128-
() => self.bits & (1 << 63) == 1 << 63,
129-
#[cfg(target_pointer_width = "128")]
130-
() => self.bits & (1 << 127) == 1 << 127,
131-
}
138+
self.bits & (1 << (usize::BITS as usize - 1)) != 0
132139
}
133140

134141
/// Is trap cause an exception.

0 commit comments

Comments
 (0)