xref: /rk3399_ARM-atf/lib/aarch64/cache_helpers.S (revision 8b779620d3bad024b83650ecfeaafd7b3ae26ccf)
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	flush_dcache_range
354ecca339SDan Handley	.globl	inv_dcache_range
364ecca339SDan Handley	.globl	dcsw_op_louis
374ecca339SDan Handley	.globl	dcsw_op_all
388e857916SSoby Mathew	.globl	dcsw_op_level1
398e857916SSoby Mathew	.globl	dcsw_op_level2
408e857916SSoby Mathew	.globl	dcsw_op_level3
414ecca339SDan Handley
424ecca339SDan Handley	/* ------------------------------------------
434ecca339SDan Handley	 * Clean+Invalidate from base address till
444ecca339SDan Handley	 * size. 'x0' = addr, 'x1' = size
454ecca339SDan Handley	 * ------------------------------------------
464ecca339SDan Handley	 */
474ecca339SDan Handleyfunc flush_dcache_range
484ecca339SDan Handley	dcache_line_size x2, x3
494ecca339SDan Handley	add	x1, x0, x1
504ecca339SDan Handley	sub	x3, x2, #1
514ecca339SDan Handley	bic	x0, x0, x3
524ecca339SDan Handleyflush_loop:
534ecca339SDan Handley	dc	civac, x0
544ecca339SDan Handley	add	x0, x0, x2
554ecca339SDan Handley	cmp	x0, x1
564ecca339SDan Handley	b.lo    flush_loop
574ecca339SDan Handley	dsb	sy
584ecca339SDan Handley	ret
59*8b779620SKévin Petitendfunc flush_dcache_range
604ecca339SDan Handley
614ecca339SDan Handley
624ecca339SDan Handley	/* ------------------------------------------
634ecca339SDan Handley	 * Invalidate from base address till
644ecca339SDan Handley	 * size. 'x0' = addr, 'x1' = size
654ecca339SDan Handley	 * ------------------------------------------
664ecca339SDan Handley	 */
674ecca339SDan Handleyfunc inv_dcache_range
684ecca339SDan Handley	dcache_line_size x2, x3
694ecca339SDan Handley	add	x1, x0, x1
704ecca339SDan Handley	sub	x3, x2, #1
714ecca339SDan Handley	bic	x0, x0, x3
724ecca339SDan Handleyinv_loop:
734ecca339SDan Handley	dc	ivac, x0
744ecca339SDan Handley	add	x0, x0, x2
754ecca339SDan Handley	cmp	x0, x1
764ecca339SDan Handley	b.lo    inv_loop
774ecca339SDan Handley	dsb	sy
784ecca339SDan Handley	ret
79*8b779620SKévin Petitendfunc inv_dcache_range
804ecca339SDan Handley
814ecca339SDan Handley
825f6032a8SAndrew Thoelke	/* ---------------------------------------------------------------
835f6032a8SAndrew Thoelke	 * Data cache operations by set/way to the level specified
845f6032a8SAndrew Thoelke	 *
855f6032a8SAndrew Thoelke	 * The main function, do_dcsw_op requires:
865f6032a8SAndrew Thoelke	 * x0: The operation type (0-2), as defined in arch.h
875f6032a8SAndrew Thoelke	 * x3: The last cache level to operate on
885f6032a8SAndrew Thoelke	 * x9: clidr_el1
898e857916SSoby Mathew	 * x10: The cache level to begin operation from
905f6032a8SAndrew Thoelke	 * and will carry out the operation on each data cache from level 0
915f6032a8SAndrew Thoelke	 * to the level in x3 in sequence
925f6032a8SAndrew Thoelke	 *
935f6032a8SAndrew Thoelke	 * The dcsw_op macro sets up the x3 and x9 parameters based on
945f6032a8SAndrew Thoelke	 * clidr_el1 cache information before invoking the main function
955f6032a8SAndrew Thoelke	 * ---------------------------------------------------------------
964ecca339SDan Handley	 */
975f6032a8SAndrew Thoelke
985f6032a8SAndrew Thoelke	.macro	dcsw_op shift, fw, ls
995f6032a8SAndrew Thoelke	mrs	x9, clidr_el1
1005f6032a8SAndrew Thoelke	ubfx	x3, x9, \shift, \fw
1015f6032a8SAndrew Thoelke	lsl	x3, x3, \ls
1028e857916SSoby Mathew	mov	x10, xzr
1035f6032a8SAndrew Thoelke	b	do_dcsw_op
1045f6032a8SAndrew Thoelke	.endm
1055f6032a8SAndrew Thoelke
1065f6032a8SAndrew Thoelkefunc do_dcsw_op
1075f6032a8SAndrew Thoelke	cbz	x3, exit
1085f6032a8SAndrew Thoelke	adr	x14, dcsw_loop_table	// compute inner loop address
1095f6032a8SAndrew Thoelke	add	x14, x14, x0, lsl #5	// inner loop is 8x32-bit instructions
1105f6032a8SAndrew Thoelke	mov	x0, x9
1115f6032a8SAndrew Thoelke	mov	w8, #1
1125f6032a8SAndrew Thoelkeloop1:
1134ecca339SDan Handley	add	x2, x10, x10, lsr #1	// work out 3x current cache level
1144ecca339SDan Handley	lsr	x1, x0, x2		// extract cache type bits from clidr
1155f6032a8SAndrew Thoelke	and	x1, x1, #7		// mask the bits for current cache only
1164ecca339SDan Handley	cmp	x1, #2			// see what cache we have at this level
1175f6032a8SAndrew Thoelke	b.lt	level_done		// nothing to do if no cache or icache
1185f6032a8SAndrew Thoelke
1194ecca339SDan Handley	msr	csselr_el1, x10		// select current cache level in csselr
1204ecca339SDan Handley	isb				// isb to sych the new cssr&csidr
1214ecca339SDan Handley	mrs	x1, ccsidr_el1		// read the new ccsidr
1224ecca339SDan Handley	and	x2, x1, #7		// extract the length of the cache lines
1234ecca339SDan Handley	add	x2, x2, #4		// add 4 (line length offset)
1245f6032a8SAndrew Thoelke	ubfx	x4, x1, #3, #10		// maximum way number
1255f6032a8SAndrew Thoelke	clz	w5, w4			// bit position of way size increment
1265f6032a8SAndrew Thoelke	lsl	w9, w4, w5		// w9 = aligned max way number
1275f6032a8SAndrew Thoelke	lsl	w16, w8, w5		// w16 = way number loop decrement
1285f6032a8SAndrew Thoelke	orr	w9, w10, w9		// w9 = combine way and cache number
1295f6032a8SAndrew Thoelke	ubfx	w6, w1, #13, #15	// w6 = max set number
1305f6032a8SAndrew Thoelke	lsl	w17, w8, w2		// w17 = set number loop decrement
1315f6032a8SAndrew Thoelke	dsb	sy			// barrier before we start this level
1325f6032a8SAndrew Thoelke	br	x14			// jump to DC operation specific loop
1335f6032a8SAndrew Thoelke
1345f6032a8SAndrew Thoelke	.macro	dcsw_loop _op
1355f6032a8SAndrew Thoelkeloop2_\_op:
1365f6032a8SAndrew Thoelke	lsl	w7, w6, w2		// w7 = aligned max set number
1375f6032a8SAndrew Thoelke
1385f6032a8SAndrew Thoelkeloop3_\_op:
1395f6032a8SAndrew Thoelke	orr	w11, w9, w7		// combine cache, way and set number
1405f6032a8SAndrew Thoelke	dc	\_op, x11
1415f6032a8SAndrew Thoelke	subs	w7, w7, w17		// decrement set number
1425f6032a8SAndrew Thoelke	b.ge	loop3_\_op
1435f6032a8SAndrew Thoelke
1445f6032a8SAndrew Thoelke	subs	x9, x9, x16		// decrement way number
1455f6032a8SAndrew Thoelke	b.ge	loop2_\_op
1465f6032a8SAndrew Thoelke
1475f6032a8SAndrew Thoelke	b	level_done
1485f6032a8SAndrew Thoelke	.endm
1495f6032a8SAndrew Thoelke
1505f6032a8SAndrew Thoelkelevel_done:
1514ecca339SDan Handley	add	x10, x10, #2		// increment cache number
1524ecca339SDan Handley	cmp	x3, x10
1535f6032a8SAndrew Thoelke	b.gt    loop1
1545f6032a8SAndrew Thoelke	msr	csselr_el1, xzr		// select cache level 0 in csselr
1555f6032a8SAndrew Thoelke	dsb	sy			// barrier to complete final cache operation
1564ecca339SDan Handley	isb
1574ecca339SDan Handleyexit:
1584ecca339SDan Handley	ret
159*8b779620SKévin Petitendfunc do_dcsw_op
1604ecca339SDan Handley
1615f6032a8SAndrew Thoelkedcsw_loop_table:
1625f6032a8SAndrew Thoelke	dcsw_loop isw
1635f6032a8SAndrew Thoelke	dcsw_loop cisw
1645f6032a8SAndrew Thoelke	dcsw_loop csw
1655f6032a8SAndrew Thoelke
1664ecca339SDan Handley
1674ecca339SDan Handleyfunc dcsw_op_louis
1685f6032a8SAndrew Thoelke	dcsw_op #LOUIS_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT
169*8b779620SKévin Petitendfunc dcsw_op_louis
1704ecca339SDan Handley
1714ecca339SDan Handley
1724ecca339SDan Handleyfunc dcsw_op_all
1735f6032a8SAndrew Thoelke	dcsw_op #LOC_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT
174*8b779620SKévin Petitendfunc dcsw_op_all
1758e857916SSoby Mathew
1768e857916SSoby Mathew	/* ---------------------------------------------------------------
1778e857916SSoby Mathew	 *  Helper macro for data cache operations by set/way for the
1788e857916SSoby Mathew	 *  level specified
1798e857916SSoby Mathew	 * ---------------------------------------------------------------
1808e857916SSoby Mathew	 */
1818e857916SSoby Mathew	.macro dcsw_op_level level
1828e857916SSoby Mathew	mrs	x9, clidr_el1
1838e857916SSoby Mathew	mov	x3, \level
1848e857916SSoby Mathew	sub	x10, x3, #2
1858e857916SSoby Mathew	b	do_dcsw_op
1868e857916SSoby Mathew	.endm
1878e857916SSoby Mathew
1888e857916SSoby Mathew	/* ---------------------------------------------------------------
1898e857916SSoby Mathew	 * Data cache operations by set/way for level 1 cache
1908e857916SSoby Mathew	 *
1918e857916SSoby Mathew	 * The main function, do_dcsw_op requires:
1928e857916SSoby Mathew	 * x0: The operation type (0-2), as defined in arch.h
1938e857916SSoby Mathew	 * ---------------------------------------------------------------
1948e857916SSoby Mathew	 */
1958e857916SSoby Mathewfunc dcsw_op_level1
1968e857916SSoby Mathew	dcsw_op_level #(1 << LEVEL_SHIFT)
197*8b779620SKévin Petitendfunc dcsw_op_level1
1988e857916SSoby Mathew
1998e857916SSoby Mathew	/* ---------------------------------------------------------------
2008e857916SSoby Mathew	 * Data cache operations by set/way for level 2 cache
2018e857916SSoby Mathew	 *
2028e857916SSoby Mathew	 * The main function, do_dcsw_op requires:
2038e857916SSoby Mathew	 * x0: The operation type (0-2), as defined in arch.h
2048e857916SSoby Mathew	 * ---------------------------------------------------------------
2058e857916SSoby Mathew	 */
2068e857916SSoby Mathewfunc dcsw_op_level2
2078e857916SSoby Mathew	dcsw_op_level #(2 << LEVEL_SHIFT)
208*8b779620SKévin Petitendfunc dcsw_op_level2
2098e857916SSoby Mathew
2108e857916SSoby Mathew	/* ---------------------------------------------------------------
2118e857916SSoby Mathew	 * Data cache operations by set/way for level 3 cache
2128e857916SSoby Mathew	 *
2138e857916SSoby Mathew	 * The main function, do_dcsw_op requires:
2148e857916SSoby Mathew	 * x0: The operation type (0-2), as defined in arch.h
2158e857916SSoby Mathew	 * ---------------------------------------------------------------
2168e857916SSoby Mathew	 */
2178e857916SSoby Mathewfunc dcsw_op_level3
2188e857916SSoby Mathew	dcsw_op_level #(3 << LEVEL_SHIFT)
219*8b779620SKévin Petitendfunc dcsw_op_level3
220