diff --git a/riscv-rt/CHANGELOG.md b/riscv-rt/CHANGELOG.md index cda604d6..d8015d2a 100644 --- a/riscv-rt/CHANGELOG.md +++ b/riscv-rt/CHANGELOG.md @@ -18,6 +18,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - In multi-hart targets, the hart ID is now validated earlier in the boot process. - General purpose registers are no longer zeroed, as this is not strictly necessary. This aligns with the `cortex-m-rt` crate. +- Better organization of the `.trap` section: + 1. `_trap_vector` (if `v-trap` is enabled). + 2. `_start_trap` (defaults to `_default_start_trap`). + 3. `_start_INTERRUPT_trap` routines (if `v-trap` is enabled). + 4. `_start_DefaultHandler_trap` and `_continue_trap` (if `v-trap` is enabled). + 5. `_start_trap_rust`. + 6. Other code in `.trap` section (usually, none) ### Fixed diff --git a/riscv-rt/link.x.in b/riscv-rt/link.x.in index 0ef9bb02..62e1acc9 100644 --- a/riscv-rt/link.x.in +++ b/riscv-rt/link.x.in @@ -90,9 +90,15 @@ SECTIONS /* Put reset handler first in .text section so it ends up as the entry */ /* point of the program. */ KEEP(*(.init)); + . = ALIGN(4); - *(.trap); - *(.trap.rust); + KEEP(*(.trap.vector)); /* for _trap_vector (vectored mode only) */ + KEEP(*(.trap.start)); /* for _start_trap routine */ + KEEP(*(.trap.start.*)); /* for _start_INTERRUPT_trap routines (vectored mode only) */ + KEEP(*(.trap.continue)); /* for _continue_trap routine (vectored mode only) */ + KEEP(*(.trap.rust)); /* for _start_trap_rust Rust function */ + KEEP(*(.trap .trap.*)); /* Other .trap symbols at the end */ + *(.text.abort); *(.text .text.*); diff --git a/riscv-rt/macros/src/lib.rs b/riscv-rt/macros/src/lib.rs index dc38e997..3e7ddd4f 100644 --- a/riscv-rt/macros/src/lib.rs +++ b/riscv-rt/macros/src/lib.rs @@ -1,4 +1,6 @@ #![deny(warnings)] +#![allow(unknown_lints)] // reason = "required for next line" +#![allow(clippy::manual_is_multiple_of)] // reason = "requires MSRV bump" use proc_macro::TokenStream; use proc_macro2::{Span, TokenStream as TokenStream2}; @@ -518,8 +520,8 @@ pub fn default_start_trap(_input: TokenStream) -> TokenStream { format!( r#" core::arch::global_asm!( -".section .trap, \"ax\" -.align 4 /* Alignment required for xtvec */ +".section .trap.start, \"ax\" +.balign 4 /* Alignment required for xtvec */ .global _default_start_trap _default_start_trap: addi sp, sp, - {trap_size} * {width} @@ -557,16 +559,15 @@ pub fn vectored_interrupt_trap(_input: TokenStream) -> TokenStream { let instructions = format!( r#" core::arch::global_asm!( -".section .trap, \"ax\" +".section .trap.continue, \"ax\" -.align 4 +.balign 4 .global _start_DefaultHandler_trap _start_DefaultHandler_trap: addi sp, sp, -{trap_size} * {width} // allocate space for trap frame {store_start} // store trap partially (only register a0) la a0, DefaultHandler // load interrupt handler address into a0 -.align 4 .global _continue_interrupt_trap _continue_interrupt_trap: {store_continue} // store trap partially (all registers except a0) @@ -685,10 +686,11 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream { /// } /// ``` pub fn core_interrupt(args: TokenStream, input: TokenStream) -> TokenStream { - let arch = if cfg!(feature = "v-trap") { - RiscvArch::try_from_env() - } else { - None + let arch = match () { + #[cfg(feature = "v-trap")] + () => RiscvArch::try_from_env(), + #[cfg(not(feature = "v-trap"))] + () => None, }; trap(args, input, RiscvPacItem::CoreInterrupt, arch) } @@ -746,13 +748,14 @@ fn trap( let export_name = format!("{int_ident:#}"); let start_trap = match arch { + #[cfg(feature = "v-trap")] Some(arch) => { let trap = start_interrupt_trap(int_ident, arch); quote! { #trap } } - None => proc_macro2::TokenStream::new(), + _ => proc_macro2::TokenStream::new(), }; let pac_trait = pac_item.impl_trait(); @@ -772,6 +775,7 @@ fn trap( .into() } +#[cfg(feature = "v-trap")] fn start_interrupt_trap(ident: &syn::Ident, arch: RiscvArch) -> proc_macro2::TokenStream { let interrupt = ident.to_string(); let width = arch.width(); @@ -780,9 +784,10 @@ fn start_interrupt_trap(ident: &syn::Ident, arch: RiscvArch) -> proc_macro2::Tok let instructions = format!( r#" +#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] core::arch::global_asm!( - ".section .trap, \"ax\" - .align 2 + ".section .trap.start.{interrupt}, \"ax\" + .balign 4 .global _start_{interrupt}_trap _start_{interrupt}_trap: addi sp, sp, -{trap_size} * {width} // allocate space for trap frame diff --git a/riscv/CHANGELOG.md b/riscv/CHANGELOG.md index 1bdbb9b5..97233feb 100644 --- a/riscv/CHANGELOG.md +++ b/riscv/CHANGELOG.md @@ -14,6 +14,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Changed - Use `cfg(any(target_arch = "riscv32", target_arch = "riscv64"))` instead of `cfg(riscv)`. +- `riscv::pac_enum(unsafe CoreInterrupt)` now locates the vector table at the `.trap.vector` + section instead of `.trap`. ### Removed diff --git a/riscv/macros/src/lib.rs b/riscv/macros/src/lib.rs index c03f3c43..5f4bf8f3 100644 --- a/riscv/macros/src/lib.rs +++ b/riscv/macros/src/lib.rs @@ -282,7 +282,7 @@ impl PacEnumItem { r#" #[cfg(all(feature = "v-trap", any(target_arch = "riscv32", target_arch = "riscv64")))] core::arch::global_asm!(" - .section .trap, \"ax\" + .section .trap.vector, \"ax\" .global _vector_table .type _vector_table, @function