Cover image for ARM Cache

ARM Cache

Words 5.2k
Views
Visitors
Timeline

Timeline

2025-10-25

init

This article introduces the basic concepts and working principles of caches in the ARM architecture. It first explains the key terms in classic cache architecture, including cache line, index, tag, offset, set, and way, and describes the role of set-associative structures in preventing cache thrashing. It then introduces the main types of caches on the ARM64 platform, such as instruction cache, data cache, and unified cache, as well as the three mapping methods: direct-mapped, fully associative, and set-associative. Through specific examples, it demonstrates the capacity and index calculation methods of set-associative caches. The article also compares the advantages and disadvantages of physical caches and virtual caches, focusing on the alias problem and homonym problem in virtual caches and their causes. On this basis, it further introduces three cache addressing methods: VIVT, PIPT, and VIPT, and details the working mechanism of VIPT, which uses the page offset of the virtual address as the index and the physical address as the tag, as well as the conditions for avoiding the alias problem and the reason it is limited by page size. Finally, the article outlines the hierarchical structure and access flow of multi-level caches, helping readers understand the data lookup process from L1 to L3 caches.

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 unit of access 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 bits of the cache address, used to determine whether the data address cached in the cache line matches the processor’s addressing address.
  • Offset: The offset within a cache line. The processor can address the contents of a cache line by word or byte.
  • SetSame index fieldform a set
  • Way: In a set-associative cache, the cache is divided into several blocks of the same size.

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

Cache internal partitioning
Cache internal partitioning

Cache types

On the ARM64 architecture, there are mainly:

  • 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 (such as L2, L3) are often unified caches (storing both instructions and data), unlike L1 which is strictly split into instruction/data.

Sometimes a cache with both I-Cache and D-Cache is called a Separate Cache. It is a split cache structure: it has both an independent I-Cache and an independent D-Cache. Typical of L1 Cache

Cache mapping methods

Direct mapping

When each set has only one cache line, it is called a direct-mapped 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, i.e., any address in main memory can map to any cache line, 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 set contains 2 cache lines (ways), and the two cache lines in the same set can replace each other.
  • 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 cache line size is 32 bytes, so the number of cache lines per way is: num_cache_line = 8KB/32B=256

From this, the cache structure diagram 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.

12345678910
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 access the cache.

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

Physical cache
Physical cache

virtual cache

The processor uses virtual addresses to address the cache.

Disadvantages: This will introduce quite a few problems:

  • Aliasing problem
  • Homonyms problem

virtual cache
virtual cache

Aliasing problem

Also known as the aliasing problem

  • BeforeIn an operating system, multiple different virtual addresses may map to the same physical address. Since a virtual cache architecture is used, these different virtual addresses will 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 in the cache there are two cache lines caching VA1 and VA2.
    • When the program writes data to VA1, the cache line corresponding to VA1 and the content of PA are changed, but VA2 still holds the old data. Thus, one physical address has two copies of data in the virtual cache, which creates ambiguity.

Aliasing problem
Aliasing problem

Homonyms problem

  • The same virtual address corresponds to different physical addresses, because different processes in the operating system have many identical virtual addresses, and after MMU translation, these identical virtual addresses yield different physical addresses, thus creating the homonyms problem.
  • The most common place for the homonyms problem is 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, and this cached data is wrong and useless for the new process. The solution is to invalidate all the cache left behind by the old process during a process switch, so that the new process gets a clean virtual cache when it runs.

Cache classification

  • VIVT (Virtual Index Virtual Tag): usesthe virtual address’s index field and 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 aliasing problem (Synonym/Aliasing): when different virtual addresses map to the same physical address, multiple copies of data may appear in the cache, which can lead to data inconsistency.
  • PIPT (Physical Index Physical Tag): usesthe physical address’s index field and tag field, which is equivalent toPhysical cache

    • The CPU first translates the virtual address into a physical address through the MMU, then uses the physical address for cache indexing and matching.
    • No aliasing problem.
    • Common L2 Cache
  • VIPT (Virtual Index Physical Tag): usesVirtual address index field and physical address tag field.

    • CPU Use the low bits of the virtual address as the cache index.Use the physical address as the tag., used for match determination. BecauseCache line alignment (usually 64 bytes or 128 bytes), the low bits of the virtual address match the low bits of the physical address., so it is safe to use the virtual address for indexing.
    • Avoids the aliasing problem., because the physical address is used as the tag.
    • Subject to Page Size Limitation: the virtual index length must be ≤ the page offset bits; otherwise, the same virtual index from different pages will conflict. (VIPT uses the low bits of the virtual address to index cache lines.)
    • Common L1 Cache

