1/* 2 * Copyright (c) 2016, 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, coproc, opc1, CRn, CRm, opc2 23 dcache_line_size r2, r3 24 add r1, r0, r1 25 sub r3, r2, #1 26 bic r0, r0, r3 27loop_\op: 28 stcopr r0, \coproc, \opc1, \CRn, \CRm, \opc2 29 add r0, r0, r2 30 cmp r0, r1 31 blo loop_\op 32 dsb sy 33 bx lr 34.endm 35 36 /* ------------------------------------------ 37 * Clean+Invalidate from base address till 38 * size. 'r0' = addr, 'r1' = size 39 * ------------------------------------------ 40 */ 41func flush_dcache_range 42 do_dcache_maintenance_by_mva cimvac, DCCIMVAC 43endfunc flush_dcache_range 44 45 /* ------------------------------------------ 46 * Clean from base address till size. 47 * 'r0' = addr, 'r1' = size 48 * ------------------------------------------ 49 */ 50func clean_dcache_range 51 do_dcache_maintenance_by_mva cmvac, DCCMVAC 52endfunc clean_dcache_range 53 54 /* ------------------------------------------ 55 * Invalidate from base address till 56 * size. 'r0' = addr, 'r1' = size 57 * ------------------------------------------ 58 */ 59func inv_dcache_range 60 do_dcache_maintenance_by_mva imvac, DCIMVAC 61endfunc inv_dcache_range 62 63 /* ---------------------------------------------------------------- 64 * Data cache operations by set/way to the level specified 65 * 66 * The main function, do_dcsw_op requires: 67 * r0: The operation type (DC_OP_ISW, DC_OP_CISW, DC_OP_CSW), 68 * as defined in arch.h 69 * r1: The cache level to begin operation from 70 * r2: clidr_el1 71 * r3: The last cache level to operate on 72 * and will carry out the operation on each data cache from level 0 73 * to the level in r3 in sequence 74 * 75 * The dcsw_op macro sets up the r2 and r3 parameters based on 76 * clidr_el1 cache information before invoking the main function 77 * ---------------------------------------------------------------- 78 */ 79 80 .macro dcsw_op shift, fw, ls 81 ldcopr r2, CLIDR 82 ubfx r3, r2, \shift, \fw 83 lsl r3, r3, \ls 84 mov r1, #0 85 b do_dcsw_op 86 .endm 87 88func do_dcsw_op 89 push {r4-r12,lr} 90 adr r11, dcsw_loop_table // compute cache op based on the operation type 91 add r6, r11, r0, lsl #3 // cache op is 2x32-bit instructions 92loop1: 93 add r10, r1, r1, LSR #1 // Work out 3x current cache level 94 mov r12, r2, LSR r10 // extract cache type bits from clidr 95 and r12, r12, #7 // mask the bits for current cache only 96 cmp r12, #2 // see what cache we have at this level 97 blo level_done // no cache or only instruction cache at this level 98 99 stcopr r1, CSSELR // select current cache level in csselr 100 isb // isb to sych the new cssr&csidr 101 ldcopr r12, CCSIDR // read the new ccsidr 102 and r10, r12, #7 // extract the length of the cache lines 103 add r10, r10, #4 // add 4 (r10 = line length offset) 104 ubfx r4, r12, #3, #10 // r4 = maximum way number (right aligned) 105 clz r5, r4 // r5 = the bit position of the way size increment 106 mov r9, r4 // r9 working copy of the aligned max way number 107 108loop2: 109 ubfx r7, r12, #13, #15 // r7 = max set number (right aligned) 110 111loop3: 112 orr r0, r1, r9, LSL r5 // factor in the way number and cache level into r0 113 orr r0, r0, r7, LSL r10 // factor in the set number 114 115 blx r6 116 subs r7, r7, #1 // decrement the set number 117 bhs loop3 118 subs r9, r9, #1 // decrement the way number 119 bhs loop2 120level_done: 121 add r1, r1, #2 // increment the cache number 122 cmp r3, r1 123 dsb sy // ensure completion of previous cache maintenance instruction 124 bhi loop1 125 126 mov r6, #0 127 stcopr r6, CSSELR //select cache level 0 in csselr 128 dsb sy 129 isb 130 pop {r4-r12,pc} 131 132dcsw_loop_table: 133 stcopr r0, DCISW 134 bx lr 135 stcopr r0, DCCISW 136 bx lr 137 stcopr r0, DCCSW 138 bx lr 139 140endfunc do_dcsw_op 141 142 /* --------------------------------------------------------------- 143 * Data cache operations by set/way till PoU. 144 * 145 * The function requires : 146 * r0: The operation type (DC_OP_ISW, DC_OP_CISW, DC_OP_CSW), 147 * as defined in arch.h 148 * --------------------------------------------------------------- 149 */ 150func dcsw_op_louis 151 dcsw_op #LOUIS_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT 152endfunc dcsw_op_louis 153 154 /* --------------------------------------------------------------- 155 * Data cache operations by set/way till PoC. 156 * 157 * The function requires : 158 * r0: The operation type (DC_OP_ISW, DC_OP_CISW, DC_OP_CSW), 159 * as defined in arch.h 160 * --------------------------------------------------------------- 161 */ 162func dcsw_op_all 163 dcsw_op #LOC_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT 164endfunc dcsw_op_all 165 166 167 /* --------------------------------------------------------------- 168 * Helper macro for data cache operations by set/way for the 169 * level specified 170 * --------------------------------------------------------------- 171 */ 172 .macro dcsw_op_level level 173 ldcopr r2, CLIDR 174 mov r3, \level 175 sub r1, r3, #2 176 b do_dcsw_op 177 .endm 178 179 /* --------------------------------------------------------------- 180 * Data cache operations by set/way for level 1 cache 181 * 182 * The main function, do_dcsw_op requires: 183 * r0: The operation type (DC_OP_ISW, DC_OP_CISW, DC_OP_CSW), 184 * as defined in arch.h 185 * --------------------------------------------------------------- 186 */ 187func dcsw_op_level1 188 dcsw_op_level #(1 << LEVEL_SHIFT) 189endfunc dcsw_op_level1 190 191 /* --------------------------------------------------------------- 192 * Data cache operations by set/way for level 2 cache 193 * 194 * The main function, do_dcsw_op requires: 195 * r0: The operation type (DC_OP_ISW, DC_OP_CISW, DC_OP_CSW), 196 * as defined in arch.h 197 * --------------------------------------------------------------- 198 */ 199func dcsw_op_level2 200 dcsw_op_level #(2 << LEVEL_SHIFT) 201endfunc dcsw_op_level2 202 203 /* --------------------------------------------------------------- 204 * Data cache operations by set/way for level 3 cache 205 * 206 * The main function, do_dcsw_op requires: 207 * r0: The operation type (DC_OP_ISW, DC_OP_CISW, DC_OP_CSW), 208 * as defined in arch.h 209 * --------------------------------------------------------------- 210 */ 211func dcsw_op_level3 212 dcsw_op_level #(3 << LEVEL_SHIFT) 213endfunc dcsw_op_level3 214