xref: /rk3399_ARM-atf/lib/aarch32/cache_helpers.S (revision 355a5d03360802e2c7b8f09ffca641df0c9e47bf)
1f24307deSSoby Mathew/*
2f24307deSSoby Mathew * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
3f24307deSSoby Mathew *
4f24307deSSoby Mathew * Redistribution and use in source and binary forms, with or without
5f24307deSSoby Mathew * modification, are permitted provided that the following conditions are met:
6f24307deSSoby Mathew *
7f24307deSSoby Mathew * Redistributions of source code must retain the above copyright notice, this
8f24307deSSoby Mathew * list of conditions and the following disclaimer.
9f24307deSSoby Mathew *
10f24307deSSoby Mathew * Redistributions in binary form must reproduce the above copyright notice,
11f24307deSSoby Mathew * this list of conditions and the following disclaimer in the documentation
12f24307deSSoby Mathew * and/or other materials provided with the distribution.
13f24307deSSoby Mathew *
14f24307deSSoby Mathew * Neither the name of ARM nor the names of its contributors may be used
15f24307deSSoby Mathew * to endorse or promote products derived from this software without specific
16f24307deSSoby Mathew * prior written permission.
17f24307deSSoby Mathew *
18f24307deSSoby Mathew * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19f24307deSSoby Mathew * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20f24307deSSoby Mathew * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21f24307deSSoby Mathew * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22f24307deSSoby Mathew * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23f24307deSSoby Mathew * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24f24307deSSoby Mathew * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25f24307deSSoby Mathew * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26f24307deSSoby Mathew * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27f24307deSSoby Mathew * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28f24307deSSoby Mathew * POSSIBILITY OF SUCH DAMAGE.
29f24307deSSoby Mathew */
30f24307deSSoby Mathew
31f24307deSSoby Mathew#include <arch.h>
32f24307deSSoby Mathew#include <asm_macros.S>
33f24307deSSoby Mathew
34f24307deSSoby Mathew	.globl	flush_dcache_range
35f24307deSSoby Mathew	.globl	clean_dcache_range
36f24307deSSoby Mathew	.globl	inv_dcache_range
37f24307deSSoby Mathew	.globl	dcsw_op_louis
38f24307deSSoby Mathew	.globl	dcsw_op_all
39f24307deSSoby Mathew	.globl	dcsw_op_level1
40f24307deSSoby Mathew	.globl	dcsw_op_level2
41f24307deSSoby Mathew	.globl	dcsw_op_level3
42f24307deSSoby Mathew
43f24307deSSoby Mathew/*
44f24307deSSoby Mathew * This macro can be used for implementing various data cache operations `op`
45f24307deSSoby Mathew */
46f24307deSSoby Mathew.macro do_dcache_maintenance_by_mva op, coproc, opc1, CRn, CRm, opc2
47f24307deSSoby Mathew	dcache_line_size r2, r3
48f24307deSSoby Mathew	add	r1, r0, r1
49f24307deSSoby Mathew	sub	r3, r2, #1
50f24307deSSoby Mathew	bic	r0, r0, r3
51f24307deSSoby Mathewloop_\op:
52f24307deSSoby Mathew	stcopr	r0, \coproc, \opc1, \CRn, \CRm, \opc2
53f24307deSSoby Mathew	add	r0, r0, r2
54f24307deSSoby Mathew	cmp	r0, r1
55f24307deSSoby Mathew	blo	loop_\op
56f24307deSSoby Mathew	dsb	sy
57f24307deSSoby Mathew	bx	lr
58f24307deSSoby Mathew.endm
59f24307deSSoby Mathew
60f24307deSSoby Mathew	/* ------------------------------------------
61f24307deSSoby Mathew	 * Clean+Invalidate from base address till
62f24307deSSoby Mathew	 * size. 'r0' = addr, 'r1' = size
63f24307deSSoby Mathew	 * ------------------------------------------
64f24307deSSoby Mathew	 */
65f24307deSSoby Mathewfunc flush_dcache_range
66f24307deSSoby Mathew	do_dcache_maintenance_by_mva cimvac, DCCIMVAC
67f24307deSSoby Mathewendfunc flush_dcache_range
68f24307deSSoby Mathew
69f24307deSSoby Mathew	/* ------------------------------------------
70f24307deSSoby Mathew	 * Clean from base address till size.
71f24307deSSoby Mathew	 * 'r0' = addr, 'r1' = size
72f24307deSSoby Mathew	 * ------------------------------------------
73f24307deSSoby Mathew	 */
74f24307deSSoby Mathewfunc clean_dcache_range
75f24307deSSoby Mathew	do_dcache_maintenance_by_mva cmvac, DCCMVAC
76f24307deSSoby Mathewendfunc clean_dcache_range
77f24307deSSoby Mathew
78f24307deSSoby Mathew	/* ------------------------------------------
79f24307deSSoby Mathew	 * Invalidate from base address till
80f24307deSSoby Mathew	 * size. 'r0' = addr, 'r1' = size
81f24307deSSoby Mathew	 * ------------------------------------------
82f24307deSSoby Mathew	 */
83f24307deSSoby Mathewfunc inv_dcache_range
84f24307deSSoby Mathew	do_dcache_maintenance_by_mva imvac, DCIMVAC
85f24307deSSoby Mathewendfunc inv_dcache_range
86f24307deSSoby Mathew
87f24307deSSoby Mathew	/* ----------------------------------------------------------------
88f24307deSSoby Mathew	 * Data cache operations by set/way to the level specified
89f24307deSSoby Mathew	 *
90f24307deSSoby Mathew	 * The main function, do_dcsw_op requires:
91f24307deSSoby Mathew	 * r0: The operation type (DC_OP_ISW, DC_OP_CISW, DC_OP_CSW),
92f24307deSSoby Mathew	 * as defined in arch.h
93f24307deSSoby Mathew	 * r1: The cache level to begin operation from
94f24307deSSoby Mathew	 * r2: clidr_el1
95f24307deSSoby Mathew	 * r3: The last cache level to operate on
96f24307deSSoby Mathew	 * and will carry out the operation on each data cache from level 0
97f24307deSSoby Mathew	 * to the level in r3 in sequence
98f24307deSSoby Mathew	 *
99f24307deSSoby Mathew	 * The dcsw_op macro sets up the r2 and r3 parameters based on
100f24307deSSoby Mathew	 * clidr_el1 cache information before invoking the main function
101f24307deSSoby Mathew	 * ----------------------------------------------------------------
102f24307deSSoby Mathew	 */
103f24307deSSoby Mathew
104f24307deSSoby Mathew	.macro	dcsw_op shift, fw, ls
105f24307deSSoby Mathew	ldcopr	r2, CLIDR
106f24307deSSoby Mathew	ubfx	r3, r2, \shift, \fw
107f24307deSSoby Mathew	lsl	r3, r3, \ls
108f24307deSSoby Mathew	mov	r1, #0
109f24307deSSoby Mathew	b	do_dcsw_op
110f24307deSSoby Mathew	.endm
111f24307deSSoby Mathew
112f24307deSSoby Mathewfunc do_dcsw_op
113f24307deSSoby Mathew	push	{r4-r12,lr}
114f24307deSSoby Mathew	adr	r11, dcsw_loop_table	// compute cache op based on the operation type
115f24307deSSoby Mathew	add	r6, r11, r0, lsl #3	// cache op is 2x32-bit instructions
116f24307deSSoby Mathewloop1:
117f24307deSSoby Mathew	add	r10, r1, r1, LSR #1	// Work out 3x current cache level
118f24307deSSoby Mathew	mov	r12, r2, LSR r10	// extract cache type bits from clidr
119f24307deSSoby Mathew	and	r12, r12, #7   		// mask the bits for current cache only
120f24307deSSoby Mathew	cmp	r12, #2			// see what cache we have at this level
121*355a5d03SDouglas Raillard	blo	level_done      	// no cache or only instruction cache at this level
122f24307deSSoby Mathew
123f24307deSSoby Mathew	stcopr	r1, CSSELR		// select current cache level in csselr
124f24307deSSoby Mathew	isb				// isb to sych the new cssr&csidr
125f24307deSSoby Mathew	ldcopr	r12, CCSIDR		// read the new ccsidr
126f24307deSSoby Mathew	and	r10, r12, #7   		// extract the length of the cache lines
127f24307deSSoby Mathew	add	r10, r10, #4        	// add 4 (r10 = line length offset)
128f24307deSSoby Mathew	ubfx	r4, r12, #3, #10	// r4 = maximum way number (right aligned)
129f24307deSSoby Mathew	clz	r5, r4            	// r5 = the bit position of the way size increment
130f24307deSSoby Mathew	mov	r9, r4			// r9 working copy of the aligned max way number
131f24307deSSoby Mathew
132f24307deSSoby Mathewloop2:
133f24307deSSoby Mathew	ubfx	r7, r12, #13, #15	// r7 = max set number (right aligned)
134f24307deSSoby Mathew
135f24307deSSoby Mathewloop3:
136f24307deSSoby Mathew	orr	r0, r1, r9, LSL r5	// factor in the way number and cache level into r0
137f24307deSSoby Mathew	orr	r0, r0, r7, LSL r10	// factor in the set number
138f24307deSSoby Mathew
139f24307deSSoby Mathew	blx	r6
140f24307deSSoby Mathew	subs	r7, r7, #1              // decrement the set number
141*355a5d03SDouglas Raillard	bhs	loop3
142f24307deSSoby Mathew	subs	r9, r9, #1              // decrement the way number
143*355a5d03SDouglas Raillard	bhs	loop2
144f24307deSSoby Mathewlevel_done:
145f24307deSSoby Mathew	add	r1, r1, #2		// increment the cache number
146f24307deSSoby Mathew	cmp	r3, r1
147f24307deSSoby Mathew	dsb	sy			// ensure completion of previous cache maintenance instruction
148*355a5d03SDouglas Raillard	bhi	loop1
149f24307deSSoby Mathew
150f24307deSSoby Mathew	mov	r6, #0
151f24307deSSoby Mathew	stcopr	r6, CSSELR		//select cache level 0 in csselr
152f24307deSSoby Mathew	dsb	sy
153f24307deSSoby Mathew	isb
154f24307deSSoby Mathew	pop	{r4-r12,pc}
155f24307deSSoby Mathew
156f24307deSSoby Mathewdcsw_loop_table:
157f24307deSSoby Mathew	stcopr	r0, DCISW
158f24307deSSoby Mathew	bx	lr
159f24307deSSoby Mathew	stcopr	r0, DCCISW
160f24307deSSoby Mathew	bx	lr
161f24307deSSoby Mathew	stcopr	r0, DCCSW
162f24307deSSoby Mathew	bx	lr
163f24307deSSoby Mathew
164f24307deSSoby Mathewendfunc do_dcsw_op
165f24307deSSoby Mathew
166f24307deSSoby Mathew	/* ---------------------------------------------------------------
167f24307deSSoby Mathew	 * Data cache operations by set/way till PoU.
168f24307deSSoby Mathew	 *
169f24307deSSoby Mathew	 * The function requires :
170f24307deSSoby Mathew	 * r0: The operation type (DC_OP_ISW, DC_OP_CISW, DC_OP_CSW),
171f24307deSSoby Mathew	 * as defined in arch.h
172f24307deSSoby Mathew	 * ---------------------------------------------------------------
173f24307deSSoby Mathew	 */
174f24307deSSoby Mathewfunc dcsw_op_louis
175f24307deSSoby Mathew	dcsw_op #LOUIS_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT
176f24307deSSoby Mathewendfunc	dcsw_op_louis
177f24307deSSoby Mathew
178f24307deSSoby Mathew	/* ---------------------------------------------------------------
179f24307deSSoby Mathew	 * Data cache operations by set/way till PoC.
180f24307deSSoby Mathew	 *
181f24307deSSoby Mathew	 * The function requires :
182f24307deSSoby Mathew	 * r0: The operation type (DC_OP_ISW, DC_OP_CISW, DC_OP_CSW),
183f24307deSSoby Mathew	 * as defined in arch.h
184f24307deSSoby Mathew	 * ---------------------------------------------------------------
185f24307deSSoby Mathew	 */
186f24307deSSoby Mathewfunc dcsw_op_all
187f24307deSSoby Mathew	dcsw_op #LOC_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT
188f24307deSSoby Mathewendfunc	dcsw_op_all
189f24307deSSoby Mathew
190f24307deSSoby Mathew
191f24307deSSoby Mathew	/* ---------------------------------------------------------------
192f24307deSSoby Mathew	 *  Helper macro for data cache operations by set/way for the
193f24307deSSoby Mathew	 *  level specified
194f24307deSSoby Mathew	 * ---------------------------------------------------------------
195f24307deSSoby Mathew	 */
196f24307deSSoby Mathew	.macro	dcsw_op_level level
197f24307deSSoby Mathew	ldcopr	r2, CLIDR
198f24307deSSoby Mathew	mov	r3, \level
199f24307deSSoby Mathew	sub	r1, r3, #2
200f24307deSSoby Mathew	b	do_dcsw_op
201f24307deSSoby Mathew	.endm
202f24307deSSoby Mathew
203f24307deSSoby Mathew	/* ---------------------------------------------------------------
204f24307deSSoby Mathew	 * Data cache operations by set/way for level 1 cache
205f24307deSSoby Mathew	 *
206f24307deSSoby Mathew	 * The main function, do_dcsw_op requires:
207f24307deSSoby Mathew	 * r0: The operation type (DC_OP_ISW, DC_OP_CISW, DC_OP_CSW),
208f24307deSSoby Mathew	 * as defined in arch.h
209f24307deSSoby Mathew	 * ---------------------------------------------------------------
210f24307deSSoby Mathew	 */
211f24307deSSoby Mathewfunc dcsw_op_level1
212f24307deSSoby Mathew	dcsw_op_level #(1 << LEVEL_SHIFT)
213f24307deSSoby Mathewendfunc dcsw_op_level1
214f24307deSSoby Mathew
215f24307deSSoby Mathew	/* ---------------------------------------------------------------
216f24307deSSoby Mathew	 * Data cache operations by set/way for level 2 cache
217f24307deSSoby Mathew	 *
218f24307deSSoby Mathew	 * The main function, do_dcsw_op requires:
219f24307deSSoby Mathew	 * r0: The operation type (DC_OP_ISW, DC_OP_CISW, DC_OP_CSW),
220f24307deSSoby Mathew	 * as defined in arch.h
221f24307deSSoby Mathew	 * ---------------------------------------------------------------
222f24307deSSoby Mathew	 */
223f24307deSSoby Mathewfunc dcsw_op_level2
224f24307deSSoby Mathew	dcsw_op_level #(2 << LEVEL_SHIFT)
225f24307deSSoby Mathewendfunc dcsw_op_level2
226f24307deSSoby Mathew
227f24307deSSoby Mathew	/* ---------------------------------------------------------------
228f24307deSSoby Mathew	 * Data cache operations by set/way for level 3 cache
229f24307deSSoby Mathew	 *
230f24307deSSoby Mathew	 * The main function, do_dcsw_op requires:
231f24307deSSoby Mathew	 * r0: The operation type (DC_OP_ISW, DC_OP_CISW, DC_OP_CSW),
232f24307deSSoby Mathew	 * as defined in arch.h
233f24307deSSoby Mathew	 * ---------------------------------------------------------------
234f24307deSSoby Mathew	 */
235f24307deSSoby Mathewfunc dcsw_op_level3
236f24307deSSoby Mathew	dcsw_op_level #(3 << LEVEL_SHIFT)
237f24307deSSoby Mathewendfunc dcsw_op_level3
238