xref: /rk3399_ARM-atf/lib/aarch64/cache_helpers.S (revision fd6fede5b6183143eaac3c79e2bcfb13c0492dea)
1/*
2 * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * Redistributions of source code must retain the above copyright notice, this
8 * list of conditions and the following disclaimer.
9 *
10 * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 *
14 * Neither the name of ARM nor the names of its contributors may be used
15 * to endorse or promote products derived from this software without specific
16 * prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include <arch.h>
32#include <asm_macros.S>
33
34	.globl	dcisw
35	.globl	dccisw
36	.globl	dccsw
37	.globl	dccvac
38	.globl	dcivac
39	.globl	dccivac
40	.globl	dccvau
41	.globl	dczva
42	.globl	flush_dcache_range
43	.globl	inv_dcache_range
44	.globl	dcsw_op_louis
45	.globl	dcsw_op_all
46
47func dcisw
48	dc	isw, x0
49	ret
50
51
52func dccisw
53	dc	cisw, x0
54	ret
55
56
57func dccsw
58	dc	csw, x0
59	ret
60
61
62func dccvac
63	dc	cvac, x0
64	ret
65
66
67func dcivac
68	dc	ivac, x0
69	ret
70
71
72func dccivac
73	dc	civac, x0
74	ret
75
76
77func dccvau
78	dc	cvau, x0
79	ret
80
81
82func dczva
83	dc	zva, x0
84	ret
85
86
87	/* ------------------------------------------
88	 * Clean+Invalidate from base address till
89	 * size. 'x0' = addr, 'x1' = size
90	 * ------------------------------------------
91	 */
92func flush_dcache_range
93	dcache_line_size x2, x3
94	add	x1, x0, x1
95	sub	x3, x2, #1
96	bic	x0, x0, x3
97flush_loop:
98	dc	civac, x0
99	add	x0, x0, x2
100	cmp	x0, x1
101	b.lo    flush_loop
102	dsb	sy
103	ret
104
105
106	/* ------------------------------------------
107	 * Invalidate from base address till
108	 * size. 'x0' = addr, 'x1' = size
109	 * ------------------------------------------
110	 */
111func inv_dcache_range
112	dcache_line_size x2, x3
113	add	x1, x0, x1
114	sub	x3, x2, #1
115	bic	x0, x0, x3
116inv_loop:
117	dc	ivac, x0
118	add	x0, x0, x2
119	cmp	x0, x1
120	b.lo    inv_loop
121	dsb	sy
122	ret
123
124
125	/* ---------------------------------------------------------------
126	 * Data cache operations by set/way to the level specified
127	 *
128	 * The main function, do_dcsw_op requires:
129	 * x0: The operation type (0-2), as defined in arch.h
130	 * x3: The last cache level to operate on
131	 * x9: clidr_el1
132	 * and will carry out the operation on each data cache from level 0
133	 * to the level in x3 in sequence
134	 *
135	 * The dcsw_op macro sets up the x3 and x9 parameters based on
136	 * clidr_el1 cache information before invoking the main function
137	 * ---------------------------------------------------------------
138	 */
139
140	.macro	dcsw_op shift, fw, ls
141	mrs	x9, clidr_el1
142	ubfx	x3, x9, \shift, \fw
143	lsl	x3, x3, \ls
144	b	do_dcsw_op
145	.endm
146
147func do_dcsw_op
148	cbz	x3, exit
149	mov	x10, xzr
150	adr	x14, dcsw_loop_table	// compute inner loop address
151	add	x14, x14, x0, lsl #5	// inner loop is 8x32-bit instructions
152	mov	x0, x9
153	mov	w8, #1
154loop1:
155	add	x2, x10, x10, lsr #1	// work out 3x current cache level
156	lsr	x1, x0, x2		// extract cache type bits from clidr
157	and	x1, x1, #7		// mask the bits for current cache only
158	cmp	x1, #2			// see what cache we have at this level
159	b.lt	level_done		// nothing to do if no cache or icache
160
161	msr	csselr_el1, x10		// select current cache level in csselr
162	isb				// isb to sych the new cssr&csidr
163	mrs	x1, ccsidr_el1		// read the new ccsidr
164	and	x2, x1, #7		// extract the length of the cache lines
165	add	x2, x2, #4		// add 4 (line length offset)
166	ubfx	x4, x1, #3, #10		// maximum way number
167	clz	w5, w4			// bit position of way size increment
168	lsl	w9, w4, w5		// w9 = aligned max way number
169	lsl	w16, w8, w5		// w16 = way number loop decrement
170	orr	w9, w10, w9		// w9 = combine way and cache number
171	ubfx	w6, w1, #13, #15	// w6 = max set number
172	lsl	w17, w8, w2		// w17 = set number loop decrement
173	dsb	sy			// barrier before we start this level
174	br	x14			// jump to DC operation specific loop
175
176	.macro	dcsw_loop _op
177loop2_\_op:
178	lsl	w7, w6, w2		// w7 = aligned max set number
179
180loop3_\_op:
181	orr	w11, w9, w7		// combine cache, way and set number
182	dc	\_op, x11
183	subs	w7, w7, w17		// decrement set number
184	b.ge	loop3_\_op
185
186	subs	x9, x9, x16		// decrement way number
187	b.ge	loop2_\_op
188
189	b	level_done
190	.endm
191
192level_done:
193	add	x10, x10, #2		// increment cache number
194	cmp	x3, x10
195	b.gt    loop1
196	msr	csselr_el1, xzr		// select cache level 0 in csselr
197	dsb	sy			// barrier to complete final cache operation
198	isb
199exit:
200	ret
201
202dcsw_loop_table:
203	dcsw_loop isw
204	dcsw_loop cisw
205	dcsw_loop csw
206
207
208func dcsw_op_louis
209	dcsw_op #LOUIS_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT
210
211
212func dcsw_op_all
213	dcsw_op #LOC_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT
214