1
1
//! scause register
2
2
3
- use bit_field:: BitField ;
4
-
5
3
/// scause register
6
4
#[ derive( Clone , Copy ) ]
7
5
pub struct Scause {
@@ -17,66 +15,88 @@ pub enum Trap {
17
15
18
16
/// Interrupt
19
17
#[ derive( Copy , Clone , Debug , Eq , PartialEq ) ]
18
+ #[ repr( usize ) ]
20
19
pub enum Interrupt {
21
- UserSoft ,
22
- SupervisorSoft ,
23
- UserTimer ,
24
- SupervisorTimer ,
25
- UserExternal ,
26
- SupervisorExternal ,
20
+ SupervisorSoft = 1 ,
21
+ SupervisorTimer = 5 ,
22
+ SupervisorExternal = 9 ,
27
23
Unknown ,
28
24
}
29
25
30
26
/// Exception
31
27
#[ derive( Copy , Clone , Debug , Eq , PartialEq ) ]
28
+ #[ repr( usize ) ]
32
29
pub enum Exception {
33
- InstructionMisaligned ,
34
- InstructionFault ,
35
- IllegalInstruction ,
36
- Breakpoint ,
37
- LoadMisaligned ,
38
- LoadFault ,
39
- StoreMisaligned ,
40
- StoreFault ,
41
- UserEnvCall ,
42
- InstructionPageFault ,
43
- LoadPageFault ,
44
- StorePageFault ,
30
+ InstructionMisaligned = 0 ,
31
+ InstructionFault = 1 ,
32
+ IllegalInstruction = 2 ,
33
+ Breakpoint = 3 ,
34
+ LoadMisaligned = 4 ,
35
+ LoadFault = 5 ,
36
+ StoreMisaligned = 6 ,
37
+ StoreFault = 7 ,
38
+ UserEnvCall = 8 ,
39
+ SupervisorEnvCall = 9 ,
40
+ InstructionPageFault = 12 ,
41
+ LoadPageFault = 13 ,
42
+ StorePageFault = 15 ,
45
43
Unknown ,
46
44
}
47
45
48
- impl Interrupt {
46
+ impl From < usize > for Interrupt {
49
47
#[ inline]
50
- pub fn from ( nr : usize ) -> Self {
48
+ fn from ( nr : usize ) -> Self {
51
49
match nr {
52
- 0 => Interrupt :: UserSoft ,
53
- 1 => Interrupt :: SupervisorSoft ,
54
- 4 => Interrupt :: UserTimer ,
55
- 5 => Interrupt :: SupervisorTimer ,
56
- 8 => Interrupt :: UserExternal ,
57
- 9 => Interrupt :: SupervisorExternal ,
58
- _ => Interrupt :: Unknown ,
50
+ 1 => Self :: SupervisorSoft ,
51
+ 5 => Self :: SupervisorTimer ,
52
+ 9 => Self :: SupervisorExternal ,
53
+ _ => Self :: Unknown ,
54
+ }
55
+ }
56
+ }
57
+
58
+ impl TryFrom < Interrupt > for usize {
59
+ type Error = Interrupt ;
60
+
61
+ #[ inline]
62
+ fn try_from ( value : Interrupt ) -> Result < Self , Self :: Error > {
63
+ match value {
64
+ Interrupt :: Unknown => Err ( Self :: Error :: Unknown ) ,
65
+ _ => Ok ( value as Self ) ,
59
66
}
60
67
}
61
68
}
62
69
63
- impl Exception {
70
+ impl From < usize > for Exception {
64
71
#[ inline]
65
- pub fn from ( nr : usize ) -> Self {
72
+ fn from ( nr : usize ) -> Self {
66
73
match nr {
67
- 0 => Exception :: InstructionMisaligned ,
68
- 1 => Exception :: InstructionFault ,
69
- 2 => Exception :: IllegalInstruction ,
70
- 3 => Exception :: Breakpoint ,
71
- 4 => Exception :: LoadMisaligned ,
72
- 5 => Exception :: LoadFault ,
73
- 6 => Exception :: StoreMisaligned ,
74
- 7 => Exception :: StoreFault ,
75
- 8 => Exception :: UserEnvCall ,
76
- 12 => Exception :: InstructionPageFault ,
77
- 13 => Exception :: LoadPageFault ,
78
- 15 => Exception :: StorePageFault ,
79
- _ => Exception :: Unknown ,
74
+ 0 => Self :: InstructionMisaligned ,
75
+ 1 => Self :: InstructionFault ,
76
+ 2 => Self :: IllegalInstruction ,
77
+ 3 => Self :: Breakpoint ,
78
+ 4 => Self :: LoadMisaligned ,
79
+ 5 => Self :: LoadFault ,
80
+ 6 => Self :: StoreMisaligned ,
81
+ 7 => Self :: StoreFault ,
82
+ 8 => Self :: UserEnvCall ,
83
+ 9 => Self :: SupervisorEnvCall ,
84
+ 12 => Self :: InstructionPageFault ,
85
+ 13 => Self :: LoadPageFault ,
86
+ 15 => Self :: StorePageFault ,
87
+ _ => Self :: Unknown ,
88
+ }
89
+ }
90
+ }
91
+
92
+ impl TryFrom < Exception > for usize {
93
+ type Error = Exception ;
94
+
95
+ #[ inline]
96
+ fn try_from ( value : Exception ) -> Result < Self , Self :: Error > {
97
+ match value {
98
+ Exception :: Unknown => Err ( Self :: Error :: Unknown ) ,
99
+ _ => Ok ( value as Self ) ,
80
100
}
81
101
}
82
102
}
@@ -91,8 +111,7 @@ impl Scause {
91
111
/// Returns the code field
92
112
#[ inline]
93
113
pub fn code ( & self ) -> usize {
94
- let bit = 1 << ( usize:: BITS as usize - 1 ) ;
95
- self . bits & !bit
114
+ self . bits & !( 1 << ( usize:: BITS as usize - 1 ) )
96
115
}
97
116
98
117
/// Trap Cause
@@ -108,7 +127,7 @@ impl Scause {
108
127
/// Is trap cause an interrupt.
109
128
#[ inline]
110
129
pub fn is_interrupt ( & self ) -> bool {
111
- self . bits . get_bit ( usize:: BITS as usize - 1 )
130
+ self . bits & ( 1 << ( usize:: BITS as usize - 1 ) ) != 0
112
131
}
113
132
114
133
/// Is trap cause an exception.
@@ -132,31 +151,10 @@ pub unsafe fn write(bits: usize) {
132
151
pub unsafe fn set ( cause : Trap ) {
133
152
let bits = match cause {
134
153
Trap :: Interrupt ( i) => {
135
- ( match i {
136
- Interrupt :: UserSoft => 0 ,
137
- Interrupt :: SupervisorSoft => 1 ,
138
- Interrupt :: UserTimer => 4 ,
139
- Interrupt :: SupervisorTimer => 5 ,
140
- Interrupt :: UserExternal => 8 ,
141
- Interrupt :: SupervisorExternal => 9 ,
142
- Interrupt :: Unknown => panic ! ( "unknown interrupt" ) ,
143
- } | ( 1 << ( usize:: BITS as usize - 1 ) ) )
144
- } // interrupt bit is 1
145
- Trap :: Exception ( e) => match e {
146
- Exception :: InstructionMisaligned => 0 ,
147
- Exception :: InstructionFault => 1 ,
148
- Exception :: IllegalInstruction => 2 ,
149
- Exception :: Breakpoint => 3 ,
150
- Exception :: LoadMisaligned => 4 ,
151
- Exception :: LoadFault => 5 ,
152
- Exception :: StoreMisaligned => 6 ,
153
- Exception :: StoreFault => 7 ,
154
- Exception :: UserEnvCall => 8 ,
155
- Exception :: InstructionPageFault => 12 ,
156
- Exception :: LoadPageFault => 13 ,
157
- Exception :: StorePageFault => 15 ,
158
- Exception :: Unknown => panic ! ( "unknown exception" ) ,
159
- } , // interrupt bit is 0
154
+ let i = usize:: try_from ( i) . expect ( "unknown interrupt" ) ;
155
+ i | ( 1 << ( usize:: BITS as usize - 1 ) ) // interrupt bit is 1
156
+ }
157
+ Trap :: Exception ( e) => usize:: try_from ( e) . expect ( "unknown exception" ) ,
160
158
} ;
161
159
_write ( bits) ;
162
160
}
0 commit comments