xref: /rk3399_ARM-atf/lib/aarch64/cache_helpers.S (revision 5f6032a8206bb88655367f96cc1270525bed9e48)
14ecca339SDan Handley/*
24ecca339SDan Handley * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
34ecca339SDan Handley *
44ecca339SDan Handley * Redistribution and use in source and binary forms, with or without
54ecca339SDan Handley * modification, are permitted provided that the following conditions are met:
64ecca339SDan Handley *
74ecca339SDan Handley * Redistributions of source code must retain the above copyright notice, this
84ecca339SDan Handley * list of conditions and the following disclaimer.
94ecca339SDan Handley *
104ecca339SDan Handley * Redistributions in binary form must reproduce the above copyright notice,
114ecca339SDan Handley * this list of conditions and the following disclaimer in the documentation
124ecca339SDan Handley * and/or other materials provided with the distribution.
134ecca339SDan Handley *
144ecca339SDan Handley * Neither the name of ARM nor the names of its contributors may be used
154ecca339SDan Handley * to endorse or promote products derived from this software without specific
164ecca339SDan Handley * prior written permission.
174ecca339SDan Handley *
184ecca339SDan Handley * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
194ecca339SDan Handley * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
204ecca339SDan Handley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
214ecca339SDan Handley * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
224ecca339SDan Handley * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
234ecca339SDan Handley * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
244ecca339SDan Handley * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
254ecca339SDan Handley * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
264ecca339SDan Handley * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
274ecca339SDan Handley * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
284ecca339SDan Handley * POSSIBILITY OF SUCH DAMAGE.
294ecca339SDan Handley */
304ecca339SDan Handley
3197043ac9SDan Handley#include <arch.h>
324ecca339SDan Handley#include <asm_macros.S>
334ecca339SDan Handley
344ecca339SDan Handley	.globl	dcisw
354ecca339SDan Handley	.globl	dccisw
364ecca339SDan Handley	.globl	dccsw
374ecca339SDan Handley	.globl	dccvac
384ecca339SDan Handley	.globl	dcivac
394ecca339SDan Handley	.globl	dccivac
404ecca339SDan Handley	.globl	dccvau
414ecca339SDan Handley	.globl	dczva
424ecca339SDan Handley	.globl	flush_dcache_range
434ecca339SDan Handley	.globl	inv_dcache_range
444ecca339SDan Handley	.globl	dcsw_op_louis
454ecca339SDan Handley	.globl	dcsw_op_all
464ecca339SDan Handley
474ecca339SDan Handleyfunc dcisw
484ecca339SDan Handley	dc	isw, x0
494ecca339SDan Handley	dsb	sy
504ecca339SDan Handley	isb
514ecca339SDan Handley	ret
524ecca339SDan Handley
534ecca339SDan Handley
544ecca339SDan Handleyfunc dccisw
554ecca339SDan Handley	dc	cisw, x0
564ecca339SDan Handley	dsb	sy
574ecca339SDan Handley	isb
584ecca339SDan Handley	ret
594ecca339SDan Handley
604ecca339SDan Handley
614ecca339SDan Handleyfunc dccsw
624ecca339SDan Handley	dc	csw, x0
634ecca339SDan Handley	dsb	sy
644ecca339SDan Handley	isb
654ecca339SDan Handley	ret
664ecca339SDan Handley
674ecca339SDan Handley
684ecca339SDan Handleyfunc dccvac
694ecca339SDan Handley	dc	cvac, x0
704ecca339SDan Handley	dsb	sy
714ecca339SDan Handley	isb
724ecca339SDan Handley	ret
734ecca339SDan Handley
744ecca339SDan Handley
754ecca339SDan Handleyfunc dcivac
764ecca339SDan Handley	dc	ivac, x0
774ecca339SDan Handley	dsb	sy
784ecca339SDan Handley	isb
794ecca339SDan Handley	ret
804ecca339SDan Handley
814ecca339SDan Handley
824ecca339SDan Handleyfunc dccivac
834ecca339SDan Handley	dc	civac, x0
844ecca339SDan Handley	dsb	sy
854ecca339SDan Handley	isb
864ecca339SDan Handley	ret
874ecca339SDan Handley
884ecca339SDan Handley
894ecca339SDan Handleyfunc dccvau
904ecca339SDan Handley	dc	cvau, x0
914ecca339SDan Handley	dsb	sy
924ecca339SDan Handley	isb
934ecca339SDan Handley	ret
944ecca339SDan Handley
954ecca339SDan Handley
964ecca339SDan Handleyfunc dczva
974ecca339SDan Handley	dc	zva, x0
984ecca339SDan Handley	dsb	sy
994ecca339SDan Handley	isb
1004ecca339SDan Handley	ret
1014ecca339SDan Handley
1024ecca339SDan Handley
1034ecca339SDan Handley	/* ------------------------------------------
1044ecca339SDan Handley	 * Clean+Invalidate from base address till
1054ecca339SDan Handley	 * size. 'x0' = addr, 'x1' = size
1064ecca339SDan Handley	 * ------------------------------------------
1074ecca339SDan Handley	 */
1084ecca339SDan Handleyfunc flush_dcache_range
1094ecca339SDan Handley	dcache_line_size x2, x3
1104ecca339SDan Handley	add	x1, x0, x1
1114ecca339SDan Handley	sub	x3, x2, #1
1124ecca339SDan Handley	bic	x0, x0, x3
1134ecca339SDan Handleyflush_loop:
1144ecca339SDan Handley	dc	civac, x0
1154ecca339SDan Handley	add	x0, x0, x2
1164ecca339SDan Handley	cmp	x0, x1
1174ecca339SDan Handley	b.lo    flush_loop
1184ecca339SDan Handley	dsb	sy
1194ecca339SDan Handley	ret
1204ecca339SDan Handley
1214ecca339SDan Handley
1224ecca339SDan Handley	/* ------------------------------------------
1234ecca339SDan Handley	 * Invalidate from base address till
1244ecca339SDan Handley	 * size. 'x0' = addr, 'x1' = size
1254ecca339SDan Handley	 * ------------------------------------------
1264ecca339SDan Handley	 */
1274ecca339SDan Handleyfunc inv_dcache_range
1284ecca339SDan Handley	dcache_line_size x2, x3
1294ecca339SDan Handley	add	x1, x0, x1
1304ecca339SDan Handley	sub	x3, x2, #1
1314ecca339SDan Handley	bic	x0, x0, x3
1324ecca339SDan Handleyinv_loop:
1334ecca339SDan Handley	dc	ivac, x0
1344ecca339SDan Handley	add	x0, x0, x2
1354ecca339SDan Handley	cmp	x0, x1
1364ecca339SDan Handley	b.lo    inv_loop
1374ecca339SDan Handley	dsb	sy
1384ecca339SDan Handley	ret
1394ecca339SDan Handley
1404ecca339SDan Handley
141*5f6032a8SAndrew Thoelke	/* ---------------------------------------------------------------
142*5f6032a8SAndrew Thoelke	 * Data cache operations by set/way to the level specified
143*5f6032a8SAndrew Thoelke	 *
144*5f6032a8SAndrew Thoelke	 * The main function, do_dcsw_op requires:
145*5f6032a8SAndrew Thoelke	 * x0: The operation type (0-2), as defined in arch.h
146*5f6032a8SAndrew Thoelke	 * x3: The last cache level to operate on
147*5f6032a8SAndrew Thoelke	 * x9: clidr_el1
148*5f6032a8SAndrew Thoelke	 * and will carry out the operation on each data cache from level 0
149*5f6032a8SAndrew Thoelke	 * to the level in x3 in sequence
150*5f6032a8SAndrew Thoelke	 *
151*5f6032a8SAndrew Thoelke	 * The dcsw_op macro sets up the x3 and x9 parameters based on
152*5f6032a8SAndrew Thoelke	 * clidr_el1 cache information before invoking the main function
153*5f6032a8SAndrew Thoelke	 * ---------------------------------------------------------------
1544ecca339SDan Handley	 */
155*5f6032a8SAndrew Thoelke
156*5f6032a8SAndrew Thoelke	.macro	dcsw_op shift, fw, ls
157*5f6032a8SAndrew Thoelke	mrs	x9, clidr_el1
158*5f6032a8SAndrew Thoelke	ubfx	x3, x9, \shift, \fw
159*5f6032a8SAndrew Thoelke	lsl	x3, x3, \ls
160*5f6032a8SAndrew Thoelke	b	do_dcsw_op
161*5f6032a8SAndrew Thoelke	.endm
162*5f6032a8SAndrew Thoelke
163*5f6032a8SAndrew Thoelkefunc do_dcsw_op
164*5f6032a8SAndrew Thoelke	cbz	x3, exit
165*5f6032a8SAndrew Thoelke	mov	x10, xzr
166*5f6032a8SAndrew Thoelke	adr	x14, dcsw_loop_table	// compute inner loop address
167*5f6032a8SAndrew Thoelke	add	x14, x14, x0, lsl #5	// inner loop is 8x32-bit instructions
168*5f6032a8SAndrew Thoelke	mov	x0, x9
169*5f6032a8SAndrew Thoelke	mov	w8, #1
170*5f6032a8SAndrew Thoelkeloop1:
1714ecca339SDan Handley	add	x2, x10, x10, lsr #1	// work out 3x current cache level
1724ecca339SDan Handley	lsr	x1, x0, x2		// extract cache type bits from clidr
173*5f6032a8SAndrew Thoelke	and	x1, x1, #7		// mask the bits for current cache only
1744ecca339SDan Handley	cmp	x1, #2			// see what cache we have at this level
175*5f6032a8SAndrew Thoelke	b.lt	level_done		// nothing to do if no cache or icache
176*5f6032a8SAndrew Thoelke
1774ecca339SDan Handley	msr	csselr_el1, x10		// select current cache level in csselr
1784ecca339SDan Handley	isb				// isb to sych the new cssr&csidr
1794ecca339SDan Handley	mrs	x1, ccsidr_el1		// read the new ccsidr
1804ecca339SDan Handley	and	x2, x1, #7		// extract the length of the cache lines
1814ecca339SDan Handley	add	x2, x2, #4		// add 4 (line length offset)
182*5f6032a8SAndrew Thoelke	ubfx	x4, x1, #3, #10		// maximum way number
183*5f6032a8SAndrew Thoelke	clz	w5, w4			// bit position of way size increment
184*5f6032a8SAndrew Thoelke	lsl	w9, w4, w5		// w9 = aligned max way number
185*5f6032a8SAndrew Thoelke	lsl	w16, w8, w5		// w16 = way number loop decrement
186*5f6032a8SAndrew Thoelke	orr	w9, w10, w9		// w9 = combine way and cache number
187*5f6032a8SAndrew Thoelke	ubfx	w6, w1, #13, #15	// w6 = max set number
188*5f6032a8SAndrew Thoelke	lsl	w17, w8, w2		// w17 = set number loop decrement
189*5f6032a8SAndrew Thoelke	dsb	sy			// barrier before we start this level
190*5f6032a8SAndrew Thoelke	br	x14			// jump to DC operation specific loop
191*5f6032a8SAndrew Thoelke
192*5f6032a8SAndrew Thoelke	.macro	dcsw_loop _op
193*5f6032a8SAndrew Thoelkeloop2_\_op:
194*5f6032a8SAndrew Thoelke	lsl	w7, w6, w2		// w7 = aligned max set number
195*5f6032a8SAndrew Thoelke
196*5f6032a8SAndrew Thoelkeloop3_\_op:
197*5f6032a8SAndrew Thoelke	orr	w11, w9, w7		// combine cache, way and set number
198*5f6032a8SAndrew Thoelke	dc	\_op, x11
199*5f6032a8SAndrew Thoelke	subs	w7, w7, w17		// decrement set number
200*5f6032a8SAndrew Thoelke	b.ge	loop3_\_op
201*5f6032a8SAndrew Thoelke
202*5f6032a8SAndrew Thoelke	subs	x9, x9, x16		// decrement way number
203*5f6032a8SAndrew Thoelke	b.ge	loop2_\_op
204*5f6032a8SAndrew Thoelke
205*5f6032a8SAndrew Thoelke	b	level_done
206*5f6032a8SAndrew Thoelke	.endm
207*5f6032a8SAndrew Thoelke
208*5f6032a8SAndrew Thoelkelevel_done:
2094ecca339SDan Handley	add	x10, x10, #2		// increment cache number
2104ecca339SDan Handley	cmp	x3, x10
211*5f6032a8SAndrew Thoelke	b.gt    loop1
212*5f6032a8SAndrew Thoelke	msr	csselr_el1, xzr		// select cache level 0 in csselr
213*5f6032a8SAndrew Thoelke	dsb	sy			// barrier to complete final cache operation
2144ecca339SDan Handley	isb
2154ecca339SDan Handleyexit:
2164ecca339SDan Handley	ret
2174ecca339SDan Handley
218*5f6032a8SAndrew Thoelkedcsw_loop_table:
219*5f6032a8SAndrew Thoelke	dcsw_loop isw
220*5f6032a8SAndrew Thoelke	dcsw_loop cisw
221*5f6032a8SAndrew Thoelke	dcsw_loop csw
222*5f6032a8SAndrew Thoelke
2234ecca339SDan Handley
2244ecca339SDan Handleyfunc dcsw_op_louis
225*5f6032a8SAndrew Thoelke	dcsw_op #LOUIS_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT
2264ecca339SDan Handley
2274ecca339SDan Handley
2284ecca339SDan Handleyfunc dcsw_op_all
229*5f6032a8SAndrew Thoelke	dcsw_op #LOC_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT
230