關于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_icacheEL1_OR_EL2_OR_EL3 x1
1: mrs x0, sctlr_el1b 4f
2: mrs x0, sctlr_el2b 4f
3: mrs x0, sctlr_el3
4: and x0, x0, #~CTRL_I_BITEL1_OR_EL2_OR_EL3 x1
1: msr sctlr_el1, x0b 4f
2: msr sctlr_el2, x0b 4f
3: msr sctlr_el3, x0
4: dsb syisbret
endfunc enable_icache
- 關閉指令 cache 的匯編代碼實現如下:
func disable_icacheEL1_OR_EL2_OR_EL3 x1
1: mrs x0, sctlr_el1b 4f
2: mrs x0, sctlr_el2b 4f
3: mrs x0, sctlr_el3
4: and x0, x0, #~CTRL_I_BITEL1_OR_EL2_OR_EL3 x1
1: msr sctlr_el1, x0b 4f
2: msr sctlr_el2, x0b 4f
3: msr sctlr_el3, x0
4: dsb syisbret
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 專欄】