Arm流水线

每一个 core 的流水线(三级流水):

fetch:取指
decode:译码
取指、译码永远都是顺序(in order)的。

执行阶段不同的CPU是不同的:
有的为了高性能是 out of ofder
有的为了低功耗是 in order

在执行阶段指令同时并发执行的最大数量限制于 pipeline 的数量

Arm的软件架构

ArmV7

ArmV7的9种模式

ModeFunctionSecurity stateprivile level
User BothPL0
FIQ BothPL1
IRQ BothPL1
Supervvisor(SVC) BothPL1
Monitor(MON) Secure onlyPL1
Abort(ABT) BothPL1
Undef(UND) BothPL1
System(SYS) BothPL1
Hyp(HYP) Non-Secure onlyPL2

Armv7通用寄存器

R0 - R15:
R0-R3 常用于函数参数
R4-R11 为可保存寄存器(函数内使用?)
R13 SP 栈指针
R14 LR 连接寄存器 保存子程序返回地址
R15 PC 程序计数器 指向下一条指令
其中部分寄存器,某些模式下拥有独立的副本。称为银行化寄存器(Banked Registers):
User:
Sys:
FIQ:R8_fiq ~ LR_fiq、SPSR_fiq
IRQ: SP_svc ~ LR_svc、SPSR_irq
ABT: SP_abt ~ LR-abt、SPSR_abt
SVC: SP_svc ~ LR_svc、SPSR_svc
UND: SP_und ~ LR und、SPSR_und
MON: SP_mon ~ LR_mon、SPSR_mon
HYP: SP_hyp、SPSR_hyp、ELR_hyp

不同模式下R0-R7访问与使用的都是同一份。

Arm程序状态寄存器

CPSR
SPSR
请看Arm手册中寄存器具体的位定义

Arm协处理器 CP15

​ CP15(Coprocessor 15)为什么叫协处理器,这是因为早期翻译的问题。并不是每个英文都有对应的中文。
实际上 CP15 他并不是一个单独的硬件,仍然属于 Arm Core 中的一部分。
​ 他操作系统寄存器的指令:
​ MRC:将C(系统寄存器)读到R(通用寄存器)中
​ MCR:将R(通用寄存器)写到C(系统寄存器)中
​ SCTLR 系统控制寄存器,具体定义请看手册。

ArmV8

aarch32 软件架构

aarch64 软件架构

armv8.0

EL levelNormal worldSecure world
EL0ApplicationSecure firmware
EL1Guest OStrusted OS
EL2HypervisorNo Hypervisor in Secure world
EL3Secure monitorSecure monitor

armv8.4

EL levelNormal worldSecure world
EL0ApplicationTrusted Services
EL1Kerneltrusted OS
EL2HypervisorSPM
EL3FirmwareFirmware

异常等级的切换模型

EL3、EL2、EL1 为特权异常级别
EL0 为非特权异常级别
EL0与EL1是必须实现的(对于 Core IP 来说)
EL2、EL3都是实现定义的(对于 Core IP 来说)
异常永远不会taken到EL0

EL3 跑 Secure monitor ---> ATF(程序名)

EL异常等级的切换

同步异常 / 异步异常
SVC、HVC、SMC 等主动同步异常,内存访问错误、未对齐访问被动异常?
IRQ、FIQ等是异步异常。

HVC 必须在EL1 中使用
SMC 必须在 EL1、EL2 中使用

异常向量表

16组异常向量:SCP_ELx

ArmV9

Armv9 在安全状态与非安全状态中多出了一个 Realm 状态,专用于 VM(arm延期还没造出来)

Arm - 两个安全状态

Secure state and Non-secure state

arm架构定义了两种安全状态
arm架构定义了两套物理地址空间
EL3永远是安全状态
EL2、EL1、EL0是否是安全状态取决于 SCR_EL3.NS 比特位(只能在EL3下修改)

Arm的两种执行状态切换

执行状态的修改只能在异常等级切换时发生
低等级异常向高等级异常切换时,执行状态可能不变或 aarch32变为aarch64,反之不行
高等级异常向低等级异常切换时,执行状态可能不变或 aarch64变为aarch32,反之不行
reset 也可能导致执行状态的变化
只有在reset时或异常级别发生变化时,才能发生执行状态的切换

低等级异常的执行状态的位数不能大于高等级异常的
EL0 执行 aarch64、EL1 执行 aarch32,这不可以。且安全世界与非安全世界的执行状态独立。