1、SCTLR
系统控制寄存器是一个64位寄存器,在ArmV8架构中提供SCTLR_EL1、SCTLR_EL2和SCTLR_EL3,都是最高级别的控制,包括对内存系统的控制。
SCTLR_EL1 在EL1和EL0提供最高级别的系统控制,AArch64系统寄存器SCTLR_EL1[31:0]在架构上映射到AArch32系统寄存器SCTLR[31:0]。
SCTLR_EL2 在EL2提供最高级别的系统控制,当HCR_EL2.E2H==1&&HCR_EL2.TGE==1时,这些控制也适用于EL0。如果EL2未实现,则该寄存器从EL3变为RES0。如果EL2未在当前安全状态下启用,则此寄存器无效。AArch64系统寄存器SCTLR_EL2[31:0]在架构上映射到AArch32系统寄存器HSCTLR[31:0]。
SCTLR_EL3 在EL3提供最高级别的系统控制,此寄存器仅在EL3实现时存在。否则,直接访问SCTLR_EL3会出现未定义。
在本文主要介绍CACHE及相关控制位如下:
M位, bit [0]
MMU控制位
-
0 MMU 被禁止
-
1 MMU 被使能
C位, bit [2]
数据缓存控制位
-
0 L1 D-Dache、统一缓(L2 Cache)、转换表(translation tables)不缓存
-
1 L1 D-Dache、转换表(translation tables)可缓存
I位, bit [12]
L1 I-cache控制位
-
0 Non-cacheable 不缓存
-
1 Cacheability 可缓存
可以通过如下指令读写:
MRS <Xt>, SCTLR_EL1
MRS <Xt>, SCTLR_EL2
MRS <Xt>, SCTLR_EL3
MSR SCTLR_EL1, <Xt>
MSR SCTLR_EL2, <Xt>
MSR SCTLR_EL3, <Xt>
2、CTR_EL0
缓存类型寄存器(Cache Type Register)是一个64位寄存器,主要提供有关缓存体系结构的信息,AArch64系统寄存器CTR_EL0[31:0]在架构上映射到AArch32系统寄存器CTR[31:0]。
其常用信息如下:
TminLine, bits [37:32]
Tag 的最小行
DminLine, bits [19:16]
D-Cache 的最小缓存行
IminLine, bits [3:0]
I-Cache 的最小缓存行
以上位字段均为只读,其算法都一样,比如读出DminLine的值为4,那么我们可以假设D-Cache 的最小缓存行为X Byte,通过log2(X / 4)= 4,得到 X=64,所以D-Cache 的最小缓存行为64 Byte。X / 4 是为了将Byte(字节)转换为Word(字)。
L1Ip, bits [15:14]
L1指令缓存策略,同样是只读,其定义如下:
-
00 保留
-
01 ASID-tagged Virtual Index, Virtual Tag (AIVIVT)
-
10 Virtual Index, Physical Tag (VIPT)
-
11 Physical Index, Physical Tag (PIPT)
注:从Armv8.0开始,值01被保留。
可以通过如下指令读取:
MRS <Xt>, CTR_EL0
3、CLIDR_EL1
缓存级别ID寄存器(Cache Level ID Register)主要标识在每个级别上实现的缓存类型或缓存集合,这些缓存可以通过按set/way操作的架构化缓存维护指令进行管理,最多支持7级。同时标识缓存层次结构的一致性级别(LoC)和统一性级别(LoU)。通过读取此寄存器的值,可以知道当前指定的cache的leve和type。
是一个64位寄存器,AArch64 系统寄存器 CLIDR_EL1 的位 [31:0] 在架构上被映射到 AArch32 系统寄存器 CLIDR[31:0]。
其常用字段如下:
LoC, bits [26:24]
Level of Coherence for the cache hierarchy,这是一个维护缓存一致性的级别,该字段定义了在Clean / Invalidate到一致性点时必须被Clean / Invalidate的最后一级缓存。LoC值是一个缓存级别。
例如:
如果LoC值为3,Clean / Invalidate一致性点的操作要求L1, L2 和 L3缓存都被Clean / Invalidate,L4以后不需要维护。
如果LoC值为0,没有任何级别的缓存需要被Clean / Invalidate。
Ctype<n> , bits [3(n-1)+2:3(n-1)]
Cache Type字段,前面介绍,Cache最多支持7级,所以 n 取值为 1 到 7,此字段描述各级缓存的类型。比如Ctype1字段,描述的是L1缓存的类型。可以有以下等类型:
-
000 无缓存
-
001 只有指令缓存
-
010 只有数据缓存
-
011 单独的指令缓存和数据缓存
-
100 统一的缓存
-
其他值 保留
如果我们从Ctype1开始向上读取缓存类型字段,一旦读取到一个值为“000”的情况,那么在之后的等级中就不存在可以管理维护的缓存。例如,如果读取到Ctype3值为“000”的缓存类型字段,那么Ctype4到Ctype7的值必须被忽略。
可以通过如下指令读取:
MRS <Xt>, CLIDR_EL1
4、CSSELR_EL1
缓存大小选择寄存器(Cache Size Selection Register),从名字上听起来或许有点不好理解,下面就介绍一下这个不友好的名字,这个寄存器的作用在于选择,此寄存器的修改,可以直接影响CCSIDR_EL1寄存器的值。
AArch64系统寄存器CSSELR_EL1[31:0]在架构上映射到AArch32系统寄存器CSSELR[31:0]。
其常用字段如下:
Level, bits [3:1]
所选择的Cache级别,对应如下:
-
000 L1 Cache
-
001 L2 Cache
-
010 L3 Cache
-
011 L4 Cache
-
100 L5 Cache
-
101 L6 Cache
-
110 L7 Cache
-
其他值 保留
InD, bit [0]
所选择的Cache类型,对应如下:
-
0 数据或统一缓存
-
1 指令缓存
如果CSSELR_EL1.{TnD, Level, InD}被设置成一个未实现的缓存级别,那么在读取CSSELR_EL1的值将是未知的。在复位后,CSSELR_EL1字段值未知。
可以通过如下指令读写:
MRS <Xt>, CSSELR_EL1
MSR CSSELR_EL1, <Xt>
5、CCSIDR_EL1
当前缓存大小ID寄存器(Current Cache Size ID Register),提供有关当前选定缓存的体系结构的信息,通俗点讲就是提供(Cache Line,set,way)等信息。前面提到CSSELR_EL1可以直接影响CCSIDR_EL1寄存器的值。所以在访问CCSIDR_EL1之前一定要设置所选择的缓存级别,一定要确保CSSELR_EL1设置的选择值正确。在实现FEAT_CCIDX和未实现FEAT_CCIDX的情况下,CCSIDR_EL1的bit位含义有所不同,具体如下:
实现FEAT_CCIDX
未实现FEAT_CCIDX
但是使用上都是一样的,下面就未实现FEAT_CCIDX做介绍。
NumSets, bits [27:13]
该字段表示的值为 set - 1,比如说该字段值为0,那么此时set=1,且该字段不必是2的幂次方。
Associativity, bits [12:3]
该字段表示的值为 way - 1,比如说该字段值为3,那么此时way=4,且该字段不必是2的幂次方。
LineSize, bits [2:0]
该字段表示的值为(Log2(Number of bytes in cache line)) - 4,比如说该字段值为2,那么就有如下等式:
(Log2(Cache Line)) - 4 = 2
那么
Cache Line = 2^(2+4) = 64 Byte
可以通过如下指令读取:
MRS <Xt>, CCSIDR_EL1