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
52 * copy_page and copy_user_page are the same for non-cache-aliased configs.
54 * copy_page (void *to, void *from)
62 __loopi a2, a4, PAGE_SIZE, 32
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.
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.
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)
117 ENTRY(clear_page_alias)
122 addi a6, a3, (PAGE_KERNEL | _PAGE_HW_WRITE)
128 __loopi a2, a7, PAGE_SIZE, 32
139 /* We need to invalidate the temporary dtlb entry. */
146 ENDPROC(clear_page_alias)
149 * copy_page_alias(void *to, void *from,
151 * unsigned long to_paddr, unsigned long from_paddr)
155 ENTRY(copy_page_alias)
159 /* Setup a temporary DTLB for destination. */
161 addi a6, a4, (PAGE_KERNEL | _PAGE_HW_WRITE)
165 /* Setup a temporary DTLB for source. */
167 addi a7, a5, PAGE_KERNEL
168 addi a8, a3, 1 # way1
173 1: __loopi a2, a4, PAGE_SIZE, 32
200 /* We need to invalidate any temporary mapping! */
202 addi a2, a2, -PAGE_SIZE
206 addi a3, a3, -PAGE_SIZE+1
212 ENDPROC(copy_page_alias)
216 #if (DCACHE_WAY_SIZE > PAGE_SIZE)
219 * void __flush_invalidate_dcache_page_alias (addr, phys)
223 ENTRY(__flush_invalidate_dcache_page_alias)
227 movi a7, 0 # required for exception handler
228 addi a6, a3, (PAGE_KERNEL | _PAGE_HW_WRITE)
233 ___flush_invalidate_dcache_page a2 a3
240 ENDPROC(__flush_invalidate_dcache_page_alias)
243 * void __invalidate_dcache_page_alias (addr, phys)
247 ENTRY(__invalidate_dcache_page_alias)
251 movi a7, 0 # required for exception handler
252 addi a6, a3, (PAGE_KERNEL | _PAGE_HW_WRITE)
257 ___invalidate_dcache_page a2 a3
264 ENDPROC(__invalidate_dcache_page_alias)
267 ENTRY(__tlbtemp_mapping_itlb)
269 #if (ICACHE_WAY_SIZE > PAGE_SIZE)
271 ENTRY(__invalidate_icache_page_alias)
275 addi a6, a3, (PAGE_KERNEL_EXEC | _PAGE_HW_WRITE)
280 ___invalidate_icache_page a2 a3
286 ENDPROC(__invalidate_icache_page_alias)
290 /* End of special treatment in tlb miss exception */
292 ENTRY(__tlbtemp_mapping_end)
297 * void __invalidate_icache_page(ulong start)
300 ENTRY(__invalidate_icache_page)
304 ___invalidate_icache_page a2 a3
309 ENDPROC(__invalidate_icache_page)
312 * void __invalidate_dcache_page(ulong start)
315 ENTRY(__invalidate_dcache_page)
319 ___invalidate_dcache_page a2 a3
324 ENDPROC(__invalidate_dcache_page)
327 * void __flush_invalidate_dcache_page(ulong start)
330 ENTRY(__flush_invalidate_dcache_page)
334 ___flush_invalidate_dcache_page a2 a3
339 ENDPROC(__flush_invalidate_dcache_page)
342 * void __flush_dcache_page(ulong start)
345 ENTRY(__flush_dcache_page)
349 ___flush_dcache_page a2 a3
354 ENDPROC(__flush_dcache_page)
357 * void __invalidate_icache_range(ulong start, ulong size)
360 ENTRY(__invalidate_icache_range)
364 ___invalidate_icache_range a2 a3 a4
369 ENDPROC(__invalidate_icache_range)
372 * void __flush_invalidate_dcache_range(ulong start, ulong size)
375 ENTRY(__flush_invalidate_dcache_range)
379 ___flush_invalidate_dcache_range a2 a3 a4
384 ENDPROC(__flush_invalidate_dcache_range)
387 * void _flush_dcache_range(ulong start, ulong size)
390 ENTRY(__flush_dcache_range)
394 ___flush_dcache_range a2 a3 a4
399 ENDPROC(__flush_dcache_range)
402 * void _invalidate_dcache_range(ulong start, ulong size)
405 ENTRY(__invalidate_dcache_range)
409 ___invalidate_dcache_range a2 a3 a4
413 ENDPROC(__invalidate_dcache_range)
416 * void _invalidate_icache_all(void)
419 ENTRY(__invalidate_icache_all)
423 ___invalidate_icache_all a2 a3
428 ENDPROC(__invalidate_icache_all)
431 * void _flush_invalidate_dcache_all(void)
434 ENTRY(__flush_invalidate_dcache_all)
438 ___flush_invalidate_dcache_all a2 a3
443 ENDPROC(__flush_invalidate_dcache_all)
446 * void _invalidate_dcache_all(void)
449 ENTRY(__invalidate_dcache_all)
453 ___invalidate_dcache_all a2 a3
458 ENDPROC(__invalidate_dcache_all)