Cover image for ARM Cache

ARM Cache

Timeline

Timeline

2025-10-25

init

This article introduces the basic architecture and core concepts of ARM Cache, discussing in detail the components of cache lines, cache types, mapping methods, and the advantages and disadvantages of physical and virtual caches. It also summarizes the working principles and alias issues of cache architectures such as VIVT, PIPT, and VIPT, and briefly describes the hierarchical structure of multi-level cache systems.

Reference documents:

Classic cache architecture

Classic cache architecture
Classic cache architecture

Cache internal architecture diagram

Cache internal architecture diagram
Cache internal architecture diagram

  • Cache line: The smallest access unit in the cache
  • Index field: Used to index and locate which line in the cache
  • Tag: Part of the cache address encoding, usually the high-order part of the cache address, used to determine whether the data address cached in the cache line matches the processor’s addressing address
  • Offset: Offset within a cache line. The processor can address the contents of a cache line by word or byte.
  • SetSame index fieldCache lines form a set
  • Way: In set-associative caches, the cache is divided into several blocks of equal size.

The main purpose of sets is to prevent cache “thrashing”.

Internal cache organization
Internal cache organization

Cache types

On the ARM64 architecture, the main types are:

  • Instruction Cache (I-Cache)
    Dedicated to caching instruction streams to speed up instruction fetching.
  • Data Cache (D-Cache)
    Caches data reads and writes (Load/Store).
  • Unified Cache
    Some levels (e.g., L2, L3) are often unified caches (storing both instructions and data), unlike L1 which strictly separates instructions and data.

Sometimes a cache with both I-Cache and D-Cache is called a Separate Cache, which is a split cache structure: it has both an independent I-Cache and an independent D-Cache. Typical inL1 Cache

Cache mapping methods

Direct mapping

When each group has only one cache line, it is called a direct-mapping cache.

Direct mapping
Direct mapping

Example:

Example of direct mapping
Example of direct mapping

0x00, 0x40, and 0x80 all map to the same cache line, causing frequent cache replacements and low performance.

Fully associative

When the cache has only one set, meaning only one address in main memory corresponds to n cache lines, it is called fully associative.

Example of fully associative
Example of fully associative

Set associative

  • Taking a two-way set associative cache as an example, each way includes 4 cache lines, so every two sets have two cache lines available for replacement.
  • Reduce cache thrashing

Set associative
Set associative

Example:

  • The total cache size is 32KB, and it is 4-way, so each way is 8KB: way_size = 32/4 = 8 (KB).
  • The size of a cache line is 32 bytes, so the number of cache lines per way is: num_cache_line = 8KB/32B=256

From this, the structure diagram of the cache can be drawn:

Cache Structure Diagram
Cache Structure Diagram

The index value is 12-5+1 = 8 bits, totaling 2^8=256, which can index 256 cache lines

1
2
3
4
5
6
7
8
9
10
Cache Level (L1 / L2 / L3)
┌──────────────┐
│ Set 0 │── Way 0 → Cache Line
│ │── Way 1 → Cache Line
│ │── Way 2 → Cache Line
│ │── Way 3 → Cache Line
├──────────────┤
│ Set 1 │── Way 0 → Cache Line
│ ... │
└──────────────┘

Physical Cache

After the processor queries the MMU and TLB to obtain the physical address, it uses the physical address to query the cache

Disadvantages: The processor can only access the cache after querying the MMU and TLB, increasing pipeline latency

Physical Cache
Physical Cache

Virtual Cache

The processor uses virtual addresses to address the cache

Disadvantages: This introduces several problems:

  • Aliasing Problem
  • Homonyms Problem

Virtual Cache
Virtual Cache

Aliasing Problem

Also known as the synonym problem

  • Inan operating system, multiple different virtual addresses may map to the same physical address. Due to the use of a virtual cache architecture, these different virtual addresses occupy different cache lines in the cache, but they correspond to the same physical address
  • For example: VA1 and VA2 both map to PA, and there are two cache lines in the cache that cache VA1 and VA2
    • When a program writes data to VA1, the cache line corresponding to VA1 and the content of PA are updated, but VA2 still holds the old data. Thus, one physical address has two copies of data in the virtual cache, which causes ambiguity

Synonym Problem
Synonym Problem

