riscv_rt/
exceptions.rs

1//! Exception handling for targets that comply with the RISC-V exception handling standard.
2//!
3//! Exception dispatching is performed by the [`_dispatch_exception`] function.
4//! This function is called by the [crate::start_trap_rust] whenever an exception is triggered.
5//! This approach relies on the [`__EXCEPTIONS`] array, which sorts all the exception handlers
6//! depending on their corresponding exception source code.
7//!
8//! # Note
9//!
10//! If your target has custom exception sources, the target PAC might provide equivalent
11//! code to adapt for the target needs. In this case, you may need to opt out this module.
12//! To do so, activate the `no-exceptions` feature of the `riscv-rt` crate.
13
14use crate::TrapFrame;
15
16extern "C" {
17    fn InstructionMisaligned(trap_frame: &TrapFrame);
18    fn InstructionFault(trap_frame: &TrapFrame);
19    fn IllegalInstruction(trap_frame: &TrapFrame);
20    fn Breakpoint(trap_frame: &TrapFrame);
21    fn LoadMisaligned(trap_frame: &TrapFrame);
22    fn LoadFault(trap_frame: &TrapFrame);
23    fn StoreMisaligned(trap_frame: &TrapFrame);
24    fn StoreFault(trap_frame: &TrapFrame);
25    fn UserEnvCall(trap_frame: &TrapFrame);
26    fn SupervisorEnvCall(trap_frame: &TrapFrame);
27    fn MachineEnvCall(trap_frame: &TrapFrame);
28    fn InstructionPageFault(trap_frame: &TrapFrame);
29    fn LoadPageFault(trap_frame: &TrapFrame);
30    fn StorePageFault(trap_frame: &TrapFrame);
31}
32
33/// Array with all the exception handlers sorted according to their exception source code.
34#[no_mangle]
35pub static __EXCEPTIONS: [Option<unsafe extern "C" fn(&TrapFrame)>; 16] = [
36    Some(InstructionMisaligned),
37    Some(InstructionFault),
38    Some(IllegalInstruction),
39    Some(Breakpoint),
40    Some(LoadMisaligned),
41    Some(LoadFault),
42    Some(StoreMisaligned),
43    Some(StoreFault),
44    Some(UserEnvCall),
45    Some(SupervisorEnvCall),
46    None,
47    Some(MachineEnvCall),
48    Some(InstructionPageFault),
49    Some(LoadPageFault),
50    None,
51    Some(StorePageFault),
52];
53
54/// It calls the corresponding exception handler depending on the exception source code.
55///
56/// # Safety
57///
58/// This function must be called only from the [`crate::start_trap_rust`] function.
59/// Do **NOT** call this function directly.
60#[no_mangle]
61pub unsafe extern "C" fn _dispatch_exception(trap_frame: &TrapFrame, code: usize) {
62    extern "C" {
63        fn ExceptionHandler(trap_frame: &TrapFrame);
64    }
65    match __EXCEPTIONS.get(code) {
66        Some(Some(handler)) => handler(trap_frame),
67        _ => ExceptionHandler(trap_frame),
68    }
69}