/*1* arch/xtensa/mm/misc.S2*3* Miscellaneous assembly functions.4*5* This file is subject to the terms and conditions of the GNU General Public6* License. See the file "COPYING" in the main directory of this archive7* for more details.8*9* Copyright (C) 2001 - 2007 Tensilica Inc.10*11* Chris Zankel <[email protected]>12*/131415#include <linux/linkage.h>16#include <linux/pgtable.h>17#include <asm/page.h>18#include <asm/asmmacro.h>19#include <asm/cacheasm.h>20#include <asm/tlbflush.h>212223/*24* clear_page and clear_user_page are the same for non-cache-aliased configs.25*26* clear_page (unsigned long page)27* a228*/2930ENTRY(clear_page)3132abi_entry_default3334movi a3, 035__loopi a2, a7, PAGE_SIZE, 3236s32i a3, a2, 037s32i a3, a2, 438s32i a3, a2, 839s32i a3, a2, 1240s32i a3, a2, 1641s32i a3, a2, 2042s32i a3, a2, 2443s32i a3, a2, 2844__endla a2, a7, 324546abi_ret_default4748ENDPROC(clear_page)49EXPORT_SYMBOL(clear_page)5051/*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 a356*/5758ENTRY(copy_page)5960abi_entry_default6162__loopi a2, a4, PAGE_SIZE, 326364l32i a8, a3, 065l32i a9, a3, 466s32i a8, a2, 067s32i a9, a2, 46869l32i a8, a3, 870l32i a9, a3, 1271s32i a8, a2, 872s32i a9, a2, 127374l32i a8, a3, 1675l32i a9, a3, 2076s32i a8, a2, 1677s32i a9, a2, 207879l32i a8, a3, 2480l32i a9, a3, 2881s32i a8, a2, 2482s32i a9, a2, 288384addi a2, a2, 3285addi a3, a3, 328687__endl a2, a48889abi_ret_default9091ENDPROC(copy_page)92EXPORT_SYMBOL(copy_page)9394#ifdef CONFIG_MMU95/*96* If we have to deal with cache aliasing, we use temporary memory mappings97* to ensure that the source and destination pages have the same color as98* the virtual address. We use way 0 and 1 for temporary mappings in such cases.99*100* The temporary DTLB entries shouldn't be flushed by interrupts, but are101* flushed by preemptive task switches. Special code in the102* fast_second_level_miss handler re-established the temporary mapping.103* It requires that the PPNs for the destination and source addresses are104* in a6, and a7, respectively.105*/106107/* TLB miss exceptions are treated special in the following region */108109ENTRY(__tlbtemp_mapping_start)110111#if (DCACHE_WAY_SIZE > PAGE_SIZE)112113/*114* clear_page_alias(void *addr, unsigned long paddr)115* a2 a3116*/117118ENTRY(clear_page_alias)119120abi_entry_default121122movi a5, PAGE_OFFSET123addi a6, a3, (PAGE_KERNEL | _PAGE_HW_WRITE)124mov a4, a2125wdtlb a6, a2126dsync127128movi a3, 0129__loopi a2, a7, PAGE_SIZE, 32130s32i a3, a2, 0131s32i a3, a2, 4132s32i a3, a2, 8133s32i a3, a2, 12134s32i a3, a2, 16135s32i a3, a2, 20136s32i a3, a2, 24137s32i a3, a2, 28138__endla a2, a7, 32139140/* We need to invalidate the temporary dtlb entry. */141142idtlb a4143dsync144145abi_ret_default146147ENDPROC(clear_page_alias)148149/*150* copy_page_alias(void *to, void *from,151* a2 a3152* unsigned long to_paddr, unsigned long from_paddr)153* a4 a5154*/155156ENTRY(copy_page_alias)157158abi_entry_default159160/* Setup a temporary DTLB for destination. */161162addi a6, a4, (PAGE_KERNEL | _PAGE_HW_WRITE)163wdtlb a6, a2164dsync165166/* Setup a temporary DTLB for source. */167168addi a7, a5, PAGE_KERNEL169addi a8, a3, 1 # way1170171wdtlb a7, a8172dsync1731741: __loopi a2, a4, PAGE_SIZE, 32175176l32i a8, a3, 0177l32i a9, a3, 4178s32i a8, a2, 0179s32i a9, a2, 4180181l32i a8, a3, 8182l32i a9, a3, 12183s32i a8, a2, 8184s32i a9, a2, 12185186l32i a8, a3, 16187l32i a9, a3, 20188s32i a8, a2, 16189s32i a9, a2, 20190191l32i a8, a3, 24192l32i a9, a3, 28193s32i a8, a2, 24194s32i a9, a2, 28195196addi a2, a2, 32197addi a3, a3, 32198199__endl a2, a4200201/* We need to invalidate any temporary mapping! */202203addi a2, a2, -PAGE_SIZE204idtlb a2205dsync206207addi a3, a3, -PAGE_SIZE+1208idtlb a3209dsync210211abi_ret_default212213ENDPROC(copy_page_alias)214215#endif216217#if (DCACHE_WAY_SIZE > PAGE_SIZE)218219/*220* void __flush_invalidate_dcache_page_alias (addr, phys)221* a2 a3222*/223224ENTRY(__flush_invalidate_dcache_page_alias)225226abi_entry_default227228movi a7, 0 # required for exception handler229addi a6, a3, (PAGE_KERNEL | _PAGE_HW_WRITE)230mov a4, a2231wdtlb a6, a2232dsync233234___flush_invalidate_dcache_page a2 a3235236idtlb a4237dsync238239abi_ret_default240241ENDPROC(__flush_invalidate_dcache_page_alias)242243/*244* void __invalidate_dcache_page_alias (addr, phys)245* a2 a3246*/247248ENTRY(__invalidate_dcache_page_alias)249250abi_entry_default251252movi a7, 0 # required for exception handler253addi a6, a3, (PAGE_KERNEL | _PAGE_HW_WRITE)254mov a4, a2255wdtlb a6, a2256dsync257258___invalidate_dcache_page a2 a3259260idtlb a4261dsync262263abi_ret_default264265ENDPROC(__invalidate_dcache_page_alias)266#endif267268ENTRY(__tlbtemp_mapping_itlb)269270#if (ICACHE_WAY_SIZE > PAGE_SIZE)271272ENTRY(__invalidate_icache_page_alias)273274abi_entry_default275276addi a6, a3, (PAGE_KERNEL_EXEC | _PAGE_HW_WRITE)277mov a4, a2278witlb a6, a2279isync280281___invalidate_icache_page a2 a3282283iitlb a4284isync285abi_ret_default286287ENDPROC(__invalidate_icache_page_alias)288289#endif290291/* End of special treatment in tlb miss exception */292293ENTRY(__tlbtemp_mapping_end)294295#endif /* CONFIG_MMU296297/*298* void __invalidate_icache_page(ulong start)299*/300301ENTRY(__invalidate_icache_page)302303abi_entry_default304305___invalidate_icache_page a2 a3306isync307308abi_ret_default309310ENDPROC(__invalidate_icache_page)311312/*313* void __invalidate_dcache_page(ulong start)314*/315316ENTRY(__invalidate_dcache_page)317318abi_entry_default319320___invalidate_dcache_page a2 a3321dsync322323abi_ret_default324325ENDPROC(__invalidate_dcache_page)326327/*328* void __flush_invalidate_dcache_page(ulong start)329*/330331ENTRY(__flush_invalidate_dcache_page)332333abi_entry_default334335___flush_invalidate_dcache_page a2 a3336337dsync338abi_ret_default339340ENDPROC(__flush_invalidate_dcache_page)341342/*343* void __flush_dcache_page(ulong start)344*/345346ENTRY(__flush_dcache_page)347348abi_entry_default349350___flush_dcache_page a2 a3351352dsync353abi_ret_default354355ENDPROC(__flush_dcache_page)356357/*358* void __invalidate_icache_range(ulong start, ulong size)359*/360361ENTRY(__invalidate_icache_range)362363abi_entry_default364365___invalidate_icache_range a2 a3 a4366isync367368abi_ret_default369370ENDPROC(__invalidate_icache_range)371EXPORT_SYMBOL(__invalidate_icache_range)372373/*374* void __flush_invalidate_dcache_range(ulong start, ulong size)375*/376377ENTRY(__flush_invalidate_dcache_range)378379abi_entry_default380381___flush_invalidate_dcache_range a2 a3 a4382dsync383384abi_ret_default385386ENDPROC(__flush_invalidate_dcache_range)387388/*389* void _flush_dcache_range(ulong start, ulong size)390*/391392ENTRY(__flush_dcache_range)393394abi_entry_default395396___flush_dcache_range a2 a3 a4397dsync398399abi_ret_default400401ENDPROC(__flush_dcache_range)402EXPORT_SYMBOL(__flush_dcache_range)403404/*405* void _invalidate_dcache_range(ulong start, ulong size)406*/407408ENTRY(__invalidate_dcache_range)409410abi_entry_default411412___invalidate_dcache_range a2 a3 a4413414abi_ret_default415416ENDPROC(__invalidate_dcache_range)417EXPORT_SYMBOL(__invalidate_dcache_range)418419/*420* void _invalidate_icache_all(void)421*/422423ENTRY(__invalidate_icache_all)424425abi_entry_default426427___invalidate_icache_all a2 a3428isync429430abi_ret_default431432ENDPROC(__invalidate_icache_all)433434/*435* void _flush_invalidate_dcache_all(void)436*/437438ENTRY(__flush_invalidate_dcache_all)439440abi_entry_default441442___flush_invalidate_dcache_all a2 a3443dsync444445abi_ret_default446447ENDPROC(__flush_invalidate_dcache_all)448449/*450* void _invalidate_dcache_all(void)451*/452453ENTRY(__invalidate_dcache_all)454455abi_entry_default456457___invalidate_dcache_all a2 a3458dsync459460abi_ret_default461462ENDPROC(__invalidate_dcache_all)463464465