From fc4f314cc569745be8f25bbbf50470a5b0182c9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rom=C3=A1n=20C=C3=A1rdenas=20Rodr=C3=ADguez?= Date: Thu, 27 Jun 2024 17:40:15 +0200 Subject: [PATCH] Add vector table --- riscv-pac/macros/src/lib.rs | 40 ++++++++++++++++++++++ riscv-rt/src/asm.rs | 32 ----------------- riscv-rt/src/interrupt.rs | 68 +++++++++++++++++++++++++++++++++++++ riscv-rt/src/lib.rs | 46 ++----------------------- riscv/README.md | 2 +- 5 files changed, 111 insertions(+), 77 deletions(-) create mode 100644 riscv-rt/src/interrupt.rs diff --git a/riscv-pac/macros/src/lib.rs b/riscv-pac/macros/src/lib.rs index 01090b1d..7924372a 100644 --- a/riscv-pac/macros/src/lib.rs +++ b/riscv-pac/macros/src/lib.rs @@ -192,6 +192,42 @@ impl PacEnumItem { vectors } + fn vector_table(&self) -> TokenStream2 { + let mut asm = String::from( + r#" +core::arch::global_asm!(" + .section .trap, \"ax\" + .global _vector_table + .type _vector_table, @function + + .option push + .balign 0x4 // TODO check if this is the correct alignment + .option norelax + .option norvc + + _vector_table: + j _start_trap // Interrupt 0 is used for exceptions +"#, + ); + + for i in 1..=self.max_number { + if let Some(ident) = self.numbers.get(&i) { + asm.push_str(&format!(" j _start_{ident}_trap\n")); + } else { + asm.push_str(&format!( + " j _start_DefaultHandler_trap // Interrupt {i} is reserved\n" + )); + } + } + + asm.push_str( + r#" .option pop" +);"#, + ); + + TokenStream2::from_str(&asm).unwrap() + } + /// Returns a vector of token streams representing the trait implementations for /// the enum. If the trait is an interrupt trait, the implementation also includes /// the interrupt handler functions and the interrupt array. @@ -269,6 +305,10 @@ impl PacEnumItem { } } }); + + if let InterruptType::Core = interrupt_type { + res.push(self.vector_table()); + } } res diff --git a/riscv-rt/src/asm.rs b/riscv-rt/src/asm.rs index 7883c446..bc177e7e 100644 --- a/riscv-rt/src/asm.rs +++ b/riscv-rt/src/asm.rs @@ -287,38 +287,6 @@ riscv_rt_macros::vectored_interrupt_trap_riscv32!(); #[cfg(all(riscv64, feature = "v-trap"))] riscv_rt_macros::vectored_interrupt_trap_riscv64!(); -#[cfg(feature = "v-trap")] -cfg_global_asm!( - // Set the vector mode to vectored. - r#".section .trap, "ax" - .weak _vector_table - .type _vector_table, @function - - .option push - .balign 0x4 // TODO check if this is the correct alignment - .option norelax - .option norvc - - _vector_table: - j _start_trap // Interrupt 0 is used for exceptions - j _start_SupervisorSoft_trap - j _start_DefaultHandler_trap // Interrupt 2 is reserved - j _start_MachineSoft_trap - j _start_DefaultHandler_trap // Interrupt 4 is reserved - j _start_SupervisorTimer_trap - j _start_DefaultHandler_trap // Interrupt 6 is reserved - j _start_MachineTimer_trap - j _start_DefaultHandler_trap // Interrupt 8 is reserved - j _start_SupervisorExternal_trap - j _start_DefaultHandler_trap // Interrupt 10 is reserved - j _start_MachineExternal_trap - - // default table does not include the remaining interrupts. - // Targets with extra interrupts should override this table. - - .option pop"#, -); - #[rustfmt::skip] global_asm!( ".section .text.abort diff --git a/riscv-rt/src/interrupt.rs b/riscv-rt/src/interrupt.rs new file mode 100644 index 00000000..01f23eb9 --- /dev/null +++ b/riscv-rt/src/interrupt.rs @@ -0,0 +1,68 @@ +extern "C" { + fn SupervisorSoft(); + fn MachineSoft(); + fn SupervisorTimer(); + fn MachineTimer(); + fn SupervisorExternal(); + fn MachineExternal(); + fn DefaultHandler(); +} + +#[doc(hidden)] +#[no_mangle] +pub static __CORE_INTERRUPTS: [Option; 12] = [ + None, + Some(SupervisorSoft), + None, + Some(MachineSoft), + None, + Some(SupervisorTimer), + None, + Some(MachineTimer), + None, + Some(SupervisorExternal), + None, + Some(MachineExternal), +]; + +#[export_name = "_dispatch_core_interrupt"] +unsafe extern "C" fn dispatch_core_interrupt(code: usize) { + if code < __CORE_INTERRUPTS.len() { + let h = &__CORE_INTERRUPTS[code]; + if let Some(handler) = h { + handler(); + } else { + DefaultHandler(); + } + } else { + DefaultHandler(); + } +} + +#[cfg(all(riscv, feature = "v-trap"))] +core::arch::global_asm!( + r#" .section .trap, "ax" + .weak _vector_table + .type _vector_table, @function + + .option push + .balign 0x4 // TODO check if this is the correct alignment + .option norelax + .option norvc + + _vector_table: + j _start_trap // Interrupt 0 is used for exceptions + j _start_SupervisorSoft_trap + j _start_DefaultHandler_trap // Interrupt 2 is reserved + j _start_MachineSoft_trap + j _start_DefaultHandler_trap // Interrupt 4 is reserved + j _start_SupervisorTimer_trap + j _start_DefaultHandler_trap // Interrupt 6 is reserved + j _start_MachineTimer_trap + j _start_DefaultHandler_trap // Interrupt 8 is reserved + j _start_SupervisorExternal_trap + j _start_DefaultHandler_trap // Interrupt 10 is reserved + j _start_MachineExternal_trap + + .option pop"# +); diff --git a/riscv-rt/src/lib.rs b/riscv-rt/src/lib.rs index 7e63dc8e..07aa91a5 100644 --- a/riscv-rt/src/lib.rs +++ b/riscv-rt/src/lib.rs @@ -460,6 +460,8 @@ #[cfg(riscv)] mod asm; +mod interrupt; + #[cfg(feature = "s-mode")] use riscv::register::scause as xcause; @@ -578,47 +580,3 @@ pub static __EXCEPTIONS: [Option; 16] = [ None, Some(StorePageFault), ]; - -#[export_name = "_dispatch_core_interrupt"] -unsafe extern "C" fn dispatch_core_interrupt(code: usize) { - extern "C" { - fn DefaultHandler(); - } - - if code < __INTERRUPTS.len() { - let h = &__INTERRUPTS[code]; - if let Some(handler) = h { - handler(); - } else { - DefaultHandler(); - } - } else { - DefaultHandler(); - } -} - -extern "C" { - fn SupervisorSoft(); - fn MachineSoft(); - fn SupervisorTimer(); - fn MachineTimer(); - fn SupervisorExternal(); - fn MachineExternal(); -} - -#[doc(hidden)] -#[no_mangle] -pub static __INTERRUPTS: [Option; 12] = [ - None, - Some(SupervisorSoft), - None, - Some(MachineSoft), - None, - Some(SupervisorTimer), - None, - Some(MachineTimer), - None, - Some(SupervisorExternal), - None, - Some(MachineExternal), -]; diff --git a/riscv/README.md b/riscv/README.md index f67ac78c..2a958981 100644 --- a/riscv/README.md +++ b/riscv/README.md @@ -11,7 +11,7 @@ This project is developed and maintained by the [RISC-V team][team]. ## Minimum Supported Rust Version (MSRV) -This crate is guaranteed to compile on stable Rust 1.60 and up. It *might* +This crate is guaranteed to compile on stable Rust 1.61 and up. It *might* compile with older versions but that may change in any new patch release. ## License