From 28b4fd979219031622c0513cf6bc051d349e28c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rom=C3=A1n=20C=C3=A1rdenas=20Rodr=C3=ADguez?= Date: Mon, 9 Feb 2026 14:01:16 +0100 Subject: [PATCH 1/4] riscv-rt: new setup_interrupts macro --- riscv-macros/CHANGELOG.md | 1 + riscv-macros/Cargo.toml | 3 +++ riscv-macros/src/lib.rs | 31 +++++++++++++++++++++++++++++++ riscv-macros/src/riscv_rt.rs | 20 +++++++++++++++----- riscv-rt/CHANGELOG.md | 9 +++++++++ riscv-rt/Cargo.toml | 1 + riscv-rt/link.x.in | 7 ------- riscv-rt/src/lib.rs | 31 ++++++++++++++++++------------- 8 files changed, 78 insertions(+), 25 deletions(-) diff --git a/riscv-macros/CHANGELOG.md b/riscv-macros/CHANGELOG.md index ddc23a87..b306f227 100644 --- a/riscv-macros/CHANGELOG.md +++ b/riscv-macros/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Added +- New `setup_interrupts` macro for custom interrupt setup routines. - New `exception`, `core_interrupt`, and `external_interrupt` macros for trap handlers. - New `entry` macro for the Rust entry point (for `riscv-rt`). - New `rvrt-u-boot` feature to adapt `entry` macro for U-Boot. diff --git a/riscv-macros/Cargo.toml b/riscv-macros/Cargo.toml index b23f9708..8629e135 100644 --- a/riscv-macros/Cargo.toml +++ b/riscv-macros/Cargo.toml @@ -12,6 +12,9 @@ repository = "https://github.com/rust-embedded/riscv" version = "0.4.1" edition = "2021" +[package.metadata.docs.rs] +features = ["riscv-rt"] + [lib] proc-macro = true diff --git a/riscv-macros/src/lib.rs b/riscv-macros/src/lib.rs index 56cc8f78..e6f4b34b 100644 --- a/riscv-macros/src/lib.rs +++ b/riscv-macros/src/lib.rs @@ -64,6 +64,7 @@ pub fn pac_enum(attr: TokenStream, item: TokenStream) -> TokenStream { } /// Attribute to mark which function will be called before jumping to the entry point. +/// /// You must enable the `post-init` feature in the `riscv-rt` crate to use this macro. /// /// In contrast with `__pre_init`, this function is called after the static variables @@ -91,6 +92,36 @@ pub fn post_init(args: TokenStream, input: TokenStream) -> TokenStream { riscv_rt::Fn::post_init(args, input) } +/// Attribute to mark which function will set interrupts before jumping to the entry point. +/// +/// The `riscv-rt` crates provides a default implementation that works for most cases. +/// If you want to provide your own implementation, you must enable the `custom-setup-interrupts` +/// feature in the `riscv-rt` crate and use this macro on your function. +/// The `riscv-rt` crate re-exports this macro if the `custom-setup-interrupts` feature is enabled, +/// so you can use it as `riscv_rt::setup_interrupts` without depending on `riscv-macros` directly. +/// +/// The function must have the signature of `[unsafe] fn([usize])`, where the argument +/// corresponds to the hart ID of the current hart. This is useful for multi-hart systems +/// to perform hart-specific interrupt setup. +/// +/// # IMPORTANT +/// +/// This attribute can appear at most *once* in the dependency graph. +/// +/// # Examples +/// +/// ``` +/// #[riscv_macros::setup_interrupts] +/// unsafe fn setup_interrupts(hart_id: usize) { +/// // do something here +/// } +/// ``` +#[cfg(feature = "riscv-rt")] +#[proc_macro_attribute] +pub fn setup_interrupts(args: TokenStream, input: TokenStream) -> TokenStream { + riscv_rt::Fn::setup_interrupts(args, input) +} + /// Attribute to declare the entry point of the program /// /// The specified function will be called by the reset handler *after* RAM has been initialized. diff --git a/riscv-macros/src/riscv_rt.rs b/riscv-macros/src/riscv_rt.rs index 886e8ba4..989fd3ca 100644 --- a/riscv-macros/src/riscv_rt.rs +++ b/riscv-macros/src/riscv_rt.rs @@ -37,6 +37,7 @@ impl TrapType { /// Enum representing the supported runtime function attributes pub enum Fn { PostInit, + SetupInterrupts, Entry, Trap(Trap), } @@ -48,6 +49,12 @@ impl Fn { Self::PostInit.quote_fn(input, errors) } + /// Convenience method to generate the token stream for the `setup_interrupts` attribute + pub fn setup_interrupts(args: TokenStream, input: TokenStream) -> TokenStream { + let errors = Self::SetupInterrupts.check_args_empty(args).err(); + Self::SetupInterrupts.quote_fn(input, errors) + } + /// Convenience method to generate the token stream for the `entry` attribute pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream { let errors = Self::Entry.check_args_empty(args).err(); @@ -141,7 +148,9 @@ impl Fn { fn check_inputs(&self, inputs: &Punctuated, errors: &mut Option) { // Use this match to specify expected input arguments for different functions in the future match self { - Self::PostInit => self.check_fn_args(inputs, &["usize"], errors), + Self::PostInit | Self::SetupInterrupts => { + self.check_fn_args(inputs, &["usize"], errors) + } #[cfg(not(feature = "rvrt-u-boot"))] Self::Entry => self.check_fn_args(inputs, &["usize", "usize", "usize"], errors), #[cfg(feature = "rvrt-u-boot")] @@ -161,7 +170,7 @@ impl Fn { fn check_output(&self, output: &ReturnType, errors: &mut Option) { // Use this match to specify expected output types for different functions in the future match self { - Self::PostInit => check_output_empty(output, errors), + Self::PostInit | Self::SetupInterrupts => check_output_empty(output, errors), Self::Entry => check_output_never(output, errors), Self::Trap(_) => check_output_empty_or_never(output, errors), } @@ -177,7 +186,7 @@ impl Fn { // Use this match to specify extra items for different functions in the future match self { - Self::PostInit | Self::Entry => None, + Self::PostInit | Self::SetupInterrupts | Self::Entry => None, Self::Trap(Trap { path, ty }) => { let mut extras = vec![]; @@ -217,12 +226,13 @@ impl Fn { // Use this match to specify export names for different functions in the future let export_name = match self { Self::PostInit => Some("__post_init".to_string()), + Self::SetupInterrupts => Some("_setup_interrupts".to_string()), Self::Entry => Some("main".to_string()), Self::Trap(Trap { path, .. }) => Some(path.segments.last().unwrap().ident.to_string()), }; export_name.map(|name| match self { - Self::PostInit | Self::Trap(_) => quote! { + Self::PostInit | Self::SetupInterrupts | Self::Trap(_) => quote! { #[export_name = #name] }, Self::Entry => quote! { @@ -237,7 +247,7 @@ impl Fn { // Use this match to specify section names for different functions in the future let section_name: Option = match self { // TODO: check if we want specific sections for these functions - Self::PostInit | Self::Entry | Self::Trap(_) => None, + Self::PostInit | Self::SetupInterrupts | Self::Entry | Self::Trap(_) => None, }; section_name.map(|section| quote! { diff --git a/riscv-rt/CHANGELOG.md b/riscv-rt/CHANGELOG.md index 5de59ea6..c0a75560 100644 --- a/riscv-rt/CHANGELOG.md +++ b/riscv-rt/CHANGELOG.md @@ -7,8 +7,17 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## v0.19.0 - Unreleased +### Added + +- New `custom-setup-interrupts` feature to opt-out default implementation of + `_setup_interrupts`. When this feature is active, the `riscv-rt` crate reexports + the `riscv_macros::setup_interrupts` attribute macro. + ### Changed +- `_setup_interrupts` can now optionally receive an `usize` input argument + with the ID of the running hart. This allows users to implement hart-specific + interrupt setup in multi-hart targets. - Use macros from `riscv-macros` instead of `riscv-rt-macros` ### Removed diff --git a/riscv-rt/Cargo.toml b/riscv-rt/Cargo.toml index 69f49c15..e81cfe25 100644 --- a/riscv-rt/Cargo.toml +++ b/riscv-rt/Cargo.toml @@ -38,6 +38,7 @@ riscv = { path = "../riscv", version = "0.16.0", features = ["critical-section-s [features] pre-init = [] post-init = [] +custom-setup-interrupts = [] s-mode = ["riscv-macros/s-mode"] single-hart = [] v-trap = ["riscv/rt-v-trap", "riscv-macros/rt-v-trap"] diff --git a/riscv-rt/link.x.in b/riscv-rt/link.x.in index 16314860..99cfaa86 100644 --- a/riscv-rt/link.x.in +++ b/riscv-rt/link.x.in @@ -45,13 +45,6 @@ PROVIDE(_mp_hook = _default_mp_hook); EXTERN(_default_start_trap); PROVIDE(_start_trap = _default_start_trap); -/* Default interrupt setup entry point. If not _setup_interrupts symbol is provided, then - _setup_interrupts maps to _default_setup_interrupts, which in direct mode sets the value - of the xtvec register to _start_trap and, in vectored mode, sets its value to - _vector_table and enables vectored mode. */ -EXTERN(_default_setup_interrupts); -PROVIDE(_setup_interrupts = _default_setup_interrupts); - /* Default main routine. If no hal_main symbol is provided, then hal_main maps to main, which is usually defined by final users via the #[riscv_rt::entry] attribute. Using hal_main instead of main directly allow HALs to inject code before jumping to user main. */ diff --git a/riscv-rt/src/lib.rs b/riscv-rt/src/lib.rs index 35d460ca..39a07768 100644 --- a/riscv-rt/src/lib.rs +++ b/riscv-rt/src/lib.rs @@ -687,16 +687,14 @@ pub mod exceptions; pub mod interrupts; #[cfg(feature = "s-mode")] -use riscv::register::{ - scause as xcause, - stvec::{self as xtvec, Stvec as Xtvec, TrapMode}, -}; +use riscv::register::scause as xcause; +#[cfg(all(feature = "s-mode", not(feature = "custom-setup-interrupts")))] +use riscv::register::stvec::{self as xtvec, Stvec as Xtvec, TrapMode}; #[cfg(not(feature = "s-mode"))] -use riscv::register::{ - mcause as xcause, - mtvec::{self as xtvec, Mtvec as Xtvec, TrapMode}, -}; +use riscv::register::mcause as xcause; +#[cfg(all(not(feature = "s-mode"), not(feature = "custom-setup-interrupts")))] +use riscv::register::mtvec::{self as xtvec, Mtvec as Xtvec, TrapMode}; pub use riscv_macros::{core_interrupt, entry, exception, external_interrupt}; pub use riscv_types::*; @@ -704,6 +702,9 @@ pub use riscv_types::*; #[cfg(feature = "post-init")] pub use riscv_macros::post_init; +#[cfg(feature = "custom-setup-interrupts")] +pub use riscv_macros::setup_interrupts; + /// We export this static with an informative name so that if an application attempts to link /// two copies of riscv-rt together, linking will fail. We also declare a links key in /// Cargo.toml which is the more modern way to solve the same problem, but we have to keep @@ -729,13 +730,13 @@ pub unsafe extern "C" fn start_rust(a0: usize, a1: usize, a2: usize) -> ! { extern "Rust" { #[cfg(feature = "post-init")] fn __post_init(a0: usize); - fn _setup_interrupts(); + fn _setup_interrupts(a0: usize); fn hal_main(a0: usize, a1: usize, a2: usize) -> !; } #[cfg(feature = "post-init")] __post_init(a0); - _setup_interrupts(); + _setup_interrupts(a0); hal_main(a0, a1, a2); } @@ -746,14 +747,18 @@ pub unsafe extern "C" fn start_rust(a0: usize, a1: usize, a2: usize) -> ! { /// /// # Note /// -/// Users can override this function by defining their own `_setup_interrupts` function. +/// You can define your own `_setup_interrupts` function to override the default implementation. +/// To do so, you must enable the `custom-setup-interrupts` feature to opt-out the default implementation. +/// Then, you can use the [`riscv_macros::setup_interrupts`] attribute on your custom function. +/// This macro is re-exported by this crate if the `custom-setup-interrupts` feature is enabled. /// /// # Safety /// /// This function should not be called directly by the user, and should instead /// be invoked by the runtime implicitly. It is expected to be called before the main function. -#[export_name = "_default_setup_interrupts"] -pub unsafe extern "Rust" fn setup_interrupts() { +#[cfg(not(feature = "custom-setup-interrupts"))] +#[riscv_macros::setup_interrupts] +unsafe fn default_setup_interrupts() { extern "C" { #[cfg(not(feature = "v-trap"))] fn _start_trap(); From bacf1935c468bd9339625d0bffbdb30ae9d4060f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rom=C3=A1n=20C=C3=A1rdenas=20Rodr=C3=ADguez?= Date: Mon, 9 Feb 2026 14:11:01 +0100 Subject: [PATCH 2/4] riscv_rt: add trybuild tests for setup_interrupts macro --- tests-trybuild/Cargo.toml | 1 + .../riscv-rt/setup_interrupts/fail_full.rs | 8 +++ .../setup_interrupts/fail_full.stderr | 65 +++++++++++++++++++ .../setup_interrupts/pass_empty_safe.rs | 4 ++ .../setup_interrupts/pass_empty_unsafe.rs | 4 ++ .../riscv-rt/setup_interrupts/pass_safe.rs | 4 ++ .../riscv-rt/setup_interrupts/pass_unsafe.rs | 4 ++ 7 files changed, 90 insertions(+) create mode 100644 tests-trybuild/tests/riscv-rt/setup_interrupts/fail_full.rs create mode 100644 tests-trybuild/tests/riscv-rt/setup_interrupts/fail_full.stderr create mode 100644 tests-trybuild/tests/riscv-rt/setup_interrupts/pass_empty_safe.rs create mode 100644 tests-trybuild/tests/riscv-rt/setup_interrupts/pass_empty_unsafe.rs create mode 100644 tests-trybuild/tests/riscv-rt/setup_interrupts/pass_safe.rs create mode 100644 tests-trybuild/tests/riscv-rt/setup_interrupts/pass_unsafe.rs diff --git a/tests-trybuild/Cargo.toml b/tests-trybuild/Cargo.toml index 40270009..91969fe0 100644 --- a/tests-trybuild/Cargo.toml +++ b/tests-trybuild/Cargo.toml @@ -5,6 +5,7 @@ edition = "2021" [dependencies] riscv = { path = "../riscv" } +riscv-macros = { path = "../riscv-macros" } riscv-rt = { path = "../riscv-rt", features = ["no-exceptions", "no-interrupts", "post-init"] } trybuild = "1.0" diff --git a/tests-trybuild/tests/riscv-rt/setup_interrupts/fail_full.rs b/tests-trybuild/tests/riscv-rt/setup_interrupts/fail_full.rs new file mode 100644 index 00000000..e5d2ef48 --- /dev/null +++ b/tests-trybuild/tests/riscv-rt/setup_interrupts/fail_full.rs @@ -0,0 +1,8 @@ +#[riscv_macros::setup_interrupts(arg)] +pub const async extern "Rust" fn setup_interrupts<'a, T>(_h: u32, _d: &'a T, _v: ...) -> ! +where + T: Copy, +{ +} + +fn main() {} diff --git a/tests-trybuild/tests/riscv-rt/setup_interrupts/fail_full.stderr b/tests-trybuild/tests/riscv-rt/setup_interrupts/fail_full.stderr new file mode 100644 index 00000000..3c1d8b9c --- /dev/null +++ b/tests-trybuild/tests/riscv-rt/setup_interrupts/fail_full.stderr @@ -0,0 +1,65 @@ +error: macro arguments are not allowed + --> tests/riscv-rt/setup_interrupts/fail_full.rs:1:34 + | +1 | #[riscv_macros::setup_interrupts(arg)] + | ^^^ + +error: function must be private + --> tests/riscv-rt/setup_interrupts/fail_full.rs:2:1 + | +2 | pub const async extern "Rust" fn setup_interrupts<'a, T>(_h: u32, _d: &'a T, _v: ...) -> ! + | ^^^ + +error: function must not be const + --> tests/riscv-rt/setup_interrupts/fail_full.rs:2:5 + | +2 | pub const async extern "Rust" fn setup_interrupts<'a, T>(_h: u32, _d: &'a T, _v: ...) -> ! + | ^^^^^ + +error: function must not be async + --> tests/riscv-rt/setup_interrupts/fail_full.rs:2:11 + | +2 | pub const async extern "Rust" fn setup_interrupts<'a, T>(_h: u32, _d: &'a T, _v: ...) -> ! + | ^^^^^ + +error: ABI must not be specified + --> tests/riscv-rt/setup_interrupts/fail_full.rs:2:17 + | +2 | pub const async extern "Rust" fn setup_interrupts<'a, T>(_h: u32, _d: &'a T, _v: ...) -> ! + | ^^^^^^ + +error: generics are not allowed + --> tests/riscv-rt/setup_interrupts/fail_full.rs:2:51 + | +2 | pub const async extern "Rust" fn setup_interrupts<'a, T>(_h: u32, _d: &'a T, _v: ...) -> ! + | ^^ + +error: argument type must be `usize` + --> tests/riscv-rt/setup_interrupts/fail_full.rs:2:62 + | +2 | pub const async extern "Rust" fn setup_interrupts<'a, T>(_h: u32, _d: &'a T, _v: ...) -> ! + | ^^^ + +error: too many input arguments + --> tests/riscv-rt/setup_interrupts/fail_full.rs:2:67 + | +2 | pub const async extern "Rust" fn setup_interrupts<'a, T>(_h: u32, _d: &'a T, _v: ...) -> ! + | ^^ + +error: variadic arguments are not allowed + --> tests/riscv-rt/setup_interrupts/fail_full.rs:2:78 + | +2 | pub const async extern "Rust" fn setup_interrupts<'a, T>(_h: u32, _d: &'a T, _v: ...) -> ! + | ^^ + +error: return type must be () + --> tests/riscv-rt/setup_interrupts/fail_full.rs:2:87 + | +2 | pub const async extern "Rust" fn setup_interrupts<'a, T>(_h: u32, _d: &'a T, _v: ...) -> ! + | ^ + +error: where clause is not allowed + --> tests/riscv-rt/setup_interrupts/fail_full.rs:3:1 + | +3 | where + | ^^^^^ diff --git a/tests-trybuild/tests/riscv-rt/setup_interrupts/pass_empty_safe.rs b/tests-trybuild/tests/riscv-rt/setup_interrupts/pass_empty_safe.rs new file mode 100644 index 00000000..c2cda914 --- /dev/null +++ b/tests-trybuild/tests/riscv-rt/setup_interrupts/pass_empty_safe.rs @@ -0,0 +1,4 @@ +#[riscv_macros::setup_interrupts] +fn setup_interrupts() {} + +fn main() {} diff --git a/tests-trybuild/tests/riscv-rt/setup_interrupts/pass_empty_unsafe.rs b/tests-trybuild/tests/riscv-rt/setup_interrupts/pass_empty_unsafe.rs new file mode 100644 index 00000000..eccc3596 --- /dev/null +++ b/tests-trybuild/tests/riscv-rt/setup_interrupts/pass_empty_unsafe.rs @@ -0,0 +1,4 @@ +#[riscv_macros::setup_interrupts] +unsafe fn setup_interrupts() {} + +fn main() {} diff --git a/tests-trybuild/tests/riscv-rt/setup_interrupts/pass_safe.rs b/tests-trybuild/tests/riscv-rt/setup_interrupts/pass_safe.rs new file mode 100644 index 00000000..598d18a2 --- /dev/null +++ b/tests-trybuild/tests/riscv-rt/setup_interrupts/pass_safe.rs @@ -0,0 +1,4 @@ +#[riscv_macros::setup_interrupts] +fn setup_interrupts(_hart_id: usize) {} + +fn main() {} diff --git a/tests-trybuild/tests/riscv-rt/setup_interrupts/pass_unsafe.rs b/tests-trybuild/tests/riscv-rt/setup_interrupts/pass_unsafe.rs new file mode 100644 index 00000000..f35ce4d9 --- /dev/null +++ b/tests-trybuild/tests/riscv-rt/setup_interrupts/pass_unsafe.rs @@ -0,0 +1,4 @@ +#[riscv_macros::setup_interrupts] +unsafe fn setup_interrupts(_hart_id: usize) {} + +fn main() {} From 42e478231d454768d1967b679684b4fafca14f39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rom=C3=A1n=20C=C3=A1rdenas=20Rodr=C3=ADguez?= Date: Mon, 9 Feb 2026 14:30:12 +0100 Subject: [PATCH 3/4] riscv_rt: add documentation for custom-setup-interrupts feature --- riscv-rt/Cargo.toml | 2 +- riscv-rt/src/lib.rs | 41 +++++++++++++++++++++++------------------ 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/riscv-rt/Cargo.toml b/riscv-rt/Cargo.toml index e81cfe25..ca8e0d86 100644 --- a/riscv-rt/Cargo.toml +++ b/riscv-rt/Cargo.toml @@ -14,7 +14,7 @@ links = "riscv-rt" # Prevent multiple versions of riscv-rt being linked [package.metadata.docs.rs] default-target = "riscv64imac-unknown-none-elf" -features = ["pre-init", "post-init"] +features = ["pre-init", "post-init", "custom-setup-interrupts"] targets = [ "riscv32i-unknown-none-elf", "riscv32imc-unknown-none-elf", "riscv32imac-unknown-none-elf", "riscv64imac-unknown-none-elf", "riscv64gc-unknown-none-elf", diff --git a/riscv-rt/src/lib.rs b/riscv-rt/src/lib.rs index 39a07768..90d87906 100644 --- a/riscv-rt/src/lib.rs +++ b/riscv-rt/src/lib.rs @@ -371,24 +371,6 @@ //! ); //! ``` //! -//! ## `_setup_interrupts` -//! -//! This function is called right before the main function and is responsible for setting up -//! the interrupt controller. -//! -//! Default implementation sets the trap vector to `_start_trap` in direct mode. -//! If the `v-trap` feature is enabled, the trap vector is set to `_vector_table` -//! in vectored mode. Users can override this function by defining their own `_setup_interrupts`. -//! -//! This function can be redefined in the following way: -//! -//! ``` no_run -//! #[export_name = "_setup_interrupts"] -//! pub fn setup_interrupts() { -//! // ... -//! } -//! ``` -//! //! ## `hal_main` //! //! Internally, `riscv-rt` does not jump to the `main` function created by the user using the @@ -561,6 +543,28 @@ //! //! You can use the [`#[post_init]`][attr-post-init] attribute to define a post-init function with Rust. //! +//! ## `custom-setup-interrupts` +//! +//! The `riscv-rt` crate provides a default implementation for the `_setup_interrupts` function. +//! This function is called right before the main function and is responsible for setting up the interrupt controller. +//! Default implementation sets the trap vector to `_start_trap` in direct mode. If the `v-trap` feature is enabled, +//! the trap vector is set to `_vector_table` in vectored mode. +//! +//! However, in some cases, users may want to provide their own implementation of this function to customize the interrupt +//! setup process. Users can override this function by: +//! +//! 1. Enabling the `custom-setup-interrupts` feature to opt-out the default implementation. +//! 2. Using the [`#[setup_interrupts]`][attr-setup-interrupts] attribute on their custom function. +//! +//! This function can be redefined in the following way: +//! +//! ``` no_run +//! #[riscv_rt::setup_interrupts] +//! fn setup_interrupts(hart_id: usize) { +//! // ... +//! } +//!``` +//! //! ## `single-hart` //! //! Saves a little code size if there is only one hart on the target. @@ -672,6 +676,7 @@ //! [attr-external-interrupt]: attr.external_interrupt.html //! [attr-core-interrupt]: attr.core_interrupt.html //! [attr-post-init]: attr.post_init.html +//! [attr-setup-interrupts]: attr.setup_interrupts.html // NOTE: Adapted from cortex-m/src/lib.rs #![no_std] From a231b37be6c001e3f85833fd79b03a85b91902f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rom=C3=A1n=20C=C3=A1rdenas=20Rodr=C3=ADguez?= Date: Wed, 4 Mar 2026 14:51:34 +0100 Subject: [PATCH 4/4] Do not allow input parameters for post_init or setup_interrupts when u-boot is enabled --- riscv-macros/src/riscv_rt.rs | 5 ++++- riscv-rt/src/lib.rs | 7 ++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/riscv-macros/src/riscv_rt.rs b/riscv-macros/src/riscv_rt.rs index 989fd3ca..a96d1393 100644 --- a/riscv-macros/src/riscv_rt.rs +++ b/riscv-macros/src/riscv_rt.rs @@ -149,7 +149,10 @@ impl Fn { // Use this match to specify expected input arguments for different functions in the future match self { Self::PostInit | Self::SetupInterrupts => { - self.check_fn_args(inputs, &["usize"], errors) + #[cfg(not(feature = "rvrt-u-boot"))] + self.check_fn_args(inputs, &["usize"], errors); + #[cfg(feature = "rvrt-u-boot")] + self.check_fn_args(inputs, &[], errors); } #[cfg(not(feature = "rvrt-u-boot"))] Self::Entry => self.check_fn_args(inputs, &["usize", "usize", "usize"], errors), diff --git a/riscv-rt/src/lib.rs b/riscv-rt/src/lib.rs index 90d87906..fb8460f0 100644 --- a/riscv-rt/src/lib.rs +++ b/riscv-rt/src/lib.rs @@ -621,9 +621,10 @@ //! //! ## `u-boot` //! -//! When the U-boot feature is enabled, acceptable signature for `#[entry]` macros is changed. This is required -//! because when booting from elf, U-boot passes `argc` and `argv`. This feature also implies `single-hart`. -//! The only way to get boot-hart is through fdt, so other harts initialization is up to you. +//! When the U-boot feature is enabled, acceptable signature for `#[post_init]`, `#[setup_interrupts]`, +//! and`#[entry]` macros is changed. This is required because when booting from elf, U-boot passes +//! `argc` and `argv`. This feature also implies `single-hart`. The only way to get boot-hart is through +//! fdt, so other harts initialization is up to you. //! //! ## `pre-default-start-trap` //!