1 /*-
2 * Copyright (C) 2008 MARVELL INTERNATIONAL LTD.
3 * All rights reserved.
4 *
5 * Developed by Semihalf.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of MARVELL nor the names of contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32 #include <machine/asm.h>
33 __FBSDID("$FreeBSD: releng/9.1/sys/arm/arm/cpufunc_asm_sheeva.S 212825 2010-09-18 16:57:05Z mav $");
34
35 #include <machine/param.h>
36
37 .Lsheeva_cache_line_size:
38 .word _C_LABEL(arm_pdcache_line_size)
39 .Lsheeva_asm_page_mask:
40 .word _C_LABEL(PAGE_MASK)
41
42 ENTRY(sheeva_setttb)
43 /* Disable irqs */
44 mrs r2, cpsr
45 orr r3, r2, #I32_bit | F32_bit
46 msr cpsr_c, r3
47
48 mov r1, #0
49 mcr p15, 0, r1, c7, c5, 0 /* Invalidate ICache */
50 1: mrc p15, 0, r15, c7, c14, 3 /* Test, clean and invalidate DCache */
51 bne 1b /* More to do? */
52
53 mcr p15, 1, r1, c15, c9, 0 /* Clean L2 */
54 mcr p15, 1, r1, c15, c11, 0 /* Invalidate L2 */
55
56 /* Reenable irqs */
57 msr cpsr_c, r2
58
59 mcr p15, 0, r1, c7, c10, 4 /* drain the write buffer */
60
61 mcr p15, 0, r0, c2, c0, 0 /* load new TTB */
62
63 mcr p15, 0, r0, c8, c7, 0 /* invalidate I+D TLBs */
64 RET
65
66 ENTRY(sheeva_dcache_wbinv_range)
67 str lr, [sp, #-4]!
68 mrs lr, cpsr
69 /* Start with cache line aligned address */
70 ldr ip, .Lsheeva_cache_line_size
71 ldr ip, [ip]
72 sub ip, ip, #1
73 and r2, r0, ip
74 add r1, r1, r2
75 add r1, r1, ip
76 bics r1, r1, ip
77 bics r0, r0, ip
78
79 ldr ip, .Lsheeva_asm_page_mask
80 and r2, r0, ip
81 rsb r2, r2, #PAGE_SIZE
82 cmp r1, r2
83 movcc ip, r1
84 movcs ip, r2
85 1:
86 add r3, r0, ip
87 sub r2, r3, #1
88 /* Disable irqs */
89 orr r3, lr, #I32_bit | F32_bit
90 msr cpsr_c, r3
91 mcr p15, 5, r0, c15, c15, 0 /* Clean and inv zone start address */
92 mcr p15, 5, r2, c15, c15, 1 /* Clean and inv zone end address */
93 /* Enable irqs */
94 msr cpsr_c, lr
95
96 add r0, r0, ip
97 sub r1, r1, ip
98 cmp r1, #PAGE_SIZE
99 movcc ip, r1
100 movcs ip, #PAGE_SIZE
101 cmp r1, #0
102 bne 1b
103 mov r0, #0
104 mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */
105 ldr lr, [sp], #4
106 RET
107
108 ENTRY(sheeva_idcache_wbinv_range)
109 str lr, [sp, #-4]!
110 mrs lr, cpsr
111 /* Start with cache line aligned address */
112 ldr ip, .Lsheeva_cache_line_size
113 ldr ip, [ip]
114 sub ip, ip, #1
115 and r2, r0, ip
116 add r1, r1, r2
117 add r1, r1, ip
118 bics r1, r1, ip
119 bics r0, r0, ip
120
121 ldr ip, .Lsheeva_asm_page_mask
122 and r2, r0, ip
123 rsb r2, r2, #PAGE_SIZE
124 cmp r1, r2
125 movcc ip, r1
126 movcs ip, r2
127 1:
128 add r3, r0, ip
129 sub r2, r3, #1
130 /* Disable irqs */
131 orr r3, lr, #I32_bit | F32_bit
132 msr cpsr_c, r3
133 mcr p15, 5, r0, c15, c15, 0 /* Clean and inv zone start address */
134 mcr p15, 5, r2, c15, c15, 1 /* Clean and inv zone end address */
135 /* Enable irqs */
136 msr cpsr_c, lr
137
138 /* Invalidate and clean icache line by line */
139 ldr r3, .Lsheeva_cache_line_size
140 ldr r3, [r3]
141 2:
142 mcr p15, 0, r0, c7, c5, 1
143 add r0, r0, r3
144 cmp r2, r0
145 bhi 2b
146
147 add r0, r2, #1
148 sub r1, r1, ip
149 cmp r1, #PAGE_SIZE
150 movcc ip, r1
151 movcs ip, #PAGE_SIZE
152 cmp r1, #0
153 bne 1b
154 mov r0, #0
155 mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */
156 ldr lr, [sp], #4
157 RET
158
159 ENTRY(sheeva_dcache_inv_range)
160 str lr, [sp, #-4]!
161 mrs lr, cpsr
162 /* Start with cache line aligned address */
163 ldr ip, .Lsheeva_cache_line_size
164 ldr ip, [ip]
165 sub ip, ip, #1
166 and r2, r0, ip
167 add r1, r1, r2
168 add r1, r1, ip
169 bics r1, r1, ip
170 bics r0, r0, ip
171
172 ldr ip, .Lsheeva_asm_page_mask
173 and r2, r0, ip
174 rsb r2, r2, #PAGE_SIZE
175 cmp r1, r2
176 movcc ip, r1
177 movcs ip, r2
178 1:
179 add r3, r0, ip
180 sub r2, r3, #1
181 /* Disable irqs */
182 orr r3, lr, #I32_bit | F32_bit
183 msr cpsr_c, r3
184 mcr p15, 5, r0, c15, c14, 0 /* Inv zone start address */
185 mcr p15, 5, r2, c15, c14, 1 /* Inv zone end address */
186 /* Enable irqs */
187 msr cpsr_c, lr
188
189 add r0, r0, ip
190 sub r1, r1, ip
191 cmp r1, #PAGE_SIZE
192 movcc ip, r1
193 movcs ip, #PAGE_SIZE
194 cmp r1, #0
195 bne 1b
196 mov r0, #0
197 mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */
198 ldr lr, [sp], #4
199 RET
200
201 ENTRY(sheeva_dcache_wb_range)
202 str lr, [sp, #-4]!
203 mrs lr, cpsr
204 /* Start with cache line aligned address */
205 ldr ip, .Lsheeva_cache_line_size
206 ldr ip, [ip]
207 sub ip, ip, #1
208 and r2, r0, ip
209 add r1, r1, r2
210 add r1, r1, ip
211 bics r1, r1, ip
212 bics r0, r0, ip
213
214 ldr ip, .Lsheeva_asm_page_mask
215 and r2, r0, ip
216 rsb r2, r2, #PAGE_SIZE
217 cmp r1, r2
218 movcc ip, r1
219 movcs ip, r2
220 1:
221 add r3, r0, ip
222 sub r2, r3, #1
223 /* Disable irqs */
224 orr r3, lr, #I32_bit | F32_bit
225 msr cpsr_c, r3
226 mcr p15, 5, r0, c15, c13, 0 /* Clean zone start address */
227 mcr p15, 5, r2, c15, c13, 1 /* Clean zone end address */
228 /* Enable irqs */
229 msr cpsr_c, lr
230
231 add r0, r0, ip
232 sub r1, r1, ip
233 cmp r1, #PAGE_SIZE
234 movcc ip, r1
235 movcs ip, #PAGE_SIZE
236 cmp r1, #0
237 bne 1b
238 mov r0, #0
239 mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */
240 ldr lr, [sp], #4
241 RET
242
243 ENTRY(sheeva_l2cache_wbinv_range)
244 str lr, [sp, #-4]!
245 mrs lr, cpsr
246 /* Start with cache line aligned address */
247 ldr ip, .Lsheeva_cache_line_size
248 ldr ip, [ip]
249 sub ip, ip, #1
250 and r2, r0, ip
251 add r1, r1, r2
252 add r1, r1, ip
253 bics r1, r1, ip
254 bics r0, r0, ip
255
256 ldr ip, .Lsheeva_asm_page_mask
257 and r2, r0, ip
258 rsb r2, r2, #PAGE_SIZE
259 cmp r1, r2
260 movcc ip, r1
261 movcs ip, r2
262 1:
263 add r3, r0, ip
264 sub r2, r3, #1
265 /* Disable irqs */
266 orr r3, lr, #I32_bit | F32_bit
267 msr cpsr_c, r3
268 mcr p15, 1, r0, c15, c9, 4 /* Clean L2 zone start address */
269 mcr p15, 1, r2, c15, c9, 5 /* Clean L2 zone end address */
270 mcr p15, 1, r0, c15, c11, 4 /* Inv L2 zone start address */
271 mcr p15, 1, r2, c15, c11, 5 /* Inv L2 zone end address */
272 /* Enable irqs */
273 msr cpsr_c, lr
274
275 add r0, r0, ip
276 sub r1, r1, ip
277 cmp r1, #PAGE_SIZE
278 movcc ip, r1
279 movcs ip, #PAGE_SIZE
280 cmp r1, #0
281 bne 1b
282 mov r0, #0
283 mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */
284 ldr lr, [sp], #4
285 RET
286
287 ENTRY(sheeva_l2cache_inv_range)
288 str lr, [sp, #-4]!
289 mrs lr, cpsr
290 /* Start with cache line aligned address */
291 ldr ip, .Lsheeva_cache_line_size
292 ldr ip, [ip]
293 sub ip, ip, #1
294 and r2, r0, ip
295 add r1, r1, r2
296 add r1, r1, ip
297 bics r1, r1, ip
298 bics r0, r0, ip
299
300 ldr ip, .Lsheeva_asm_page_mask
301 and r2, r0, ip
302 rsb r2, r2, #PAGE_SIZE
303 cmp r1, r2
304 movcc ip, r1
305 movcs ip, r2
306 1:
307 add r3, r0, ip
308 sub r2, r3, #1
309 /* Disable irqs */
310 orr r3, lr, #I32_bit | F32_bit
311 msr cpsr_c, r3
312 mcr p15, 1, r0, c15, c11, 4 /* Inv L2 zone start address */
313 mcr p15, 1, r2, c15, c11, 5 /* Inv L2 zone end address */
314 /* Enable irqs */
315 msr cpsr_c, lr
316
317 add r0, r0, ip
318 sub r1, r1, ip
319 cmp r1, #PAGE_SIZE
320 movcc ip, r1
321 movcs ip, #PAGE_SIZE
322 cmp r1, #0
323 bne 1b
324 mov r0, #0
325 mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */
326 ldr lr, [sp], #4
327 RET
328
329 ENTRY(sheeva_l2cache_wb_range)
330 str lr, [sp, #-4]!
331 mrs lr, cpsr
332 /* Start with cache line aligned address */
333 ldr ip, .Lsheeva_cache_line_size
334 ldr ip, [ip]
335 sub ip, ip, #1
336 and r2, r0, ip
337 add r1, r1, r2
338 add r1, r1, ip
339 bics r1, r1, ip
340 bics r0, r0, ip
341
342 ldr ip, .Lsheeva_asm_page_mask
343 and r2, r0, ip
344 rsb r2, r2, #PAGE_SIZE
345 cmp r1, r2
346 movcc ip, r1
347 movcs ip, r2
348 1:
349 add r3, r0, ip
350 sub r2, r3, #1
351 /* Disable irqs */
352 orr r3, lr, #I32_bit | F32_bit
353 msr cpsr_c, r3
354 mcr p15, 1, r0, c15, c9, 4 /* Clean L2 zone start address */
355 mcr p15, 1, r2, c15, c9, 5 /* Clean L2 zone end address */
356 /* Enable irqs */
357 msr cpsr_c, lr
358
359 add r0, r0, ip
360 sub r1, r1, ip
361 cmp r1, #PAGE_SIZE
362 movcc ip, r1
363 movcs ip, #PAGE_SIZE
364 cmp r1, #0
365 bne 1b
366 mov r0, #0
367 mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */
368 ldr lr, [sp], #4
369 RET
370
371 ENTRY(sheeva_l2cache_wbinv_all)
372 mov r0, #0
373 mcr p15, 1, r0, c15, c9, 0 /* Clean L2 */
374 mcr p15, 1, r0, c15, c11, 0 /* Invalidate L2 */
375 mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */
376 RET
377
378 /* This function modifies register value as follows:
379 *
380 * arg1 arg EFFECT (bit value saved into register)
381 * 0 0 not changed
382 * 0 1 negated
383 * 1 0 cleared
384 * 1 1 set
385 */
386 ENTRY(sheeva_control_ext)
387 mrc p15, 1, r3, c15, c1, 0 /* Read the control register */
388 bic r2, r3, r0 /* Clear bits */
389 eor r2, r2, r1 /* XOR bits */
390
391 teq r2, r3 /* Only write if there is a change */
392 mcrne p15, 1, r2, c15, c1, 0 /* Write new control register */
393 mov r0, r3 /* Return old value */
394 RET
395
396 ENTRY(sheeva_cpu_sleep)
397 mov r0, #0
398 mcr p15, 0, r0, c7, c10, 4 /* Drain write buffer */
399 mcr p15, 0, r0, c7, c0, 4 /* Wait for interrupt */
400 mov pc, lr
401
Cache object: 6e575f825b4aec0b7347dbbb4dff6c68
|