Merge remote-tracking branches 'asoc/topic/simple', 'asoc/topic/sirf', 'asoc/topic...
[deliverable/linux.git] / arch / xtensa / mm / misc.S
1 /*
2 * arch/xtensa/mm/misc.S
3 *
4 * Miscellaneous assembly functions.
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * Copyright (C) 2001 - 2007 Tensilica Inc.
11 *
12 * Chris Zankel <chris@zankel.net>
13 */
14
15
16 #include <linux/linkage.h>
17 #include <asm/page.h>
18 #include <asm/pgtable.h>
19 #include <asm/asmmacro.h>
20 #include <asm/cacheasm.h>
21 #include <asm/tlbflush.h>
22
23
24 /*
25 * clear_page and clear_user_page are the same for non-cache-aliased configs.
26 *
27 * clear_page (unsigned long page)
28 * a2
29 */
30
31 ENTRY(clear_page)
32
33 entry a1, 16
34
35 movi a3, 0
36 __loopi a2, a7, PAGE_SIZE, 32
37 s32i a3, a2, 0
38 s32i a3, a2, 4
39 s32i a3, a2, 8
40 s32i a3, a2, 12
41 s32i a3, a2, 16
42 s32i a3, a2, 20
43 s32i a3, a2, 24
44 s32i a3, a2, 28
45 __endla a2, a7, 32
46
47 retw
48
49 ENDPROC(clear_page)
50
51 /*
52 * copy_page and copy_user_page are the same for non-cache-aliased configs.
53 *
54 * copy_page (void *to, void *from)
55 * a2 a3
56 */
57
58 ENTRY(copy_page)
59
60 entry a1, 16
61
62 __loopi a2, a4, PAGE_SIZE, 32
63
64 l32i a8, a3, 0
65 l32i a9, a3, 4
66 s32i a8, a2, 0
67 s32i a9, a2, 4
68
69 l32i a8, a3, 8
70 l32i a9, a3, 12
71 s32i a8, a2, 8
72 s32i a9, a2, 12
73
74 l32i a8, a3, 16
75 l32i a9, a3, 20
76 s32i a8, a2, 16
77 s32i a9, a2, 20
78
79 l32i a8, a3, 24
80 l32i a9, a3, 28
81 s32i a8, a2, 24
82 s32i a9, a2, 28
83
84 addi a2, a2, 32
85 addi a3, a3, 32
86
87 __endl a2, a4
88
89 retw
90
91 ENDPROC(copy_page)
92
93 #ifdef CONFIG_MMU
94 /*
95 * If we have to deal with cache aliasing, we use temporary memory mappings
96 * to ensure that the source and destination pages have the same color as
97 * the virtual address. We use way 0 and 1 for temporary mappings in such cases.
98 *
99 * The temporary DTLB entries shouldn't be flushed by interrupts, but are
100 * flushed by preemptive task switches. Special code in the
101 * fast_second_level_miss handler re-established the temporary mapping.
102 * It requires that the PPNs for the destination and source addresses are
103 * in a6, and a7, respectively.
104 */
105
106 /* TLB miss exceptions are treated special in the following region */
107
108 ENTRY(__tlbtemp_mapping_start)
109
110 #if (DCACHE_WAY_SIZE > PAGE_SIZE)
111
112 /*
113 * clear_page_alias(void *addr, unsigned long paddr)
114 * a2 a3
115 */
116
117 ENTRY(clear_page_alias)
118
119 entry a1, 32
120
121 /* Skip setting up a temporary DTLB if not aliased low page. */
122
123 movi a5, PAGE_OFFSET
124 movi a6, 0
125 beqz a3, 1f
126
127 /* Setup a temporary DTLB for the addr. */
128
129 addi a6, a3, (PAGE_KERNEL | _PAGE_HW_WRITE)
130 mov a4, a2
131 wdtlb a6, a2
132 dsync
133
134 1: movi a3, 0
135 __loopi a2, a7, PAGE_SIZE, 32
136 s32i a3, a2, 0
137 s32i a3, a2, 4
138 s32i a3, a2, 8
139 s32i a3, a2, 12
140 s32i a3, a2, 16
141 s32i a3, a2, 20
142 s32i a3, a2, 24
143 s32i a3, a2, 28
144 __endla a2, a7, 32
145
146 bnez a6, 1f
147 retw
148
149 /* We need to invalidate the temporary idtlb entry, if any. */
150
151 1: idtlb a4
152 dsync
153
154 retw
155
156 ENDPROC(clear_page_alias)
157
158 /*
159 * copy_page_alias(void *to, void *from,
160 * a2 a3
161 * unsigned long to_paddr, unsigned long from_paddr)
162 * a4 a5
163 */
164
165 ENTRY(copy_page_alias)
166
167 entry a1, 32
168
169 /* Skip setting up a temporary DTLB for destination if not aliased. */
170
171 movi a6, 0
172 movi a7, 0
173 beqz a4, 1f
174
175 /* Setup a temporary DTLB for destination. */
176
177 addi a6, a4, (PAGE_KERNEL | _PAGE_HW_WRITE)
178 wdtlb a6, a2
179 dsync
180
181 /* Skip setting up a temporary DTLB for source if not aliased. */
182
183 1: beqz a5, 1f
184
185 /* Setup a temporary DTLB for source. */
186
187 addi a7, a5, PAGE_KERNEL
188 addi a8, a3, 1 # way1
189
190 wdtlb a7, a8
191 dsync
192
193 1: __loopi a2, a4, PAGE_SIZE, 32
194
195 l32i a8, a3, 0
196 l32i a9, a3, 4
197 s32i a8, a2, 0
198 s32i a9, a2, 4
199
200 l32i a8, a3, 8
201 l32i a9, a3, 12
202 s32i a8, a2, 8
203 s32i a9, a2, 12
204
205 l32i a8, a3, 16
206 l32i a9, a3, 20
207 s32i a8, a2, 16
208 s32i a9, a2, 20
209
210 l32i a8, a3, 24
211 l32i a9, a3, 28
212 s32i a8, a2, 24
213 s32i a9, a2, 28
214
215 addi a2, a2, 32
216 addi a3, a3, 32
217
218 __endl a2, a4
219
220 /* We need to invalidate any temporary mapping! */
221
222 bnez a6, 1f
223 bnez a7, 2f
224 retw
225
226 1: addi a2, a2, -PAGE_SIZE
227 idtlb a2
228 dsync
229 bnez a7, 2f
230 retw
231
232 2: addi a3, a3, -PAGE_SIZE+1
233 idtlb a3
234 dsync
235
236 retw
237
238 ENDPROC(copy_page_alias)
239
240 #endif
241
242 #if (DCACHE_WAY_SIZE > PAGE_SIZE)
243
244 /*
245 * void __flush_invalidate_dcache_page_alias (addr, phys)
246 * a2 a3
247 */
248
249 ENTRY(__flush_invalidate_dcache_page_alias)
250
251 entry sp, 16
252
253 movi a7, 0 # required for exception handler
254 addi a6, a3, (PAGE_KERNEL | _PAGE_HW_WRITE)
255 mov a4, a2
256 wdtlb a6, a2
257 dsync
258
259 ___flush_invalidate_dcache_page a2 a3
260
261 idtlb a4
262 dsync
263
264 retw
265
266 ENDPROC(__flush_invalidate_dcache_page_alias)
267
268 /*
269 * void __invalidate_dcache_page_alias (addr, phys)
270 * a2 a3
271 */
272
273 ENTRY(__invalidate_dcache_page_alias)
274
275 entry sp, 16
276
277 movi a7, 0 # required for exception handler
278 addi a6, a3, (PAGE_KERNEL | _PAGE_HW_WRITE)
279 mov a4, a2
280 wdtlb a6, a2
281 dsync
282
283 ___invalidate_dcache_page a2 a3
284
285 idtlb a4
286 dsync
287
288 retw
289
290 ENDPROC(__invalidate_dcache_page_alias)
291 #endif
292
293 ENTRY(__tlbtemp_mapping_itlb)
294
295 #if (ICACHE_WAY_SIZE > PAGE_SIZE)
296
297 ENTRY(__invalidate_icache_page_alias)
298
299 entry sp, 16
300
301 addi a6, a3, (PAGE_KERNEL_EXEC | _PAGE_HW_WRITE)
302 mov a4, a2
303 witlb a6, a2
304 isync
305
306 ___invalidate_icache_page a2 a3
307
308 iitlb a4
309 isync
310 retw
311
312 ENDPROC(__invalidate_icache_page_alias)
313
314 #endif
315
316 /* End of special treatment in tlb miss exception */
317
318 ENTRY(__tlbtemp_mapping_end)
319
320 #endif /* CONFIG_MMU
321
322 /*
323 * void __invalidate_icache_page(ulong start)
324 */
325
326 ENTRY(__invalidate_icache_page)
327
328 entry sp, 16
329
330 ___invalidate_icache_page a2 a3
331 isync
332
333 retw
334
335 ENDPROC(__invalidate_icache_page)
336
337 /*
338 * void __invalidate_dcache_page(ulong start)
339 */
340
341 ENTRY(__invalidate_dcache_page)
342
343 entry sp, 16
344
345 ___invalidate_dcache_page a2 a3
346 dsync
347
348 retw
349
350 ENDPROC(__invalidate_dcache_page)
351
352 /*
353 * void __flush_invalidate_dcache_page(ulong start)
354 */
355
356 ENTRY(__flush_invalidate_dcache_page)
357
358 entry sp, 16
359
360 ___flush_invalidate_dcache_page a2 a3
361
362 dsync
363 retw
364
365 ENDPROC(__flush_invalidate_dcache_page)
366
367 /*
368 * void __flush_dcache_page(ulong start)
369 */
370
371 ENTRY(__flush_dcache_page)
372
373 entry sp, 16
374
375 ___flush_dcache_page a2 a3
376
377 dsync
378 retw
379
380 ENDPROC(__flush_dcache_page)
381
382 /*
383 * void __invalidate_icache_range(ulong start, ulong size)
384 */
385
386 ENTRY(__invalidate_icache_range)
387
388 entry sp, 16
389
390 ___invalidate_icache_range a2 a3 a4
391 isync
392
393 retw
394
395 ENDPROC(__invalidate_icache_range)
396
397 /*
398 * void __flush_invalidate_dcache_range(ulong start, ulong size)
399 */
400
401 ENTRY(__flush_invalidate_dcache_range)
402
403 entry sp, 16
404
405 ___flush_invalidate_dcache_range a2 a3 a4
406 dsync
407
408 retw
409
410 ENDPROC(__flush_invalidate_dcache_range)
411
412 /*
413 * void _flush_dcache_range(ulong start, ulong size)
414 */
415
416 ENTRY(__flush_dcache_range)
417
418 entry sp, 16
419
420 ___flush_dcache_range a2 a3 a4
421 dsync
422
423 retw
424
425 ENDPROC(__flush_dcache_range)
426
427 /*
428 * void _invalidate_dcache_range(ulong start, ulong size)
429 */
430
431 ENTRY(__invalidate_dcache_range)
432
433 entry sp, 16
434
435 ___invalidate_dcache_range a2 a3 a4
436
437 retw
438
439 ENDPROC(__invalidate_dcache_range)
440
441 /*
442 * void _invalidate_icache_all(void)
443 */
444
445 ENTRY(__invalidate_icache_all)
446
447 entry sp, 16
448
449 ___invalidate_icache_all a2 a3
450 isync
451
452 retw
453
454 ENDPROC(__invalidate_icache_all)
455
456 /*
457 * void _flush_invalidate_dcache_all(void)
458 */
459
460 ENTRY(__flush_invalidate_dcache_all)
461
462 entry sp, 16
463
464 ___flush_invalidate_dcache_all a2 a3
465 dsync
466
467 retw
468
469 ENDPROC(__flush_invalidate_dcache_all)
470
471 /*
472 * void _invalidate_dcache_all(void)
473 */
474
475 ENTRY(__invalidate_dcache_all)
476
477 entry sp, 16
478
479 ___invalidate_dcache_all a2 a3
480 dsync
481
482 retw
483
484 ENDPROC(__invalidate_dcache_all)
This page took 0.08441 seconds and 6 git commands to generate.