1 // Copyright 2020 The Fuchsia Authors
2 //
3 // Use of this source code is governed by a MIT-style
4 // license that can be found in the LICENSE file or at
5 // https://opensource.org/licenses/MIT
6 
7 #pragma once
8 
9 // clang-format off
10 
11 #ifdef __ASSEMBLER__
12 
13 // Routine to iterate over all ways/sets across all levels of data caches
14 // from level 0 to the point of coherence.
15 //
16 // Adapted from example code in the ARM Architecture Reference Manual ARMv8.
17 .macro cache_way_set_op, op name
18     mrs     x0, clidr_el1
19     and     w3, w0, #0x07000000     // get 2x level of coherence
20     lsr     w3, w3, #23
21     cbz     w3, .Lfinished_\name
22     mov     w10, #0                 // w10 = 2x cache level
23     mov     w8, #1                  // w8 = constant 1
24 .Lloop1_\name:
25     add     w2, w10, w10, lsr #1    // calculate 3x cache level
26     lsr     w1, w0, w2              // extract 3 bit cache type for this level
27     and     w1, w1, #0x7
28     cmp     w1, #2
29     b.lt    .Lskip_\name            // no data or unified cache at this level
30     msr     csselr_el1, x10         // select this cache level
31     isb                             // synchronize change to csselr
32     mrs     x1, ccsidr_el1          // w1 = ccsidr
33     and     w2, w1, #7              // w2 = log2(line len) - 4
34     add     w2, w2, #4              // w2 = log2(line len)
35     ubfx    w4, w1, #3, #10         // w4 = max way number, right aligned
36     clz     w5, w4                  // w5 = 32 - log2(ways), bit position of way in DC operand
37     lsl     w9, w4, w5              // w9 = max way number, aligned to position in DC operand
38     lsl     w12, w8, w5             // w12 = amount to decrement way number per iteration
39 
40 .Lloop2_\name:
41     ubfx    w7, w1, #13, #15        // w7 = max set number, right aligned
42     lsl     w7, w7, w2              // w7 = max set number, aligned to position in DC operand
43     lsl     w13, w8, w2             // w13 = amount to decrement set number per iteration
44 .Lloop3_\name:
45     orr     w11, w10, w9            // w11 = combine way number and cache number
46     orr     w11, w11, w7            //       and set number for DC operand
47     dc      \op, x11                // data cache op
48     subs    w7, w7, w13             // decrement set number
49     b.ge    .Lloop3_\name
50 
51     subs    x9, x9, x12             // decrement way number
52     b.ge    .Lloop2_\name
53 .Lskip_\name:
54     add     w10, w10, #2            // increment 2x cache level
55     cmp     w3, w10
56     dsb     sy                      // ensure completetion of previous cache maintainance instructions
57     b.gt    .Lloop1_\name
58 .Lfinished_\name:
59 .endm
60 
61 #endif
62