blob: fd9b33f2d5547c2ac5eac747a4e473bdcfa87ae5 [file] [log] [blame]
Soby Mathewd29f67b2016-05-05 12:31:57 +01001/*
johpow0174b7e442021-12-01 13:18:30 -06002 * Copyright (c) 2016-2021, Arm Limited and Contributors. All rights reserved.
Soby Mathewd29f67b2016-05-05 12:31:57 +01003 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Soby Mathewd29f67b2016-05-05 12:31:57 +01005 */
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
Soby Mathewf7e8aee2017-06-15 16:18:45 +010023 /* Exit early if size is zero */
24 cmp r1, #0
25 beq exit_loop_\op
Soby Mathewd29f67b2016-05-05 12:31:57 +010026 dcache_line_size r2, r3
27 add r1, r0, r1
28 sub r3, r2, #1
29 bic r0, r0, r3
30loop_\op:
31 stcopr r0, \coproc, \opc1, \CRn, \CRm, \opc2
32 add r0, r0, r2
33 cmp r0, r1
34 blo loop_\op
35 dsb sy
Soby Mathewf7e8aee2017-06-15 16:18:45 +010036exit_loop_\op:
Soby Mathewd29f67b2016-05-05 12:31:57 +010037 bx lr
38.endm
39
Okash Khawaja037b56e2022-11-04 12:38:01 +000040.macro check_plat_can_cmo
41#if CONDITIONAL_CMO
42 mov r3, lr
43 mov r2, r0
44 bl plat_can_cmo
45 mov lr, r3
46 cmp r0, #0
47 bne 1f
48 bx lr
491:
50 mov r0, r2
51#endif
52.endm
53
Soby Mathewd29f67b2016-05-05 12:31:57 +010054 /* ------------------------------------------
55 * Clean+Invalidate from base address till
56 * size. 'r0' = addr, 'r1' = size
57 * ------------------------------------------
58 */
59func flush_dcache_range
Okash Khawaja037b56e2022-11-04 12:38:01 +000060 check_plat_can_cmo
Soby Mathewd29f67b2016-05-05 12:31:57 +010061 do_dcache_maintenance_by_mva cimvac, DCCIMVAC
62endfunc flush_dcache_range
63
64 /* ------------------------------------------
65 * Clean from base address till size.
66 * 'r0' = addr, 'r1' = size
67 * ------------------------------------------
68 */
69func clean_dcache_range
Okash Khawaja037b56e2022-11-04 12:38:01 +000070 check_plat_can_cmo
Soby Mathewd29f67b2016-05-05 12:31:57 +010071 do_dcache_maintenance_by_mva cmvac, DCCMVAC
72endfunc clean_dcache_range
73
74 /* ------------------------------------------
75 * Invalidate from base address till
76 * size. 'r0' = addr, 'r1' = size
77 * ------------------------------------------
78 */
79func inv_dcache_range
Okash Khawaja037b56e2022-11-04 12:38:01 +000080 check_plat_can_cmo
Soby Mathewd29f67b2016-05-05 12:31:57 +010081 do_dcache_maintenance_by_mva imvac, DCIMVAC
82endfunc inv_dcache_range
83
84 /* ----------------------------------------------------------------
85 * Data cache operations by set/way to the level specified
86 *
87 * The main function, do_dcsw_op requires:
88 * r0: The operation type (DC_OP_ISW, DC_OP_CISW, DC_OP_CSW),
89 * as defined in arch.h
90 * r1: The cache level to begin operation from
91 * r2: clidr_el1
92 * r3: The last cache level to operate on
93 * and will carry out the operation on each data cache from level 0
94 * to the level in r3 in sequence
95 *
96 * The dcsw_op macro sets up the r2 and r3 parameters based on
97 * clidr_el1 cache information before invoking the main function
98 * ----------------------------------------------------------------
99 */
100
101 .macro dcsw_op shift, fw, ls
102 ldcopr r2, CLIDR
103 ubfx r3, r2, \shift, \fw
104 lsl r3, r3, \ls
105 mov r1, #0
106 b do_dcsw_op
107 .endm
108
109func do_dcsw_op
Joel Huttond7590972019-04-09 14:52:59 +0100110 push {r4-r12, lr}
johpow0174b7e442021-12-01 13:18:30 -0600111 ldcopr r8, ID_MMFR4 // stash FEAT_CCIDX identifier in r8
112 ubfx r8, r8, #ID_MMFR4_CCIDX_SHIFT, #ID_MMFR4_CCIDX_LENGTH
Soby Mathewd29f67b2016-05-05 12:31:57 +0100113 adr r11, dcsw_loop_table // compute cache op based on the operation type
114 add r6, r11, r0, lsl #3 // cache op is 2x32-bit instructions
115loop1:
116 add r10, r1, r1, LSR #1 // Work out 3x current cache level
117 mov r12, r2, LSR r10 // extract cache type bits from clidr
Joel Huttond7590972019-04-09 14:52:59 +0100118 and r12, r12, #7 // mask the bits for current cache only
Soby Mathewd29f67b2016-05-05 12:31:57 +0100119 cmp r12, #2 // see what cache we have at this level
Joel Huttond7590972019-04-09 14:52:59 +0100120 blo level_done // no cache or only instruction cache at this level
Soby Mathewd29f67b2016-05-05 12:31:57 +0100121
122 stcopr r1, CSSELR // select current cache level in csselr
123 isb // isb to sych the new cssr&csidr
124 ldcopr r12, CCSIDR // read the new ccsidr
Joel Huttond7590972019-04-09 14:52:59 +0100125 and r10, r12, #7 // extract the length of the cache lines
126 add r10, r10, #4 // add 4 (r10 = line length offset)
johpow0174b7e442021-12-01 13:18:30 -0600127
128 cmp r8, #0 // check for FEAT_CCIDX for Associativity
129 beq 1f
130 ubfx r4, r12, #3, #21 // r4 = associativity CCSIDR[23:3]
131 b 2f
1321:
133 ubfx r4, r12, #3, #10 // r4 = associativity CCSIDR[12:3]
1342:
Joel Huttond7590972019-04-09 14:52:59 +0100135 clz r5, r4 // r5 = the bit position of the way size increment
Soby Mathewd29f67b2016-05-05 12:31:57 +0100136 mov r9, r4 // r9 working copy of the aligned max way number
137
138loop2:
johpow0174b7e442021-12-01 13:18:30 -0600139 cmp r8, #0 // check for FEAT_CCIDX for NumSets
140 beq 3f
141 ldcopr r12, CCSIDR2 // FEAT_CCIDX numsets is in CCSIDR2
142 ubfx r7, r12, #0, #24 // r7 = numsets CCSIDR2[23:0]
143 b loop3
1443:
145 ubfx r7, r12, #13, #15 // r7 = numsets CCSIDR[27:13]
Soby Mathewd29f67b2016-05-05 12:31:57 +0100146loop3:
147 orr r0, r1, r9, LSL r5 // factor in the way number and cache level into r0
148 orr r0, r0, r7, LSL r10 // factor in the set number
149
150 blx r6
Joel Huttond7590972019-04-09 14:52:59 +0100151 subs r7, r7, #1 // decrement the set number
Douglas Raillard9d92e8c2017-03-07 16:36:14 +0000152 bhs loop3
Joel Huttond7590972019-04-09 14:52:59 +0100153 subs r9, r9, #1 // decrement the way number
Douglas Raillard9d92e8c2017-03-07 16:36:14 +0000154 bhs loop2
Soby Mathewd29f67b2016-05-05 12:31:57 +0100155level_done:
156 add r1, r1, #2 // increment the cache number
157 cmp r3, r1
Joel Hutton50ed13a2019-04-09 14:45:34 +0100158 // Ensure completion of previous cache maintenance instruction. Note
159 // this also mitigates erratum 814220 on Cortex-A7
160 dsb sy
Douglas Raillard9d92e8c2017-03-07 16:36:14 +0000161 bhi loop1
Soby Mathewd29f67b2016-05-05 12:31:57 +0100162
163 mov r6, #0
164 stcopr r6, CSSELR //select cache level 0 in csselr
165 dsb sy
166 isb
Joel Huttond7590972019-04-09 14:52:59 +0100167 pop {r4-r12, pc}
Soby Mathewd29f67b2016-05-05 12:31:57 +0100168
169dcsw_loop_table:
170 stcopr r0, DCISW
171 bx lr
172 stcopr r0, DCCISW
173 bx lr
174 stcopr r0, DCCSW
175 bx lr
176
177endfunc do_dcsw_op
178
179 /* ---------------------------------------------------------------
180 * Data cache operations by set/way till PoU.
181 *
182 * The function 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_louis
Okash Khawaja037b56e2022-11-04 12:38:01 +0000188 check_plat_can_cmo
Soby Mathewd29f67b2016-05-05 12:31:57 +0100189 dcsw_op #LOUIS_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT
190endfunc dcsw_op_louis
191
192 /* ---------------------------------------------------------------
193 * Data cache operations by set/way till PoC.
194 *
195 * The function requires :
196 * r0: The operation type (DC_OP_ISW, DC_OP_CISW, DC_OP_CSW),
197 * as defined in arch.h
198 * ---------------------------------------------------------------
199 */
200func dcsw_op_all
Okash Khawaja037b56e2022-11-04 12:38:01 +0000201 check_plat_can_cmo
Soby Mathewd29f67b2016-05-05 12:31:57 +0100202 dcsw_op #LOC_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT
203endfunc dcsw_op_all
204
205
206 /* ---------------------------------------------------------------
207 * Helper macro for data cache operations by set/way for the
208 * level specified
209 * ---------------------------------------------------------------
210 */
211 .macro dcsw_op_level level
212 ldcopr r2, CLIDR
213 mov r3, \level
214 sub r1, r3, #2
215 b do_dcsw_op
216 .endm
217
218 /* ---------------------------------------------------------------
219 * Data cache operations by set/way for level 1 cache
220 *
221 * The main function, do_dcsw_op requires:
222 * r0: The operation type (DC_OP_ISW, DC_OP_CISW, DC_OP_CSW),
223 * as defined in arch.h
224 * ---------------------------------------------------------------
225 */
226func dcsw_op_level1
Okash Khawaja037b56e2022-11-04 12:38:01 +0000227 check_plat_can_cmo
Soby Mathewd29f67b2016-05-05 12:31:57 +0100228 dcsw_op_level #(1 << LEVEL_SHIFT)
229endfunc dcsw_op_level1
230
231 /* ---------------------------------------------------------------
232 * Data cache operations by set/way for level 2 cache
233 *
234 * The main function, do_dcsw_op requires:
235 * r0: The operation type (DC_OP_ISW, DC_OP_CISW, DC_OP_CSW),
236 * as defined in arch.h
237 * ---------------------------------------------------------------
238 */
239func dcsw_op_level2
Okash Khawaja037b56e2022-11-04 12:38:01 +0000240 check_plat_can_cmo
Soby Mathewd29f67b2016-05-05 12:31:57 +0100241 dcsw_op_level #(2 << LEVEL_SHIFT)
242endfunc dcsw_op_level2
243
244 /* ---------------------------------------------------------------
245 * Data cache operations by set/way for level 3 cache
246 *
247 * The main function, do_dcsw_op requires:
248 * r0: The operation type (DC_OP_ISW, DC_OP_CISW, DC_OP_CSW),
249 * as defined in arch.h
250 * ---------------------------------------------------------------
251 */
252func dcsw_op_level3
Okash Khawaja037b56e2022-11-04 12:38:01 +0000253 check_plat_can_cmo
Soby Mathewd29f67b2016-05-05 12:31:57 +0100254 dcsw_op_level #(3 << LEVEL_SHIFT)
255endfunc dcsw_op_level3