1.前言
本文介紹異常相關內容,包括異常類型,異常進入,異常返回,異常層次結構,異常的路由等
2. RESET
- ARMV8體系結構支持兩種類型的RESET
Cold reset:Reset PE所有的邏輯,包括集成的debug功能
Warm reset:Reset PE所有的邏輯,不包括集成的debug功能
注:ARMV8也支持外部debug reset
- Reset時pe進入最高的異常級別
- 運行狀態
(1)Reset后最高異常級別可以選用任何一種運行狀態
(2)cold reset由輸入信號配置,warm reset由RMR_ELx.AA64配置
(3)如果reset后最高異常級別選用A64,則
a).選用SP_ELx
b).Reset向量的執行地址由廠商定義,RVBAR持有向量地址
3. 異常處理
3.1 AArch64 state異常處理流程
| 流程 |
說明 |
| 1、保存PSTATE 數據到SPSR_ELx,(x = 1,2,3) |
異常返回時需要從SPSR_ELx中恢復PSTATE |
| 2、保存異常進入地址到ELR_ELx,同步異常(und/abt等)是當前地址,而異步異常(irq/fiq等)是下一條指令地址 |
64位架構LR和ELR是獨立分開的,這點和32位架構有所差別 |
| 3、保存異常原因信息到ESR_ELx |
ESR_ELx.EC代表Exception Class,關注這個bit |
| 4、PE根據目標EL的異常向量表中定義的異常地址強制跳轉到異常處理程序 |
跳轉到哪個EL使用哪個向量偏移地址又路由關系決定 |
| 5、堆棧指針SP的使用由目標EL決定 |
(SPSR_ELx.M[0] == 1) ? h(ELx): t(EL0) |
3.2 AArch32 state異常處理流程
| 流程 |
說明 |
| 1、PE根據異常類型跳轉到對應的異常模式x, x = {und/svc/abt/irq/fiq/hyp/mon} |
PE跳轉到哪一種模式通常由路由關系決定 |
| 2、保存異常返回地址到LR_x,用於異常返回用 |
LR也是對應模式的R[14]_x寄存器,32位系統下LR和ELR是同一個寄存器,而64位是獨立的 |
| 3、備份PSTATE 數據到SPSR_x |
異常返回時需要從SPSR_x恢復PSTATE |
| 4、PSTATE 操作: PSTATE.M[4:0]設置為異常模式x PSTATE.{A,I,F} = 1 PSTATE.T = 1,強制進入A32模式 PSTATE.IT[7:2] = “00000” |
PSTATE.M[4]只是對32位系統有效,64為下是保留的,因為64位下沒有各種mode的概念. 異常處理都要切換到ARM下進行; 進入異常時需要暫時關閉A,I,F中斷; |
| 5、據異常模式x的向量偏移跳轉到進入異常處理 |
各個mode有對應的Vector base addr + offset |
3.3 AArch64異常向量表偏移量
| exception level遷移情況 |
Synchronous exception的offset值 |
IRQ和vIRQ exception的offset值 |
FIQ和vFIQ exception的offset值 |
SError和vSError exception的offset值 |
| 同級exception level遷移,使用SP_EL0。例如EL1遷移到EL1 |
0x000 |
0x080 |
0x100 |
0x180 |
| 同級exception level遷移,使用SP_ELx。例如EL1遷移到EL1 |
0x200 |
0x280 |
0x300 |
0x380 |
| ELx遷移到ELy,其中y>x並且ELx處於AArch64狀態 |
0x400 |
0x480 |
0x500 |
0x580 |
| ELx遷移到ELy,其中y>x並且ELx處於AArch32狀態 |
0x600 |
0x680 |
0x700 |
0x780 |
| 注:每個異常等級都有一個關聯的 Vector Base Address Register (VBAR),它定義了每個異常等級向量表的基址 |
||||
.
4. 異常返回
如下為AArch64 ERET異常返回流程:
| 1. 用ELR_ELx恢復PC值 |
| 2. SPSR_ELx恢復PSTATE值 |
| 注:ERET指令同時會為執行ERET指令的PE設置event register,reset local monitor |
5.異常層級控制

