From 6e94c15158998432153f8b3f476ca8dd3a560581 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rom=C3=A1n=20C=C3=A1rdenas=20Rodr=C3=ADguez?= Date: Wed, 29 Apr 2026 08:32:39 +0200 Subject: [PATCH] `riscv-rt`: use `pac_enum` macro for exception handling --- riscv-rt/CHANGELOG.md | 5 +-- riscv-rt/Cargo.toml | 2 +- riscv-rt/src/exceptions.rs | 74 ++++++++++---------------------------- riscv-rt/src/lib.rs | 2 ++ 4 files changed, 25 insertions(+), 58 deletions(-) diff --git a/riscv-rt/CHANGELOG.md b/riscv-rt/CHANGELOG.md index 5c1eb871..d6ca8216 100644 --- a/riscv-rt/CHANGELOG.md +++ b/riscv-rt/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). -## v0.19.0 - Unreleased +## v0.18.0 - Unreleased ### Added @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Changed +- Use `riscv::pac_enum` macro for exceptions - Deprecate `no-interrupts` feature in favor of `custom-interrupts` - Deprecate `no-exceptions` feature in favor of `custom-exceptions` - `_setup_interrupts` can now optionally receive an `usize` input argument @@ -26,7 +27,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - We no longer re-export the `pre_init` macro. Use `core::arch::global_asm` instead. -## v0.18.0 - 2026-01-13 +## v0.17.1 - 2026-01-13 ### Fixed diff --git a/riscv-rt/Cargo.toml b/riscv-rt/Cargo.toml index c2f89fb2..49d5dd1b 100644 --- a/riscv-rt/Cargo.toml +++ b/riscv-rt/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "riscv-rt" -version = "0.19.0" +version = "0.18.0" rust-version = "1.81" repository = "https://github.com/rust-embedded/riscv" authors = ["The RISC-V Team "] diff --git a/riscv-rt/src/exceptions.rs b/riscv-rt/src/exceptions.rs index 4433dded..9c4e53e6 100644 --- a/riscv-rt/src/exceptions.rs +++ b/riscv-rt/src/exceptions.rs @@ -11,59 +11,23 @@ //! code to adapt for the target needs. In this case, you may need to opt out this module. //! To do so, activate the `custom-exceptions` feature of the `riscv-rt` crate. -use crate::TrapFrame; - -extern "C" { - fn InstructionMisaligned(trap_frame: &TrapFrame); - fn InstructionFault(trap_frame: &TrapFrame); - fn IllegalInstruction(trap_frame: &TrapFrame); - fn Breakpoint(trap_frame: &TrapFrame); - fn LoadMisaligned(trap_frame: &TrapFrame); - fn LoadFault(trap_frame: &TrapFrame); - fn StoreMisaligned(trap_frame: &TrapFrame); - fn StoreFault(trap_frame: &TrapFrame); - fn UserEnvCall(trap_frame: &TrapFrame); - fn SupervisorEnvCall(trap_frame: &TrapFrame); - fn MachineEnvCall(trap_frame: &TrapFrame); - fn InstructionPageFault(trap_frame: &TrapFrame); - fn LoadPageFault(trap_frame: &TrapFrame); - fn StorePageFault(trap_frame: &TrapFrame); -} - -/// Array with all the exception handlers sorted according to their exception source code. -#[no_mangle] -pub static __EXCEPTIONS: [Option; 16] = [ - Some(InstructionMisaligned), - Some(InstructionFault), - Some(IllegalInstruction), - Some(Breakpoint), - Some(LoadMisaligned), - Some(LoadFault), - Some(StoreMisaligned), - Some(StoreFault), - Some(UserEnvCall), - Some(SupervisorEnvCall), - None, - Some(MachineEnvCall), - Some(InstructionPageFault), - Some(LoadPageFault), - None, - Some(StorePageFault), -]; - -/// It calls the corresponding exception handler depending on the exception source code. -/// -/// # Safety -/// -/// This function must be called only from the [`crate::start_trap_rust`] function. -/// Do **NOT** call this function directly. -#[no_mangle] -pub unsafe extern "C" fn _dispatch_exception(trap_frame: &TrapFrame, code: usize) { - extern "C" { - fn ExceptionHandler(trap_frame: &TrapFrame); - } - match __EXCEPTIONS.get(code) { - Some(Some(handler)) => handler(trap_frame), - _ => ExceptionHandler(trap_frame), - } +#[riscv::pac_enum(unsafe ExceptionNumber)] +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[allow(dead_code)] // otherwise compiler complains about Exception not being used +enum Exception { + InstructionMisaligned = 0, + InstructionFault = 1, + IllegalInstruction = 2, + Breakpoint = 3, + LoadMisaligned = 4, + LoadFault = 5, + StoreMisaligned = 6, + StoreFault = 7, + UserEnvCall = 8, + SupervisorEnvCall = 9, + MachineEnvCall = 11, + InstructionPageFault = 12, + LoadPageFault = 13, + StorePageFault = 15, } diff --git a/riscv-rt/src/lib.rs b/riscv-rt/src/lib.rs index 5d0c907e..aa051d20 100644 --- a/riscv-rt/src/lib.rs +++ b/riscv-rt/src/lib.rs @@ -683,6 +683,8 @@ #![no_std] #![deny(missing_docs)] +extern crate self as riscv_rt; // To use macros that refer to items in this crate. + /// Backwards-compatibility deprecation warnings for renamed feature `no-interrupts`. /// If a user enables the old feature, emit a warning pointing them to the new `custom-interrupts`. #[cfg(feature = "no-interrupts")]