首页 > 代码库 > ARMV8 datasheet学习笔记4:AArch64系统级体系结构之编程模型(3)- 异常
ARMV8 datasheet学习笔记4:AArch64系统级体系结构之编程模型(3)- 异常
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 AArch64同步异常优先级
优先级 |
说明 |
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产生的同步外部终止异常 |
EL1异常层级系统寄存器控制 |
|||
|
SCTLR_EL1 |
MDSCR_EL1 |
|
{A, SA}: 使能对齐检查 |
{MDE, SS}:
|
||
|
{M, C, I, WXN}: 内存系统控制位; |
KDE:
|
|
|
EE:定义了端; E0E:EL0端; UMA:非特权mask访问 |
TDCC: |
|
|
{SED, ITD, CP15BEN}: |
|
|
ARMV8 datasheet学习笔记4:AArch64系统级体系结构之编程模型(3)- 异常