表 異常層級的控制
5.1 EL3異常層級系統寄存器控制
| SCR_EL3 |
SCTLR_EL3 |
MDCR_EL3 |
|
| NS:決定了EL1和EL0的安全狀態;
|
{A, SA}:使能對齊檢查,A-EL3訪問數據時做對齊檢查;SA-EL3對SP做對齊檢查; |
{EPMAD, EDAD}: 使能外部debugger訪問;
|
|
| RW:決定了低一級的異常等級運行狀態; |
{M, C, I, WXN}: 內存系統控制位; |
{SPME, SDD, SPD32}: 安全debug控制; |
|
| {EA, FIQ, IRQ}:EA-SError和同步Aborts切換到EL3;FIQ-物理FIQ切換到EL3;IRQ-物理IRQ切換到EL3; |
EE:定義了端; |
{TDOSA, TDA, TPM}: 陷阱控制 |
|
| SMD:禁用SMC; |
|
|
|
| HCE:使能Hypervisor call異常; |
|
|
|
| ST:使能secure EL1訪問secure timer; |
|
|
|
| SIF:安裝指令獲取,當secure state禁止從non secuer內存取指; |
|
|
|
| TWI:陷入WFI; |
|
|
|
| TWE:陷入WFE |
|
|
|
5.2 EL2異常層級系統寄存器控制
| HCR_EL2 |
SCTLR_EL2 |
MDCR_EL2 |
HSTR_EL2 |
| RW:決定了低一級的異常等級運行狀態;
|
{A, SA}: 使能對齊檢查 |
{TDRA, TDOSA, TDA}: |
Tn, for values of n in the set {0-3, 5-13, 15}: |
| {AMO, IMO, FMO}:路由物理中斷到EL2 |
{M, C, I, WXN}: 內存系統控制位; |
TDE:路由從非安全EL0 EL1 EL2來的debug異常 |
|
| {VSE, VI, VF}:設置虛擬中斷pending; |
EE:定義了端; |
{TPM, TPMCR}:陷阱控制; |
|
| VM: |
|
HPMN: |
|
| {SWIO, PTW, FB, BSU, DC, CD, ID}: |
|
|
|
| HCD Hypervisor Call Disable |
|
|
|
| {TRVM, TDZ, TVM, TTLB, TPU, TPC, TSW, TACR, TIDCP, TSC, TID1, TID2, TID3, TWE, TWI}: |
|
|
|
| TGE: Trap General Exceptions |
|
|
|
5.3 EL1異常層級系統寄存器控制
| TLR_EL1 | MDSCR_EL1 | ||
| {A, SA}: 使能對齊檢查 |
{MDE, SS} | ||
| {M, C, I, WXN}: 內存系統控制位; |
KDE: |
||
| EE:定義了端; E0E:EL0端; UMA:非特權mask訪問 |
TDCC: | ||
| {SED, ITD, CP15BEN}: |
6. 同步異常類型、路由和優先級
6.1 同步異常類型
| 異常類型 |
描述 |
| Undefined Instruction |
未定義指令異常 |
| Illegal Execution State |
非法執行狀態異常 |
| System Call |
系統調用指令異常(SVC/HVC/SMC) |
| Misaligned PC/SP |
PC/SP未對齊異常 |
| Instruction Abort |
指令終止異常 |
| Data Abort |
數據終止異常 |
| Debug exception |
軟件斷點指令/斷點/觀察點/向量捕獲/軟件單步 等Debug異常 |
6.2 同步異常路由
如果HCR_EL2.TGE為1,None-secure EL0下的異常不會傳遞給None-secure EL1,而是直接傳遞給EL2
6.3 同步異常優先級
| 優先級 |
說明 |
| 1 |
單步異常 |
| 2 |
PC對齊錯誤異常 |
| 3 |
指令終止異常 |
| 4 |
斷點異常或向量捕獲異常?? |
| 5 |
非法執行狀態異常 |
| 6 |
HSTR_EL2.Tn和HCR_EL2.TIDCP設置使得異常從EL1傳遞給EL2 |
| 7 |
指令未定義異常 |
| 8 |
除1-7外,通過設置HCR_EL2.TGE 為1,使得異常從EL1傳遞到EL2 |
| 9 |
設置HSTR_EL2.Tn和HCR_EL2.TIDCP使得異常從EL0傳遞到EL2 |
| 10 |
配置CPTR_EL2使得異常傳遞給EL2 |
| 11 |
通過配置HCR_EL2, other than the TIDCP bit 或 CNTHCTL_EL2 或MDCR_EL2使得異常傳遞給EL2 |
| 12 |
除1-11外,通過配置其它一些寄存器使得異常傳遞給EL2 |
| 13 |
SCR_EL3.SMD設為1,導致SMC指令未定義產生的異常 |
| 14 |
執行了異常產生指令而產生的異常 |
| 15 |
配置CPTR_EL3使得異常傳遞給EL3 |
| 16 |
AArch32 Secure EL1 trap到EL3指令的執行使得異常傳遞給EL3 |
| 17 |
配置MDCR_EL3使得EL0 EL1 EL2的異常都傳遞給EL3 |
| 18 |
除1-17外,通過配置其它一些寄存器使得異常傳遞給EL3 |
| 19 |
Trapped 浮點異常 |
| 20 |
SP對齊異常 |
| 21 |
數據終止異常,不是translation table walk產生的同步外部終止異常除外 |
| 22 |
Watchpoint異常 |
| 23 |
數據終止異常,由translation table walk產生的同步外部終止異常 |
7. 異步異常(中斷)類型、路由和優先級
7.1 異步異常(中斷)類型
| 類型 |
描述 |
| SError or vSError |
系統錯誤類型,包括外部數據終止 |
| IRQ or vIRQ |
外部中斷 or 虛擬外部中斷 |
| FIQ or vFIQ |
快速中斷 or 虛擬快速中斷 |
7.2 異步異常(中斷)路由
- AArch32與AArch64路由控制位對比
| Execution State |
異步異常(中斷) |
路由控制位(按優先級排列. 1允許 0禁止) |
| AArch32 |
Asynchronous Data Abort (異步數據終止) |
SCR.EA HCR.TGE HCR.AMO |
| IRQ or vIRQ |
SCR.IRQ HCR.TGE HCR.IMO |
|
| FIQ or vFIQ |
SCR.FIQ HCR.TGE HCR.FMO |
|
|
AArch64 |
SError or vSError |
SCR_EL3.EA HCR_EL2.TGE HCR_EL2.AMO |
| IRQ or vIRQ |
SCR_EL3.IRQ HCR_EL2.TGE HCR_EL2.IMO |
|
| FIQ or vFIQ |
SCR_EL3.FIQ HCR_EL2.TGE HCR_EL2.FMO |
|
| 注:若HCR_EL2.TGE ==1所有的虛擬中斷將被禁止,HCR.{AMO,IMO,FMO} HCR_EL2.{AMO,IMO,FMO}被當成1處理. |
||
- 最高異常級別使用AArch64異步異常路由規則
| EL2和EL3都實現的路由規則 |
1. 若SCR_EL3.{EA, FIQ, IRQ} == 1,則所有相應的SError\FIQ\IRQ 中斷都被路由到EL3; 2. 若HCR_EL2.{AMO, IMO, FMO} == 1,則EL1/EL0所有對應的SError\FIQ\IRQ中斷都被路由到EL2,同時使能對應的虛擬中斷VSE,VI,VF; 3. 若HCR_EL2.TGE == 1,那么會忽略HCR_EL2.{AMO, IMO, FMO}的具體值,直接當成1處理,則EL1/EL0所有對應的SError\FIQ\IRQ中斷都被路由到EL2,同時禁止所有虛擬中斷 注意: SCR_EL3.{EA, FIQ, IRQ}bit的優先級高於HCR_EL2.{AMO, IMO, FMO} bit優先級,路由優先考慮SCR_EL3 |
| EL3實現,EL2沒實現的路由規則 |
![]() |
| EL3沒實現,EL2實現的路由規則 |
|
如上三條路由規則的流程圖表示如下:

