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