1/* 2 * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7#include <arch.h> 8#include <asm_macros.S> 9 10 .globl flush_dcache_range 11 .globl clean_dcache_range 12 .globl inv_dcache_range 13 .globl dcsw_op_louis 14 .globl dcsw_op_all 15 .globl dcsw_op_level1 16 .globl dcsw_op_level2 17 .globl dcsw_op_level3 18 19/* 20 * This macro can be used for implementing various data cache operations `op` 21 */ 22.macro do_dcache_maintenance_by_mva op 23 dcache_line_size x2, x3 24 add x1, x0, x1 25 sub x3, x2, #1 26 bic x0, x0, x3 27loop_\op: 28 dc \op, x0 29 add x0, x0, x2 30 cmp x0, x1 31 b.lo loop_\op 32 dsb sy 33 ret 34.endm 35 /* ------------------------------------------ 36 * Clean+Invalidate from base address till 37 * size. 'x0' = addr, 'x1' = size 38 * ------------------------------------------ 39 */ 40func flush_dcache_range 41 do_dcache_maintenance_by_mva civac 42endfunc flush_dcache_range 43 44 /* ------------------------------------------ 45 * Clean from base address till size. 46 * 'x0' = addr, 'x1' = size 47 * ------------------------------------------ 48 */ 49func clean_dcache_range 50 do_dcache_maintenance_by_mva cvac 51endfunc clean_dcache_range 52 53 /* ------------------------------------------ 54 * Invalidate from base address till 55 * size. 'x0' = addr, 'x1' = size 56 * ------------------------------------------ 57 */ 58func inv_dcache_range 59 do_dcache_maintenance_by_mva ivac 60endfunc inv_dcache_range 61 62 63 /* --------------------------------------------------------------- 64 * Data cache operations by set/way to the level specified 65 * 66 * The main function, do_dcsw_op requires: 67 * x0: The operation type (0-2), as defined in arch.h 68 * x3: The last cache level to operate on 69 * x9: clidr_el1 70 * x10: The cache level to begin operation from 71 * and will carry out the operation on each data cache from level 0 72 * to the level in x3 in sequence 73 * 74 * The dcsw_op macro sets up the x3 and x9 parameters based on 75 * clidr_el1 cache information before invoking the main function 76 * --------------------------------------------------------------- 77 */ 78 79 .macro dcsw_op shift, fw, ls 80 mrs x9, clidr_el1 81 ubfx x3, x9, \shift, \fw 82 lsl x3, x3, \ls 83 mov x10, xzr 84 b do_dcsw_op 85 .endm 86 87func do_dcsw_op 88 cbz x3, exit 89 adr x14, dcsw_loop_table // compute inner loop address 90 add x14, x14, x0, lsl #5 // inner loop is 8x32-bit instructions 91 mov x0, x9 92 mov w8, #1 93loop1: 94 add x2, x10, x10, lsr #1 // work out 3x current cache level 95 lsr x1, x0, x2 // extract cache type bits from clidr 96 and x1, x1, #7 // mask the bits for current cache only 97 cmp x1, #2 // see what cache we have at this level 98 b.lo level_done // nothing to do if no cache or icache 99 100 msr csselr_el1, x10 // select current cache level in csselr 101 isb // isb to sych the new cssr&csidr 102 mrs x1, ccsidr_el1 // read the new ccsidr 103 and x2, x1, #7 // extract the length of the cache lines 104 add x2, x2, #4 // add 4 (line length offset) 105 ubfx x4, x1, #3, #10 // maximum way number 106 clz w5, w4 // bit position of way size increment 107 lsl w9, w4, w5 // w9 = aligned max way number 108 lsl w16, w8, w5 // w16 = way number loop decrement 109 orr w9, w10, w9 // w9 = combine way and cache number 110 ubfx w6, w1, #13, #15 // w6 = max set number 111 lsl w17, w8, w2 // w17 = set number loop decrement 112 dsb sy // barrier before we start this level 113 br x14 // jump to DC operation specific loop 114 115 .macro dcsw_loop _op 116loop2_\_op: 117 lsl w7, w6, w2 // w7 = aligned max set number 118 119loop3_\_op: 120 orr w11, w9, w7 // combine cache, way and set number 121 dc \_op, x11 122 subs w7, w7, w17 // decrement set number 123 b.hs loop3_\_op 124 125 subs x9, x9, x16 // decrement way number 126 b.hs loop2_\_op 127 128 b level_done 129 .endm 130 131level_done: 132 add x10, x10, #2 // increment cache number 133 cmp x3, x10 134 b.hi loop1 135 msr csselr_el1, xzr // select cache level 0 in csselr 136 dsb sy // barrier to complete final cache operation 137 isb 138exit: 139 ret 140endfunc do_dcsw_op 141 142dcsw_loop_table: 143 dcsw_loop isw 144 dcsw_loop cisw 145 dcsw_loop csw 146 147 148func dcsw_op_louis 149 dcsw_op #LOUIS_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT 150endfunc dcsw_op_louis 151 152 153func dcsw_op_all 154 dcsw_op #LOC_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT 155endfunc dcsw_op_all 156 157 /* --------------------------------------------------------------- 158 * Helper macro for data cache operations by set/way for the 159 * level specified 160 * --------------------------------------------------------------- 161 */ 162 .macro dcsw_op_level level 163 mrs x9, clidr_el1 164 mov x3, \level 165 sub x10, x3, #2 166 b do_dcsw_op 167 .endm 168 169 /* --------------------------------------------------------------- 170 * Data cache operations by set/way for level 1 cache 171 * 172 * The main function, do_dcsw_op requires: 173 * x0: The operation type (0-2), as defined in arch.h 174 * --------------------------------------------------------------- 175 */ 176func dcsw_op_level1 177 dcsw_op_level #(1 << LEVEL_SHIFT) 178endfunc dcsw_op_level1 179 180 /* --------------------------------------------------------------- 181 * Data cache operations by set/way for level 2 cache 182 * 183 * The main function, do_dcsw_op requires: 184 * x0: The operation type (0-2), as defined in arch.h 185 * --------------------------------------------------------------- 186 */ 187func dcsw_op_level2 188 dcsw_op_level #(2 << LEVEL_SHIFT) 189endfunc dcsw_op_level2 190 191 /* --------------------------------------------------------------- 192 * Data cache operations by set/way for level 3 cache 193 * 194 * The main function, do_dcsw_op requires: 195 * x0: The operation type (0-2), as defined in arch.h 196 * --------------------------------------------------------------- 197 */ 198func dcsw_op_level3 199 dcsw_op_level #(3 << LEVEL_SHIFT) 200endfunc dcsw_op_level3 201