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:
@@ -561,15 +599,27 @@ pub unsafe extern "C" fn start_trap_rust(trap_frame: *const TrapFrame) {
561
599
}
562
600
563
601
let cause = xcause:: read ( ) ;
602
+ let code = cause. code ( ) ;
564
603
565
604
if cause. is_exception ( ) {
566
- ExceptionHandler ( & * trap_frame)
567
- } else if cause. code ( ) < __INTERRUPTS. len ( ) {
568
- let h = & __INTERRUPTS[ cause. code ( ) ] ;
569
- if h. reserved == 0 {
570
- DefaultHandler ( ) ;
605
+ let trap_frame = & * trap_frame;
606
+ if code < __EXCEPTIONS. len ( ) {
607
+ let h = & __EXCEPTIONS[ code] ;
608
+ if let Some ( handler) = h {
609
+ handler ( trap_frame) ;
610
+ } else {
611
+ ExceptionHandler ( trap_frame) ;
612
+ }
571
613
} else {
572
- ( h. handler ) ( ) ;
614
+ ExceptionHandler ( trap_frame) ;
615
+ }
616
+ ExceptionHandler ( trap_frame)
617
+ } else if code < __INTERRUPTS. len ( ) {
618
+ let h = & __INTERRUPTS[ code] ;
619
+ if let Some ( handler) = h {
620
+ handler ( ) ;
621
+ } else {
622
+ DefaultHandler ( ) ;
573
623
}
574
624
} else {
575
625
DefaultHandler ( ) ;
@@ -589,7 +639,7 @@ pub fn DefaultExceptionHandler(trap_frame: &TrapFrame) -> ! {
589
639
590
640
#[ doc( hidden) ]
591
641
#[ no_mangle]
592
- #[ allow( unused_variables , non_snake_case) ]
642
+ #[ allow( non_snake_case) ]
593
643
pub fn DefaultInterruptHandler ( ) {
594
644
loop {
595
645
// Prevent this from turning into a UDF instruction
@@ -598,76 +648,78 @@ pub fn DefaultInterruptHandler() {
598
648
}
599
649
}
600
650
601
- /* Interrupts */
602
- #[ doc( hidden) ]
603
- pub enum Interrupt {
604
- UserSoft ,
605
- SupervisorSoft ,
606
- MachineSoft ,
607
- UserTimer ,
608
- SupervisorTimer ,
609
- MachineTimer ,
610
- UserExternal ,
611
- SupervisorExternal ,
612
- MachineExternal ,
651
+ extern "C" {
652
+ fn InstructionMisaligned ( trap_frame : & TrapFrame ) ;
653
+ fn InstructionFault ( trap_frame : & TrapFrame ) ;
654
+ fn IllegalInstruction ( trap_frame : & TrapFrame ) ;
655
+ fn Breakpoint ( trap_frame : & TrapFrame ) ;
656
+ fn LoadMisaligned ( trap_frame : & TrapFrame ) ;
657
+ fn LoadFault ( trap_frame : & TrapFrame ) ;
658
+ fn StoreMisaligned ( trap_frame : & TrapFrame ) ;
659
+ fn StoreFault ( trap_frame : & TrapFrame ) ;
660
+ fn UserEnvCall ( trap_frame : & TrapFrame ) ;
661
+ fn SupervisorEnvCall ( trap_frame : & TrapFrame ) ;
662
+ fn MachineEnvCall ( trap_frame : & TrapFrame ) ;
663
+ fn InstructionPageFault ( trap_frame : & TrapFrame ) ;
664
+ fn LoadPageFault ( trap_frame : & TrapFrame ) ;
665
+ fn StorePageFault ( trap_frame : & TrapFrame ) ;
613
666
}
614
667
615
- pub use self :: Interrupt as interrupt;
668
+ #[ doc( hidden) ]
669
+ #[ no_mangle]
670
+ pub static __EXCEPTIONS: [ Option < unsafe extern "C" fn ( & TrapFrame ) > ; 16 ] = [
671
+ Some ( InstructionMisaligned ) ,
672
+ Some ( InstructionFault ) ,
673
+ Some ( IllegalInstruction ) ,
674
+ Some ( Breakpoint ) ,
675
+ Some ( LoadMisaligned ) ,
676
+ Some ( LoadFault ) ,
677
+ Some ( StoreMisaligned ) ,
678
+ Some ( StoreFault ) ,
679
+ Some ( UserEnvCall ) ,
680
+ Some ( SupervisorEnvCall ) ,
681
+ None ,
682
+ Some ( MachineEnvCall ) ,
683
+ Some ( InstructionPageFault ) ,
684
+ Some ( LoadPageFault ) ,
685
+ None ,
686
+ Some ( StorePageFault ) ,
687
+ ] ;
616
688
617
689
extern "C" {
618
- fn UserSoft ( ) ;
619
690
fn SupervisorSoft ( ) ;
620
691
fn MachineSoft ( ) ;
621
- fn UserTimer ( ) ;
622
692
fn SupervisorTimer ( ) ;
623
693
fn MachineTimer ( ) ;
624
- fn UserExternal ( ) ;
625
694
fn SupervisorExternal ( ) ;
626
695
fn MachineExternal ( ) ;
627
696
}
628
697
629
- #[ doc( hidden) ]
630
- pub union Vector {
631
- pub handler : unsafe extern "C" fn ( ) ,
632
- pub reserved : usize ,
633
- }
634
-
635
698
#[ doc( hidden) ]
636
699
#[ no_mangle]
637
- pub static __INTERRUPTS: [ Vector ; 12 ] = [
638
- Vector { handler : UserSoft } ,
639
- Vector {
640
- handler : SupervisorSoft ,
641
- } ,
642
- Vector { reserved : 0 } ,
643
- Vector {
644
- handler : MachineSoft ,
645
- } ,
646
- Vector { handler : UserTimer } ,
647
- Vector {
648
- handler : SupervisorTimer ,
649
- } ,
650
- Vector { reserved : 0 } ,
651
- Vector {
652
- handler : MachineTimer ,
653
- } ,
654
- Vector {
655
- handler : UserExternal ,
656
- } ,
657
- Vector {
658
- handler : SupervisorExternal ,
659
- } ,
660
- Vector { reserved : 0 } ,
661
- Vector {
662
- handler : MachineExternal ,
663
- } ,
700
+ pub static __INTERRUPTS: [ Option < unsafe extern "C" fn ( ) > ; 12 ] = [
701
+ None ,
702
+ Some ( SupervisorSoft ) ,
703
+ None ,
704
+ Some ( MachineSoft ) ,
705
+ None ,
706
+ Some ( SupervisorTimer ) ,
707
+ None ,
708
+ Some ( MachineTimer ) ,
709
+ None ,
710
+ Some ( SupervisorExternal ) ,
711
+ None ,
712
+ Some ( MachineExternal ) ,
664
713
] ;
665
714
715
+ /// Default implementation of `_pre_init` does nothing.
716
+ /// Users can override this function with the [`#[pre_init]`] macro.
666
717
#[ doc( hidden) ]
667
718
#[ no_mangle]
668
719
#[ rustfmt:: skip]
669
- pub unsafe extern "Rust" fn default_pre_init ( ) { }
720
+ pub extern "Rust" fn default_pre_init ( ) { }
670
721
722
+ /// Default implementation of `_mp_hook` wakes hart 0 and busy-loops all the other harts.
671
723
#[ doc( hidden) ]
672
724
#[ no_mangle]
673
725
#[ rustfmt:: skip]
@@ -681,7 +733,7 @@ pub extern "Rust" fn default_mp_hook(hartid: usize) -> bool {
681
733
}
682
734
}
683
735
684
- /// Default implementation of `_setup_interrupts` that sets `mtvec`/`stvec` to a trap handler address .
736
+ /// Default implementation of `_setup_interrupts` sets `mtvec`/`stvec` to the address of `_start_trap` .
685
737
#[ doc( hidden) ]
686
738
#[ no_mangle]
687
739
#[ rustfmt:: skip]
0 commit comments