treewide: remove redundant IS_ERR() before error code check
[linux/fpc-iii.git] / arch / xtensa / mm / misc.S
blob6aa036c427c3b952ac4092de2b2932ae73403631
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  */
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>
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  */
31 ENTRY(clear_page)
33         abi_entry_default
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
47         abi_ret_default
49 ENDPROC(clear_page)
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  */
58 ENTRY(copy_page)
60         abi_entry_default
62         __loopi a2, a4, PAGE_SIZE, 32
64         l32i    a8, a3, 0
65         l32i    a9, a3, 4
66         s32i    a8, a2, 0
67         s32i    a9, a2, 4
69         l32i    a8, a3, 8
70         l32i    a9, a3, 12
71         s32i    a8, a2, 8
72         s32i    a9, a2, 12
74         l32i    a8, a3, 16
75         l32i    a9, a3, 20
76         s32i    a8, a2, 16
77         s32i    a9, a2, 20
79         l32i    a8, a3, 24
80         l32i    a9, a3, 28
81         s32i    a8, a2, 24
82         s32i    a9, a2, 28
84         addi    a2, a2, 32
85         addi    a3, a3, 32
87         __endl  a2, a4
89         abi_ret_default
91 ENDPROC(copy_page)
93 #ifdef CONFIG_MMU
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  */
106 /* TLB miss exceptions are treated special in the following region */
108 ENTRY(__tlbtemp_mapping_start)
110 #if (DCACHE_WAY_SIZE > PAGE_SIZE)
113  * clear_page_alias(void *addr, unsigned long paddr)
114  *                     a2              a3
115  */
117 ENTRY(clear_page_alias)
119         abi_entry_default
121         /* Skip setting up a temporary DTLB if not aliased low page. */
123         movi    a5, PAGE_OFFSET
124         movi    a6, 0
125         beqz    a3, 1f
127         /* Setup a temporary DTLB for the addr. */
129         addi    a6, a3, (PAGE_KERNEL | _PAGE_HW_WRITE)
130         mov     a4, a2
131         wdtlb   a6, a2
132         dsync
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
146         bnez    a6, 1f
147         abi_ret_default
149         /* We need to invalidate the temporary idtlb entry, if any. */
151 1:      idtlb   a4
152         dsync
154         abi_ret_default
156 ENDPROC(clear_page_alias)
159  * copy_page_alias(void *to, void *from,
160  *                      a2        a3
161  *                 unsigned long to_paddr, unsigned long from_paddr)
162  *                               a4                      a5
163  */
165 ENTRY(copy_page_alias)
167         abi_entry_default
169         /* Skip setting up a temporary DTLB for destination if not aliased. */
171         movi    a6, 0
172         movi    a7, 0
173         beqz    a4, 1f
175         /* Setup a temporary DTLB for destination. */
177         addi    a6, a4, (PAGE_KERNEL | _PAGE_HW_WRITE)
178         wdtlb   a6, a2
179         dsync
181         /* Skip setting up a temporary DTLB for source if not aliased. */
183 1:      beqz    a5, 1f
185         /* Setup a temporary DTLB for source. */
187         addi    a7, a5, PAGE_KERNEL
188         addi    a8, a3, 1                               # way1
190         wdtlb   a7, a8
191         dsync
193 1:      __loopi a2, a4, PAGE_SIZE, 32
195         l32i    a8, a3, 0
196         l32i    a9, a3, 4
197         s32i    a8, a2, 0
198         s32i    a9, a2, 4
200         l32i    a8, a3, 8
201         l32i    a9, a3, 12
202         s32i    a8, a2, 8
203         s32i    a9, a2, 12
205         l32i    a8, a3, 16
206         l32i    a9, a3, 20
207         s32i    a8, a2, 16
208         s32i    a9, a2, 20
210         l32i    a8, a3, 24
211         l32i    a9, a3, 28
212         s32i    a8, a2, 24
213         s32i    a9, a2, 28
215         addi    a2, a2, 32
216         addi    a3, a3, 32
218         __endl  a2, a4
220         /* We need to invalidate any temporary mapping! */
222         bnez    a6, 1f
223         bnez    a7, 2f
224         abi_ret_default
226 1:      addi    a2, a2, -PAGE_SIZE
227         idtlb   a2
228         dsync
229         bnez    a7, 2f
230         abi_ret_default
232 2:      addi    a3, a3, -PAGE_SIZE+1
233         idtlb   a3
234         dsync
236         abi_ret_default
238 ENDPROC(copy_page_alias)
240 #endif
242 #if (DCACHE_WAY_SIZE > PAGE_SIZE)
245  * void __flush_invalidate_dcache_page_alias (addr, phys)
246  *                                             a2    a3
247  */
249 ENTRY(__flush_invalidate_dcache_page_alias)
251         abi_entry_default
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
259         ___flush_invalidate_dcache_page a2 a3
261         idtlb   a4
262         dsync
264         abi_ret_default
266 ENDPROC(__flush_invalidate_dcache_page_alias)
269  * void __invalidate_dcache_page_alias (addr, phys)
270  *                                       a2    a3
271  */
273 ENTRY(__invalidate_dcache_page_alias)
275         abi_entry_default
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
283         ___invalidate_dcache_page a2 a3
285         idtlb   a4
286         dsync
288         abi_ret_default
290 ENDPROC(__invalidate_dcache_page_alias)
291 #endif
293 ENTRY(__tlbtemp_mapping_itlb)
295 #if (ICACHE_WAY_SIZE > PAGE_SIZE)
296         
297 ENTRY(__invalidate_icache_page_alias)
299         abi_entry_default
301         addi    a6, a3, (PAGE_KERNEL_EXEC | _PAGE_HW_WRITE)
302         mov     a4, a2
303         witlb   a6, a2
304         isync
306         ___invalidate_icache_page a2 a3
308         iitlb   a4
309         isync
310         abi_ret_default
312 ENDPROC(__invalidate_icache_page_alias)
314 #endif
316 /* End of special treatment in tlb miss exception */
318 ENTRY(__tlbtemp_mapping_end)
320 #endif /* CONFIG_MMU
323  * void __invalidate_icache_page(ulong start)
324  */
326 ENTRY(__invalidate_icache_page)
328         abi_entry_default
330         ___invalidate_icache_page a2 a3
331         isync
333         abi_ret_default
335 ENDPROC(__invalidate_icache_page)
338  * void __invalidate_dcache_page(ulong start)
339  */
341 ENTRY(__invalidate_dcache_page)
343         abi_entry_default
345         ___invalidate_dcache_page a2 a3
346         dsync
348         abi_ret_default
350 ENDPROC(__invalidate_dcache_page)
353  * void __flush_invalidate_dcache_page(ulong start)
354  */
356 ENTRY(__flush_invalidate_dcache_page)
358         abi_entry_default
360         ___flush_invalidate_dcache_page a2 a3
362         dsync
363         abi_ret_default
365 ENDPROC(__flush_invalidate_dcache_page)
368  * void __flush_dcache_page(ulong start)
369  */
371 ENTRY(__flush_dcache_page)
373         abi_entry_default
375         ___flush_dcache_page a2 a3
377         dsync
378         abi_ret_default
380 ENDPROC(__flush_dcache_page)
383  * void __invalidate_icache_range(ulong start, ulong size)
384  */
386 ENTRY(__invalidate_icache_range)
388         abi_entry_default
390         ___invalidate_icache_range a2 a3 a4
391         isync
393         abi_ret_default
395 ENDPROC(__invalidate_icache_range)
398  * void __flush_invalidate_dcache_range(ulong start, ulong size)
399  */
401 ENTRY(__flush_invalidate_dcache_range)
403         abi_entry_default
405         ___flush_invalidate_dcache_range a2 a3 a4
406         dsync
408         abi_ret_default
410 ENDPROC(__flush_invalidate_dcache_range)
413  * void _flush_dcache_range(ulong start, ulong size)
414  */
416 ENTRY(__flush_dcache_range)
418         abi_entry_default
420         ___flush_dcache_range a2 a3 a4
421         dsync
423         abi_ret_default
425 ENDPROC(__flush_dcache_range)
428  * void _invalidate_dcache_range(ulong start, ulong size)
429  */
431 ENTRY(__invalidate_dcache_range)
433         abi_entry_default
435         ___invalidate_dcache_range a2 a3 a4
437         abi_ret_default
439 ENDPROC(__invalidate_dcache_range)
442  * void _invalidate_icache_all(void)
443  */
445 ENTRY(__invalidate_icache_all)
447         abi_entry_default
449         ___invalidate_icache_all a2 a3
450         isync
452         abi_ret_default
454 ENDPROC(__invalidate_icache_all)
457  * void _flush_invalidate_dcache_all(void)
458  */
460 ENTRY(__flush_invalidate_dcache_all)
462         abi_entry_default
464         ___flush_invalidate_dcache_all a2 a3
465         dsync
467         abi_ret_default
469 ENDPROC(__flush_invalidate_dcache_all)
472  * void _invalidate_dcache_all(void)
473  */
475 ENTRY(__invalidate_dcache_all)
477         abi_entry_default
479         ___invalidate_dcache_all a2 a3
480         dsync
482         abi_ret_default
484 ENDPROC(__invalidate_dcache_all)