|
7 | 7 | //! |
8 | 8 | //! In vectored mode (i.e., `v-trap` feature enabled), interrupt dispatching is handled by hardware. |
9 | 9 | //! To support this mode, we provide inline assembly code that defines the interrupt vector table. |
| 10 | +//! Since the alignment constraint of this vector table is implementation-specific, it can be |
| 11 | +//! changed by setting the `RISCV_MTVEC_ALIGN` environment variable (the default is 4). |
10 | 12 | //! |
11 | 13 | //! # Note |
12 | 14 | //! |
13 | | -//! If your target has custom core interrupt sources, the target PAC might provide equivalent |
14 | | -//! code to adapt for the target needs. In this case, you may need to opt out this module. |
15 | | -//! To do so, activate the `no-interrupts` feature of the `riscv-rt` crate. |
16 | | -
|
17 | | -#[cfg(not(feature = "v-trap"))] |
18 | | -extern "C" { |
19 | | - fn SupervisorSoft(); |
20 | | - fn MachineSoft(); |
21 | | - fn SupervisorTimer(); |
22 | | - fn MachineTimer(); |
23 | | - fn SupervisorExternal(); |
24 | | - fn MachineExternal(); |
25 | | -} |
26 | | - |
27 | | -/// Array with all the core interrupt handlers sorted according to their interrupt source code. |
28 | | -/// |
29 | | -/// # Note |
30 | | -/// |
31 | | -/// This array is necessary only in direct mode (i.e., `v-trap` feature disabled). |
32 | | -#[cfg(not(feature = "v-trap"))] |
33 | | -#[no_mangle] |
34 | | -pub static __CORE_INTERRUPTS: [Option<unsafe extern "C" fn()>; 12] = [ |
35 | | - None, |
36 | | - Some(SupervisorSoft), |
37 | | - None, |
38 | | - Some(MachineSoft), |
39 | | - None, |
40 | | - Some(SupervisorTimer), |
41 | | - None, |
42 | | - Some(MachineTimer), |
43 | | - None, |
44 | | - Some(SupervisorExternal), |
45 | | - None, |
46 | | - Some(MachineExternal), |
47 | | -]; |
48 | | - |
49 | | -/// It calls the corresponding interrupt handler depending on the interrupt source code. |
50 | | -/// |
51 | | -/// # Note |
52 | | -/// |
53 | | -/// This function is only required in direct mode (i.e., `v-trap` feature disabled). |
54 | | -/// In vectored mode, interrupt handler dispatching is performed directly by hardware. |
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 | | -#[cfg(not(feature = "v-trap"))] |
61 | | -#[inline] |
62 | | -#[no_mangle] |
63 | | -pub unsafe extern "C" fn _dispatch_core_interrupt(code: usize) { |
64 | | - extern "C" { |
65 | | - fn DefaultHandler(); |
66 | | - } |
67 | | - match __CORE_INTERRUPTS.get(code) { |
68 | | - Some(Some(handler)) => handler(), |
69 | | - _ => DefaultHandler(), |
70 | | - } |
71 | | -} |
| 15 | +//! If your target has custom core interrupt sources, the target PAC might provide equivalent code |
| 16 | +//! to adapt for the target needs (and is responsible for any alignment constraint). In this case, |
| 17 | +//! you may need to opt out this module. To do so, activate the `no-interrupts` feature of the |
| 18 | +//! `riscv-rt` crate. |
72 | 19 |
|
73 | 20 | // In vectored mode, we also must provide a vector table |
74 | | -#[cfg(all( |
75 | | - any(target_arch = "riscv32", target_arch = "riscv64"), |
76 | | - feature = "v-trap" |
77 | | -))] |
78 | | -core::arch::global_asm!( |
79 | | - r#" .section .trap, "ax" |
80 | | - .weak _vector_table |
81 | | - .type _vector_table, @function |
82 | | - |
83 | | - .option push |
84 | | - .balign 0x4 // TODO check if this is the correct alignment |
85 | | - .option norelax |
86 | | - .option norvc |
87 | | - |
88 | | - _vector_table: |
89 | | - j _start_trap // Interrupt 0 is used for exceptions |
90 | | - j _start_SupervisorSoft_trap |
91 | | - j _start_DefaultHandler_trap // Interrupt 2 is reserved |
92 | | - j _start_MachineSoft_trap |
93 | | - j _start_DefaultHandler_trap // Interrupt 4 is reserved |
94 | | - j _start_SupervisorTimer_trap |
95 | | - j _start_DefaultHandler_trap // Interrupt 6 is reserved |
96 | | - j _start_MachineTimer_trap |
97 | | - j _start_DefaultHandler_trap // Interrupt 8 is reserved |
98 | | - j _start_SupervisorExternal_trap |
99 | | - j _start_DefaultHandler_trap // Interrupt 10 is reserved |
100 | | - j _start_MachineExternal_trap |
101 | | - |
102 | | - .option pop"# |
103 | | -); |
| 21 | +#[riscv::pac_enum(unsafe CoreInterruptNumber)] |
| 22 | +#[derive(Clone, Copy, Debug, Eq, PartialEq)] |
| 23 | +enum Interrupt { |
| 24 | + SupervisorSoft = 1, |
| 25 | + MachineSoft = 3, |
| 26 | + SupervisorTimer = 5, |
| 27 | + MachineTimer = 7, |
| 28 | + SupervisorExternal = 9, |
| 29 | + MachineExternal = 11, |
| 30 | +} |
0 commit comments