xref: /rk3399_ARM-atf/lib/aarch64/cache_helpers.S (revision fb037bfb7cbf7b404c069b4ebac5a10059d948b1)
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_helpers.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	dsb	sy
50	isb
51	ret
52
53
54func dccisw
55	dc	cisw, x0
56	dsb	sy
57	isb
58	ret
59
60
61func dccsw
62	dc	csw, x0
63	dsb	sy
64	isb
65	ret
66
67
68func dccvac
69	dc	cvac, x0
70	dsb	sy
71	isb
72	ret
73
74
75func dcivac
76	dc	ivac, x0
77	dsb	sy
78	isb
79	ret
80
81
82func dccivac
83	dc	civac, x0
84	dsb	sy
85	isb
86	ret
87
88
89func dccvau
90	dc	cvau, x0
91	dsb	sy
92	isb
93	ret
94
95
96func dczva
97	dc	zva, x0
98	dsb	sy
99	isb
100	ret
101
102
103	/* ------------------------------------------
104	 * Clean+Invalidate from base address till
105	 * size. 'x0' = addr, 'x1' = size
106	 * ------------------------------------------
107	 */
108func flush_dcache_range
109	dcache_line_size x2, x3
110	add	x1, x0, x1
111	sub	x3, x2, #1
112	bic	x0, x0, x3
113flush_loop:
114	dc	civac, x0
115	add	x0, x0, x2
116	cmp	x0, x1
117	b.lo    flush_loop
118	dsb	sy
119	ret
120
121
122	/* ------------------------------------------
123	 * Invalidate from base address till
124	 * size. 'x0' = addr, 'x1' = size
125	 * ------------------------------------------
126	 */
127func inv_dcache_range
128	dcache_line_size x2, x3
129	add	x1, x0, x1
130	sub	x3, x2, #1
131	bic	x0, x0, x3
132inv_loop:
133	dc	ivac, x0
134	add	x0, x0, x2
135	cmp	x0, x1
136	b.lo    inv_loop
137	dsb	sy
138	ret
139
140
141	/* ------------------------------------------
142	 * Data cache operations by set/way to the
143	 * level specified
144	 * ------------------------------------------
145	 * ----------------------------------
146	 * Call this func with the clidr in
147	 * x0, starting cache level in x10,
148	 * last cache level in x3 & cm op in
149	 * x14
150	 * ----------------------------------
151	 */
152func dcsw_op
153all_start_at_level:
154	add	x2, x10, x10, lsr #1            // work out 3x current cache level
155	lsr	x1, x0, x2                      // extract cache type bits from clidr
156	and	x1, x1, #7                      // mask of the bits for current cache only
157	cmp	x1, #2                          // see what cache we have at this level
158	b.lt	skip                            // skip if no cache, or just i-cache
159	msr	csselr_el1, x10                 // select current cache level in csselr
160	isb                                     // isb to sych the new cssr&csidr
161	mrs	x1, ccsidr_el1                  // read the new ccsidr
162	and	x2, x1, #7                      // extract the length of the cache lines
163	add	x2, x2, #4                      // add 4 (line length offset)
164	mov	x4, #0x3ff
165	and	x4, x4, x1, lsr #3              // find maximum number on the way size
166	clz	w5, w4                          // find bit position of way size increment
167	mov	x7, #0x7fff
168	and	x7, x7, x1, lsr #13             // extract max number of the index size
169loop2:
170	mov	x9, x4                          // create working copy of max way size
171loop3:
172	lsl	x6, x9, x5
173	orr	x11, x10, x6                    // factor way and cache number into x11
174	lsl	x6, x7, x2
175	orr	x11, x11, x6                    // factor index number into x11
176	mov	x12, x0
177	mov	x13, x30 // lr
178	mov	x0, x11
179	blr	x14
180	mov	x0, x12
181	mov	x30, x13 // lr
182	subs	x9, x9, #1                      // decrement the way
183	b.ge    loop3
184	subs	x7, x7, #1                      // decrement the index
185	b.ge    loop2
186skip:
187	add	x10, x10, #2                    // increment cache number
188	cmp	x3, x10
189	b.gt    all_start_at_level
190finished:
191	mov	x10, #0                         // swith back to cache level 0
192	msr	csselr_el1, x10                 // select current cache level in csselr
193	dsb	sy
194	isb
195	ret
196
197
198func do_dcsw_op
199	cbz	x3, exit
200	cmp	x0, #DCISW
201	b.eq	dc_isw
202	cmp	x0, #DCCISW
203	b.eq	dc_cisw
204	cmp	x0, #DCCSW
205	b.eq	dc_csw
206dc_isw:
207	mov	x0, x9
208	adr	x14, dcisw
209	b	dcsw_op
210dc_cisw:
211	mov	x0, x9
212	adr	x14, dccisw
213	b	dcsw_op
214dc_csw:
215	mov	x0, x9
216	adr	x14, dccsw
217	b	dcsw_op
218exit:
219	ret
220
221
222func dcsw_op_louis
223	dsb	sy
224	setup_dcsw_op_args x10, x3, x9, #LOUIS_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT
225	b	do_dcsw_op
226
227
228func dcsw_op_all
229	dsb	sy
230	setup_dcsw_op_args x10, x3, x9, #LOC_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT
231	b	do_dcsw_op
232