VIPT working process

From a general perspective:

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

From the VIPT perspectivePODivided into:

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

Assume the L1 cache is 64KB and the cache line is 64B:

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

  • So the cache index uses the virtual address’s 10 bits

  • Page offset = 12 bits (4KB page)

  • The page offset in virtual and physical addresses 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), 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 map to the same physical page, the two 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 alias problem can becache layout avoided by making the VIPT cache’sindex bits come only from the page offset portion of the virtual address(not VPN)

Cache hierarchy

two-level cachesystem

two-level cache
two-level cache

L3 cachesystem

L3 cache
L3 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 cachein, then the CPU directly fromL1 cachefetches the data
  • Case2: If the value of x1 is not inL1 cachein, but rather inL2 cachein
    • ifL1 cachein, there is no space, then some will be evictedcache line
    • data fromL2 cache lineload intoL1 cache line
    • CPU fromL1 cache linereads data from
  • Case3: the value of x1 is in neither L1 nor L2 cachein, but in memory
    • ifL1 cacheandL2 cachein, there is no space, then some will be evictedcache line
    • data loaded from memory into L2 and L1’scache linein
    • CPU fromL1 cache linereads data from

Multi-level cache access latency

Multi-level access latency
Multi-level access latency

Cache strategies (Cache Policies)

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

  • Cache strategies include:

    • Cacheable/non-cacheable
    • Cacheable subcategories
      • 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 policy:

    • Write-back(WB): Write-back operation only updates the cache and does not immediately update 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; its biggest disadvantage is that it consumes 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)

    • Writes only update the cache and mark the cache line as dirty. 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 memoryYou can set inner or outer shareability.
  • How to distinguish inner or outer varies by design.
    • inner attributeUsually,CPU 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 shareable and outer shareable
Inner shareable and outer shareable

Prefetch instruction

Prefetch instructions in AArch64 (ARMv8 64-bit)

In A64, the one used is PRFM(Prefetch Memory)。

Instruction format

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

Description of the prfop syntax structure

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

example

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

Meaning: take the address(X0 + 32)the corresponding data is loaded in advance to L1 Cache, and marked asmay be reused repeatedly


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

Meaning: take[X1]preload into the cache, butnot retained for long(suitable for sequential streaming reads like memcpy).


Equivalent immediate notation
1
PRFM #0, [X0]

#0Corresponds to the default in the ARM prefetch hint tablePLDL1KEEP

uimm5 valueCorresponds to prfopmeaning
#0PLDL1KEEPRead prefetch to L1, reuse (most common)
#1PLDL1STRMRead prefetch to L1, streaming (used only 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 in a CPUinstruction cachedata cacheandMMUTLBetc. see the same copy of memory
    • PoU for a PE, meaning to guaranteePEwhat is seenI/D cacheandMMUis the same copy. In most cases,PoU is viewed from the perspective of a single-core system
    • PoU for inner share, meaning that ininner shareall withinPEcan all see the same copy
  • PoC: all observers in the system, such asDSP, GPU, CPU, DMAetc. can all see the same memory copy

PoU
PoU

PoU and PoC
PoU and PoC

Difference between PoU and PoC

  • PoCIt is a system concept, related to system configuration.
  • For example,Cortex-A53can be configuredL2 cacheand withoutL2 cache, may affectPoUthe scope of

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 particular cache line. The data in the cache will be discarded.
    • Clean (Clean) the entire cache or a particular cache line.Write back dirty cache line data to the next-level cache or main memory.(also called flush)
    • Zero (Zero) operation
  • Cache management objects
    • ALL : the entire cache
    • VA: a virtual address, sometimes called MVA (Modified Virtual Address, which is a cache line containing a particular virtual address)
    • Set/Way: a 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 take an address parameter use a 64-bit register that holds 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 fault is generated.