圖 最高異常級別使用AArch64異步異常路由規則
7.3 異步異常(中斷)mask
- 運行在AArch64 state的異常mask規則
| 當一個中斷被mask,則這個中斷發生時不會被傳遞 |
|
| 目標異常等級 < 當前的異常等級 |
中斷自動被mask |
| 目標異常等級 == 當前異常等級相同 |
通過PSTATE.A(SError) PSTATE.I(IRQ) PSTATE.F(FIQ)來mask對應中斷 |
| 目標異常級別 > 當前異常級別 |
|
| 如果本異常級別下PSTATE.{A, I, F}都設為1,則傳遞到本異常級別的任何中斷都被mask |
|
- 最高異常級別使用AArch64時中斷mask對中斷路由的影響
| 實現了EL2和EL3的物理中斷masking |
|
| 實現EL3但沒有實現EL2的物理中斷masking |
![]() |
| 實現EL2但沒有實現EL3的物理中斷masking |
![]() |
| 注: A---無論處理器狀態mask為何值,中斷發生時都會被傳遞 B---如果mask為1則中斷發生時不會被傳遞,mask為0中斷發生時會被傳遞 C---無論處理器狀態mask為何值,中斷發生時都不會被傳遞 |
|
7.5 虛擬中斷規則
| 當HCR_EL2.TGE 為 0設置 HCR_EL2.{FMO, IMO, AMO}路由控制位為1使能對應的虛擬中斷 |
| 當HCR_EL2.TGE為1所有的虛擬中斷被禁用 |
| 虛擬中斷只能從Non-secure EL0或Non-secure EL1傳遞到Non-secure EL1 |
| 當一個虛擬中斷類型被使能時,虛擬中斷可以通過如下幾種方式產生:
當一個虛擬中斷類型被禁用: 1. 這個虛擬中斷不能被傳遞; 2. ISR_EL1中不會看到; |
7.6. 中斷優先級與中斷識別
| 同步事件之前如果有任何中斷pending,中斷將在同步事件之后的第一條指令前被捕獲 同步事件包括如下: |
| ISB指令的執行 |
| 異常進入 |
| 異常返回 |
| 退出debug狀態 |
7.7. 多寄存器load/store期間發生異常的處理
| Single-reg load/single-reg store |
Single load/single store訪存期間發生的中斷會被捕獲處理 |
| Multy-regs load/multy- regs store |
|
8.參考文檔
[1] DDI0487A_k_armv8_arm_iss10775.pdf



