Exceptions
aarch64-rt provides a trait to define exception handlers, and a macro to
generate the assembly code for the exception vector to call them.
The trait has default implementations for each method which simply panic, so we can omit methods for exceptions we don’t expect to happen.
use aarch64_rt::{ExceptionHandlers, RegisterStateRef, exception_handlers}; use log::error; use smccc::Hvc; use smccc::psci::system_off; struct Handlers; impl ExceptionHandlers for Handlers { extern "C" fn sync_current(_state: RegisterStateRef) { error!("sync_current"); system_off::<Hvc>().unwrap(); } extern "C" fn irq_current(_state: RegisterStateRef) { error!("irq_current"); system_off::<Hvc>().unwrap(); } extern "C" fn fiq_current(_state: RegisterStateRef) { error!("fiq_current"); system_off::<Hvc>().unwrap(); } extern "C" fn serror_current(_state: RegisterStateRef) { error!("serror_current"); system_off::<Hvc>().unwrap(); } } exception_handlers!(Handlers);
- The
exception_handlersmacro generates aglobal_asm!block with the exception vector to call into the Rust code, similar to theexceptions.Swe had before. RegisterStateRefwraps a reference to the stack frame where the register values were saved by the assembly code when the exception happed. This can be used for example to extract the parameters for an SMC or HVC call from a lower EL, and update the values to be restored when the exception handler returns.