此文分析基于arm官方文档
ARM Architecture Reference Manual ARMv8, for ARMv8-A architecture profile
ARM Architecture Reference Manual Supplement ARMv8.1, for ARMv8-A architecture profile Errata markup
1. A64 64位ARM指令集,这里64位指数据处理能力即一条指令处理的数据宽度,指令编码使用定长32比特编码
2. A32 32位ARM指令集,这里32位指数据处理能力即一条指令处理的数据宽度,指令编码使用定长32比特编码
3. T32 thumb指令集,32位指令(即一条指令可以处理32比特到数据),指令编码为16比特32比特混合编码(具有更高的指令密度,16比特指令可以访问的寄存器数受限,性能会低很多)
arm64有31通用寄存器X0-X30,可以作为32或64比特的寄存器,32比特时记为W0-W30,64比特时记为X0-X30。
指令使用5比特编码寄存器。当寄存器编号为31时,使用零寄存器(zero register)。零寄存器非物理寄存器,32比特时记作WZR,64比特时记作XZR。
LR为X30。LR(链接寄存器)在函数调用指令(BL、BLR)中使用,用于保存返回地址
SP(stack point)、PC(program counter)、CPSR(current program state register)为特殊功能寄存器,通过特殊指令访问,在指令中没有寄存器编号。
SP(stack point)
CPSR(current program state register)非物理寄存器,是一组寄存器(NZCV/DAIF/CurrentEL/SPSel)的映射,不能通过指令直接访问。通过访问NZCV/DAIF/CurrentEL/SPSel寄存器间接访问CPSR
异常等级是ARMv8引入到权限等级,ARMv8有4级异常等级EL0、EL1、EL2、EL3数值越大权限越大,具体芯片可以选择实现EL3、EL2
通常
EL0用于User App
EL1用于OS
EL2用于Hypervisor
EL3用于Secure monitor
ARMv8有两种执行状态:
AArch64用于执行64位指令集
AArch32用于执行32位指令集
执行状态的控制
如果高异常等级执行在AARCH32状态下,低的异常等级必须执行在AARCH32状态下
EL3执行状态
MRC P15, 0,
; Read RMR into RtMCR P15, 0,
; Write Rt to RMREL2执行状态
EL1执行状态
Non-secure(EL0、EL1、EL2) 只能访问Non-secure memory
secure(EL0、EL1、EL3) 可以访问secure & Non-secure memory
EL0不能处理异常,所以EL0没有异常向量
每一个异常等级有一个寄存器用于设置异常的起始地址,Vector Base Address Register(VBAR_ELx)
根据异常得来源异常向量被分为4段(当前异常等级并使用SP_EL0,当前异常等级并使用SP_ELx,低异常等级64位模式,低异常等级32位模式)
每一段有4中异常Synchronous exception/SError/IRQ/FIQ
异常地址如下:
异常来源 | Synchronous | IRQ | FIQ | SError |
---|---|---|---|---|
当前异常等级并使用SP_EL0 | 0x000 | 0x080 | 0x100 | 0x180 |
当前异常等级并使用SP_ELx | 0x200 | 0x280 | 0x300 | 0x380 |
低异常等级AARCH64 | 0x400 | 0x480 | 0x500 | 0x580 |
低异常等级AARCH32 | 0x600 | 0x680 | 0x700 | 0x780 |
ARMv8支持4k/16k/64k三种类型的页
ARMv8最大支持48位的物理地址空间(即支持256T的物理内存)
ARMv8支持48位的虚拟地址空间(即支持256T的虚拟地址空间)
ARMv8有两级地址转换单元(stage1/stage2)
地址转换规则
ARMv8支持多级页表,即通过页表描述符找到的地址是下一级页表的地址,需要多次转换才能找到最终的地址
ARMv8把输入地址分为多个段(每个段分别作为各级页表的偏移量,或者目标页的偏移量)
4k页时虚拟地址分段规则
+--------+--------+--------+--------+--------+--------+--------+--------+
|63 56|55 48|47 40|39 32|31 24|23 16|15 8|7 0|
+--------+--------+--------+--------+--------+--------+--------+--------+
| | | | | |
| | | | | v
| | | | | [11:0] in-page offset
| | | | +-> [20:12] L3 index
| | | +-----------> [29:21] L2 index
| | +---------------------> [38:30] L1 index
| +-------------------------------> [47:39] L0 index
+-------------------------------------------------> [63] TTBR0/1
+--------+--------+--------+--------+--------+--------+--------+--------+
|63 56|55 48|47 40|39 32|31 24|23 16|15 8|7 0|
+--------+--------+--------+--------+--------+--------+--------+--------+
| || | | |
| || | | v
| || | | [13:0] in-page offset
| || | +------->[24:14] L3 index
| || +------------------->[35:25] L2 index
| |+------------------------------->[46:36] L1 index
| +-------------------------------->[47] L0 index
+-------------------------------------------------->[63] TTBR0/1
+--------+--------+--------+--------+--------+--------+--------+--------+
|63 56|55 48|47 40|39 32|31 24|23 16|15 8|7 0|
+--------+--------+--------+--------+--------+--------+--------+--------+
| | | | |
| | | | v
| | | | [15:0] in-page offset
| | | +----------> [28:16] L3 index
| | +--------------------------> [41:29] L2 index
| +-------------------------------> [47:42] L1 index
+-------------------------------------------------> [63] TTBR0/1
页表描述符
页表描述符64位,地址8字节对齐,所以在查找下一级页表时低3比特全部为0。页表描述符在表示目标页地址时低12(4k)/14(16k)/16(64k)位都为0。所以在页表描述符中,低3比特肯定是无效位。
ARMv8利用这个特性使用了其中低两个比特位,用于标识页表描述符的类型
L0/L1/L2时
L3时
页表描述符[47:3]比特记录地址信息,根据每一级页表偏移的位数或页偏移的位数把低位清0,这样只需要或上偏移量就可以算出目标地址
页表描述符,高16位无效(64-48),ARMv8把这一部分用于记录权限信息(只在stage1转换期间有效,在stage2转换期间保留为0)
缓存(cache)一般由tag data controller组成。tag用于记录下一级内存中那一部分被缓存了,data用于保存缓存的内容,controller用于控制缓存的工作。
缓存可以分为三类
全关联缓存(fully-associative)
这种缓存不使用page,直接通过line与下一级存储器交换数据,它的page容量等于line的容量
具有速度快、缓存粒度小、容量小、电路复杂的特征
直接映射(direct map)
这种缓存只有一个页。
具有速度慢、缓存粒度大、容量大、电路简单的特征
组关联(set-associative)
这种缓存具有多个缓存页。
这种缓存是性能和成本介于上面两种缓存中一种缓存
缓存策略指何时向下一级缓存亲求数据以及何时把数据写入到下一级缓存
Write Allocation(WA)
写操作不命中时进行缓存操作
Read Allocation(RA)
读操作不命中时进行缓存操作
Write-back (WB)
在缓存失效时,把脏的缓存写入下一级存储器
Write-through (WT)
写的数据不缓存,直接写入到下一级存储器
在SOC内部有多个主控设备(CPU、MMU、DSP等),按些主控观察到的相同的内存点分类,ARM把内存一致性分为两类POC、POU
POC(Point of Coherency)
POC指所有主控看到内存一致的存储器。一般为主存储器。
POU
指一个主控看到的内存一致的存储器。ARM一般把一级缓存分为数据缓存和指令缓存,所以一般的ARM芯片的POU指二级缓存,在没有二级缓存的芯片上就为主存储器。