diff options
Diffstat (limited to 'arch/parisc/kernel/pacache.S')
| -rw-r--r-- | arch/parisc/kernel/pacache.S | 170 |
1 files changed, 31 insertions, 139 deletions
diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S index 187f032c9dd8..541370d14559 100644 --- a/arch/parisc/kernel/pacache.S +++ b/arch/parisc/kernel/pacache.S @@ -1,22 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * PARISC TLB and cache flushing support * Copyright (C) 2000-2001 Hewlett-Packard (John Marvin) * Copyright (C) 2001 Matthew Wilcox (willy at parisc-linux.org) * Copyright (C) 2002 Richard Hirst (rhirst with parisc-linux.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* @@ -34,12 +21,12 @@ #include <asm/psw.h> #include <asm/assembly.h> -#include <asm/pgtable.h> #include <asm/cache.h> #include <asm/ldcw.h> #include <asm/alternative.h> #include <linux/linkage.h> #include <linux/init.h> +#include <linux/pgtable.h> .section .text.hot .align 16 @@ -76,7 +63,7 @@ ENTRY_CFI(flush_tlb_all_local) /* Flush Instruction Tlb */ - LDREG ITLB_SID_BASE(%r1), %r20 +88: LDREG ITLB_SID_BASE(%r1), %r20 LDREG ITLB_SID_STRIDE(%r1), %r21 LDREG ITLB_SID_COUNT(%r1), %r22 LDREG ITLB_OFF_BASE(%r1), %arg0 @@ -116,6 +103,7 @@ fitonemiddle: /* Loop if LOOP = 1 */ add %r21, %r20, %r20 /* increment space */ fitdone: + ALTERNATIVE(88b, fitdone, ALT_COND_NO_SPLIT_TLB, INSN_NOP) /* Flush Data Tlb */ @@ -186,6 +174,15 @@ fdtdone: 2: bv %r0(%r2) nop + + /* + * When running in qemu, drop whole flush_tlb_all_local function and + * replace by one pdtlbe instruction, for which QEMU will drop all + * local TLB entries. + */ +3: pdtlbe %r0(%sr1,%r0) + bv,n %r0(%r2) + ALTERNATIVE_CODE(flush_tlb_all_local, 2, ALT_COND_RUN_ON_QEMU, 3b) ENDPROC_CFI(flush_tlb_all_local) .import cache_info,data @@ -303,7 +300,6 @@ fdoneloop2: fdce,m %arg1(%sr1, %arg0) /* Fdce for one loop */ fdsync: - syncdma sync mtsm %r22 /* restore I-bit */ 89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP) @@ -311,39 +307,6 @@ fdsync: nop ENDPROC_CFI(flush_data_cache_local) -/* Macros to serialize TLB purge operations on SMP. */ - - .macro tlb_lock la,flags,tmp -#ifdef CONFIG_SMP -98: -#if __PA_LDCW_ALIGNMENT > 4 - load32 pa_tlb_lock + __PA_LDCW_ALIGNMENT-1, \la - depi 0,31,__PA_LDCW_ALIGN_ORDER, \la -#else - load32 pa_tlb_lock, \la -#endif - rsm PSW_SM_I,\flags -1: LDCW 0(\la),\tmp - cmpib,<>,n 0,\tmp,3f -2: ldw 0(\la),\tmp - cmpb,<> %r0,\tmp,1b - nop - b,n 2b -3: -99: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP) -#endif - .endm - - .macro tlb_unlock la,flags,tmp -#ifdef CONFIG_SMP -98: ldi 1,\tmp - sync - stw \tmp,0(\la) - mtsm \flags -99: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP) -#endif - .endm - /* Clear page using kernel mapping. */ ENTRY_CFI(clear_page_asm) @@ -524,6 +487,8 @@ ENDPROC_CFI(copy_page_asm) * parisc chip designers that there will not ever be a parisc * chip with a larger alias boundary (Never say never :-) ). * + * Yah, what about the PA8800 and PA8900 processors? + * * Subtle: the dtlb miss handlers support the temp alias region by * "knowing" that if a dtlb miss happens within the temp alias * region it must have occurred while in clear_user_page. Since @@ -535,19 +500,10 @@ ENDPROC_CFI(copy_page_asm) * miss on the translation, the dtlb miss handler inserts the * translation into the tlb using these values: * - * %r26 physical page (shifted for tlb insert) of "to" translation - * %r23 physical page (shifted for tlb insert) of "from" translation + * %r26 physical address of "to" translation + * %r23 physical address of "from" translation */ - /* Drop prot bits and convert to page addr for iitlbt and idtlbt */ - #define PAGE_ADD_SHIFT (PAGE_SHIFT-12) - .macro convert_phys_for_tlb_insert20 phys - extrd,u \phys, 56-PAGE_ADD_SHIFT, 32-PAGE_ADD_SHIFT, \phys -#if _PAGE_SIZE_ENCODING_DEFAULT - depdi _PAGE_SIZE_ENCODING_DEFAULT, 63, (63-58), \phys -#endif - .endm - /* * copy_user_page_asm() performs a page copy using mappings * equivalent to the user page mappings. It can be used to @@ -576,24 +532,10 @@ ENTRY_CFI(copy_user_page_asm) sub %r25, %r1, %r23 ldil L%(TMPALIAS_MAP_START), %r28 -#ifdef CONFIG_64BIT -#if (TMPALIAS_MAP_START >= 0x80000000) - depdi 0, 31,32, %r28 /* clear any sign extension */ -#endif - convert_phys_for_tlb_insert20 %r26 /* convert phys addr to tlb insert format */ - convert_phys_for_tlb_insert20 %r23 /* convert phys addr to tlb insert format */ - depd %r24,63,22, %r28 /* Form aliased virtual address 'to' */ - depdi 0, 63,PAGE_SHIFT, %r28 /* Clear any offset bits */ + dep_safe %r24, 31,TMPALIAS_SIZE_BITS, %r28 /* Form aliased virtual address 'to' */ + depi_safe 0, 31,PAGE_SHIFT, %r28 /* Clear any offset bits */ copy %r28, %r29 - depdi 1, 41,1, %r29 /* Form aliased virtual address 'from' */ -#else - extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */ - extrw,u %r23, 24,25, %r23 /* convert phys addr to tlb insert format */ - depw %r24, 31,22, %r28 /* Form aliased virtual address 'to' */ - depwi 0, 31,PAGE_SHIFT, %r28 /* Clear any offset bits */ - copy %r28, %r29 - depwi 1, 9,1, %r29 /* Form aliased virtual address 'from' */ -#endif + depi_safe 1, 31-TMPALIAS_SIZE_BITS,1, %r29 /* Form aliased virtual address 'from' */ /* Purge any old translations */ @@ -601,10 +543,8 @@ ENTRY_CFI(copy_user_page_asm) pdtlb,l %r0(%r28) pdtlb,l %r0(%r29) #else - tlb_lock %r20,%r21,%r22 0: pdtlb %r0(%r28) 1: pdtlb %r0(%r29) - tlb_unlock %r20,%r21,%r22 ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB) ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SMP, INSN_PxTLB) #endif @@ -725,27 +665,15 @@ ENTRY_CFI(clear_user_page_asm) tophys_r1 %r26 ldil L%(TMPALIAS_MAP_START), %r28 -#ifdef CONFIG_64BIT -#if (TMPALIAS_MAP_START >= 0x80000000) - depdi 0, 31,32, %r28 /* clear any sign extension */ -#endif - convert_phys_for_tlb_insert20 %r26 /* convert phys addr to tlb insert format */ - depd %r25, 63,22, %r28 /* Form aliased virtual address 'to' */ - depdi 0, 63,PAGE_SHIFT, %r28 /* Clear any offset bits */ -#else - extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */ - depw %r25, 31,22, %r28 /* Form aliased virtual address 'to' */ - depwi 0, 31,PAGE_SHIFT, %r28 /* Clear any offset bits */ -#endif + dep_safe %r25, 31,TMPALIAS_SIZE_BITS, %r28 /* Form aliased virtual address 'to' */ + depi_safe 0, 31,PAGE_SHIFT, %r28 /* Clear any offset bits */ /* Purge any old translation */ #ifdef CONFIG_PA20 pdtlb,l %r0(%r28) #else - tlb_lock %r20,%r21,%r22 0: pdtlb %r0(%r28) - tlb_unlock %r20,%r21,%r22 ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB) #endif @@ -803,27 +731,15 @@ ENDPROC_CFI(clear_user_page_asm) ENTRY_CFI(flush_dcache_page_asm) ldil L%(TMPALIAS_MAP_START), %r28 -#ifdef CONFIG_64BIT -#if (TMPALIAS_MAP_START >= 0x80000000) - depdi 0, 31,32, %r28 /* clear any sign extension */ -#endif - convert_phys_for_tlb_insert20 %r26 /* convert phys addr to tlb insert format */ - depd %r25, 63,22, %r28 /* Form aliased virtual address 'to' */ - depdi 0, 63,PAGE_SHIFT, %r28 /* Clear any offset bits */ -#else - extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */ - depw %r25, 31,22, %r28 /* Form aliased virtual address 'to' */ - depwi 0, 31,PAGE_SHIFT, %r28 /* Clear any offset bits */ -#endif + dep_safe %r25, 31,TMPALIAS_SIZE_BITS, %r28 /* Form aliased virtual address 'to' */ + depi_safe 0, 31,PAGE_SHIFT, %r28 /* Clear any offset bits */ /* Purge any old translation */ #ifdef CONFIG_PA20 pdtlb,l %r0(%r28) #else - tlb_lock %r20,%r21,%r22 0: pdtlb %r0(%r28) - tlb_unlock %r20,%r21,%r22 ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB) #endif @@ -864,27 +780,15 @@ ENDPROC_CFI(flush_dcache_page_asm) ENTRY_CFI(purge_dcache_page_asm) ldil L%(TMPALIAS_MAP_START), %r28 -#ifdef CONFIG_64BIT -#if (TMPALIAS_MAP_START >= 0x80000000) - depdi 0, 31,32, %r28 /* clear any sign extension */ -#endif - convert_phys_for_tlb_insert20 %r26 /* convert phys addr to tlb insert format */ - depd %r25, 63,22, %r28 /* Form aliased virtual address 'to' */ - depdi 0, 63,PAGE_SHIFT, %r28 /* Clear any offset bits */ -#else - extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */ - depw %r25, 31,22, %r28 /* Form aliased virtual address 'to' */ - depwi 0, 31,PAGE_SHIFT, %r28 /* Clear any offset bits */ -#endif + dep_safe %r25, 31,TMPALIAS_SIZE_BITS, %r28 /* Form aliased virtual address 'to' */ + depi_safe 0, 31,PAGE_SHIFT, %r28 /* Clear any offset bits */ /* Purge any old translation */ #ifdef CONFIG_PA20 pdtlb,l %r0(%r28) #else - tlb_lock %r20,%r21,%r22 0: pdtlb %r0(%r28) - tlb_unlock %r20,%r21,%r22 ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB) #endif @@ -925,18 +829,8 @@ ENDPROC_CFI(purge_dcache_page_asm) ENTRY_CFI(flush_icache_page_asm) ldil L%(TMPALIAS_MAP_START), %r28 -#ifdef CONFIG_64BIT -#if (TMPALIAS_MAP_START >= 0x80000000) - depdi 0, 31,32, %r28 /* clear any sign extension */ -#endif - convert_phys_for_tlb_insert20 %r26 /* convert phys addr to tlb insert format */ - depd %r25, 63,22, %r28 /* Form aliased virtual address 'to' */ - depdi 0, 63,PAGE_SHIFT, %r28 /* Clear any offset bits */ -#else - extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */ - depw %r25, 31,22, %r28 /* Form aliased virtual address 'to' */ - depwi 0, 31,PAGE_SHIFT, %r28 /* Clear any offset bits */ -#endif + dep_safe %r25, 31,TMPALIAS_SIZE_BITS, %r28 /* Form aliased virtual address 'to' */ + depi_safe 0, 31,PAGE_SHIFT, %r28 /* Clear any offset bits */ /* Purge any old translation. Note that the FIC instruction * may use either the instruction or data TLB. Given that we @@ -948,10 +842,8 @@ ENTRY_CFI(flush_icache_page_asm) 1: pitlb,l %r0(%sr4,%r28) ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SPLIT_TLB, INSN_NOP) #else - tlb_lock %r20,%r21,%r22 0: pdtlb %r0(%r28) 1: pitlb %r0(%sr4,%r28) - tlb_unlock %r20,%r21,%r22 ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB) ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SMP, INSN_PxTLB) ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SPLIT_TLB, INSN_NOP) @@ -997,6 +889,7 @@ ENDPROC_CFI(flush_icache_page_asm) ENTRY_CFI(flush_kernel_dcache_page_asm) 88: ldil L%dcache_stride, %r1 ldw R%dcache_stride(%r1), %r23 + depi_safe 0, 31,PAGE_SHIFT, %r26 /* Clear any offset bits */ #ifdef CONFIG_64BIT depdi,z 1, 63-PAGE_SHIFT,1, %r25 @@ -1033,6 +926,7 @@ ENDPROC_CFI(flush_kernel_dcache_page_asm) ENTRY_CFI(purge_kernel_dcache_page_asm) 88: ldil L%dcache_stride, %r1 ldw R%dcache_stride(%r1), %r23 + depi_safe 0, 31,PAGE_SHIFT, %r26 /* Clear any offset bits */ #ifdef CONFIG_64BIT depdi,z 1, 63-PAGE_SHIFT,1, %r25 @@ -1144,7 +1038,6 @@ ENTRY_CFI(flush_kernel_dcache_range_asm) sync 89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP) - syncdma bv %r0(%r2) nop ENDPROC_CFI(flush_kernel_dcache_range_asm) @@ -1186,7 +1079,6 @@ ENTRY_CFI(purge_kernel_dcache_range_asm) sync 89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP) - syncdma bv %r0(%r2) nop ENDPROC_CFI(purge_kernel_dcache_range_asm) @@ -1310,7 +1202,7 @@ ENTRY_CFI(flush_kernel_icache_range_asm) nop ENDPROC_CFI(flush_kernel_icache_range_asm) - __INIT + .text /* align should cover use of rfi in disable_sr_hashing_asm and * srdis_done. |
