例外狀況
AArch64 定義了包含 16 個項目的例外狀況向量表,適用於 4 種狀態的 4 種例外狀況,即同步、IRQ、FIQ、SError。4 種狀態則分別為目前 EL 搭配 SP0、目前 EL 搭配 SPx、較低 EL 使用 AArch64 和較低 EL 使用 AArch32。這是在組語中實作,以便在呼叫 Rust 程式碼之前,將揮發性暫存器儲存至堆疊:
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 執行。
- 為求簡單,我們不會針對目前 EL 例外狀況區分 SP0 和 SPx,也不會針對較低 EL 例外狀況區分 AArch32 和 AArch64。
- 在此範例中,我們只需記錄例外狀況並關機,因為我們並不預期會實際發生任何例外狀況。
- 例外狀況處理常式和主執行環境,其實可以約略視為不同執行緒。
Send
和Sync
會控管可在它們之間分享的內容,就像執行緒一樣。舉例來說,如要在例外狀況處理常式與程式其餘部分之間分享某個值,而且是Send
(而非Sync
),我們就需要將該值包裝在Mutex
等項目中並放入靜態項目。