blob: 6faf545a142dbc29a542f4f24a58da8d07743cea [file] [log] [blame]
Achin Gupta4f6ad662013-10-25 09:08:21 +01001/*
Robert Wakim48e6b572021-10-21 15:39:56 +01002 * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
Achin Gupta4f6ad662013-10-25 09:08:21 +01003 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Achin Gupta4f6ad662013-10-25 09:08:21 +01005 */
6
Dan Handley2bd4ef22014-04-09 13:14:54 +01007#include <arch.h>
Achin Gupta4f6ad662013-10-25 09:08:21 +01008#include <asm_macros.S>
9
Achin Gupta4f6ad662013-10-25 09:08:21 +010010 .globl flush_dcache_range
Robert Wakim48e6b572021-10-21 15:39:56 +010011 .globl flush_dcache_to_popa_range
Achin Guptae9c4a642015-09-11 16:03:13 +010012 .globl clean_dcache_range
Achin Gupta4f6ad662013-10-25 09:08:21 +010013 .globl inv_dcache_range
14 .globl dcsw_op_louis
15 .globl dcsw_op_all
Soby Mathew42aa5eb2014-09-02 10:47:33 +010016 .globl dcsw_op_level1
17 .globl dcsw_op_level2
18 .globl dcsw_op_level3
Achin Gupta4f6ad662013-10-25 09:08:21 +010019
Achin Guptae9c4a642015-09-11 16:03:13 +010020/*
21 * This macro can be used for implementing various data cache operations `op`
22 */
23.macro do_dcache_maintenance_by_mva op
Soby Mathewf7e8aee2017-06-15 16:18:45 +010024 /* Exit early if size is zero */
25 cbz x1, exit_loop_\op
Achin Gupta4f6ad662013-10-25 09:08:21 +010026 dcache_line_size x2, x3
27 add x1, x0, x1
28 sub x3, x2, #1
29 bic x0, x0, x3
Achin Guptae9c4a642015-09-11 16:03:13 +010030loop_\op:
31 dc \op, x0
Achin Gupta4f6ad662013-10-25 09:08:21 +010032 add x0, x0, x2
33 cmp x0, x1
Petre-Ionut Tudore5a6fef2019-11-07 15:18:03 +000034 b.lo loop_\op
Achin Gupta4f6ad662013-10-25 09:08:21 +010035 dsb sy
Soby Mathewf7e8aee2017-06-15 16:18:45 +010036exit_loop_\op:
Achin Gupta4f6ad662013-10-25 09:08:21 +010037 ret
Achin Guptae9c4a642015-09-11 16:03:13 +010038.endm
39 /* ------------------------------------------
40 * Clean+Invalidate from base address till
41 * size. 'x0' = addr, 'x1' = size
42 * ------------------------------------------
43 */
44func flush_dcache_range
45 do_dcache_maintenance_by_mva civac
Kévin Petita877c252015-03-24 14:03:57 +000046endfunc flush_dcache_range
Achin Gupta4f6ad662013-10-25 09:08:21 +010047
Achin Guptae9c4a642015-09-11 16:03:13 +010048 /* ------------------------------------------
49 * Clean from base address till size.
50 * 'x0' = addr, 'x1' = size
51 * ------------------------------------------
52 */
53func clean_dcache_range
54 do_dcache_maintenance_by_mva cvac
55endfunc clean_dcache_range
Achin Gupta4f6ad662013-10-25 09:08:21 +010056
57 /* ------------------------------------------
58 * Invalidate from base address till
59 * size. 'x0' = addr, 'x1' = size
60 * ------------------------------------------
61 */
Andrew Thoelke38bde412014-03-18 13:46:55 +000062func inv_dcache_range
Achin Guptae9c4a642015-09-11 16:03:13 +010063 do_dcache_maintenance_by_mva ivac
Kévin Petita877c252015-03-24 14:03:57 +000064endfunc inv_dcache_range
Achin Gupta4f6ad662013-10-25 09:08:21 +010065
66
Robert Wakim48e6b572021-10-21 15:39:56 +010067 /*
68 * On implementations with FEAT_MTE2,
69 * Root firmware must issue DC_CIGDPAPA instead of DC_CIPAPA ,
70 * in order to additionally clean and invalidate Allocation Tags
71 * associated with the affected locations.
72 *
73 * ------------------------------------------
74 * Clean+Invalidate by PA to POPA
75 * from base address till size.
76 * 'x0' = addr, 'x1' = size
77 * ------------------------------------------
78 */
79func flush_dcache_to_popa_range
80 /* Exit early if size is zero */
81 cbz x1, exit_loop_dc_cipapa
82 dcache_line_size x2, x3
83 sub x3, x2, #1
84 bic x0, x0, x3
85 add x1, x1, x0
86loop_dc_cipapa:
87 sys #6, c7, c14, #1, x0 /* DC CIPAPA,<Xt> */
88 add x0, x0, x2
89 cmp x0, x1
90 b.lo loop_dc_cipapa
91 dsb osh
92exit_loop_dc_cipapa:
93 ret
94endfunc flush_dcache_to_popa_range
95
Andrew Thoelke6a5b3a42014-04-25 10:49:30 +010096 /* ---------------------------------------------------------------
97 * Data cache operations by set/way to the level specified
98 *
99 * The main function, do_dcsw_op requires:
100 * x0: The operation type (0-2), as defined in arch.h
101 * x3: The last cache level to operate on
102 * x9: clidr_el1
Soby Mathew42aa5eb2014-09-02 10:47:33 +0100103 * x10: The cache level to begin operation from
Andrew Thoelke6a5b3a42014-04-25 10:49:30 +0100104 * and will carry out the operation on each data cache from level 0
105 * to the level in x3 in sequence
106 *
107 * The dcsw_op macro sets up the x3 and x9 parameters based on
108 * clidr_el1 cache information before invoking the main function
109 * ---------------------------------------------------------------
Achin Gupta4f6ad662013-10-25 09:08:21 +0100110 */
Achin Gupta4f6ad662013-10-25 09:08:21 +0100111
Andrew Thoelke6a5b3a42014-04-25 10:49:30 +0100112 .macro dcsw_op shift, fw, ls
113 mrs x9, clidr_el1
114 ubfx x3, x9, \shift, \fw
115 lsl x3, x3, \ls
Soby Mathew42aa5eb2014-09-02 10:47:33 +0100116 mov x10, xzr
Andrew Thoelke6a5b3a42014-04-25 10:49:30 +0100117 b do_dcsw_op
118 .endm
Achin Gupta4f6ad662013-10-25 09:08:21 +0100119
Andrew Thoelke38bde412014-03-18 13:46:55 +0000120func do_dcsw_op
Achin Gupta4f6ad662013-10-25 09:08:21 +0100121 cbz x3, exit
johpow0174b7e442021-12-01 13:18:30 -0600122 mrs x12, ID_AA64MMFR2_EL1 // stash FEAT_CCIDX identifier in x12
123 ubfx x12, x12, #ID_AA64MMFR2_EL1_CCIDX_SHIFT, #ID_AA64MMFR2_EL1_CCIDX_LENGTH
Andrew Thoelke6a5b3a42014-04-25 10:49:30 +0100124 adr x14, dcsw_loop_table // compute inner loop address
125 add x14, x14, x0, lsl #5 // inner loop is 8x32-bit instructions
Alexei Fedorov90f2e882019-05-24 12:17:09 +0100126#if ENABLE_BTI
127 add x14, x14, x0, lsl #2 // inner loop is + "bti j" instruction
128#endif
Achin Gupta4f6ad662013-10-25 09:08:21 +0100129 mov x0, x9
Andrew Thoelke6a5b3a42014-04-25 10:49:30 +0100130 mov w8, #1
131loop1:
132 add x2, x10, x10, lsr #1 // work out 3x current cache level
133 lsr x1, x0, x2 // extract cache type bits from clidr
134 and x1, x1, #7 // mask the bits for current cache only
135 cmp x1, #2 // see what cache we have at this level
Douglas Raillard9d92e8c2017-03-07 16:36:14 +0000136 b.lo level_done // nothing to do if no cache or icache
Andrew Thoelke6a5b3a42014-04-25 10:49:30 +0100137
138 msr csselr_el1, x10 // select current cache level in csselr
139 isb // isb to sych the new cssr&csidr
140 mrs x1, ccsidr_el1 // read the new ccsidr
141 and x2, x1, #7 // extract the length of the cache lines
142 add x2, x2, #4 // add 4 (line length offset)
johpow0174b7e442021-12-01 13:18:30 -0600143
144 cbz x12, 1f // check for FEAT_CCIDX for Associativity
145 ubfx x4, x1, #3, #21 // x4 = associativity CCSIDR_EL1[23:3]
146 b 2f
1471:
148 ubfx x4, x1, #3, #10 // x4 = associativity CCSIDR_EL1[12:3]
1492:
Andrew Thoelke6a5b3a42014-04-25 10:49:30 +0100150 clz w5, w4 // bit position of way size increment
151 lsl w9, w4, w5 // w9 = aligned max way number
152 lsl w16, w8, w5 // w16 = way number loop decrement
153 orr w9, w10, w9 // w9 = combine way and cache number
johpow0174b7e442021-12-01 13:18:30 -0600154
155 cbz x12, 3f // check for FEAT_CCIDX for NumSets
156 ubfx x6, x1, #32, #24 // x6 (w6) = numsets CCSIDR_EL1[55:32]
157 // ISA will not allow x->w ubfx
158 b 4f
1593:
160 ubfx w6, w1, #13, #15 // w6 = numsets CCSIDR_EL1[27:13]
1614:
Andrew Thoelke6a5b3a42014-04-25 10:49:30 +0100162 lsl w17, w8, w2 // w17 = set number loop decrement
163 dsb sy // barrier before we start this level
164 br x14 // jump to DC operation specific loop
165
166 .macro dcsw_loop _op
Alexei Fedorov90f2e882019-05-24 12:17:09 +0100167#if ENABLE_BTI
168 bti j
169#endif
Andrew Thoelke6a5b3a42014-04-25 10:49:30 +0100170loop2_\_op:
171 lsl w7, w6, w2 // w7 = aligned max set number
172
173loop3_\_op:
174 orr w11, w9, w7 // combine cache, way and set number
175 dc \_op, x11
176 subs w7, w7, w17 // decrement set number
Douglas Raillard9d92e8c2017-03-07 16:36:14 +0000177 b.hs loop3_\_op
Andrew Thoelke6a5b3a42014-04-25 10:49:30 +0100178
179 subs x9, x9, x16 // decrement way number
Douglas Raillard9d92e8c2017-03-07 16:36:14 +0000180 b.hs loop2_\_op
Andrew Thoelke6a5b3a42014-04-25 10:49:30 +0100181
182 b level_done
183 .endm
184
185level_done:
186 add x10, x10, #2 // increment cache number
187 cmp x3, x10
Petre-Ionut Tudore5a6fef2019-11-07 15:18:03 +0000188 b.hi loop1
Andrew Thoelke6a5b3a42014-04-25 10:49:30 +0100189 msr csselr_el1, xzr // select cache level 0 in csselr
190 dsb sy // barrier to complete final cache operation
191 isb
Achin Gupta4f6ad662013-10-25 09:08:21 +0100192exit:
193 ret
Kévin Petita877c252015-03-24 14:03:57 +0000194endfunc do_dcsw_op
Achin Gupta4f6ad662013-10-25 09:08:21 +0100195
Andrew Thoelke6a5b3a42014-04-25 10:49:30 +0100196dcsw_loop_table:
197 dcsw_loop isw
198 dcsw_loop cisw
199 dcsw_loop csw
200
Achin Gupta4f6ad662013-10-25 09:08:21 +0100201
Andrew Thoelke38bde412014-03-18 13:46:55 +0000202func dcsw_op_louis
Andrew Thoelke6a5b3a42014-04-25 10:49:30 +0100203 dcsw_op #LOUIS_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT
Kévin Petita877c252015-03-24 14:03:57 +0000204endfunc dcsw_op_louis
Achin Gupta4f6ad662013-10-25 09:08:21 +0100205
206
Andrew Thoelke38bde412014-03-18 13:46:55 +0000207func dcsw_op_all
Andrew Thoelke6a5b3a42014-04-25 10:49:30 +0100208 dcsw_op #LOC_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT
Kévin Petita877c252015-03-24 14:03:57 +0000209endfunc dcsw_op_all
Soby Mathew42aa5eb2014-09-02 10:47:33 +0100210
211 /* ---------------------------------------------------------------
212 * Helper macro for data cache operations by set/way for the
213 * level specified
214 * ---------------------------------------------------------------
215 */
216 .macro dcsw_op_level level
217 mrs x9, clidr_el1
218 mov x3, \level
219 sub x10, x3, #2
220 b do_dcsw_op
221 .endm
222
223 /* ---------------------------------------------------------------
224 * Data cache operations by set/way for level 1 cache
225 *
226 * The main function, do_dcsw_op requires:
227 * x0: The operation type (0-2), as defined in arch.h
228 * ---------------------------------------------------------------
229 */
230func dcsw_op_level1
231 dcsw_op_level #(1 << LEVEL_SHIFT)
Kévin Petita877c252015-03-24 14:03:57 +0000232endfunc dcsw_op_level1
Soby Mathew42aa5eb2014-09-02 10:47:33 +0100233
234 /* ---------------------------------------------------------------
235 * Data cache operations by set/way for level 2 cache
236 *
237 * The main function, do_dcsw_op requires:
238 * x0: The operation type (0-2), as defined in arch.h
239 * ---------------------------------------------------------------
240 */
241func dcsw_op_level2
242 dcsw_op_level #(2 << LEVEL_SHIFT)
Kévin Petita877c252015-03-24 14:03:57 +0000243endfunc dcsw_op_level2
Soby Mathew42aa5eb2014-09-02 10:47:33 +0100244
245 /* ---------------------------------------------------------------
246 * Data cache operations by set/way for level 3 cache
247 *
248 * The main function, do_dcsw_op requires:
249 * x0: The operation type (0-2), as defined in arch.h
250 * ---------------------------------------------------------------
251 */
252func dcsw_op_level3
253 dcsw_op_level #(3 << LEVEL_SHIFT)
Kévin Petita877c252015-03-24 14:03:57 +0000254endfunc dcsw_op_level3