استثناها

‏ AArch64 یک جدول برداری استثنایی با ۱۶ ورودی، برای ۴ نوع استثنا (synchronous، IRQ، FIQ، SError) از ۴ حالت (Ecurrent EL with SP0, current EL with SPx, lower EL using AArch64, lower EL using AArch32) تعریف می‌کند. ما این کار را در اسمبلی پیاده‌سازی می‌کنیم تا رجیسترهای فرار (volatile) را قبل از فراخوانی Rust در stack ذخیره کنیم:

use log::error;
use smccc::psci::system_off;
use smccc::Hvc;

#[no_mangle]
extern "C" fn sync_exception_current(_elr: u64, _spsr: u64) {
    error!("sync_exception_current");
    system_off::<Hvc>().unwrap();
}

#[no_mangle]
extern "C" fn irq_current(_elr: u64, _spsr: u64) {
    error!("irq_current");
    system_off::<Hvc>().unwrap();
}

#[no_mangle]
extern "C" fn fiq_current(_elr: u64, _spsr: u64) {
    error!("fiq_current");
    system_off::<Hvc>().unwrap();
}

#[no_mangle]
extern "C" fn serr_current(_elr: u64, _spsr: u64) {
    error!("serr_current");
    system_off::<Hvc>().unwrap();
}

#[no_mangle]
extern "C" fn sync_lower(_elr: u64, _spsr: u64) {
    error!("sync_lower");
    system_off::<Hvc>().unwrap();
}

#[no_mangle]
extern "C" fn irq_lower(_elr: u64, _spsr: u64) {
    error!("irq_lower");
    system_off::<Hvc>().unwrap();
}

#[no_mangle]
extern "C" fn fiq_lower(_elr: u64, _spsr: u64) {
    error!("fiq_lower");
    system_off::<Hvc>().unwrap();
}

#[no_mangle]
extern "C" fn serr_lower(_elr: u64, _spsr: u64) {
    error!("serr_lower");
    system_off::<Hvc>().unwrap();
}
  • ‏ EL سطح استثنا است. تمام نمونه‌های ما امروز بعدازظهر در EL1 اجرا می‌شوند.
  • برای سادگی، ما بین SP0 و SPx برای استثناهای EL فعلی، یا بین AArch32 و AArch64 برای استثناهای پایین EL تمایز قائل نمی‌شویم.
  • برای این مثال، ما فقط exception را log کرده و سپس خاموش می‌کنیم، زیرا انتظار نداریم هیچ یک از آنها واقعاً اتفاق بیفتد.
  • We can think of exception handlers and our main execution context more or less like different threads. Send and Sync will control what we can share between them, just like with threads. For example, if we want to share some value between exception handlers and the rest of the program, and it's Send but not Sync, then we'll need to wrap it in something like a Mutex and put it in a static.