From b4ac798546638aee7a9dbae31e276b2ebc2d70c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rom=C3=A1n=20C=C3=A1rdenas?= Date: Wed, 26 Apr 2023 12:02:56 +0200 Subject: [PATCH] exception table --- CHANGELOG.md | 5 ++++ link.x | 15 +++++++++++ src/lib.rs | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 90 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 95f4e33..6d31b12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +## Added + +- Standard exceptions enum +- __EXCEPTIONS array for dedicated handlers for each exception type. + ## [v0.11.0] - 2023-01-18 ### Changed diff --git a/link.x b/link.x index 1f52024..7cca90b 100644 --- a/link.x +++ b/link.x @@ -4,6 +4,21 @@ PROVIDE(_max_hart_id = 0); PROVIDE(_hart_stack_size = 2K); PROVIDE(_heap_size = 0); +PROVIDE(InstrAddressMisaligned = ExceptionHandler); +PROVIDE(InstrAccessFault = ExceptionHandler); +PROVIDE(IlegalInstr = ExceptionHandler); +PROVIDE(Breakpoint = ExceptionHandler); +PROVIDE(LoadAddressMisaligned = ExceptionHandler); +PROVIDE(LoadAccessFault = ExceptionHandler); +PROVIDE(StoreAMOAddressMisaligned = ExceptionHandler); +PROVIDE(StoreAMOAccessFault = ExceptionHandler); +PROVIDE(EnvUserCall = ExceptionHandler); +PROVIDE(EnvSupervisorCall = ExceptionHandler); +PROVIDE(EnvMachineCall = ExceptionHandler); +PROVIDE(InstrPageFault = ExceptionHandler); +PROVIDE(LoadPageFault = ExceptionHandler); +PROVIDE(StoreAMOPageFault = ExceptionHandler); + PROVIDE(UserSoft = DefaultHandler); PROVIDE(SupervisorSoft = DefaultHandler); PROVIDE(MachineSoft = DefaultHandler); diff --git a/src/lib.rs b/src/lib.rs index 3027452..10e5825 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -464,7 +464,14 @@ pub extern "C" fn start_trap_rust(trap_frame: *const TrapFrame) { let cause = xcause::read(); if cause.is_exception() { - ExceptionHandler(&*trap_frame) + if cause.code() < __EXCEPTIONS.len() { + match __EXCEPTIONS[cause.code()] { + Some(handler) => handler(&*trap_frame), + None => ExceptionHandler(&*trap_frame), + }; + } else { + ExceptionHandler(&*trap_frame); + } } else { if cause.code() < __INTERRUPTS.len() { let h = &__INTERRUPTS[cause.code()]; @@ -502,6 +509,68 @@ pub fn DefaultInterruptHandler() { } } +/// Standard exception categories. +#[doc(hidden)] +#[repr(u32)] +pub enum Exception { + InstrAddressMisaligned = 0, + InstrAccessFault = 1, + IlegalInstr = 2, + Breakpoint = 3, + LoadAddressMisaligned = 4, + LoadAccessFault = 5, + StoreAMOAddressMisaligned = 6, + StoreAMOAccessFault = 7, + EnvUserCall = 8, + EnvSupervisorCall = 9, + // Reserved = 10, + EnvMachineCall = 11, + InstrPageFault = 12, + LoadPageFault = 13, + // Reserved = 14, + StoreAMOPageFault = 15, +} + +pub use self::Exception as exception; + +extern "C" { + fn InstrAddressMisaligned(trap_frame: &TrapFrame); + fn InstrAccessFault(trap_frame: &TrapFrame); + fn IlegalInstr(trap_frame: &TrapFrame); + fn Breakpoint(trap_frame: &TrapFrame); + fn LoadAddressMisaligned(trap_frame: &TrapFrame); + fn LoadAccessFault(trap_frame: &TrapFrame); + fn StoreAMOAddressMisaligned(trap_frame: &TrapFrame); + fn StoreAMOAccessFault(trap_frame: &TrapFrame); + fn EnvUserCall(trap_frame: &TrapFrame); + fn EnvSupervisorCall(trap_frame: &TrapFrame); + fn EnvMachineCall(trap_frame: &TrapFrame); + fn InstrPageFault(trap_frame: &TrapFrame); + fn LoadPageFault(trap_frame: &TrapFrame); + fn StoreAMOPageFault(trap_frame: &TrapFrame); +} + +#[doc(hidden)] +#[no_mangle] +pub static __EXCEPTIONS: [Option; 16] = [ + Some(InstrAddressMisaligned), + Some(InstrAccessFault), + Some(IlegalInstr), + Some(Breakpoint), + Some(LoadAddressMisaligned), + Some(LoadAccessFault), + Some(StoreAMOAddressMisaligned), + Some(StoreAMOAccessFault), + Some(EnvUserCall), + Some(EnvSupervisorCall), + None, // 10 is reserved + Some(EnvMachineCall), + Some(InstrPageFault), + Some(LoadPageFault), + None, // 14 is reserved + Some(StoreAMOPageFault), +]; + /* Interrupts */ #[doc(hidden)] pub enum Interrupt {