Homonym Problem

  • The same virtual address corresponds to different physical addresses, because different processes in an operating system have many identical virtual addresses, and after MMU translation, these identical virtual addresses yield different physical addresses, thus creating the homonym problem
  • The most common occurrence of the homonym problem is during process switching. When one process switches to another, if the new process uses virtual addresses to access the cache, it will access the cache left behind by the old process, which is incorrect and useless for the new process. The solution is to invalidate all cache entries left by the old process during process switching, ensuring that the new process gets a clean virtual cache when it executes.

Cache Classification

  • VIVT(Virtual Index Virtual Tag): Usesvirtual address index field and virtual address tag field, which is equivalent tovirtual cache

    • When the CPU accesses the cache, it does not need to perform address translation (virtual address → physical address) first; it directly uses the virtual address to determine the cache line (index) and match the tag.
    • There is an alias problem (Synonym/Aliasing): when different virtual addresses map to the same physical address, multiple copies of data may appear in the cache, potentially leading to data inconsistency.
  • PIPT(Physical Index Physical Tag): usesphysical address index field and physical address tag field, which is equivalent tophysical cache

    • The CPU first converts the virtual address to a physical address through the MMU, then uses the physical address for cache indexing and matching.
    • There is no alias problem
    • Common L2 Cache
  • VIPT(Virtual Index Physical Tag): usesvirtual address index field and physical address tag field

    • CPU uses the low-order part of the virtual address as the cache indexUse physical address as tag, for matching judgment. Becausecache line alignment (usually 64 bytes or 128 bytes), the low bits of virtual address are consistent with the low bits of physical address, so it is safe to index with virtual address.
    • Avoids the aliasing problem, because physical address is used as tag
    • Subject toPage Sizelimitation: virtual index length must be ≤ page offset bits, otherwise the same virtual index from different pages will conflict. (VIPT uses low bits of virtual address to index cache lines)
    • Common L1 Cache

VIPT working process

From a general perspective:

1
VA = 虚拟页号 (VPN) | 页内偏移 (PO)

From a VIPT perspectivePODivided into:

1
PO = Cache Index | Cache Line Offset
  • VIPT cache’sindex bits come only from the page offset part of the virtual address(rather than VPN), this is to prevent the index bits from being affected by virtual address translation (PO is consistent in both virtual and physical addresses).
  • The cache line offset is used to locate specific bytes within a cache line.

Assume L1 Cache is 64KB with a cache line size of 64B:

  • Index bits = log₂(64KB / 64B) = log₂(1024) = 10 bits

  • So the cache index uses the virtual address’s10 bits

  • Page offset = 12 bits (4KB page)

  • The page offset isexactly the same(the paging mechanism only translates VPN, not PO).

  • If the index bits fall entirely within the page offset (i.e., index bit length ≤ page offset bit length), then the cache index uses address bits that are consistent between virtual and physical addresses, avoiding the cache alias problem caused by different VPNs but the same physical page.

Therefore, the requirement is: index bits ≤ page offset bits

VIPT Workflow Diagram
VIPT Workflow Diagram

The left and right steps proceed simultaneously

VIPT Alias Problem

When two virtual pages are simultaneously mapped to the same physical page, both virtual pages together fill one way of the cache.

Two virtual addresses map to the same physical page.
Two virtual addresses map to the same physical page.

As shown in the figure, after Virtual Page1 is modified, Virtual Page2 still accesses the original data.

Example
Example

This aliasing problem can be avoided bycache layoutmaking the index bits of the VIPT cachecome only from the page offset portion of the virtual address(rather than the VPN)

Cache hierarchy

Two-level cachesystem

Two-level cache
Two-level cache

Three-level cachesystem

Three-level cache
Three-level cache

Multi-level cache processing flow

Example:

1
LDR x0,[x1]

Load the value at address x1 into x0, assuming x1 is cacheable

Multi-level cache
Multi-level cache

  • Case1: If the value of x1 is inL1 cache, then the CPU directly gets data fromL1 cachegets the data
  • Case2: If the value of x1 is not inL1 cache, but inL2 cachemiddle
    • IfL1 cachehas no space, then some data will be evicted fromcache line
    • Data fromL2 cache lineloaded intoL1 cache line
    • CPU fromL1 cache lineread data from
  • Case3: the value of x1 is not in L1 or L2cache, but is in memory
    • IfL1 cacheandL2 cachethere is no space in, then some will be evictedcache line
    • data is loaded from memory into L2 and L1cache linein
    • The CPU reads data fromL1 cache linereads data from

