|
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