xref: /rk3399_ARM-atf/lib/aarch64/cache_helpers.S (revision 8cec598ba3b689b86d9dfc58bca5610bdc48f55a)
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
127	 * level specified
128	 * ------------------------------------------
129	 * ----------------------------------
130	 * Call this func with the clidr in
131	 * x0, starting cache level in x10,
132	 * last cache level in x3 & cm op in
133	 * x14
134	 * ----------------------------------
135	 */
136func dcsw_op
137all_start_at_level:
138	add	x2, x10, x10, lsr #1            // work out 3x current cache level
139	lsr	x1, x0, x2                      // extract cache type bits from clidr
140	and	x1, x1, #7                      // mask of the bits for current cache only
141	cmp	x1, #2                          // see what cache we have at this level
142	b.lt	skip                            // skip if no cache, or just i-cache
143	msr	csselr_el1, x10                 // select current cache level in csselr
144	isb                                     // isb to sych the new cssr&csidr
145	mrs	x1, ccsidr_el1                  // read the new ccsidr
146	and	x2, x1, #7                      // extract the length of the cache lines
147	add	x2, x2, #4                      // add 4 (line length offset)
148	mov	x4, #0x3ff
149	and	x4, x4, x1, lsr #3              // find maximum number on the way size
150	clz	w5, w4                          // find bit position of way size increment
151	mov	x7, #0x7fff
152	and	x7, x7, x1, lsr #13             // extract max number of the index size
153loop2:
154	mov	x9, x4                          // create working copy of max way size
155loop3:
156	lsl	x6, x9, x5
157	orr	x11, x10, x6                    // factor way and cache number into x11
158	lsl	x6, x7, x2
159	orr	x11, x11, x6                    // factor index number into x11
160	mov	x12, x0
161	mov	x13, x30 // lr
162	mov	x0, x11
163	blr	x14
164	mov	x0, x12
165	mov	x30, x13 // lr
166	subs	x9, x9, #1                      // decrement the way
167	b.ge    loop3
168	subs	x7, x7, #1                      // decrement the index
169	b.ge    loop2
170skip:
171	add	x10, x10, #2                    // increment cache number
172	cmp	x3, x10
173	b.gt    all_start_at_level
174finished:
175	mov	x10, #0                         // swith back to cache level 0
176	msr	csselr_el1, x10                 // select current cache level in csselr
177	dsb	sy
178	isb
179	ret
180
181
182func do_dcsw_op
183	cbz	x3, exit
184	cmp	x0, #DCISW
185	b.eq	dc_isw
186	cmp	x0, #DCCISW
187	b.eq	dc_cisw
188	cmp	x0, #DCCSW
189	b.eq	dc_csw
190dc_isw:
191	mov	x0, x9
192	adr	x14, dcisw
193	b	dcsw_op
194dc_cisw:
195	mov	x0, x9
196	adr	x14, dccisw
197	b	dcsw_op
198dc_csw:
199	mov	x0, x9
200	adr	x14, dccsw
201	b	dcsw_op
202exit:
203	ret
204
205
206func dcsw_op_louis
207	dsb	sy
208	setup_dcsw_op_args x10, x3, x9, #LOUIS_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT
209	b	do_dcsw_op
210
211
212func dcsw_op_all
213	dsb	sy
214	setup_dcsw_op_args x10, x3, x9, #LOC_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT
215	b	do_dcsw_op
216