关于ARM Cache 详细学习推荐专栏:
【ARM Cache 专栏】
【ARM ACE Bus 与 Cache 专栏】
文章目录
- ARMv8/v9 Cache 设置寄存器
- ARMv8 指令 Cache 使能函数
- 测试代码
ARMv8/v9 Cache 设置寄存器
关于寄存器SCTRL_EL1
的详细介绍见文章:【ARMv8/v9 异常模型入门及渐进2 - 系统控制寄存器 SCTRL_ELx 介绍】,这篇文章主要是介绍如果通过控制这个寄存器来 enable cache 和 disable cache的。
如上图所示,可以通过SCTRL_E1
的 I
域 和 C
域来打开 指令cache和数据cache。接下来以使能指令cache为例进行简单介绍。
ARMv8 指令 Cache 使能函数
- 打开指令 cache 汇编代码实现如下:
.set CTRL_C_BIT, (1 << 2)
.set CTRL_SA_BIT, (1 << 3)
.set CTRL_I_BIT, (1 << 12)
func enable_icache
EL1_OR_EL2_OR_EL3 x1
1: mrs x0, sctlr_el1
b 4f
2: mrs x0, sctlr_el2
b 4f
3: mrs x0, sctlr_el3
4: and x0, x0, #~CTRL_I_BIT
EL1_OR_EL2_OR_EL3 x1
1: msr sctlr_el1, x0
b 4f
2: msr sctlr_el2, x0
b 4f
3: msr sctlr_el3, x0
4: dsb sy
isb
ret
endfunc enable_icache
- 关闭指令 cache 的汇编代码实现如下:
func disable_icache
EL1_OR_EL2_OR_EL3 x1
1: mrs x0, sctlr_el1
b 4f
2: mrs x0, sctlr_el2
b 4f
3: mrs x0, sctlr_el3
4: and x0, x0, #~CTRL_I_BIT
EL1_OR_EL2_OR_EL3 x1
1: msr sctlr_el1, x0
b 4f
2: msr sctlr_el2, x0
b 4f
3: msr sctlr_el3, x0
4: dsb sy
isb
ret
endfunc disable_icache
既然有了指令cache的开和关,那么我们简单看下,关闭指令cache和打开指令cache的芯片行程差异如何:
测试代码
void foo(void)
{
for (volatile int i = 0; i < 0x10000; i++)
i++;
}
int icache_test(void *data)
{
uint64_t start, end;
enable_icache();
start = syscnt();
foo();
end = syscnt();
log_info("when icache enable, cost time: 0x%llx\n", end -start);
disable_icache();
start = syscnt();
foo();
end = syscnt();
log_info("when icache disable, cost time: 0x%llx\n", end -start);
return 0;
}
关于汇编宏EL1_OR_EL2_OR_EL3
的实现将文章:【ARMv8/v9 系统寄存器 6 – EL 异常等级判定寄存器 CurrentEL 使用详细将介绍】
测试结果:
可以看到打开指令cache和关闭指令cache两者是有一定时间差的,随着测试量的加大这个时间差将会进一步加大,所以代码中一般都会将cache打开。
关于ARM Cache 详细学习推荐专栏:
【ARM Cache 专栏】
【ARM ACE Bus 与 Cache 专栏】