Skip to content

Commit c3e3e55

Browse files
committed
Feature-gate trap-related code in riscv
1 parent 18cc082 commit c3e3e55

File tree

5 files changed

+66
-48
lines changed

5 files changed

+66
-48
lines changed

riscv/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1111

1212
- Add `miselect` CSR
1313
- Improved assembly macro handling in asm.rs
14+
- New `rt` and `rt-v-trap` features to opt-in `riscv-rt`-related code in `riscv::pac_enum` macro.
15+
16+
# Changed
17+
18+
- Now, `riscv::pac_enum` macro only includes trap-related code if `rt` or `rt-v-trap` features are enabled.
1419

1520
## [v0.15.0] - 2025-09-08
1621

riscv/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ targets = [
2323
default = ["riscv-macros"]
2424
s-mode = []
2525
critical-section-single-hart = ["critical-section/restore-state-bool"]
26+
rt = ["riscv-macros/rt"]
27+
rt-v-trap = ["rt", "riscv-macros/rt-v-trap"]
2628

2729
[dependencies]
2830
critical-section = "1.2.0"

riscv/macros/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ edition = "2021"
1515
[lib]
1616
proc-macro = true
1717

18+
[features]
19+
rt = []
20+
rt-v-trap = ["rt"]
21+
1822
[dependencies]
1923
proc-macro2 = "1.0"
2024
quote = "1.0"

riscv/macros/src/lib.rs

Lines changed: 44 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ impl PacEnumItem {
264264
vectors
265265
}
266266

267+
#[cfg(feature = "rt-v-trap")]
267268
fn vector_table(&self) -> TokenStream2 {
268269
let align = match std::env::var("RISCV_MTVEC_ALIGN") {
269270
Ok(x) => x.parse::<u32>().ok(),
@@ -280,7 +281,7 @@ impl PacEnumItem {
280281
};
281282
let mut asm = format!(
282283
r#"
283-
#[cfg(all(feature = "v-trap", any(target_arch = "riscv32", target_arch = "riscv64")))]
284+
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
284285
core::arch::global_asm!("
285286
.section .trap.vector, \"ax\"
286287
.global _vector_table
@@ -328,8 +329,6 @@ core::arch::global_asm!("
328329
let max_discriminant = self.max_number;
329330
let valid_matches = self.valid_matches();
330331

331-
let is_core_interrupt = matches!(attr, PacTrait::Interrupt(InterruptType::Core));
332-
333332
// Push the trait implementation
334333
res.push(quote! {
335334
unsafe impl riscv::#trait_name for #name {
@@ -354,54 +353,51 @@ core::arch::global_asm!("
354353
res.push(quote! { unsafe impl riscv::#marker_trait_name for #name {} });
355354
}
356355

356+
#[cfg(feature = "rt")]
357357
if let Some(trap_config) = attr.trap_config() {
358-
let default_handler = &trap_config.default_handler;
359-
let extern_signature = trap_config.extern_signature();
360-
let handler_input = trap_config.handler_input();
361-
let array_signature = trap_config.array_signature();
362-
let dispatch_fn_name = &trap_config.dispatch_fn_name;
363-
let dispatch_fn_args = &trap_config.dispatch_fn_signature();
364-
let vector_table = &trap_config.handlers_array_name;
365-
366-
let handlers = self.handlers(&trap_config);
367-
let interrupt_array = self.handlers_array();
368-
let cfg_v_trap = match is_core_interrupt {
369-
true => Some(quote!(#[cfg(not(feature = "v-trap"))])),
370-
false => None,
371-
};
372-
373-
// Push the interrupt handler functions and the interrupt array
374-
res.push(quote! {
375-
#cfg_v_trap
376-
extern "C" {
377-
#(#handlers;)*
358+
match attr {
359+
#[cfg(feature = "rt-v-trap")]
360+
PacTrait::Interrupt(InterruptType::Core) => {
361+
res.push(self.vector_table());
378362
}
379-
380-
#cfg_v_trap
381-
#[doc(hidden)]
382-
#[no_mangle]
383-
pub static #vector_table: [Option<unsafe extern "C" fn(#(#array_signature),*)>; #max_discriminant + 1] = [
384-
#(#interrupt_array),*
385-
];
386-
387-
#cfg_v_trap
388-
#[inline]
389-
#[no_mangle]
390-
unsafe extern "C" fn #dispatch_fn_name(#(#dispatch_fn_args),*) {
391-
extern "C" {
392-
fn #default_handler(#(#extern_signature),*);
393-
}
394-
395-
match #vector_table.get(code) {
396-
Some(Some(handler)) => handler(#(#handler_input),*),
397-
_ => #default_handler(#(#handler_input),*),
398-
}
363+
_ => {
364+
let default_handler = &trap_config.default_handler;
365+
let extern_signature = trap_config.extern_signature();
366+
let handler_input = trap_config.handler_input();
367+
let array_signature = trap_config.array_signature();
368+
let dispatch_fn_name = &trap_config.dispatch_fn_name;
369+
let dispatch_fn_args = &trap_config.dispatch_fn_signature();
370+
let vector_table = &trap_config.handlers_array_name;
371+
372+
let handlers = self.handlers(&trap_config);
373+
let interrupt_array = self.handlers_array();
374+
375+
res.push(quote! {
376+
extern "C" {
377+
#(#handlers;)*
378+
}
379+
380+
#[doc(hidden)]
381+
#[no_mangle]
382+
pub static #vector_table: [Option<unsafe extern "C" fn(#(#array_signature),*)>; #max_discriminant + 1] = [
383+
#(#interrupt_array),*
384+
];
385+
386+
#[inline]
387+
#[no_mangle]
388+
unsafe extern "C" fn #dispatch_fn_name(#(#dispatch_fn_args),*) {
389+
extern "C" {
390+
fn #default_handler(#(#extern_signature),*);
391+
}
392+
393+
match #vector_table.get(code) {
394+
Some(Some(handler)) => handler(#(#handler_input),*),
395+
_ => #default_handler(#(#handler_input),*),
396+
}
397+
}
398+
});
399399
}
400-
});
401-
}
402-
403-
if is_core_interrupt {
404-
res.push(self.vector_table());
400+
}
405401
}
406402

407403
res

riscv/src/lib.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,17 @@
3131
//! and may cause functional problems in systems where some interrupts must NOT be disabled
3232
//! or critical sections are managed as part of an RTOS. In these cases, you should use
3333
//! a target-specific implementation instead, typically provided by a HAL or RTOS crate.
34+
//!
35+
//! ## `rt`
36+
//!
37+
//! This feature enables code related to [`riscv-rt`](https://github.com/rust-embedded/riscv/tree/master/riscv-rt)
38+
//! runtime support in the `riscv::pac_enum` macro. Namely, it enables the generation of
39+
//! trap handler functions and dispatch functions.
40+
//!
41+
//! ## `rt-v-trap`
42+
//!
43+
//! This feature enables code related to vectored trap handling in addition to the `rt` feature.
44+
//! Namely, it enables the generation of a vector table and the corresponding assembly code for core interrupts.
3445
3546
#![no_std]
3647
#![allow(clippy::missing_safety_doc)]

0 commit comments

Comments
 (0)