ARM官方文档下载链接:
目录
1,SCTLR, System Control Register,系统控制寄存器
2,CTR_EL0,The Cache Type Register, 缓存类型寄存器
3,CLIDR_EL1, Cache Level ID Register 缓存级别ID寄存器
4,CCSIDR_EL1, Current Cache Size ID Register,当前缓存大小ID寄存器
5,CSSELR_EL1, Cache Size Selection Register 缓存大小选择寄存器
ARMv8缓存识别寄存器(identification registers)描述了由在PE上执行的缓存维护指令影响的实现缓存。 这包括以下内容的缓存维护指令:
- 影响整个缓存
- VA操作
- set/way操作
这些寄存器包括:
1,SCTLR, System Control Register,系统控制寄存器
SCTLR寄存器是系统顶层的寄存器,可以控制内存系统,其中包括Cache和MMU等,下面将简单研究关于cache和MMU的disable、enable相关操作。
ARMv7
ARMv8-aarch32:
其中主要是I,C以及M bit:
I 位,bit[12]:I-cache的enable,这是个全局的指令缓存使能位:
- 0 表示I-Cache被禁止
- 1 表示I-Cache被使能
C 位,bit[2]: 缓存使能位,针对数据缓存(data cache)和统一缓存(unified cache,L2 cache):
- 0 表示Data-Cache和Unified Cache(L2 Cache)被禁止
- 1 表示I-Cache被使能
M 位,bit[0] : MMU使能位,针对PL0和PL1阶段的MMU使能控制:
- 0 表示PL0和PL1阶段的MMU 被禁止
- 1 表示PL0和PL1阶段的MMU 被使能
从上述功能位可知,软件可以单独控制I-Cache的使能,但是Data Cache和L2 Cache是绑定在一起控制的。通过使用CP15,可以对SCTLR进行操作,其中两个操作码为0,按顺序使用c1和c0:
MRC p15, 0, <Rt>, c1, c0, 0 ; Read SCTLR into Rt
MCR p15, 0, <Rt>, c1, c0, 0 ; Write Rt to SCTLR
2,CTR_EL0,The Cache Type Register, 缓存类型寄存器
该寄存器为只读属性(ReadOnly),通过这个寄存器,可以获取指定缓存的一些属性,其中较常使用的有:
- TminLine, bits [37:32]:Tag minimum Line
- DminLine, bits [19:16]:数据缓存(Data Cache)和统一缓存(Unified Cache)中的一个cache line中,包含的字(word)的数量。其值做了一次log2的运算。若一个cache line中包含16个word,则DminLine的值应为 0b100 = 4.
- IminLine, bits [3:0]:指令缓存(Instruction Cache)中的一个cache line中,包含的字(word)的数量。其值做了一次log2的运算。若一个cache line中包含16个word,则DminLine的值应为 0b100 = 4.
- L1Ip, bits [15:14]:Level 1中的指令缓存(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)
AArch32模式下:
使用CP15读取CTR寄存器的值:
MRC p15, 0, <Rt>, c0, c0, 1 ; Read CTR into Rt
3,CLIDR_EL1, Cache Level ID Register 缓存级别ID寄存器
通过读取此寄存器的值,可以知道当前指定的cache的leve和type。
可以看到ARM中最多支持七个等级的cache,其实一般情况下,比如自己的PC机只实现了2至3级缓存。
其中经常使用的两个字段为:
- LoC, bits [26:24]:Level of Coherence for the cache hierarchy.此字段描述了可以被清理清除的最后一个等级。如果值为3,说明当前可以被清理清除的缓存级别有:Level1、Level2和Level3。已经实现的内存等级有Level1、Level2、Level3和Level4。
- Ctype<n>, bits [3(n-1)+2:3(n-1)], for n = 7 to 1,Cache Type字段,描述各个缓存等级的的类型。比如Ctype1字段,描述的是Level1缓存的类型。可以有以下值:
- 0b000 No cache,表示无缓存
- 0b001 Instruction cache only.表示只有指令缓存
- 0b010 Data cache only.表示只有数据缓存
- 0b011 Separate instruction and data caches.单独的指令缓存和数据缓存
- 0b100 Unified cache.统一的缓存
- 其他 保留字段
使用CP15读取CLIDR寄存器指令:
MRC p15, 1, <Rt>, c0, c0, 1 ; Read CLIDR into Rt
4,CCSIDR_EL1, Current Cache Size ID Register,当前缓存大小ID寄存器
如果FEAT_CCIDX被实现:
否则:
在访问CCSIDR之前,必须先在CSSELR寄存器中写入正确的值, 与CSSELR相对应,会根据CSSELR中的内容,显示指定cache的cache line大小、way的数量以及set的数量。
其中,经常使用的三个字段为:
- NumSets:(Number of sets in cache)-1,缓存中的集合数-1,也就是说该字段的数值加1,才是当前cache的set数量。该数值不必是2的幂次方。
- Associativity:Number of ways in cache -1,如果Associativity = 3,则说明有4个way。
- LineSize:(Log2(Number of bytes in cache line)) - 4,表示一个cache line的大小为多少个字节。它的值需要进行换算:如果LineSize = 0,2^(0+4) = 16,表明此时的cache line大小为16个字节。相反,如果cache line大小为64 bytes,此时LineSize = log2(64) - 4 = 6 - 4 = 2 =0x10。
使用CP15访问CSSIDR寄存器:
MRC p15, 1, <Rt>, c0, c0, 0 ; Read current CCSIDR into Rt
5,CSSELR_EL1, Cache Size Selection Register 缓存大小选择寄存器
通过往此寄存器内写入数据,选择需要操作的缓存等级和缓存类型。Cache Size ID Register, CCSIDR_EL1寄存器的值也会相应发生变化。
其中经常使用的字段为:
- Level, bits [3:1]:选择的cache level
- InD, bit [0]:选择的cache type
- 0b0 Data or unified cache.
- 0b1 Instruction cache.
使用CP15对CSSELR进行读写操作:
MRC p15, 2, <Rt>, c0, c0, 0 ; Read CSSELR into Rt
MCR p15, 2, <Rt>, c0, c0, 0 ; Write Rt to CSSELR