summaryrefslogtreecommitdiff
path: root/arch/parisc/kernel/pacache.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/parisc/kernel/pacache.S')
-rw-r--r--arch/parisc/kernel/pacache.S170
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.