Example 1

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

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
// AArch64: Data Cache Clean by Set/Way// Can be executed at EL1 (kernel mode).global clean_data_cacheclean_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 1Loop1:    // 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            // Extract the 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 the 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             // Step size for each decrementLoop2:    // ---- Parse Set ----    UBFX    W7, W1, #13, #15        // bits[27:13]: sets-1    LSL     W7, W7, W2              // Align set bits    LSL     W17, W8, W2             // Step size for each decrementLoop3:    // ---- Assemble DC operation parameters ----    ORR     W11, W10, W9            // Combine level + way    ORR     W11, W11, W7            // Add set		// The middle and low bit fields in X11 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    Loop2Skip:    ADD     W10, W10, #2           // Next cache level    CMP     W3, W10    DSB                             // Ensure the previous clean is fully executed    B.GT    Loop1Finished:    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 types in the system
2Parse LoCDetermine how many cache levels need to be traversed
3Loop through each levelProcess each cache level in sequence from L1 → L2 → L3…
4Use CSSELR_EL1 to select the cache levelTell the CPU which cache level to access next
5Read CCSIDR_EL1Query the detailed configuration of this Cache (number of sets, ways, line size)
6Nested loopIterate over Set and Way, cleaning the cache line by line
7DC CSWExecute Clean by Set/Way
8DSB+ISBData synchronization barrier, ensuring that execution continues only after the cleanup is complete

Under normal circumstances, cleaning or invalidating the entire cache is something only firmware should do, as part of the kernel power-on or power-off sequence. It may also take a significant amount of time; the number of lines in an L2 cache can be very 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

123456789
/* Coherency example for data and instruction accesses within the same InnerShareable 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 cacheIC IVAU, Xn // Invalidate instruction cache by VA to PoUDSB ISH // Ensure completion of the invalidationsISB // Synchronize the fetched instruction stream

This code is standard. Self-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 the write-back completes
  4. Invalidate the corresponding address in I-Cache
  5. DSB: ensure invalidation completes
  6. ISB: flush the instruction fetch pipeline, CPU executes new instructions

Cache discovery

  • When we perform 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 level of cache, what are its set and way counts?
    • For the zero operation, 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; you can read the number of cache levels
  • Cache Type Register(CTR, CTR_EL0): cache line size; you 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) UCT bit to complete.
  • sets and ways: requires accessing 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 a zero operation.

    • DC ZVA (Data Cache Zero by Virtual Address)

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

      • SCTLR_EL1.DZE: Controls whether DC ZVA is allowed at EL0
      • HCR_EL2.TDZ: Controls whether DC ZVA is allowed for EL0/EL1 in the Non-secure world
  • SCTLR/SCTLR_The [DZE] bit of EL1 and the [TDZ] bit of the Hypervisor Configuration Register (HCR/HCR_EL2) 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’s TDZ bit. In this case, reading DCZID_EL0 returns 0, indicating that the instruction is not supported.

  • The CLIDR register only knows how many levels of cache the processor itself integrates. 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 does not know about any external L3 cache. When executing cache maintenance or maintaining consistency with integrated caches, non-integrated caches may need to be considered.

Cache Experiment 1: Cache Enumeration (Cache Discovery)

Experiment 1
Experiment 1

Experimental results:

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

Code

Core idea:

  1. First identify the cache type at each level (CLIDR)
  2. Select level and type, read configuration registers (CSSELR/CCSIDR)
  3. Calculate the set/way/line size and total size of each cache level
  4. Print boundary information and L1 I-Cache addressing strategy**
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
#include "cache_info.h"static const char *cache_type_string[] = {"nocache", "i-cache", "d-cache",                                          "separate cache", "unified cache"};// Instruction cache policies// L1 instruction cache addressing strategy// 0 = VPIPT// 1 = Reserved// 2 = VIPT// 3 = PIPTstatic 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_CTR at EL0_CWG(Cache WriteBack Granule)// Maximum granularity of cache write-back: 2^(val) * 4 bytesstatic inline unsigned int cache_type_cwg(void) {  return (read_sysreg(CTR_EL0) >> CTR_CWG_SHIFT) & CTR_CWG_MASK;}// Under normal circumstances, cache_line_size = CWG// Get the cache line size: 2^(CWG) * 4 = 4 << CWGstatic 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, read the CTYPE field of CLIDR_EL1static 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, we can know: * 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 the CSSELR_EL1 register (Cache Size Selection Register) to indicate which cache to query   */  // Write the level and cache type (0b0 data cache or unified cache, or 0b1 instruction  // cache)  tmp = (level - 1) << CSSELR_LEVEL_SHIFT | ind;  write_sysreg(tmp, CSSELR_EL1);  /*   * 2.   * ReadCCSIDR_EL1the register value,When not implementedARMv8.3-CCIDXwhen,This register only has the low32is valid。   * Note that this register has twolayoutways。   * */  val = read_sysreg(CCSIDR_EL1);  // NumSets bit field, describes the number of sets in the cache  set = (val & CCSIDR_NUMSETS_MASK) >> CCSIDR_NUMSETS_SHIFT;  set += 1;  // Associativity bit field, describes the number of ways of the cache  way = (val & CCSIDR_ASS_MASK) >> CCSIDR_ASS_SHIFT;  way += 1;  // LineSize bit field 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");  // Traverse each cache level  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 processorPoUofcacheBoundary。   * LOC: PoCofcacheBoundary   * LOUIS:PoU for inner shareofcacheBoundary。   * */  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 bit, read/write has 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 (Cache Level)
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 read from CSSELR_EL1 is indeterminate.
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 read from CSSELR_EL1 are indeterminate.

