aarch64異常(一)aarch64異常簡介

目錄

 

Aarch64中異常的基本概念

異常發生時硬件做了哪些事情?

 

異常的處理


Aarch64中異常的基本概念

在aarch64中,將中斷、系統調用、數據指令異常等等情況統稱爲異常。異常會中斷當前cpu執行流,轉而執行具有更高權限的代碼,即exception handler。當異常處理完畢後cpu會再次返回到之前的被中斷的代碼流繼續執行。

常見的異常有中斷、系統調用、數據指令失效訪問等等。雖然異常類型各種各樣,但aarch64將異常分爲同步異常(synchronous exception)和異步異常(asynchronous exception)兩類。

  • asynchronous exception的特點:

1異常發生的時機無法預料,與CPU執行的指令無關; 

2異常處理的返回地址並非是產生異常時的那一條指令。

IRQ、FIQ和SError interrupt屬於asynchronous exception。

  • synchronous exception的特點:

1 異常的產生是和CPU執行的指令或者試圖執行的指令有關; 

2 異常處理的返回地址就是產生異常的那一條指令所在的地址。 

 

異常發生時硬件做了哪些事情?

  • 異常返回地址保存到ELR_ELn寄存器中

PE會根據異常的類型選擇一個合適返回地址保存到ELR_ELn中,n的含義和簽名SPSR_ELn類似。等到異常處理完畢、軟件主動調用ERET指令,這個指令會將ELR_ELn的內容更新到PC指針,實現異常的返回跳轉。

  • 將當前PE狀態保存到SPSR_ELn寄存器中

其中n表示target exception level。例如,在linux中用戶態任務(EL0)執行時觸發一個數據訪問異常,此時target exception level就是EL1。

待異常處理完畢後,軟件會主動調用ERET指令,這個指令的一個功能就是將SPSR_ELn恢復到PSATE寄存器中(嚴格來說PSTATE不是一個寄存器,是一組表示PE狀態寄存器的組合)。

  • 更新PE狀態寄存器進入目標EL

發生異常,PE進入要給全新的執行狀態,因而PSATE寄存器的各個狀態域也會隨之更新。

其中DAIF域的各個位都會被mask,從而禁止在此cpu上這些異常事件的發生;因而異常處理過程中除非軟件顯示的unmask DAIF中的bit位,否則這些異常一直處於禁止狀態,知道ERET指令執行時DAIF的值從SPSR_ELn寄存器恢復到異常前的狀態。

  • 堆棧指針SP_ELn的切換

程序運行在EL0時使用的是SP_EL0;其他Exception level下,可以使用SP_EL0或者當前Exception level所對應的SP_ELn寄存器;具體使用SP_EL0還是SP_EL1是由PSTATE.SP決定,對應的寄存器是Spsel。若Spsel==0,那麼強制使用SP_EL0,否則使用用SP_ELn。在linux中Spsel默認位1。因而異常發生時,默認會切換到SP_ELn。

  • 視情況更新ESR_ELn寄存器

如果發生的是同步異常或者SError異常,則將異常原因信息更新到ESR_ELn寄存器中。其他FIQ、IRQ異常則不會更新此寄存器。

  • 視情況更新FAR_ELn寄存器

FAR_ELn寄存器全稱叫Fault Address Registe。在指令或者數據 Aborts異常、非對齊異常時,這個寄存器保存引發異常的地址。

 

異常的處理

根據發生在內核態還是用戶態,中斷還是異常, cpu會自動跳轉到異常向量表中的el1_sync,el1_irq,el0_sync,el0_irq處;

異常處理完畢後軟件通過執行ERET指令返回異常,這條指令完成:將SPSR_ELn寄存器的值恢復到PSTATE中;

如圖所示(下圖來自):

                          

 

參考:

https://static.docs.arm.com/100933/0100/aarch64_exception_and_interrupt_handling_100933_0100_en.pdf

《ARM® Cortex®-A Series Programmer’s Guide for ARMv8-A》

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章