请阅读【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.csdn.net/luolaihua2018/article/details/119271704