TnD
TnD

Level
Level

InD
InD

CCSIDR_EL1

Current Cache Size ID Register

CCSIDR_EL1
CCSIDR_EL1

Note
Note

BitsNamemeaning
63:56RES0Reserved bit
55:32NumSetsNumber of sets in the cache minus 1 → actual number of sets = NumSets + 1. Note: The number of sets is not necessarily a power of 2.
31:24RES0Reserved bit
23:3AssociativityDescribes cache way countCache’s associativity (ways) minus 1 → actual associativity = Associativity + 1. Note: not necessarily a power of 2.
2:0LineSizeCalculation formula for log2 of cache line size minus 4:line_size_bytes = 1 << (LineSize + 4)

Accessing the CCSIDR_EL1
Accessing the CCSIDR_EL1

ifARMv8.5-MemTag is implemented and enabed

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 implementedonly then is it effective

CCSIDR2_EL1
CCSIDR2_EL1

BitsNamemeaning
63:24RES0Reserved bit, read/write has no meaning
23:0NumSetsThe number of sets in the cache is reduced by 1.Calculation methodNumSets + 1Get the actual number of sets.Note:set number is not necessarily a power of 2
  • Purpose: query of the specified cache set quantity
  • This register is generally with CSSELR_EL1 For use with:
    1. Write CSSELR_EL1 to select cache level and type (data/instruction/tag)
    2. Read CCSIDR2_EL1 to get the number of sets of this cache.
  • NumSets = 0 represents 1 set
  • NumSets > 0 represents Actual 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
    • Identify the type of each level of cache in the processor (Instruction/Data/Unified/Tag).
    • point out that it can be used Set/Way cache maintenance instructions Managed cache.
    • provide Cache hierarchy consistency and sharing level information(LoC、LoU、LoUIS)。
    • Supports up to 7 levels of cache.
BitsNamemeaning
63:47RES0Reserved bit
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: Separate instruction and data cache
0b100: Unified cache
CTR_EL0

Cache Type Register

Its purpose is 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 minimum cache line size covered by 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 an I-cache invalidate is required to make data writes visible to the I-cache.
0 = After a data write, the I-cache must be invalidated for instructions to fetch the latest data.
1 = No need to invalidate the I-cache.
28IDCData cache clean requirements for instruction to data coherenceDetermines whether the D-cache needs to be cleaned to ensure I/D consistency.
0 = The data cache needs to be cleaned to PoU to ensure I/D consistency.
1 = D-cache clean is not required.
Usually modern cores set this to 1, indicating that hardware automatically ensures consistency.
27-24CWGCache Writeback GranuleCache Writeback Granule, the maximum writeback granularity of the cache (log2, in units of word=4B). Indicates the maximum memory block size that may be affected when a cache line is written back (in units of word=4B).
For example, CWG=0b0100 → 2^(4) = 16 words = 64 bytes.
23-20ERGExclusives reservation granuleExclusive Reservation Granule, the maximum reservation range 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

In general,CWG = maximum cache line size, because write-back is performed in units of entire cache lines.

However, the ARM specification allows microarchitectural differences:

  1. CWG ≥ cache line size: some implementations may merge multiple cache lines into a larger burst write (e.g., 128B) during write-back.
  2. CWG = cache line size: common case, e.g., line=64B → CWG=0b0100 (16 words).
  3. CWG not provided (0b0000): must assumemaximum write-back granularity is 2KB, or read the Cache Size ID Registers yourself to infer.
Loading comments…