xref: /rk3399_ARM-atf/lib/aarch32/cache_helpers.S (revision 82cb2c1ad9897473743f08437d0a3995bed561b9)
1f24307deSSoby Mathew/*
2f24307deSSoby Mathew * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
3f24307deSSoby Mathew *
4*82cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause
5f24307deSSoby Mathew */
6f24307deSSoby Mathew
7f24307deSSoby Mathew#include <arch.h>
8f24307deSSoby Mathew#include <asm_macros.S>
9f24307deSSoby Mathew
10f24307deSSoby Mathew	.globl	flush_dcache_range
11f24307deSSoby Mathew	.globl	clean_dcache_range
12f24307deSSoby Mathew	.globl	inv_dcache_range
13f24307deSSoby Mathew	.globl	dcsw_op_louis
14f24307deSSoby Mathew	.globl	dcsw_op_all
15f24307deSSoby Mathew	.globl	dcsw_op_level1
16f24307deSSoby Mathew	.globl	dcsw_op_level2
17f24307deSSoby Mathew	.globl	dcsw_op_level3
18f24307deSSoby Mathew
19f24307deSSoby Mathew/*
20f24307deSSoby Mathew * This macro can be used for implementing various data cache operations `op`
21f24307deSSoby Mathew */
22f24307deSSoby Mathew.macro do_dcache_maintenance_by_mva op, coproc, opc1, CRn, CRm, opc2
23f24307deSSoby Mathew	dcache_line_size r2, r3
24f24307deSSoby Mathew	add	r1, r0, r1
25f24307deSSoby Mathew	sub	r3, r2, #1
26f24307deSSoby Mathew	bic	r0, r0, r3
27f24307deSSoby Mathewloop_\op:
28f24307deSSoby Mathew	stcopr	r0, \coproc, \opc1, \CRn, \CRm, \opc2
29f24307deSSoby Mathew	add	r0, r0, r2
30f24307deSSoby Mathew	cmp	r0, r1
31f24307deSSoby Mathew	blo	loop_\op
32f24307deSSoby Mathew	dsb	sy
33f24307deSSoby Mathew	bx	lr
34f24307deSSoby Mathew.endm
35f24307deSSoby Mathew
36f24307deSSoby Mathew	/* ------------------------------------------
37f24307deSSoby Mathew	 * Clean+Invalidate from base address till
38f24307deSSoby Mathew	 * size. 'r0' = addr, 'r1' = size
39f24307deSSoby Mathew	 * ------------------------------------------
40f24307deSSoby Mathew	 */
41f24307deSSoby Mathewfunc flush_dcache_range
42f24307deSSoby Mathew	do_dcache_maintenance_by_mva cimvac, DCCIMVAC
43f24307deSSoby Mathewendfunc flush_dcache_range
44f24307deSSoby Mathew
45f24307deSSoby Mathew	/* ------------------------------------------
46f24307deSSoby Mathew	 * Clean from base address till size.
47f24307deSSoby Mathew	 * 'r0' = addr, 'r1' = size
48f24307deSSoby Mathew	 * ------------------------------------------
49f24307deSSoby Mathew	 */
50f24307deSSoby Mathewfunc clean_dcache_range
51f24307deSSoby Mathew	do_dcache_maintenance_by_mva cmvac, DCCMVAC
52f24307deSSoby Mathewendfunc clean_dcache_range
53f24307deSSoby Mathew
54f24307deSSoby Mathew	/* ------------------------------------------
55f24307deSSoby Mathew	 * Invalidate from base address till
56f24307deSSoby Mathew	 * size. 'r0' = addr, 'r1' = size
57f24307deSSoby Mathew	 * ------------------------------------------
58f24307deSSoby Mathew	 */
59f24307deSSoby Mathewfunc inv_dcache_range
60f24307deSSoby Mathew	do_dcache_maintenance_by_mva imvac, DCIMVAC
61f24307deSSoby Mathewendfunc inv_dcache_range
62f24307deSSoby Mathew
63f24307deSSoby Mathew	/* ----------------------------------------------------------------
64f24307deSSoby Mathew	 * Data cache operations by set/way to the level specified
65f24307deSSoby Mathew	 *
66f24307deSSoby Mathew	 * The main function, do_dcsw_op requires:
67f24307deSSoby Mathew	 * r0: The operation type (DC_OP_ISW, DC_OP_CISW, DC_OP_CSW),
68f24307deSSoby Mathew	 * as defined in arch.h
69f24307deSSoby Mathew	 * r1: The cache level to begin operation from
70f24307deSSoby Mathew	 * r2: clidr_el1
71f24307deSSoby Mathew	 * r3: The last cache level to operate on
72f24307deSSoby Mathew	 * and will carry out the operation on each data cache from level 0
73f24307deSSoby Mathew	 * to the level in r3 in sequence
74f24307deSSoby Mathew	 *
75f24307deSSoby Mathew	 * The dcsw_op macro sets up the r2 and r3 parameters based on
76f24307deSSoby Mathew	 * clidr_el1 cache information before invoking the main function
77f24307deSSoby Mathew	 * ----------------------------------------------------------------
78f24307deSSoby Mathew	 */
79f24307deSSoby Mathew
80f24307deSSoby Mathew	.macro	dcsw_op shift, fw, ls
81f24307deSSoby Mathew	ldcopr	r2, CLIDR
82f24307deSSoby Mathew	ubfx	r3, r2, \shift, \fw
83f24307deSSoby Mathew	lsl	r3, r3, \ls
84f24307deSSoby Mathew	mov	r1, #0
85f24307deSSoby Mathew	b	do_dcsw_op
86f24307deSSoby Mathew	.endm
87f24307deSSoby Mathew
88f24307deSSoby Mathewfunc do_dcsw_op
89f24307deSSoby Mathew	push	{r4-r12,lr}
90f24307deSSoby Mathew	adr	r11, dcsw_loop_table	// compute cache op based on the operation type
91f24307deSSoby Mathew	add	r6, r11, r0, lsl #3	// cache op is 2x32-bit instructions
92f24307deSSoby Mathewloop1:
93f24307deSSoby Mathew	add	r10, r1, r1, LSR #1	// Work out 3x current cache level
94f24307deSSoby Mathew	mov	r12, r2, LSR r10	// extract cache type bits from clidr
95f24307deSSoby Mathew	and	r12, r12, #7   		// mask the bits for current cache only
96f24307deSSoby Mathew	cmp	r12, #2			// see what cache we have at this level
97355a5d03SDouglas Raillard	blo	level_done      	// no cache or only instruction cache at this level
98f24307deSSoby Mathew
99f24307deSSoby Mathew	stcopr	r1, CSSELR		// select current cache level in csselr
100f24307deSSoby Mathew	isb				// isb to sych the new cssr&csidr
101f24307deSSoby Mathew	ldcopr	r12, CCSIDR		// read the new ccsidr
102f24307deSSoby Mathew	and	r10, r12, #7   		// extract the length of the cache lines
103f24307deSSoby Mathew	add	r10, r10, #4        	// add 4 (r10 = line length offset)
104f24307deSSoby Mathew	ubfx	r4, r12, #3, #10	// r4 = maximum way number (right aligned)
105f24307deSSoby Mathew	clz	r5, r4            	// r5 = the bit position of the way size increment
106f24307deSSoby Mathew	mov	r9, r4			// r9 working copy of the aligned max way number
107f24307deSSoby Mathew
108f24307deSSoby Mathewloop2:
109f24307deSSoby Mathew	ubfx	r7, r12, #13, #15	// r7 = max set number (right aligned)
110f24307deSSoby Mathew
111f24307deSSoby Mathewloop3:
112f24307deSSoby Mathew	orr	r0, r1, r9, LSL r5	// factor in the way number and cache level into r0
113f24307deSSoby Mathew	orr	r0, r0, r7, LSL r10	// factor in the set number
114f24307deSSoby Mathew
115f24307deSSoby Mathew	blx	r6
116f24307deSSoby Mathew	subs	r7, r7, #1              // decrement the set number
117355a5d03SDouglas Raillard	bhs	loop3
118f24307deSSoby Mathew	subs	r9, r9, #1              // decrement the way number
119355a5d03SDouglas Raillard	bhs	loop2
120f24307deSSoby Mathewlevel_done:
121f24307deSSoby Mathew	add	r1, r1, #2		// increment the cache number
122f24307deSSoby Mathew	cmp	r3, r1
123f24307deSSoby Mathew	dsb	sy			// ensure completion of previous cache maintenance instruction
124355a5d03SDouglas Raillard	bhi	loop1
125f24307deSSoby Mathew
126f24307deSSoby Mathew	mov	r6, #0
127f24307deSSoby Mathew	stcopr	r6, CSSELR		//select cache level 0 in csselr
128f24307deSSoby Mathew	dsb	sy
129f24307deSSoby Mathew	isb
130f24307deSSoby Mathew	pop	{r4-r12,pc}
131f24307deSSoby Mathew
132f24307deSSoby Mathewdcsw_loop_table:
133f24307deSSoby Mathew	stcopr	r0, DCISW
134f24307deSSoby Mathew	bx	lr
135f24307deSSoby Mathew	stcopr	r0, DCCISW
136f24307deSSoby Mathew	bx	lr
137f24307deSSoby Mathew	stcopr	r0, DCCSW
138f24307deSSoby Mathew	bx	lr
139f24307deSSoby Mathew
140f24307deSSoby Mathewendfunc do_dcsw_op
141f24307deSSoby Mathew
142f24307deSSoby Mathew	/* ---------------------------------------------------------------
143f24307deSSoby Mathew	 * Data cache operations by set/way till PoU.
144f24307deSSoby Mathew	 *
145f24307deSSoby Mathew	 * The function requires :
146f24307deSSoby Mathew	 * r0: The operation type (DC_OP_ISW, DC_OP_CISW, DC_OP_CSW),
147f24307deSSoby Mathew	 * as defined in arch.h
148f24307deSSoby Mathew	 * ---------------------------------------------------------------
149f24307deSSoby Mathew	 */
150f24307deSSoby Mathewfunc dcsw_op_louis
151f24307deSSoby Mathew	dcsw_op #LOUIS_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT
152f24307deSSoby Mathewendfunc	dcsw_op_louis
153f24307deSSoby Mathew
154f24307deSSoby Mathew	/* ---------------------------------------------------------------
155f24307deSSoby Mathew	 * Data cache operations by set/way till PoC.
156f24307deSSoby Mathew	 *
157f24307deSSoby Mathew	 * The function requires :
158f24307deSSoby Mathew	 * r0: The operation type (DC_OP_ISW, DC_OP_CISW, DC_OP_CSW),
159f24307deSSoby Mathew	 * as defined in arch.h
160f24307deSSoby Mathew	 * ---------------------------------------------------------------
161f24307deSSoby Mathew	 */
162f24307deSSoby Mathewfunc dcsw_op_all
163f24307deSSoby Mathew	dcsw_op #LOC_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT
164f24307deSSoby Mathewendfunc	dcsw_op_all
165f24307deSSoby Mathew
166f24307deSSoby Mathew
167f24307deSSoby Mathew	/* ---------------------------------------------------------------
168f24307deSSoby Mathew	 *  Helper macro for data cache operations by set/way for the
169f24307deSSoby Mathew	 *  level specified
170f24307deSSoby Mathew	 * ---------------------------------------------------------------
171f24307deSSoby Mathew	 */
172f24307deSSoby Mathew	.macro	dcsw_op_level level
173f24307deSSoby Mathew	ldcopr	r2, CLIDR
174f24307deSSoby Mathew	mov	r3, \level
175f24307deSSoby Mathew	sub	r1, r3, #2
176f24307deSSoby Mathew	b	do_dcsw_op
177f24307deSSoby Mathew	.endm
178f24307deSSoby Mathew
179f24307deSSoby Mathew	/* ---------------------------------------------------------------
180f24307deSSoby Mathew	 * Data cache operations by set/way for level 1 cache
181f24307deSSoby Mathew	 *
182f24307deSSoby Mathew	 * The main function, do_dcsw_op requires:
183f24307deSSoby Mathew	 * r0: The operation type (DC_OP_ISW, DC_OP_CISW, DC_OP_CSW),
184f24307deSSoby Mathew	 * as defined in arch.h
185f24307deSSoby Mathew	 * ---------------------------------------------------------------
186f24307deSSoby Mathew	 */
187f24307deSSoby Mathewfunc dcsw_op_level1
188f24307deSSoby Mathew	dcsw_op_level #(1 << LEVEL_SHIFT)
189f24307deSSoby Mathewendfunc dcsw_op_level1
190f24307deSSoby Mathew
191f24307deSSoby Mathew	/* ---------------------------------------------------------------
192f24307deSSoby Mathew	 * Data cache operations by set/way for level 2 cache
193f24307deSSoby Mathew	 *
194f24307deSSoby Mathew	 * The main function, do_dcsw_op requires:
195f24307deSSoby Mathew	 * r0: The operation type (DC_OP_ISW, DC_OP_CISW, DC_OP_CSW),
196f24307deSSoby Mathew	 * as defined in arch.h
197f24307deSSoby Mathew	 * ---------------------------------------------------------------
198f24307deSSoby Mathew	 */
199f24307deSSoby Mathewfunc dcsw_op_level2
200f24307deSSoby Mathew	dcsw_op_level #(2 << LEVEL_SHIFT)
201f24307deSSoby Mathewendfunc dcsw_op_level2
202f24307deSSoby Mathew
203f24307deSSoby Mathew	/* ---------------------------------------------------------------
204f24307deSSoby Mathew	 * Data cache operations by set/way for level 3 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_level3
212f24307deSSoby Mathew	dcsw_op_level #(3 << LEVEL_SHIFT)
213f24307deSSoby Mathewendfunc dcsw_op_level3
214