Access latency of multi-level cache

Latency of multi-level access
Latency of multi-level access

Cache Policies

  • Cache-related policies areconfigured in the MMU page tableOnly Normal memory can be cacheable

  • Cache strategies include:

    • Cacheable/non-cacheable
    • Cacheable subdivision
      • Read/write-allocate
      • Write-Back cacheable, write-through cacheable
      • Shareability
  • Cache allocation policy

    • Write allocation(WA): Allocate a new cache line only on a write miss
    • Read allocation(RA): Allocate a new cache line only on a read miss
  • Cache write-back policy:

    • Write-back(WB): Write-back operation only updates the cache, not immediately updating memory (cache line is marked as dirty)
    • Write through(WT): Write-through operation directly updates both cache and memory

Write Back and Write Through

Write Back and Write Through
Write Back and Write Through

  • WT write-through mode
    • When performing a write operation, data is written simultaneously to the current cache, the next-level cache, or main memory
    • Write-through mode can reduce the difficulty of implementing cache coherence, but its biggest drawback is consuming more bus bandwidth
    • ARM Cortex-A series processors treat WT mode as Non-cacheable
      • The Cortex-A72 processor memory system treats all Write-Through pages as Non-cacheable

WT
WT

  • WB mode write-back mode

    • Write only updates the cache and marks the cache line as dirty. The external memory is updated only when the cache line is flushed or explicitly cleared.
    • Cache line becomes dirty data

    WB
    WB

Inner and Outer Shareability

  • Normal memoryCan set inner or outer shareability
  • How to distinguish between inner and outer varies with different designs
    • inner attributeUsuallyCPU IPIntegrated caches
    • outer attribute are exported on the bus

Inner and Outer Shareability
Inner and Outer Shareability

inner and outer
inner and outer

inner and outer
inner and outer

  • The inner attribute is the internally integrated cache
  • The outer attribute is the external cache attached to the external bus

Inner shareability and outer shareability
Inner shareability and outer shareability

Prefetch instruction

Prefetch instruction in AArch64 (ARMv8 64-bit)

In A64, the one used isPRFM(Prefetch Memory)。

Instruction format

