ARM Cortex-A Series Programmer's Guide for ARMv7-A, ARM
ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition, ARM
GNU ARM Assembler Quick Reference
ARM SoC mainline进展(会有滞后):参照postmarketOS RK3588主线化 sunxi主线化
开源GPU驱动:Mesa (Gallium3D),内核态DRM部分见kernel.org
Lima (ARM Mali Utgard) Panfrost (ARM Mali Midgard and later) Imagination (Imagination Rogue) Etnaviv (Vivante GC) Freedreno (Qualcomm Adreno) Tegra/Nouveau (NVIDIA Tegra K1/X1)
Imagination GPU相关:Wikipedia
绝大部分ARM SoC中GPU不负责视频解码,也不负责显示输出,只是一个单纯的3D加速器。视频解码由单独的VPU解码单元负责
为自己的ARM SoC编译构建Alpine:参照Alpine wiki
Linux From Scratch:见LFS
交叉工具链构建工具:crosstool-NG
构建系统:Buildroot Armbian构建系统 OpenWrt构建系统 yocto
ARMv7 Cortex-A和R、M两个系列不同,它面向完整的现代操作系统应用,拥有更强大的性能与功能,最大的特性是具备MMU。同时,ARMv7-A系列通常还具备较长的流水线,更高的运行频率,并配备有Cache。多数内核支持超标量,部分内核支持乱序执行。除Cortex-A8以外其他处理器都原生支持多核配置,每个Cluster可以配备1到4个核心(现在部分ARMv8新产品已经不再限制4核。Cluster主要是为了核间通信,Cache一致性,中断控制等多核系统的需求而设计,方便了SoC厂商模块化集成)。同时为满足多媒体运算需求,ARMv7 Cortex-A核心通常会配备有VFP以及NEON SIMD扩展
本笔记主要分析ARMv7-A体系结构,ARMv8-A作为补充说明。ARMv9本质就是ARMv8,主要添加了一些高性能运算,访存,虚拟化,安全相关的扩展而已,不像ARMv7到ARMv8那样直接设计了一个新的ISA,添加64位支持
本笔记重点在于内存架构、中断异常、多核和PSCI,这是ARMv7-A区别于R、M两种核心的重要特性。ARMv8出于兼容ARMv7的目的,大部分IP依旧保留了对32位程序的支持
ARMv7-A的体系规范不包含DMA,DMA是ISA无关的部件。ARM提供DMA330,DMA350等IP
ARMv7-A部分指令和ARMv7-M工作原理相同,例如IT
指令,这里不再详细讲述,具体内容可以看ARMv7-M体系结构笔记
后来推出的Cortex-A17是Cortex-A12的改进版
首先以Cortex-A9为例
Cortex-A9是ARM推出的第一款支持多核配置的ARMv7 MPCore处理器,拥有9-12级可变长度流水线,动态分支预测,双发射乱序执行结构
MPCore,单个Cluster结构
Cortex-A9 MPCore可以配备1至4个核心,且单个核心的功能只包含指令的执行、数据的运算和存取,每个核心包含了自己的L1指令和数据缓存(L1i和L1d),以及MMU等独享部件
其他部件相当于处理器核心的外壳,每一个核心可以拥有一个私有的定时器以及看门狗。其他的部件,如全局定时器,访存并行加速器ACP,AXI总线接口,SCU,L2二级缓存等,都是所有CPU核共享的。这个系统内的中断由一个GIC进行分配和控制,一个GICv2中断控制器可以连接8个CPU核
其他MPCore处理器除核心外,组成结构基本类似。支持的指令集或总线版本会有所不同
大小核
ARM会推出拥有相近指令特性但能耗特性不同的CPU核来组成大小核,较早的大小核使用ARM的
big.LITTLE
技术(ARMv8.2以前的CPU核),采用该技术的系统中,通常一个Cluster至多只能有4
个同类型核心;而ARMv8.2及以后的CPU核基本都使用新的DynamIQ
大小核技术(从Cortex-A55,Cortex-A75开始),克服了以往big.LITTLE
系统的一些限制ARMv7中使用A7+A15,或A7+A17组成大小核。而ARMv8常见的有A53(高频)+A53(低频)组合,A53+A72组合,A53+A73组合,A55(高频)+A55(低频)组合,A55+A76组合,A55+A77组合等。最新的ARMv9有Cortex-A510+Cortex-A710。此外X系列超大核也开始普及
双指令集,支持32位定长指令ARM
模式以及16/32位变长指令Thumb-2
模式
MMU硬件实现的地址查表转换
支持大小端模式
内存页可配置大小:4KB,64KB,1MB,16MB
TrustZone安全扩展
虚拟化扩展(Virtualization)
大内存扩展(LPAE),在32位架构上支持大于4GB的内存地址空间
可选的VFP浮点扩展,NEON SIMD扩展
ARMv7-A处理器中,Jazelle以及ThumbEE支持是可选的。有些SoC厂商会选择不配备这些扩展
Cortex-A的运行模式和Cortex-M完全不同
带有虚拟化扩展以及TrustZone安全扩展的ARMv7-A处理器支持以下工作模式,共计PL0 PL1 PL2
三种模式
PL0
为非特权模式(Unprivileged),PL1 PL2
为特权模式(Privileged)。PL1 PL2
模式可以访问的部件更多
模式 | 全称 | CPSR.M[4:0] | 等级 | 说明 | 安全模式(如果处理器支持TrustZone) |
---|---|---|---|---|---|
USR |
User 用户模式 | 10000 |
PL0 |
用户程序代码的工作模式,受限访问MMU等敏感部件的配置寄存器 | Secure/Non-secure |
SYS |
System 系统模式 | 11111 |
PL1 |
操作系统代码的工作模式,可以访问MMU,GIC等部件 | Secure/Non-secure |
FIQ |
快速中断 | 10001 |
PL1 |
执行快速中断的工作模式。快速中断一般用于实时性要求较高的场合,在寄存器压栈等方面做出了改进,提供相比IRQ 更快的响应性能 |
Secure/Non-secure |
IRQ |
普通中断 | 10010 |
PL1 |
执行普通中断的工作模式 | Secure/Non-secure |
SVC |
Supervisor | 10011 |
PL1 |
CPU复位或执行SVC 指令后进入的模式。SVC 指令一般由用户程序执行来请求系统调用 |
Secure/Non-secure |
ABT |
Abort 访存异常 | 10111 |
PL1 |
访存异常后进入的模式 | Secure/Non-secure |
UND |
Undef 未定义指令 | 11011 |
PL1 |
执行未定义指令后进入的模式 | Secure/Non-secure |
HYP |
Hypervisor | 11010 |
PL2 |
支持虚拟化的处理器中,Hypervisor代码运行的模式,用以支持同时运行多操作系统 | Non-secure |
MON |
Monitor 监视模式 | 10110 |
PL1 |
在支持TrustZone扩展的处理器中的特殊模式,用于切换Secure Non-secure 模式 |
Secure |
在支持TrustZone安全扩展的处理器中,运行状态的Secure
或Non-secure
模式(TrustZone)和PL
模式是互相独立的,两者没有必然联系。运行在Non-secure
模式下的处理器无法访问Secure
模式下使用的内存,包括外设。MON
模式就是用于切换处理器运行的Secure
和Non-secure
模式,如下
通常情况下,用户程序以及操作系统内核都运行在
Non-secure
模式下。只有一些硬件固件以及包含敏感信息的软件需要通过TrustZone来保护
在支持虚拟化扩展的处理器中,Hypervisor和操作系统、用户程序的关系如下
和ARMv7-M一样,ARMv7 Cortex-A也拥有16个基本的通用寄存器GPR。其中R0
到R7
为低寄存器,R8
到R12
为高寄存器,剩余3个有特殊用途,R13
为SP
栈寄存器,R14
为LR
链接寄存器(函数调用时用于存放返回地址,模式切换时用于存放之后PC
返回值),R15
为PC
程序计数器
ARM模式下读取
PC
获得的是当前指令地址+8
,Thumb模式下获得的是当前指令地址+4
,相当于两条指令的长度。因为最早的ARM是3级流水线结构复位后,处理器的
R0
到R14
是不确定值,SP
必须由代码进行初始化后才能正常使用
此外ARMv7-A处理器在特权模式下,部分寄存器会被替换为物理上单独的专用寄存器,这些寄存器会取代原来用户模式(非特权模式)下的寄存器,称为banking
(这个术语在之后会经常用到)
上表中蓝色块代表该模式下被bank的寄存器。其中除
SYS
模式以外,其余所有特权模式都bank了SP
寄存器,同时添加了SPSR
用于保存进入当前模式之前CPSR
的状态,以便任务执行完毕以后将SPSR
恢复到CPSR
回到原来的状态
FIQ
快速中断相比普通中断IRQ
bank了高寄存器,这意味着进入FIQ
时高寄存器可以不用压栈,这也是FIQ
有更快响应性能的原因之一
HYP
模式下同时具有LR
以及ELR
寄存器,LR
和USR
模式使用的是同一个,用于HYP
模式下的函数调用返回;而ELR
用于异常返回
CPSR
定义如下
USR
模式下实际只能访问CPSR
的APSR
部分(A
指Application)。此时APSR
只有N Z C V Q
以及GE[3:0]
是可访问的
各bit功能,和ARMv7-M不同
名称 | 位域 | 作用 | 复位值 | 备注 |
---|---|---|---|---|
N |
31 | Negative标志,整数计算结果首位为1 | UNKNOWN | 任意模式下可以任意读写,建议通过指令自动更改。条件指令依照这些位执行 |
Z |
30 | Zero标志,整数计算结果为0 | UNKNOWN | 同上 |
C |
29 | Carry标志,无符号运算产生进位 | UNKNOWN | 同上 |
V |
28 | Overflow标志,有符号运算产生溢出,例如加法中正正得负或负负得正 | UNKNOWN | 同上 |
Q |
27 | 整数饱和运算标志 | UNKNOWN | 同上,但是不属于N Z C V 标准标志位,条件指令不会检测该位 |
IT[1:0] |
26:25 | 用于IT 条件指令 |
00 |
MRS 读取全0 ,MSR 写无效 |
J |
24 | Jazelle模式。大部分ARMv7处理器不再使用此扩展,该位没有实际作用 | 0 |
MRS 读取为0 ,MSR 写无效 |
GE[3:0] |
19:16 | 用于部分整数SIMD指令(不是NEON或VFP),表示32位运算中每个字节大于或等于 | UNKNOWN | 同N Z C V ,但是影响例如SEL 的执行 |
IT[7:2] |
15:10 | 用于IT 条件指令 |
000000 |
MRS 读取全0 ,MSR 写无效 |
E |
9 | 指示数据大小端模式Endianness,0 小端,1 大端。指令大小端不受影响 |
=SCTLR.EE ,一般为0 小端模式 |
在PL1 及以上模式可以使用MRS MSR 读写,但是不建议这样操作。更改大小端需要使用SETEND 指令 |
A |
8 | Asynchronous abort屏蔽位 | 1 ,默认禁用 |
仅支持TrustZone的处理器中,如果SCR.AW=0 该位无法更改。如果还支持虚拟化,SCR.AW=0 会使得该位的更改受限 |
I |
7 | IRQ 屏蔽位 |
1 ,默认禁用 |
|
F |
6 | FIQ 屏蔽位 |
1 ,默认禁用 |
仅支持TrustZone的处理器中,如果SCR.FW=0 该位无法更改。如果还支持虚拟化,SCR.FW=0 会使得该位的更改受限。如果处理器支持NMFI 不可屏蔽快速中断,也即SCTLR.NMFI=1 ,该位无法置1 |
T |
5 | 指令模式,J 为0 时置1 表示Thumb-2,置0 表示ARM |
=SCTLR.TE ,一般为0 处于ARM模式 |
MRS 读取为0 ,MSR 写无效 |
M[4:0] |
4:0 | 表示当前工作模式 | 10011 ,默认处于SVC 模式 |
通常只在PL1 及以上运行模式下读写 |
IT J E T
位为指示位,除调试模式外,只有专用的指令才能更改这些位。IT
位对应IT
条件指令(Thumb模式专有指令),E
使用SETEND
指令。更改T
需要使用跳转指令进行ARM和Thumb模式的切换
协处理器在ARMv8中被废弃,转而使用特殊寄存器指令访问这些系统配置相关的寄存器
ARMv7-A依然沿用了协处理器,使用专用的协处理器指令如MRC
MCR
访问,共计16个协处理器CP0
到CP15
,其中CP8
到CP15
为ARM保留使用。现实中协处理器CP14 CP15
主要用于系统配置,CP10 CP11
主要用于VFP以及NEON SIMD相关功能
为方便对于协处理器概念的理解,这里给出协处理器指令MRC
MRRC
格式如下(MCR
MCRR
类似)
MRC
指令读取指定协处理器的一个32位寄存器并存入到1个指定的GPR,而MRRC
指令读取指定协处理器的一个64位寄存器并存入到2个指定的GPR
MRC
指令中,opc1
以及opc2
为操作码,CRn
以及CRm
为协处理器中的逻辑寄存器。由于MRC
指令中操作码长度为3
,所以每个操作码支持8
种操作;而CRn
和CRm
地址长度为4
,所以支持16
个寄存器,使用c0
到c15
表示协处理器如
CP15
在实际的应用中作为配置寄存器使用。我们可以将协处理器完全视作一堆寄存器,而opc1 opc2 CRn CRm
中所有编码的任意组合视作一个地址,那么一个协处理器可以支持2^(3+3+4+4)=16384
个32
位寄存器。而如果使用MRRC
访问,一个协处理器可以支持2^(4+4)=256
个64
位寄存器
CP15
为System Control coprocessor,在系统的控制中有重要作用。而在Cortex-M中这些配置寄存器通常位于内存空间,使用例如SCB
MPU
这样的结构体访问
使用
MRC
指令访问时,指令中的CRn
指定CP15
的Primary register
;使用MRRC
访问时,指令中的CRm
指定CP15
的Primary register
。协处理器中同一个Primary register
对应的物理寄存器功能通常属于同一类别,如下所示
CP15
中各Primary register
对应寄存器的主要作用
寄存器编号 | 作用 |
---|---|
c0 |
处理器基本信息 |
c1 |
System Control registers,系统控制 |
c2 c3 |
Memory protection and control registers,用于配置MMU |
c5 c6 |
Memory system fault registers,访存错误信息 |
c7 |
Cache maintenance and other functio访问ns,主要用于配置Cache |
c8 |
TLB maintenance operations,用于配置TLB快表 |
c9 |
Performance monitors,用于监视性能 |
c12 |
Security Extensions registers,TrustZone扩展 |
c13 |
Process, context and thread ID registers,操作系统相关 |
c15 |
Implementation defined |
以下是CP15
中部分物理寄存器的作用,在C代码中访问CP15
时使用这些寄存器名访问
寄存器名 | 作用 | 所属 |
---|---|---|
MIDR |
Main ID,主要是处理器的基本信息 | c0 |
MPIDR |
用于区分多核系统中的每个核 | c0 |
SCTLR |
System Control Register,最重要的系统控制寄存器 | c1 |
ACTLR |
Auxiliary Control Register,不同的处理器功能不同 | c1 |
CPACR |
控制除CP14 CP15 以外所有的协处理器访问权限 |
c1 |
SCR |
安全配置,用于TrustZone扩展 | c1 |
TTBR0 |
MMU相关,level 1转换表基址 | c2 c3 |
TTBR1 |
MMU相关,level 1转换表基址 | c2 c3 |
TTBCR |
控制TTB0 和TTB1 |
c2 c3 |
DFSR |
数据访存错误状态信息 | c5 c6 |
IFSR |
指令访存错误状态信息 | c5 c6 |
DFAR |
数据访存错误地址(Virtual address) | c5 c6 |
IFAR |
指令访存错误地址(Virtual address) | c5 c6 |
VBAR |
TrustZone扩展,非Monitor模式中断异常向量基址 | c12 |
MVBAR |
TrustZone扩展,Monitor模式中断异常向量基址 | c12 |
CONTEXTIDR |
ASID | c13 |
CBAR |
GIC、定时器等外设配置基址 | c15 |
SCTLR
寄存器
SCTLR
长度32位,位于c1
,是重要的系统配置寄存器,同时也是A系列处理器MMU的配置寄存器之一,完整定义如下
这里只讲述部分bit的定义,如下
名称 | 位域 | 作用 | 复位值 | R/W | 备注 | TrustZone |
---|---|---|---|---|---|---|
TE |
30 | 进入异常时使用0 ARM模式或1 Thumb模式 |
通常0 |
RW | 控制包括Reset 异常在内的模式,可使用外部信号配置默认复位值 |
Banked |
NMFI |
27 | 是否支持NMFI 不可屏蔽FIQ 。为1 表示CPSR.F 无法置1 |
R | NMFI 特性只能通过硬件配置,软件无法更改。支持虚拟化扩展的处理器通常不支持NMFI |
Common | |
EE |
25 | 进入异常时使用0 小端模式或1 大端模式 |
通常0 |
RW | 控制包括Reset 异常在内的模式,可使用外部信号配置默认复位值。同时控制内存映射表的大小端 |
Banked |
U |
22 | 表示访存对齐模式,1 表示支持不对齐访问 |
1 |
R | ARMv7中永远为1 |
Common |
FI |
21 | FIQ 响应性能配置。0 普通,1 快速 |
0 |
RW | 在支持TrustZone扩展的处理器中,只有在Secure模式下该位才可更改 | Common |
V |
13 | 中断向量表基址设置。0 位于0x00000000 ,1 位于0x0000FFFF |
通常0 |
RW | 可使用外部信号配置默认复位值。支持TrustZone的处理器可以配置V=0 时的基址 |
Banked |
I |
12 | 为1 使能Icache指令缓存 |
0 |
RW | Banked | |
Z |
11 | 为1 使能分支预测 |
0 |
RW | 部分处理器不支持分支预测或无法禁用该特性 | Banked |
C |
2 | 为1 使能Dcache以及L2缓存 |
0 |
RW | Banked | |
A |
1 | 为1 使能访存对齐检查,不对齐访存会触发Abort (Alignment Fault ) |
0 |
RW | 带有虚拟化扩展的处理器中非对齐访问Device 或Strongly-ordered 永远会触发Abort |
Banked |
M |
0 | 为1 使能1级MMU(PL1&0) |
0 |
RW | 带虚拟化扩展的处理器支持2级MMU(PL1&0),以及1级MMU(PL2,1&0) | Banked |