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