请阅读【ARM Cache 及 MMU/MPU 系列文章专栏导读】
及【嵌入式开发学习必备专栏】
文章目录
- Cache 常用寄存器
- Cache CSSELR 寄存器
- Cache CSSELR 使用场景
- Cache CSSELR 操作示例
- Cache CLIDR 寄存器
- LoUU 介绍
- LoUU 使用
- LoUIS 介绍
- CLIDR 使用
- Cache CCSIDR 寄存器
- Cache CTR_EL0
Cache 常用寄存器
ARM Cache 常用到寄存器有以下几个:
- CSSELR, Cache Size Selection Register
- CLIDR, Cache Level ID Register
- CTR, Cache Type Register
- CCSIDR, Current Cache Size ID Register
Cache CSSELR 寄存器
CSSELR
(Cache Size Selection Register)是ARM架构中用于选择当前缓存大小ID寄存器(CCSIDR
)的寄存器。通过指定所需的缓存级别和缓存类型(指令缓存或数据缓存),可以让处理器知道当前操作的是哪一级和类型的缓存。如果实现了FEAT_CCIDX
特性,CSSELR
还可以用来选择当前的CCSIDR2
寄存器。
寄存器映射:
- 对于AArch32状态,
CSSELR
寄存器的位[31:0]直接映射到AArch64状态的CSSELR_EL1
寄存器的位[31:0]。
此寄存器仅在
EL1
能够使用AArch32
状态时存在。如果不支持AArch32
,直接访问CSSELR
将是未定义的。
字段解释:
-
Level (位[3:1]): 所需缓存的缓存级别。如果
CSSELR
中的{level, ind}
被设置为一个未实现的缓存级别,那么读取CSSELR
时,这个字段的值是未知的。-
0b000
Level 1 cache. -
0b001
Level 2 cache. -
0b010
Level 3 cache. -
0b011
Level 4 cache. -
0b100
Level 5 cache. -
0b101
Level 6 cache. -
0b110
Level 7 cache.
-
-
IND (位[0]): 指令非数据位。它指示选择的是指令缓存还是数据(或统一)缓存。允许的值有:
-
0b0
:数据缓存或统一缓存。 -
0b1
:指令缓存。
-
Cache CSSELR 使用场景
通过编程CSSELR
寄存器,软件可以查询CCSIDR
(或CCSIDR2
,如果使用feat_ccidx
)以获取特定级别和类型的缓存的详细配置信息,包括缓存的大小、行大小、关联性等。这对于理解和优化系统性能至关重要,因为不同级别和类型的缓存可能具有不同的特性和性能影响。
例如,在性能调优或者系统初始化时,了解具体的缓存参数可以帮助开发者更好地设计数据结构和算法,以减少缓存未命中(misses)和提高数据访问效率。
Cache CSSELR 操作示例
例如要操作 L1 Dcache,可以这样编程CSSELR
寄存器:
MOV X0, #0 // 选择L1数据缓存,Level = 0b001, IND = 0b0
MSR CSSELR_EL1, X0 // 写入CSSELR_EL1寄存器
ISB // 确保更新立即生效
接下来,就可以通过读取CCSIDR_EL1
寄存器来获取L1数据缓存的配置信息了。这种灵活的选择和查询机制为软件提供了强大的工具,以便根据系统的实际缓存配置进行优化和调试
Cache CLIDR 寄存器
CLIDR
(Cache Level ID Register)是ARM架构中用以识别每个级别上实现的缓存类型的寄存器,以及通过set/way方式操作缓存可以管理的缓存级别,最多可达七个级别。此外,CLIDR
还标识了cache level结构的一致性级别(Level of Coherence, LOC)和 Level of Unification, LOU。
寄存器映射
- 对于AArch32状态,
CLIDR
寄存器的位[31:0]直接映射到AArch64状态的CLIDR_EL1
寄存器的位[31:0]。
该寄存器仅在
EL1
能够使用AArch32
状态时存在。否则,直接访问CLIDR
将是未定义的。
字段详解:
-
ICB, 位[31:30]:内部缓存边界(Inner Cache Boundary)。这个字段指示了内部可缓存内存区域的边界。
-
0b00
Not disclosed by this mechanism. -
0b01
L1 cache is the highest Inner Cacheable level. -
0b10
L2 cache is the highest Inner Cacheable level. -
0b11
L3 cache is the highest Inner Cacheable level.
-
-
LOUU, bits[29:27]:缓存层次结构的单处理器统一级别(Level of Unification Uni-processor), 具体见下节内容。
-
LOC, bits[26:24]:缓存层次结构的一致性级别(Level of Coherence)。
-
LOUIS, bits[23:21]:缓存层次结构内部共享的统一级别(Level of Unification Inner Shareable)。当实现
feat_s2fwb
特性时,架构同样要求这个字段为0。 -
CType, bits[3(n-1)+2:3(n-1)], 对于 n = 7 到 1:缓存类型字段, 描述各个缓存等级的的类型。比如Ctype1字段,描述的是Level1缓存的类型。可以有以下值:
-
0b000
No cache,表示无缓存 -
0b001
Instruction cache only.表示只有指令缓存 -
0b010
Data cache only.表示只有数据缓存 -
0b011
Separate instruction and data caches.单独的指令缓存和数据缓存 -
0b100
Unified cache.统一的缓存 -
其他 保留字段
LoUU 介绍
LoUU
(Level of Unification, Uniprocessor)是ARMv9架构中的术语,指在针对处理器元素(PE)执行PoU clean 或者 invalidate 时,必须clean或invalidate的最后一级缓存。与LOC
(Level of Coherence,一致性级别)类似,LoUU
的值也代表了一个缓存级别。
- 当
LoUU
字段值为0x0
时,意味着在执行到 PoU clean 或 invalidate 时,不需要clean 或者 invalidate任何缓存级别。这种情况下,可以认为所有的缓存操作都是在一个更紧密的层次结构内完成,不需要对外部cache level结构进行任何操作。 - 如果
LoUU
字段值是一个非零值,且对应的缓存级别没有被实现,这表示所有已实现的缓存都位于PoU之前。这意味着,一旦数据到达了这个指定的缓存级别,就认为它已经处于一个对所有处理器核心来说,可视为统一的状态。
LoUU 使用
LoUU
的概念主要用于处理器的缓存维护操作中,确保在执行某些特定的内存操作(如上下文切换、DMA操作前后或在运行关键任务代码之前)时,处理器可以正确地管理其缓存数据,保证数据的一致性和正确性。在多核处理器系统中,这一点尤为重要,因为不同核心间的数据共享和同步需要仔细控制。
假如一个系统,其LoUU
值被设置为2,表示L2缓存是执行到 PoU clean 或者 invalidate操作时必须clean 或者 invalidate的最后一级缓存。这意味着,如果一个核心需要保证其修改对其他核心可见,它需要确保至少对 L2 缓存执行了clean 或者 invalidate操作。
关于PoC 和 PoU 的详细内容见:【ARM Cache 系列文章 2 – Cache Coherence及内存顺序模学习】
LoUIS 介绍
LOUIS
用于描述在内部共享的共享域(Inner Shareable Shareability Domain)执行统一点(Point of Unification)clean 或者 invalidate操作时,必须clean 或者 invalidate的最后一级缓存。
Inner Shareable Shareability Domain 是指可以在处理器的多个核心或处理单元间共享数据的特定区域。内部共享的共享域允许数据在不同的处理单元间高效共享,优化了数据同步和通信。
-
当
LOUIS
字段值为0x0
时,意味着在针对Inner Shareable Shareability Domain 执行到PoU的clean 或者 invalidate操作时,不需要对任何缓存级别进行clean 或者 invalidate。 -
如果
LOUIS
字段值是非零且对应的缓存级别未被实现,这表明所有已实现的缓存都位于PoU之前。
CLIDR 使用
CLIDR_EL1
寄存器为软件提供了一种机制来发现并理解系统中实现的cache level结构,包括:
- 缓存的类型(如数据缓存、指令缓存或统一缓存)和级别。
- 系统的缓存一致性和统一性特性。
通过检查CLIDR_EL1
,系统软件(如操作系统或固件)可以确定如何有效地利用和维护缓存,优化性能,特别是在设计多线程和多核心处理的高效缓存一致性策略时。
Cache CCSIDR 寄存器
如果实现了 FEAT_CCIDX 则该寄存器定义如下:
否则定义如下:CCSIDR
(Current Cache Size ID Register)是ARM架构中用于提供当前选定缓存结构信息的寄存器。当实现了FEAT_CCIDX
特性时,该寄存器与CCSIDR2
结合使用。在AArch32系统寄存器中,CCSIDR
的位[31:0]在架构上映射到AArch64系统寄存器CCSIDR_EL1
的位[31:0]。只有在EL1
能够使用AArch32状态时,该寄存器才存在。否则,直接访问CCSIDR
是未定义的。
-
bits [27:13] NUMSETS
:定义了缓存中集合(Set)的数量。这个值是缓存中实际集合数减去1,因为它是从0开始计数的。 -
bits [12:3]ASSOCIATIVITY
:定义了缓存的关联度。这个值同样是实际关联度减去1的结果, 比如 如果Associativity = 3,则说明有4个way。 -
bits [2:0] LINESIZE
:定义了缓存行的大小。这个值是以字节为单位,实际大小为 2(LINESIZE+4) 字节。例如,如果LINESIZE
字段的值是4,那么缓存行大小为 2(4+4) = 256字节。
在访问CCSIDR之前,必须先在CSSELR寄存器中写入正确的值
Cache CTR_EL0
这里及Cortex-A520 core 为例进行介绍,寄存器组成如下:
IminLine, bits [3:0]:指令缓存(Instruction Cache)中的一个cache line中,包含的字(word)的数量。其值做了一次log2的运算。若一个cache line中包含16个word(64bytes),则DminLine的值应为 0b100 = 4
。
L1Ip, bits [15:14]:Level1 中的指令缓存(instruction cache)的缓存策略。指示了index和tag的生成方式。可能包含的值如下,其中,VIPT和PIPT较常使用:
- 0b00—VMID aware Physical Index, Physical tag (VPIPT)
- 0b01—ASID-tagged Virtual Index, Virtual Tag (AIVIVT)
- 0b10—Virtual Index, Physical Tag (VIPT)
- 0b11—Physical Index, Physical Tag (PIPT)
DminLine, bits [19:16]:数据缓存(Data Cache)和统一缓存(Unified Cache)中的一个cache line中,包含的字(word)的数量。其值做了一次log2的运算。若一个cache line中包含16个word,则DminLine的值应为 0b100 = 4
.
推荐阅读:
https://blog.****.net/luolaihua2018/article/details/119271704