請閱讀【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