1
PRFM <prfop>, [Xn, #imm]  // Prefetch cache from address Xn + offset

prfop syntax structure description

1
<prfop> = <type><target><policy> | #uimm5
FieldMeaningExample value
<type>Prefetch purposePLDRead,PSTWrite
<target>Prefetch target cache levelL1,L2,L3
<policy>Cache usage policyKEEP(Reuse),STRM(Streaming/one-time use)
#uimm55-bit encoding form#0~#31

Example

Prefetch data to L1, keep in cache
1
PRFM PLDL1KEEP, [X0, #32]

Meaning: load the address(X0 + 32)corresponding data intoL1 Cache, and mark it aslikely to be reused


Prefetch for one-time read (streaming access)
1
PRFM PLDL1STRM, [X1]

Meaning: load[X1]into cache, butdo not keep long-term(suitable for sequential streaming reads like memcpy).


Equivalent immediate value notation
1
PRFM #0, [X0]

#0In the ARM prefetch hint table, the defaultPLDL1KEEP

uimm5 valuecorresponds to prfopmeaning
#0PLDL1KEEPRead prefetch to L1, reuse (most common)
#1PLDL1STRMRead prefetch to L1, streaming (use once)
#4PLDL2KEEPRead prefetch to L2
#8PLDL3KEEPRead prefetch to L3
#16PSTL1KEEPWrite prefetch
#17PSTL1STRMWrite prefetch (streaming)

Point of Unification (PoU) and Point of Coherency (PoC)

  • PoU: indicates within a CPUinstruction cachedata cacheandMMUTLBetc. see the same copy of memory
    • PoU for a PE, meaning to ensurePEwhat is seen byI/D cacheandMMUIt is the same copy. In most cases,PoU is observed from the perspective of a single-core system,
    • PoU for inner sharemeaning that withininner shareallPEcan see the same copy
  • PoC: all observers in the system, such asDSP, GPU, CPU, DMAetc., can see the same memory copy

PoU
PoU

PoU and PoC
PoU and PoC

The difference between PoU and PoC

  • PoCis a system concept, related to system configuration
  • For example,Cortex-A53can be configured withL2 cacheand withoutL2 cache, which may affectPoUthe scope

Difference between PoU and PoC
Difference between PoU and PoC

PoU and PoC
PoU and PoC

Cache maintenance

  • Cache management operations
    • Invalidate (Invalidate) the entire cache or a specific cache line. Data in the cache will be discarded.
    • Clean (Clean) the entire cache or a specific cache line. The corresponding cache line will be marked as dirty, and datawill be written back to the next level cache or main memory(also known as flush)
    • Zero (Zero) operation
  • Objects of cache management
    • ALL: Entire cache
    • VA: A specific virtual address, sometimes called MVA (Modified Virtual Address, which is a cache line containing a specific virtual address)
    • Set/Way: Specific cache line or set and way
  • Scope of Cache Management
    • PoC
    • PoU
  • Shareability
    • inner

Cache Instruction Format

Cache Instruction Format
Cache Instruction Format

Cache Operation Instructions
Cache Operation Instructions

System instructions for cache maintenance
System instructions for cache maintenance

Instructions that accept an address parameter use a 64-bit register holding the virtual address to be maintained. This address has no alignment restrictions.

The AArch64 data cache invalidate by address instruction DC IVAC requires write permission, otherwise a permission error is generated.

Example 1

Traverse all CPU data cache levels (L1/L2/L3…) and perform a clean by set/way for each cache level to ensure all data in the cache is written back to memory:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// AArch64: Data Cache Clean by Set/Way
// Can be executed at EL1 (kernel mode)

.global clean_data_cache
clean_data_cache:
// Read Cache Level ID (CLIDR_EL1)
MRS X0, CLIDR_EL1

// Extract Level of Coherency (3-bit per level)
AND W3, W0, #0x07000000 // mask[26:24]
LSR W3, W3, #23 // W3 = 2 * LoC
CBZ W3, Finished // Exit if no cache

MOV W10, #0 // W10 = 2 * cache level index
MOV W8, #1 // Constant 1

Loop1:
// Calculate 3 × cache level (3 bits per level describe cache type)
ADD W2, W10, W10, LSR #1 // W2 = 3*level = level*2 + level/2
LSR W1, W0, W2 // Get current level cache type

AND W1, W1, #0x7 // Get lowest three bits
CMP W1, #2 // 2 = Data Cache,3 = Unified
B.LT Skip // Skip levels without D cache

// ---- Select current cache level for operation ----
MSR CSSELR_EL1, X10 // X10 low bits specify level
ISB // Wait for selection to take effect

// Read cache configuration from CCSIDR_EL1
MRS X1, CCSIDR_EL1 // X1 holds CCSIDR

// ---- Parse Cache Line size ----
AND W2, W1, #7 // bits[2:0]: log2(line_len)-4
ADD W2, W2, #4 // W2 = log2(line_len)

// ---- Parse Way ----
UBFX W4, W1, #3, #10 // bits[12:3]: ways-1
CLZ W5, W4 // W5 = leading zero count
LSL W9, W4, W5 // Initialize way bit offset value
LSL W16, W8, W5 // Decrement step each time

Loop2:
// ---- Parse Set ----
UBFX W7, W1, #13, #15 // bits[27:13]: sets-1
LSL W7, W7, W2 // Align set bits
LSL W17, W8, W2 // Decrement step each time

Loop3:
// ---- Assemble DC operation parameters ----
ORR W11, W10, W9 // Combine level + way
ORR W11, W11, W7 // Add set

// In X11, the low-order fields encode Way + Set + Cache level, telling the CPU which cache line to clean.
DC CSW, X11 // CLEAN by set/way

SUBS W7, W7, W17 // set-- loop
B.GE Loop3

SUBS X9, X9, X16 // way-- loop
B.GE Loop2

Skip:
ADD W10, W10, #2 // Next cache level
CMP W3, W10
DSB // Ensure the previous clean is fully executed
B.GT Loop1

Finished:
DSB SY // Synchronization barrier
ISB
RET

CLIDR_EL1

Bit fieldMeaning
bits [26:24]LoC = Level of Coherency (cache coherency level × 2)
bits [2:0]L1 cache type
bits [5:3]L2 cache type

Overall code flow:

StepActionExplanation
1Read CLIDR_EL1Get the number of cache levels and their types in the system
2Parse LoC (Level of Coherence)Determine how many cache levels need to be traversed
3Loop through each levelProcess each cache level sequentially from L1 → L2 → L3…
4Select the cache level using CSSELR_EL1Tell the CPU which cache level to access next
5Read CCSIDR_EL1Query the detailed configuration of the cache (number of sets, ways, and line size)
6Double loopIterate over sets and ways, cleaning the cache line by line
7DC CSWExecuteClean by Set/Way
8DSB+ISBData synchronization barrier to ensure cleanup completes before proceeding

Under normal circumstances, cleaning or invalidating the entire cache is something only firmware should do, as part of the kernel power-up or power-down sequence. It can also be very time-consuming; the number of lines in the L2 cache can be extremely large, and it is necessary to loop through them one by one. Therefore, this kind of cleanup is definitely only for special occasions!

Example 2

1
2
3
4
5
6
7
8
9
/* Coherency example for data and instruction accesses within the same Inner
Shareable domain. Enter this code with <Wt> containing a new 32-bit instruction,
to be held in Cacheable space at a location pointed to by Xn. */
STR Wt, [Xn]
DC CVAU, Xn // Clean data cache by VA to point of unification (PoU)
DSB ISH // Ensure visibility of the data cleaned from cache
IC IVAU, Xn // Invalidate instruction cache by VA to PoU
DSB ISH // Ensure completion of the invalidations
ISB // Synchronize the fetched instruction stream

This code is standardSelf-modifying code / JIT compilation synchronizationSteps:

  1. Write new instructions to memory (possibly in D-Cache)
  2. Clean D-Cache, write data back to PoU
  3. DSB: Ensure write-back completion
  4. Invalidate the corresponding address in I-Cache
  5. DSB: Ensure invalidation completion
  6. ISB: Flush the instruction fetch pipeline, CPU executes new instructions

Cache discovery

  • When performing cache instruction management, you need to know the following information:
    • How many levels of cache does the system support?
    • What is the cache line size?
    • For each cache level, what are its sets and ways?
    • For zero operations, we need to know how much data can be zeroed?

Cache
Cache

  • Cache Level ID Register (CLIDR, CLIDR_EL1): List how many levels of cache there are, can read the number of cache levels
  • Cache Type Register(CTR, CTR_EL0): Cache line size, can read the size of the cache line
  • If this needs to be accessed by user code running at execution level EL0, this can be done by setting the system control register (SCTLR/SCTLR_EL1)'sUCTbit.
  • Sets and ways: Need to access two registers to obtain
    • Tell the Cache Size Selection Register (CSSELR, CSSELR_EL1) which cache to query
    • From the Cache Size ID Register (CCSIDR, CCSIDR_EL1) read the relevant information

Cache Discovery Additional Notes

  • The Data Cache Zero ID Register (DCZID_EL0) contains the block size to be zeroed for zero operations.

    • DC ZVA (Data Cache Zero by Virtual Address)

      • Clear the memory corresponding to a cache line to zero
      • DCZID_EL0stores the block size that can be zeroed
      • Access permissions: Only privileged levels (EL1 and above) can access DCZID_EL0
    • Control bit

      • SCTLR_EL1.DZE: Controls whether EL0 is allowed to use DC ZVA
      • HCR_EL2.TDZ: Controls whether EL0/EL1 is allowed to use DC ZVA in the non-secure world
  • SCTLR/SCTLR_The [DZE] bit of EL1 and the Hypervisor Configuration Register (HCR/HCR_EL2) [TDZ] bit control which execution levels and which worlds can access DCZID_EL0。CLIDR_EL1、CSSELR_EL1 and CCSIDR_EL1 can only be accessed by privileged code, i.e., PL1 or higher in AArch32, or EL1 or higher in AArch64.

  • If the Data Cache Zero by Virtual Address (DC ZVA) instruction is prohibited at an exception level, EL0 is controlled by SCTLR_EL1.DZE bit, and non-secure execution in EL1 and EL0 is controlled by HCR_EL2.TDZ bit; then reading this register returns a value indicating the instruction is not supported.

  • The CLIDR register only knows how many levels of cache are integrated in the processor itself. It cannot provide information about any caches in the external memory system. For example, if only L1 and L2 are integrated, CLIDR/CLIDR_EL1 identifies two levels of cache, and the processor is unaware of any external L3 cache. When performing cache maintenance or maintaining coherence with integrated caches, non-integrated caches may need to be considered.

Cache Experiment 1: Cache Discovery

Experiment 1
Experiment 1

Experiment run results:

Comparison of experimental results with Raspberry Pi official website
Comparison of experimental results with Raspberry Pi official website

Code

Core idea:

  1. First identify each cache level type (CLIDR)
  2. Select level and type, read configuration registers (CSSELR/CCSIDR)
  3. Calculate set/way/line size and total size for each cache level
  4. Print boundary information and L1 I-Cache addressing strategy**
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include "cache_info.h"

static const char *cache_type_string[] = {"nocache", "i-cache", "d-cache",
"separate cache", "unifed cache"};

// Instruction cache policies
// L1 instruction cache addressing strategy
// 0 = VPIPT
// 1 = Reserved
// 2 = VIPT
// 3 = PIPT
static const char *icache_policy_str[] = {
[0 ... ICACHE_POLICY_PIPT] = "RESERVED/UNKNOWN",
[ICACHE_POLICY_VIPT] = "VIPT",
[ICACHE_POLICY_PIPT] = "PIPT",
[ICACHE_POLICY_VPIPT] = "VPIPT",
};

// Read CTR_CRT of EL0_CWG(Cache WriteBack Granule)
// Maximum granularity of cache write-back: 2^(val) * 4 bytes
static inline unsigned int cache_type_cwg(void) {
return (read_sysreg(CTR_EL0) >> CTR_CWG_SHIFT) & CTR_CWG_MASK;
}

// Typically cache_line_size = CWG
// Get cache line size: 2^(CWG) * 4 = 4 << CWG
static inline int cache_line_size(void) {
unsigned int cwg = cache_type_cwg();
return 4 << cwg;
}

// Read CLIDR_EL1, Cache Level ID Register
// Get the cache type by reading the CTYPE field of CLIDR_EL1
static inline enum cache_type get_cache_type(int level) {
unsigned long clidr;

if (level > MAX_CACHE_LEVEL)
return CACHE_TYPE_NOCACHE;
clidr = read_sysreg(clidr_el1);
return CLIDR_CTYPE(clidr, level);
}

/*
* Get each levelcacheofwayandset
*
* From the Raspberry Pi official website, it is known that:
* https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2711/README.md
*
* Caches: 32 KB data + 48 KB instruction L1 cache per core. 1MB L2 cache.
* */
static void get_cache_set_way(unsigned int level, unsigned int ind) {
unsigned long val;
unsigned int line_size, set, way;
int tmp;

/* 1. First write to the CSSELR_EL1 register (Cache Size Selection Register) to indicate which cache to query
*/
// Write the level and cache type (0b0 for data cache or unified cache, or 0b1 for instruction
// cache)
tmp = (level - 1) << CSSELR_LEVEL_SHIFT | ind;
write_sysreg(tmp, CSSELR_EL1);

/*
* 2.
* ReadCCSIDR_EL1the value of the register,When not implementedARMv8.3-CCIDXwhen,This register only has the lower32as valid。
* Note that this register has twolayoutways。
* */
val = read_sysreg(CCSIDR_EL1);
// NumSets bitfield, describing the number of sets in the cache
set = (val & CCSIDR_NUMSETS_MASK) >> CCSIDR_NUMSETS_SHIFT;
set += 1;
// Associativity bitfield, describing the number of ways in the cache
way = (val & CCSIDR_ASS_MASK) >> CCSIDR_ASS_SHIFT;
way += 1;
// LineSize bitfield of CCSIDR_EL1
// line_size_bytes = 1 << (LineSize + 4)
line_size = (val & CCSIDR_LINESIZE_MASK);
line_size = 1 << (line_size + 4);

printk(" %s: set %u way %u line_size %u size %uKB\n",
ind ? "i-cache" : "d/u cache", set, way, line_size,
(line_size * way * set) / 1024);
}

int init_cache_info(void) {
int level;
unsigned long ctype;

printk("parse cache info:\n");
// Iterate through each level of cache
for (level = 1; level <= MAX_CACHE_LEVEL; level++) {
/* Get cache type */
ctype = get_cache_type(level);
/* If the cache type is NONCACHE, exit the loop */
if (ctype == CACHE_TYPE_NOCACHE) {
level--;
break;
}
printk(" L%u: %s, cache line size(CWG) %u\n", level,
cache_type_string[ctype], cache_line_size());
if (ctype == CACHE_TYPE_SEPARATE) {
get_cache_set_way(level, 1);
get_cache_set_way(level, 0);
} else if (ctype == CACHE_TYPE_UNIFIED)
get_cache_set_way(level, 0);
}

/*
* GetICB,LOUU,LOCandLOUIS
* ICB: Inner cache boundary
* LOUU: Single-core processorPoU'scacheboundary。
* LOC: PoC'scacheboundary
* LOUIS:PoU for inner share'scacheboundary。
* */
unsigned clidr = read_sysreg(clidr_el1);
printk(" IBC:%u LOUU:%u LoC:%u LoUIS:%u\n", CLIDR_ICB(clidr),
CLIDR_LOUU(clidr), CLIDR_LOC(clidr), CLIDR_LOUIS(clidr));

unsigned ctr = read_sysreg(ctr_el0);
printk(" Detected %s I-cache\n", icache_policy_str[CTR_L1IP(ctr)]);

return level;
}

CSSELR_EL1

Cache Size Selection Register

CSSELR_EL1
CSSELR_EL1

BitsNameMeaning
63:5RES0Reserved bits, read/write have no meaning
4TnDAllocation Tag not Data: Whether to select a separate Allocation Tag cache
0b0 → Data, instruction, or unified cache
0b1 → Separate Allocation Tag cache
Note: WhenInD = 1(instruction cache), this bit is RES0 (invalid)
3:1LevelCache Level to query
0b000 → L1
0b001 → L2
0b010 → L3
0b011 → L4
0b100 → L5
0b101 → L6
0b110 → L7
Other values reserved. Note: If an unimplemented cache level is selected, the return value of reading CSSELR_EL1 is UNKNOWN
0InDInstruction not Data: Cache type:
0b0 → Data or unified cache (Data Cache or Unified Cache )
0b1 → Instruction cache (Instruction Cache )
If an unimplemented cache level is selected, the return values of Level and InD when reading CSSELR_EL1 are UNKNOWN

TnD
TnD

Level
Level

InD
InD

CCSIDR_EL1

Current Cache Size ID Register

CCSIDR_EL1
CCSIDR_EL1

Note
Note

BitsNameMeaning
63:56RES0Reserved bits
55:32NumSetsNumber of sets in cache minus 1 → actual number of sets = NumSets + 1. Note: The number of sets is not necessarily a power of 2.
31:24RES0Reserved bits
23:3AssociativityDescribes the cache’snumber of ways, cache associativity (ways) minus 1 → actual associativity = Associativity + 1. Note: Not necessarily a power of 2.
2:0LineSizeLog2 of cache line size minus 4. Calculation formula:line_size_bytes = 1 << (LineSize + 4)

Accessing the CCSIDR_EL1
Accessing the CCSIDR_EL1

IfARMv8.5-MemTag is implemented and enabled

if ARMv8.5-MemTag is implemented and enabled
if ARMv8.5-MemTag is implemented and enabled

CCSIDR2_EL1

Current Cache Size ID Register 2

ARMv8.3-CCIDX is implementedis valid

CCSIDR2_EL1
CCSIDR2_EL1

BitsNameMeaning
63:24RES0Reserved bits, read/write has no meaning
23:0NumSetsNumber of sets in cache minus 1Calculation methodNumSets + 1Get the actual number of setsNote: The number of sets is not necessarily a power of 2
  • Purpose: Query the specified cache’snumber of sets
  • This register is generally used withCSSELR_EL1in conjunction:
    1. Write CSSELR_EL1 to select Cache Level and type (data/instruction/Tag)
    2. Read CCSIDR2_EL1 to get the number of sets for that cache
  • NumSets = 0indicates1 set
  • NumSets > 0indicatesActual number of sets = NumSets + 1

NumSets
NumSets

Notes on reading CCSIDR2_EL1:

accessing CCSIDR2_EL1
accessing CCSIDR2_EL1

CLIDR_EL1

Cache Level ID Register

CLIDR_EL1
CLIDR_EL1

  • Purpose
    • Identifies the type of cache at each level of the processor (Instruction/Data/Unified/Tag).
    • Indicates the cache that can be managed usingSet/Way cache maintenance instructionsManaged cache.
    • Providescoherency and sharing level information of the cache hierarchy(LoC、LoU、LoUIS)。
    • Supports up to 7 levels of cache.
BitsNameMeaning
63:47RES0Reserved bits
46:35Ttype(n=1…7)Tag Cache Type
0b00: No Tag Cache
0b01: Separate Allocation Tag Cache
0b10: Unified Allocation Tag + Data (same line)
0b11: Unified Allocation Tag + Data (separate lines)
34:32ICBInner Cache Boundary
0b000: Not disclosed by this mechanism.
0b001: L1 is the highest Inner Cacheable level
0b010: L2 is the highest Inner Cacheable level
……
0b110: L6 is the highest Inner Cacheable level
0b111: L7 is the highest Inner Cacheable level
31:29LoUULevel of Unification Uniprocessor
28:26LoCLevel of Coherence
25:23LoUISLevel of Unification Inner Shareable
22:0Ctype(n=1…7)Cache Type (per-level cache type)
0b000: No cache
0b001: Instruction cache only
0b010: Data cache only
0b011: Seprate instruction and data cache
0b100: Unified cache
CTR_EL0

Cache Type Register

Used to provide cache architecture information

CTR_EL0
CTR_EL0

Bit fieldBitsNameDescription
63-38RES0ReservedReserved, reads as 0
37-32TimeLineTag minimum LineTag minimum line granularity, indicating the size of the smallest cache line covered by the Allocation Tag (log2 in units of word=4B) and**Memory Tagging Extension (MTE)**related
31RES1ReservedReserved, fixed to 1
30RES0ReservedReserved, fixed to 0
29DICInstruction cache invalidation requirements for data to instruction coherenceDetermines whether I-cache invalidation is required to ensure data writes are visible to the I-cache
0 = After data write, I-cache must be invalidated for instructions to fetch the latest data.
1 = I-cache invalidation is not required.
28IDCData cache clean requirements for instruction to data coherenceDetermines whether D-cache cleaning is required to ensure I/D coherence
0 = Data cache needs to be cleaned to PoU to ensure I/D coherence.
1 = D-cache clean is not required.
Usually modern cores set it to 1, indicating hardware automatically ensures coherence.
27-24CWGCache Writeback GranuleCache Writeback Granule, the maximum granularity of cache write-back (log2, in units of word=4B). Indicates the maximum memory block size (in units of word=4B) that may be affected when a cache line is written back.
For example, CWG=0b0100 → 2^(4) = 16 words = 64 bytes.
23-20ERGExclusives reservation granuleExclusive Reservation Granule, the maximum reservation granularity of atomic instructions (LDXR/STXR) (log2, in units of word=4B).
19-16DminLineD minlineData cache minimum line size (log2, in units of word=4B).
15-14L1IPLevel 1 Instruction cache policyL1 instruction cache addressing policy:
0 = VPIPT
1 = Reserved
2 = VIPT
3 = PIPT
13-12RES1ReservedReserved.
3-0IMINLINE / DMINLINEInstruction minline / Data minlineInstruction cache minimum line size (log2, in units of word=4B).

L1Ip

Indicates the type of L1 instruction cache:

L1Ip
L1Ip

Instruction cache invalidation requirements for data to instruction coherence

DIC
DIC

Data cache clean requirements from instruction to data coherence

IDC
IDC

Cache Writeback Granule

CWG
CWG

Under normal circumstances,CWG = maximum cache line size, because write-back is done in units of entire cache lines.

However, the ARM specification allows for microarchitectural differences:

  1. CWG ≥ cache line size: Some implementations may merge multiple cache lines into a larger burst write during writeback, such as 128B.
  2. CWG = cache line size: Common case, for example line=64B → CWG=0b0100 (16 words).
  3. CWG not provided (0b0000): Must assumethe maximum writeback granularity is 2KB, or read the Cache Size ID Registers to deduce it yourself.