11//! scause register
22
3- use bit_field:: BitField ;
4-
53/// scause register
64#[ derive( Clone , Copy ) ]
75pub struct Scause {
@@ -17,66 +15,88 @@ pub enum Trap {
1715
1816/// Interrupt
1917#[ derive( Copy , Clone , Debug , Eq , PartialEq ) ]
18+ #[ repr( usize ) ]
2019pub enum Interrupt {
21- UserSoft ,
22- SupervisorSoft ,
23- UserTimer ,
24- SupervisorTimer ,
25- UserExternal ,
26- SupervisorExternal ,
20+ SupervisorSoft = 1 ,
21+ SupervisorTimer = 5 ,
22+ SupervisorExternal = 9 ,
2723 Unknown ,
2824}
2925
3026/// Exception
3127#[ derive( Copy , Clone , Debug , Eq , PartialEq ) ]
28+ #[ repr( usize ) ]
3229pub 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 ,
4543 Unknown ,
4644}
4745
48- impl Interrupt {
46+ impl From < usize > for Interrupt {
4947 #[ inline]
50- pub fn from ( nr : usize ) -> Self {
48+ fn from ( nr : usize ) -> Self {
5149 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 ) ,
5966 }
6067 }
6168}
6269
63- impl Exception {
70+ impl From < usize > for Exception {
6471 #[ inline]
65- pub fn from ( nr : usize ) -> Self {
72+ fn from ( nr : usize ) -> Self {
6673 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 ) ,
80100 }
81101 }
82102}
@@ -91,8 +111,7 @@ impl Scause {
91111 /// Returns the code field
92112 #[ inline]
93113 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 ) )
96115 }
97116
98117 /// Trap Cause
@@ -108,7 +127,7 @@ impl Scause {
108127 /// Is trap cause an interrupt.
109128 #[ inline]
110129 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
112131 }
113132
114133 /// Is trap cause an exception.
@@ -132,31 +151,10 @@ pub unsafe fn write(bits: usize) {
132151pub unsafe fn set ( cause : Trap ) {
133152 let bits = match cause {
134153 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" ) ,
160158 } ;
161159 _write ( bits) ;
162160}
0 commit comments