2 * arch/xtensa/mm/misc.S
4 * Miscellaneous assembly functions.
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
10 * Copyright (C) 2001 - 2007 Tensilica Inc.
12 * Chris Zankel <chris@zankel.net>
16 #include <linux/linkage.h>
17 #include <linux/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.
27 * clear_page (unsigned long page)
36 __loopi a2, a7, PAGE_SIZE, 32
50 EXPORT_SYMBOL(clear_page)
53 * copy_page and copy_user_page are the same for non-cache-aliased configs.
55 * copy_page (void *to, void *from)
63 __loopi a2, a4, PAGE_SIZE, 32
93 EXPORT_SYMBOL(copy_page)
97 * If we have to deal with cache aliasing, we use temporary memory mappings
98 * to ensure that the source and destination pages have the same color as
99 * the virtual address. We use way 0 and 1 for temporary mappings in such cases.
101 * The temporary DTLB entries shouldn't be flushed by interrupts, but are
102 * flushed by preemptive task switches. Special code in the
103 * fast_second_level_miss handler re-established the temporary mapping.
104 * It requires that the PPNs for the destination and source addresses are
105 * in a6, and a7, respectively.
108 /* TLB miss exceptions are treated special in the following region */
110 ENTRY(__tlbtemp_mapping_start)
112 #if (DCACHE_WAY_SIZE > PAGE_SIZE)
115 * clear_page_alias(void *addr, unsigned long paddr)
119 ENTRY(clear_page_alias)
124 addi a6, a3, (PAGE_KERNEL | _PAGE_HW_WRITE)
130 __loopi a2, a7, PAGE_SIZE, 32
141 /* We need to invalidate the temporary dtlb entry. */
148 ENDPROC(clear_page_alias)
151 * copy_page_alias(void *to, void *from,
153 * unsigned long to_paddr, unsigned long from_paddr)
157 ENTRY(copy_page_alias)
161 /* Setup a temporary DTLB for destination. */
163 addi a6, a4, (PAGE_KERNEL | _PAGE_HW_WRITE)
167 /* Setup a temporary DTLB for source. */
169 addi a7, a5, PAGE_KERNEL
170 addi a8, a3, 1 # way1
175 1: __loopi a2, a4, PAGE_SIZE, 32
202 /* We need to invalidate any temporary mapping! */
204 addi a2, a2, -PAGE_SIZE
208 addi a3, a3, -PAGE_SIZE+1
214 ENDPROC(copy_page_alias)
218 #if (DCACHE_WAY_SIZE > PAGE_SIZE)
221 * void __flush_invalidate_dcache_page_alias (addr, phys)
225 ENTRY(__flush_invalidate_dcache_page_alias)
229 movi a7, 0 # required for exception handler
230 addi a6, a3, (PAGE_KERNEL | _PAGE_HW_WRITE)
235 ___flush_invalidate_dcache_page a2 a3
242 ENDPROC(__flush_invalidate_dcache_page_alias)
245 * void __invalidate_dcache_page_alias (addr, phys)
249 ENTRY(__invalidate_dcache_page_alias)
253 movi a7, 0 # required for exception handler
254 addi a6, a3, (PAGE_KERNEL | _PAGE_HW_WRITE)
259 ___invalidate_dcache_page a2 a3
266 ENDPROC(__invalidate_dcache_page_alias)
269 ENTRY(__tlbtemp_mapping_itlb)
271 #if (ICACHE_WAY_SIZE > PAGE_SIZE)
273 ENTRY(__invalidate_icache_page_alias)
277 addi a6, a3, (PAGE_KERNEL_EXEC | _PAGE_HW_WRITE)
282 ___invalidate_icache_page a2 a3
288 ENDPROC(__invalidate_icache_page_alias)
292 /* End of special treatment in tlb miss exception */
294 ENTRY(__tlbtemp_mapping_end)
299 * void __invalidate_icache_page(ulong start)
302 ENTRY(__invalidate_icache_page)
306 ___invalidate_icache_page a2 a3
311 ENDPROC(__invalidate_icache_page)
314 * void __invalidate_dcache_page(ulong start)
317 ENTRY(__invalidate_dcache_page)
321 ___invalidate_dcache_page a2 a3
326 ENDPROC(__invalidate_dcache_page)
329 * void __flush_invalidate_dcache_page(ulong start)
332 ENTRY(__flush_invalidate_dcache_page)
336 ___flush_invalidate_dcache_page a2 a3
341 ENDPROC(__flush_invalidate_dcache_page)
344 * void __flush_dcache_page(ulong start)
347 ENTRY(__flush_dcache_page)
351 ___flush_dcache_page a2 a3
356 ENDPROC(__flush_dcache_page)
359 * void __invalidate_icache_range(ulong start, ulong size)
362 ENTRY(__invalidate_icache_range)
366 ___invalidate_icache_range a2 a3 a4
371 ENDPROC(__invalidate_icache_range)
372 EXPORT_SYMBOL(__invalidate_icache_range)
375 * void __flush_invalidate_dcache_range(ulong start, ulong size)
378 ENTRY(__flush_invalidate_dcache_range)
382 ___flush_invalidate_dcache_range a2 a3 a4
387 ENDPROC(__flush_invalidate_dcache_range)
390 * void _flush_dcache_range(ulong start, ulong size)
393 ENTRY(__flush_dcache_range)
397 ___flush_dcache_range a2 a3 a4
402 ENDPROC(__flush_dcache_range)
403 EXPORT_SYMBOL(__flush_dcache_range)
406 * void _invalidate_dcache_range(ulong start, ulong size)
409 ENTRY(__invalidate_dcache_range)
413 ___invalidate_dcache_range a2 a3 a4
417 ENDPROC(__invalidate_dcache_range)
418 EXPORT_SYMBOL(__invalidate_dcache_range)
421 * void _invalidate_icache_all(void)
424 ENTRY(__invalidate_icache_all)
428 ___invalidate_icache_all a2 a3
433 ENDPROC(__invalidate_icache_all)
436 * void _flush_invalidate_dcache_all(void)
439 ENTRY(__flush_invalidate_dcache_all)
443 ___flush_invalidate_dcache_all a2 a3
448 ENDPROC(__flush_invalidate_dcache_all)
451 * void _invalidate_dcache_all(void)
454 ENTRY(__invalidate_dcache_all)
458 ___invalidate_dcache_all a2 a3
463 ENDPROC(__invalidate_dcache_all)