@@ -15,19 +15,10 @@ pub fn render(
1515) -> Result < TokenStream > {
1616 let mut mod_items = TokenStream :: new ( ) ;
1717
18- let external_interrupts = peripherals
19- . iter ( )
20- . flat_map ( |p| p. interrupt . iter ( ) )
21- . map ( |i| ( i. value , i) )
22- . collect :: < HashMap < _ , _ > > ( ) ;
23- let mut external_interrupts = external_interrupts. into_values ( ) . collect :: < Vec < _ > > ( ) ;
24- external_interrupts. sort_by_key ( |i| i. value ) ;
25- if !external_interrupts. is_empty ( ) {
26- writeln ! ( device_x, "/* External interrupt sources */" ) ?;
27- mod_items. extend ( quote ! { pub use riscv_pac:: ExternalInterruptNumber ; } ) ;
28-
18+ if !r. core_interrupts . is_empty ( ) {
19+ writeln ! ( device_x, "/* Core interrupt sources and trap handlers */" ) ?;
2920 let mut interrupts = vec ! [ ] ;
30- for i in external_interrupts . iter ( ) {
21+ for i in r . core_interrupts . iter ( ) {
3122 let name = TokenStream :: from_str ( & i. name ) . unwrap ( ) ;
3223 let value = TokenStream :: from_str ( & format ! ( "{}" , i. value) ) . unwrap ( ) ;
3324 let description = format ! (
@@ -42,29 +33,43 @@ pub fn render(
4233 ) ;
4334
4435 writeln ! ( device_x, "PROVIDE({name} = DefaultHandler);" ) ?;
36+ writeln ! (
37+ device_x,
38+ "PROVIDE(_start_{name}_trap = _start_DefaultHandler_trap);"
39+ ) ?;
4540
4641 interrupts. push ( quote ! {
4742 #[ doc = #description]
4843 #name = #value,
49- } )
44+ } ) ;
5045 }
5146 mod_items. extend ( quote ! {
52- /// External interrupts. These interrupts are handled by the external peripherals.
53- #[ repr( usize ) ]
54- #[ riscv_pac:: pac_enum( unsafe ExternalInterruptNumber ) ]
47+ /// Core interrupts. These interrupts are handled by the core itself.
48+ #[ riscv:: pac_enum( unsafe CoreInterruptNumber ) ]
5549 #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
56- pub enum ExternalInterrupt {
50+ pub enum CoreInterrupt {
5751 #( #interrupts) *
5852 }
5953 } ) ;
54+ } else {
55+ // when no interrupts are defined, we re-export the standard riscv interrupts
56+ mod_items. extend ( quote ! { pub use riscv:: interrupt:: Interrupt as CoreInterrupt ; } ) ;
6057 }
6158
62- if !r. core_interrupts . is_empty ( ) {
63- writeln ! ( device_x, "/* Core interrupt sources and trap handlers */" ) ?;
64- mod_items. extend ( quote ! { pub use riscv_pac:: CoreInterruptNumber ; } ) ;
59+ // TODO something similar to core interrupts but for exceptions
60+ mod_items. extend ( quote ! { pub use riscv:: interrupt:: Exception ; } ) ;
6561
62+ let external_interrupts = peripherals
63+ . iter ( )
64+ . flat_map ( |p| p. interrupt . iter ( ) )
65+ . map ( |i| ( i. value , i) )
66+ . collect :: < HashMap < _ , _ > > ( ) ;
67+ let mut external_interrupts = external_interrupts. into_values ( ) . collect :: < Vec < _ > > ( ) ;
68+ external_interrupts. sort_by_key ( |i| i. value ) ;
69+ if !external_interrupts. is_empty ( ) {
70+ writeln ! ( device_x, "/* External interrupt sources */" ) ?;
6671 let mut interrupts = vec ! [ ] ;
67- for i in r . core_interrupts . iter ( ) {
72+ for i in external_interrupts . iter ( ) {
6873 let name = TokenStream :: from_str ( & i. name ) . unwrap ( ) ;
6974 let value = TokenStream :: from_str ( & format ! ( "{}" , i. value) ) . unwrap ( ) ;
7075 let description = format ! (
@@ -79,29 +84,23 @@ pub fn render(
7984 ) ;
8085
8186 writeln ! ( device_x, "PROVIDE({name} = DefaultHandler);" ) ?;
82- writeln ! (
83- device_x,
84- "PROVIDE(_start_{name}_trap = _start_DefaultHandler_trap);"
85- ) ?;
8687
8788 interrupts. push ( quote ! {
8889 #[ doc = #description]
8990 #name = #value,
90- } ) ;
91+ } )
9192 }
9293 mod_items. extend ( quote ! {
93- /// Core interrupts. These interrupts are handled by the core itself.
94- #[ repr( usize ) ]
95- #[ riscv_pac:: pac_enum( unsafe CoreInterruptNumber ) ]
94+ /// External interrupts. These interrupts are handled by the external peripherals.
95+ #[ riscv:: pac_enum( unsafe ExternalInterruptNumber ) ]
9696 #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
97- pub enum CoreInterrupt {
97+ pub enum ExternalInterrupt {
9898 #( #interrupts) *
9999 }
100100 } ) ;
101101 }
102102
103103 if !r. priorities . is_empty ( ) {
104- mod_items. extend ( quote ! { pub use riscv_pac:: PriorityNumber ; } ) ;
105104 let priorities = r. priorities . iter ( ) . map ( |p| {
106105 let name = TokenStream :: from_str ( & p. name ) . unwrap ( ) ;
107106 let value = TokenStream :: from_str ( & format ! ( "{}" , p. value) ) . unwrap ( ) ;
@@ -123,8 +122,7 @@ pub fn render(
123122 } ) ;
124123 mod_items. extend ( quote ! {
125124 /// Priority levels in the device
126- #[ repr( u8 ) ]
127- #[ riscv_pac:: pac_enum( unsafe PriorityNumber ) ]
125+ #[ riscv:: pac_enum( unsafe PriorityNumber ) ]
128126 #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
129127 pub enum Priority {
130128 #( #priorities) *
@@ -133,7 +131,6 @@ pub fn render(
133131 }
134132
135133 if !r. harts . is_empty ( ) {
136- mod_items. extend ( quote ! { pub use riscv_pac:: HartIdNumber ; } ) ;
137134 let harts = r. harts . iter ( ) . map ( |h| {
138135 let name = TokenStream :: from_str ( & h. name ) . unwrap ( ) ;
139136 let value = TokenStream :: from_str ( & format ! ( "{}" , h. value) ) . unwrap ( ) ;
@@ -155,15 +152,39 @@ pub fn render(
155152 } ) ;
156153 mod_items. extend ( quote ! {
157154 /// HARTs in the device
158- #[ repr( u16 ) ]
159- #[ riscv_pac:: pac_enum( unsafe HartIdNumber ) ]
155+ #[ riscv:: pac_enum( unsafe HartIdNumber ) ]
160156 #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
161157 pub enum Hart {
162158 #( #harts) *
163159 }
164160 } ) ;
165161 }
166162
163+ mod_items. extend ( quote ! {
164+ pub use riscv:: {
165+ CoreInterruptNumber , ExceptionNumber , PriorityNumber , HartIdNumber ,
166+ interrupt:: { enable, disable, free, nested}
167+ } ;
168+
169+ pub type Trap = riscv:: interrupt:: Trap <CoreInterrupt , Exception >;
170+
171+ /// Retrieves the cause of a trap in the current hart.
172+ ///
173+ /// If the raw cause is not a valid interrupt or exception for the target, it returns an error.
174+ #[ inline]
175+ pub fn try_cause( ) -> riscv:: result:: Result <Trap > {
176+ riscv:: interrupt:: try_cause( )
177+ }
178+
179+ /// Retrieves the cause of a trap in the current hart (machine mode).
180+ ///
181+ /// If the raw cause is not a valid interrupt or exception for the target, it panics.
182+ #[ inline]
183+ pub fn cause( ) -> Trap {
184+ try_cause( ) . unwrap( )
185+ }
186+ } ) ;
187+
167188 Ok ( quote ! {
168189 /// Interrupt numbers, priority levels, and HART IDs.
169190 pub mod interrupt {
0 commit comments