245
245
//!
246
246
//! Default implementation of this function wakes hart 0 and busy-loops all the other harts.
247
247
//!
248
+ //!
249
+ //! ### Core exception handlers
250
+ //!
251
+ //! This functions are called when corresponding exception occurs.
252
+ //! You can define an exception handler with one of the following names:
253
+ //! * `InstructionMisaligned`
254
+ //! * `InstructionFault`
255
+ //! * `IllegalInstruction`
256
+ //! * `Breakpoint`
257
+ //! * `LoadMisaligned`
258
+ //! * `LoadFault`
259
+ //! * `StoreMisaligned`
260
+ //! * `StoreFault`
261
+ //! * `UserEnvCall`
262
+ //! * `SupervisorEnvCall`
263
+ //! * `MachineEnvCall`
264
+ //! * `InstructionPageFault`
265
+ //! * `LoadPageFault`
266
+ //! * `StorePageFault`
267
+ //!
268
+ //! For example:
269
+ //! ``` no_run
270
+ //! #[export_name = "MachineEnvCall"]
271
+ //! fn custom_menv_call_handler(trap_frame: &riscv_rt::TrapFrame) {
272
+ //! // ...
273
+ //! }
274
+ //! ```
275
+ //! or
276
+ //! ``` no_run
277
+ //! #[no_mangle]
278
+ //! fn MachineEnvCall(trap_frame: &riscv_rt::TrapFrame) -> ! {
279
+ //! // ...
280
+ //! }
281
+ //! ```
282
+ //!
283
+ //! If exception handler is not explicitly defined, `ExceptionHandler` is called.
284
+ //!
248
285
//! ### `ExceptionHandler`
249
286
//!
250
- //! This function is called when exception is occured. The exception reason can be decoded from the
287
+ //! This function is called when exception without defined exception handler is occured.
288
+ //! The exception reason can be decoded from the
251
289
//! `mcause`/`scause` register.
252
290
//!
253
291
//! This function can be redefined in the following way:
@@ -581,15 +619,27 @@ pub unsafe extern "C" fn start_trap_rust(trap_frame: *const TrapFrame) {
581
619
}
582
620
583
621
let cause = xcause:: read ( ) ;
622
+ let code = cause. code ( ) ;
584
623
585
624
if cause. is_exception ( ) {
586
- ExceptionHandler ( & * trap_frame)
587
- } else if cause. code ( ) < __INTERRUPTS. len ( ) {
588
- let h = & __INTERRUPTS[ cause. code ( ) ] ;
589
- if h. reserved == 0 {
590
- DefaultHandler ( ) ;
625
+ let trap_frame = & * trap_frame;
626
+ if code < __EXCEPTIONS. len ( ) {
627
+ let h = & __EXCEPTIONS[ code] ;
628
+ if let Some ( handler) = h {
629
+ handler ( trap_frame) ;
630
+ } else {
631
+ ExceptionHandler ( trap_frame) ;
632
+ }
591
633
} else {
592
- ( h. handler ) ( ) ;
634
+ ExceptionHandler ( trap_frame) ;
635
+ }
636
+ ExceptionHandler ( trap_frame)
637
+ } else if code < __INTERRUPTS. len ( ) {
638
+ let h = & __INTERRUPTS[ code] ;
639
+ if let Some ( handler) = h {
640
+ handler ( ) ;
641
+ } else {
642
+ DefaultHandler ( ) ;
593
643
}
594
644
} else {
595
645
DefaultHandler ( ) ;
@@ -609,7 +659,7 @@ pub fn DefaultExceptionHandler(trap_frame: &TrapFrame) -> ! {
609
659
610
660
#[ doc( hidden) ]
611
661
#[ no_mangle]
612
- #[ allow( unused_variables , non_snake_case) ]
662
+ #[ allow( non_snake_case) ]
613
663
pub fn DefaultInterruptHandler ( ) {
614
664
loop {
615
665
// Prevent this from turning into a UDF instruction
@@ -618,76 +668,78 @@ pub fn DefaultInterruptHandler() {
618
668
}
619
669
}
620
670
621
- /* Interrupts */
622
- #[ doc( hidden) ]
623
- pub enum Interrupt {
624
- UserSoft ,
625
- SupervisorSoft ,
626
- MachineSoft ,
627
- UserTimer ,
628
- SupervisorTimer ,
629
- MachineTimer ,
630
- UserExternal ,
631
- SupervisorExternal ,
632
- MachineExternal ,
671
+ extern "C" {
672
+ fn InstructionMisaligned ( trap_frame : & TrapFrame ) ;
673
+ fn InstructionFault ( trap_frame : & TrapFrame ) ;
674
+ fn IllegalInstruction ( trap_frame : & TrapFrame ) ;
675
+ fn Breakpoint ( trap_frame : & TrapFrame ) ;
676
+ fn LoadMisaligned ( trap_frame : & TrapFrame ) ;
677
+ fn LoadFault ( trap_frame : & TrapFrame ) ;
678
+ fn StoreMisaligned ( trap_frame : & TrapFrame ) ;
679
+ fn StoreFault ( trap_frame : & TrapFrame ) ;
680
+ fn UserEnvCall ( trap_frame : & TrapFrame ) ;
681
+ fn SupervisorEnvCall ( trap_frame : & TrapFrame ) ;
682
+ fn MachineEnvCall ( trap_frame : & TrapFrame ) ;
683
+ fn InstructionPageFault ( trap_frame : & TrapFrame ) ;
684
+ fn LoadPageFault ( trap_frame : & TrapFrame ) ;
685
+ fn StorePageFault ( trap_frame : & TrapFrame ) ;
633
686
}
634
687
635
- pub use self :: Interrupt as interrupt;
688
+ #[ doc( hidden) ]
689
+ #[ no_mangle]
690
+ pub static __EXCEPTIONS: [ Option < unsafe extern "C" fn ( & TrapFrame ) > ; 16 ] = [
691
+ Some ( InstructionMisaligned ) ,
692
+ Some ( InstructionFault ) ,
693
+ Some ( IllegalInstruction ) ,
694
+ Some ( Breakpoint ) ,
695
+ Some ( LoadMisaligned ) ,
696
+ Some ( LoadFault ) ,
697
+ Some ( StoreMisaligned ) ,
698
+ Some ( StoreFault ) ,
699
+ Some ( UserEnvCall ) ,
700
+ Some ( SupervisorEnvCall ) ,
701
+ None ,
702
+ Some ( MachineEnvCall ) ,
703
+ Some ( InstructionPageFault ) ,
704
+ Some ( LoadPageFault ) ,
705
+ None ,
706
+ Some ( StorePageFault ) ,
707
+ ] ;
636
708
637
709
extern "C" {
638
- fn UserSoft ( ) ;
639
710
fn SupervisorSoft ( ) ;
640
711
fn MachineSoft ( ) ;
641
- fn UserTimer ( ) ;
642
712
fn SupervisorTimer ( ) ;
643
713
fn MachineTimer ( ) ;
644
- fn UserExternal ( ) ;
645
714
fn SupervisorExternal ( ) ;
646
715
fn MachineExternal ( ) ;
647
716
}
648
717
649
- #[ doc( hidden) ]
650
- pub union Vector {
651
- pub handler : unsafe extern "C" fn ( ) ,
652
- pub reserved : usize ,
653
- }
654
-
655
718
#[ doc( hidden) ]
656
719
#[ no_mangle]
657
- pub static __INTERRUPTS: [ Vector ; 12 ] = [
658
- Vector { handler : UserSoft } ,
659
- Vector {
660
- handler : SupervisorSoft ,
661
- } ,
662
- Vector { reserved : 0 } ,
663
- Vector {
664
- handler : MachineSoft ,
665
- } ,
666
- Vector { handler : UserTimer } ,
667
- Vector {
668
- handler : SupervisorTimer ,
669
- } ,
670
- Vector { reserved : 0 } ,
671
- Vector {
672
- handler : MachineTimer ,
673
- } ,
674
- Vector {
675
- handler : UserExternal ,
676
- } ,
677
- Vector {
678
- handler : SupervisorExternal ,
679
- } ,
680
- Vector { reserved : 0 } ,
681
- Vector {
682
- handler : MachineExternal ,
683
- } ,
720
+ pub static __INTERRUPTS: [ Option < unsafe extern "C" fn ( ) > ; 12 ] = [
721
+ None ,
722
+ Some ( SupervisorSoft ) ,
723
+ None ,
724
+ Some ( MachineSoft ) ,
725
+ None ,
726
+ Some ( SupervisorTimer ) ,
727
+ None ,
728
+ Some ( MachineTimer ) ,
729
+ None ,
730
+ Some ( SupervisorExternal ) ,
731
+ None ,
732
+ Some ( MachineExternal ) ,
684
733
] ;
685
734
735
+ /// Default implementation of `_pre_init` does nothing.
736
+ /// Users can override this function with the [`#[pre_init]`] macro.
686
737
#[ doc( hidden) ]
687
738
#[ no_mangle]
688
739
#[ rustfmt:: skip]
689
- pub unsafe extern "Rust" fn default_pre_init ( ) { }
740
+ pub extern "Rust" fn default_pre_init ( ) { }
690
741
742
+ /// Default implementation of `_mp_hook` wakes hart 0 and busy-loops all the other harts.
691
743
#[ doc( hidden) ]
692
744
#[ no_mangle]
693
745
#[ rustfmt:: skip]
@@ -701,7 +753,7 @@ pub extern "Rust" fn default_mp_hook(hartid: usize) -> bool {
701
753
}
702
754
}
703
755
704
- /// Default implementation of `_setup_interrupts` that sets `mtvec`/`stvec` to a trap handler address .
756
+ /// Default implementation of `_setup_interrupts` sets `mtvec`/`stvec` to the address of `_start_trap` .
705
757
#[ doc( hidden) ]
706
758
#[ no_mangle]
707
759
#[ rustfmt:: skip]
0 commit comments