fec: Use devm_request_and_ioremap()
[linux-2.6.git] / arch / xtensa / mm / misc.S
blobd97ed1ba7b0addd36d81782469ead96889535fc0
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         entry   a1, 16
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         retw
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         entry   a1, 16
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         retw
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_user_page (void *addr, unsigned long vaddr, struct page *page)
114  *                     a2              a3                 a4
115  */
117 ENTRY(clear_user_page)
119         entry   a1, 32
121         /* Mark page dirty and determine alias. */
123         movi    a7, (1 << PG_ARCH_1)
124         l32i    a5, a4, PAGE_FLAGS
125         xor     a6, a2, a3
126         extui   a3, a3, PAGE_SHIFT, DCACHE_ALIAS_ORDER
127         extui   a6, a6, PAGE_SHIFT, DCACHE_ALIAS_ORDER
128         or      a5, a5, a7
129         slli    a3, a3, PAGE_SHIFT
130         s32i    a5, a4, PAGE_FLAGS
132         /* Skip setting up a temporary DTLB if not aliased. */
134         beqz    a6, 1f
136         /* Invalidate kernel page. */
138         mov     a10, a2
139         call8   __invalidate_dcache_page
141         /* Setup a temporary DTLB with the color of the VPN */
143         movi    a4, -PAGE_OFFSET + (PAGE_KERNEL | _PAGE_HW_WRITE)
144         movi    a5, TLBTEMP_BASE_1                      # virt
145         add     a6, a2, a4                              # ppn
146         add     a2, a5, a3                              # add 'color'
148         wdtlb   a6, a2
149         dsync
151 1:      movi    a3, 0
152         __loopi a2, a7, PAGE_SIZE, 32
153         s32i    a3, a2, 0
154         s32i    a3, a2, 4
155         s32i    a3, a2, 8
156         s32i    a3, a2, 12
157         s32i    a3, a2, 16
158         s32i    a3, a2, 20
159         s32i    a3, a2, 24
160         s32i    a3, a2, 28
161         __endla a2, a7, 32
163         bnez    a6, 1f
164         retw
166         /* We need to invalidate the temporary idtlb entry, if any. */
168 1:      addi    a2, a2, -PAGE_SIZE
169         idtlb   a2
170         dsync
172         retw
174 ENDPROC(clear_user_page)
177  * copy_page_user (void *to, void *from, unsigned long vaddr, struct page *page)
178  *                    a2          a3            a4                  a5
179  */
181 ENTRY(copy_user_page)
183         entry   a1, 32
185         /* Mark page dirty and determine alias for destination. */
187         movi    a8, (1 << PG_ARCH_1)
188         l32i    a9, a5, PAGE_FLAGS
189         xor     a6, a2, a4
190         xor     a7, a3, a4
191         extui   a4, a4, PAGE_SHIFT, DCACHE_ALIAS_ORDER
192         extui   a6, a6, PAGE_SHIFT, DCACHE_ALIAS_ORDER
193         extui   a7, a7, PAGE_SHIFT, DCACHE_ALIAS_ORDER
194         or      a9, a9, a8
195         slli    a4, a4, PAGE_SHIFT
196         s32i    a9, a5, PAGE_FLAGS
197         movi    a5, -PAGE_OFFSET + (PAGE_KERNEL | _PAGE_HW_WRITE)
199         beqz    a6, 1f
201         /* Invalidate dcache */
203         mov     a10, a2
204         call8   __invalidate_dcache_page
206         /* Setup a temporary DTLB with a matching color. */
208         movi    a8, TLBTEMP_BASE_1                      # base
209         add     a6, a2, a5                              # ppn
210         add     a2, a8, a4                              # add 'color'
212         wdtlb   a6, a2
213         dsync
215         /* Skip setting up a temporary DTLB for destination if not aliased. */
217 1:      beqz    a7, 1f
219         /* Setup a temporary DTLB with a matching color. */
221         movi    a8, TLBTEMP_BASE_2                      # base
222         add     a7, a3, a5                              # ppn
223         add     a3, a8, a4
224         addi    a8, a3, 1                               # way1
226         wdtlb   a7, a8
227         dsync
229 1:      __loopi a2, a4, PAGE_SIZE, 32
231         l32i    a8, a3, 0
232         l32i    a9, a3, 4
233         s32i    a8, a2, 0
234         s32i    a9, a2, 4
236         l32i    a8, a3, 8
237         l32i    a9, a3, 12
238         s32i    a8, a2, 8
239         s32i    a9, a2, 12
241         l32i    a8, a3, 16
242         l32i    a9, a3, 20
243         s32i    a8, a2, 16
244         s32i    a9, a2, 20
246         l32i    a8, a3, 24
247         l32i    a9, a3, 28
248         s32i    a8, a2, 24
249         s32i    a9, a2, 28
251         addi    a2, a2, 32
252         addi    a3, a3, 32
254         __endl  a2, a4
256         /* We need to invalidate any temporary mapping! */
258         bnez    a6, 1f
259         bnez    a7, 2f
260         retw
262 1:      addi    a2, a2, -PAGE_SIZE
263         idtlb   a2
264         dsync
265         bnez    a7, 2f
266         retw
268 2:      addi    a3, a3, -PAGE_SIZE+1
269         idtlb   a3
270         dsync
272         retw
274 ENDPROC(copy_user_page)
276 #endif
278 #if (DCACHE_WAY_SIZE > PAGE_SIZE)
281  * void __flush_invalidate_dcache_page_alias (addr, phys)
282  *                                             a2    a3
283  */
285 ENTRY(__flush_invalidate_dcache_page_alias)
287         entry   sp, 16
289         movi    a7, 0                   # required for exception handler
290         addi    a6, a3, (PAGE_KERNEL | _PAGE_HW_WRITE)
291         mov     a4, a2
292         wdtlb   a6, a2
293         dsync
295         ___flush_invalidate_dcache_page a2 a3
297         idtlb   a4
298         dsync
300         retw
302 ENDPROC(__flush_invalidate_dcache_page_alias)
303 #endif
305 ENTRY(__tlbtemp_mapping_itlb)
307 #if (ICACHE_WAY_SIZE > PAGE_SIZE)
308         
309 ENTRY(__invalidate_icache_page_alias)
311         entry   sp, 16
313         addi    a6, a3, (PAGE_KERNEL_EXEC | _PAGE_HW_WRITE)
314         mov     a4, a2
315         witlb   a6, a2
316         isync
318         ___invalidate_icache_page a2 a3
320         iitlb   a4
321         isync
322         retw
324 ENDPROC(__invalidate_icache_page_alias)
326 #endif
328 /* End of special treatment in tlb miss exception */
330 ENTRY(__tlbtemp_mapping_end)
332 #endif /* CONFIG_MMU
335  * void __invalidate_icache_page(ulong start)
336  */
338 ENTRY(__invalidate_icache_page)
340         entry   sp, 16
342         ___invalidate_icache_page a2 a3
343         isync
345         retw
347 ENDPROC(__invalidate_icache_page)
350  * void __invalidate_dcache_page(ulong start)
351  */
353 ENTRY(__invalidate_dcache_page)
355         entry   sp, 16
357         ___invalidate_dcache_page a2 a3
358         dsync
360         retw
362 ENDPROC(__invalidate_dcache_page)
365  * void __flush_invalidate_dcache_page(ulong start)
366  */
368 ENTRY(__flush_invalidate_dcache_page)
370         entry   sp, 16
372         ___flush_invalidate_dcache_page a2 a3
374         dsync
375         retw
377 ENDPROC(__flush_invalidate_dcache_page)
380  * void __flush_dcache_page(ulong start)
381  */
383 ENTRY(__flush_dcache_page)
385         entry   sp, 16
387         ___flush_dcache_page a2 a3
389         dsync
390         retw
392 ENDPROC(__flush_dcache_page)
395  * void __invalidate_icache_range(ulong start, ulong size)
396  */
398 ENTRY(__invalidate_icache_range)
400         entry   sp, 16
402         ___invalidate_icache_range a2 a3 a4
403         isync
405         retw
407 ENDPROC(__invalidate_icache_range)
410  * void __flush_invalidate_dcache_range(ulong start, ulong size)
411  */
413 ENTRY(__flush_invalidate_dcache_range)
415         entry   sp, 16
417         ___flush_invalidate_dcache_range a2 a3 a4
418         dsync
420         retw
422 ENDPROC(__flush_invalidate_dcache_range)
425  * void _flush_dcache_range(ulong start, ulong size)
426  */
428 ENTRY(__flush_dcache_range)
430         entry   sp, 16
432         ___flush_dcache_range a2 a3 a4
433         dsync
435         retw
437 ENDPROC(__flush_dcache_range)
440  * void _invalidate_dcache_range(ulong start, ulong size)
441  */
443 ENTRY(__invalidate_dcache_range)
445         entry   sp, 16
447         ___invalidate_dcache_range a2 a3 a4
449         retw
451 ENDPROC(__invalidate_dcache_range)
454  * void _invalidate_icache_all(void)
455  */
457 ENTRY(__invalidate_icache_all)
459         entry   sp, 16
461         ___invalidate_icache_all a2 a3
462         isync
464         retw
466 ENDPROC(__invalidate_icache_all)
469  * void _flush_invalidate_dcache_all(void)
470  */
472 ENTRY(__flush_invalidate_dcache_all)
474         entry   sp, 16
476         ___flush_invalidate_dcache_all a2 a3
477         dsync
479         retw
481 ENDPROC(__flush_invalidate_dcache_all)
484  * void _invalidate_dcache_all(void)
485  */
487 ENTRY(__invalidate_dcache_all)
489         entry   sp, 16
491         ___invalidate_dcache_all a2 a3
492         dsync
494         retw
496 ENDPROC(__invalidate_dcache_all)