diff options
-rw-r--r-- | arch/parisc/include/asm/alternative.h | 47 | ||||
-rw-r--r-- | arch/parisc/include/asm/cache.h | 22 | ||||
-rw-r--r-- | arch/parisc/include/asm/pgtable.h | 3 | ||||
-rw-r--r-- | arch/parisc/include/asm/sections.h | 2 | ||||
-rw-r--r-- | arch/parisc/include/asm/tlbflush.h | 3 | ||||
-rw-r--r-- | arch/parisc/kernel/cache.c | 12 | ||||
-rw-r--r-- | arch/parisc/kernel/entry.S | 10 | ||||
-rw-r--r-- | arch/parisc/kernel/pacache.S | 64 | ||||
-rw-r--r-- | arch/parisc/kernel/setup.c | 81 | ||||
-rw-r--r-- | arch/parisc/kernel/signal.c | 1 | ||||
-rw-r--r-- | arch/parisc/kernel/vmlinux.lds.S | 6 | ||||
-rw-r--r-- | arch/parisc/mm/init.c | 15 | ||||
-rw-r--r-- | drivers/parisc/ccio-dma.c | 12 | ||||
-rw-r--r-- | drivers/parisc/sba_iommu.c | 17 |
14 files changed, 233 insertions, 62 deletions
diff --git a/arch/parisc/include/asm/alternative.h b/arch/parisc/include/asm/alternative.h new file mode 100644 index 000000000000..bf485a94d0b4 --- /dev/null +++ b/arch/parisc/include/asm/alternative.h | |||
@@ -0,0 +1,47 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | #ifndef __ASM_PARISC_ALTERNATIVE_H | ||
3 | #define __ASM_PARISC_ALTERNATIVE_H | ||
4 | |||
5 | #define ALT_COND_NO_SMP 0x01 /* when running UP instead of SMP */ | ||
6 | #define ALT_COND_NO_DCACHE 0x02 /* if system has no d-cache */ | ||
7 | #define ALT_COND_NO_ICACHE 0x04 /* if system has no i-cache */ | ||
8 | #define ALT_COND_NO_SPLIT_TLB 0x08 /* if split_tlb == 0 */ | ||
9 | #define ALT_COND_NO_IOC_FDC 0x10 /* if I/O cache does not need flushes */ | ||
10 | |||
11 | #define INSN_PxTLB 0x02 /* modify pdtlb, pitlb */ | ||
12 | #define INSN_NOP 0x08000240 /* nop */ | ||
13 | |||
14 | #ifndef __ASSEMBLY__ | ||
15 | |||
16 | #include <linux/init.h> | ||
17 | #include <linux/types.h> | ||
18 | #include <linux/stddef.h> | ||
19 | #include <linux/stringify.h> | ||
20 | |||
21 | struct alt_instr { | ||
22 | s32 orig_offset; /* offset to original instructions */ | ||
23 | u32 len; /* end of original instructions */ | ||
24 | u32 cond; /* see ALT_COND_XXX */ | ||
25 | u32 replacement; /* replacement instruction or code */ | ||
26 | }; | ||
27 | |||
28 | void set_kernel_text_rw(int enable_read_write); | ||
29 | |||
30 | /* Alternative SMP implementation. */ | ||
31 | #define ALTERNATIVE(cond, replacement) "!0:" \ | ||
32 | ".section .altinstructions, \"aw\" !" \ | ||
33 | ".word (0b-4-.), 1, " __stringify(cond) "," \ | ||
34 | __stringify(replacement) " !" \ | ||
35 | ".previous" | ||
36 | |||
37 | #else | ||
38 | |||
39 | #define ALTERNATIVE(from, to, cond, replacement)\ | ||
40 | .section .altinstructions, "aw" ! \ | ||
41 | .word (from - .), (to - from)/4 ! \ | ||
42 | .word cond, replacement ! \ | ||
43 | .previous | ||
44 | |||
45 | #endif /* __ASSEMBLY__ */ | ||
46 | |||
47 | #endif /* __ASM_PARISC_ALTERNATIVE_H */ | ||
diff --git a/arch/parisc/include/asm/cache.h b/arch/parisc/include/asm/cache.h index 150b7f30ea90..006fb939cac8 100644 --- a/arch/parisc/include/asm/cache.h +++ b/arch/parisc/include/asm/cache.h | |||
@@ -6,6 +6,7 @@ | |||
6 | #ifndef __ARCH_PARISC_CACHE_H | 6 | #ifndef __ARCH_PARISC_CACHE_H |
7 | #define __ARCH_PARISC_CACHE_H | 7 | #define __ARCH_PARISC_CACHE_H |
8 | 8 | ||
9 | #include <asm/alternative.h> | ||
9 | 10 | ||
10 | /* | 11 | /* |
11 | * PA 2.0 processors have 64 and 128-byte L2 cachelines; PA 1.1 processors | 12 | * PA 2.0 processors have 64 and 128-byte L2 cachelines; PA 1.1 processors |
@@ -41,9 +42,24 @@ extern int icache_stride; | |||
41 | extern struct pdc_cache_info cache_info; | 42 | extern struct pdc_cache_info cache_info; |
42 | void parisc_setup_cache_timing(void); | 43 | void parisc_setup_cache_timing(void); |
43 | 44 | ||
44 | #define pdtlb(addr) asm volatile("pdtlb 0(%%sr1,%0)" : : "r" (addr)); | 45 | #define pdtlb(addr) asm volatile("pdtlb 0(%%sr1,%0)" \ |
45 | #define pitlb(addr) asm volatile("pitlb 0(%%sr1,%0)" : : "r" (addr)); | 46 | ALTERNATIVE(ALT_COND_NO_SMP, INSN_PxTLB) \ |
46 | #define pdtlb_kernel(addr) asm volatile("pdtlb 0(%0)" : : "r" (addr)); | 47 | : : "r" (addr)) |
48 | #define pitlb(addr) asm volatile("pitlb 0(%%sr1,%0)" \ | ||
49 | ALTERNATIVE(ALT_COND_NO_SMP, INSN_PxTLB) \ | ||
50 | ALTERNATIVE(ALT_COND_NO_SPLIT_TLB, INSN_NOP) \ | ||
51 | : : "r" (addr)) | ||
52 | #define pdtlb_kernel(addr) asm volatile("pdtlb 0(%0)" \ | ||
53 | ALTERNATIVE(ALT_COND_NO_SMP, INSN_PxTLB) \ | ||
54 | : : "r" (addr)) | ||
55 | |||
56 | #define asm_io_fdc(addr) asm volatile("fdc %%r0(%0)" \ | ||
57 | ALTERNATIVE(ALT_COND_NO_DCACHE, INSN_NOP) \ | ||
58 | ALTERNATIVE(ALT_COND_NO_IOC_FDC, INSN_NOP) \ | ||
59 | : : "r" (addr)) | ||
60 | #define asm_io_sync() asm volatile("sync" \ | ||
61 | ALTERNATIVE(ALT_COND_NO_DCACHE, INSN_NOP) \ | ||
62 | ALTERNATIVE(ALT_COND_NO_IOC_FDC, INSN_NOP) :: ) | ||
47 | 63 | ||
48 | #endif /* ! __ASSEMBLY__ */ | 64 | #endif /* ! __ASSEMBLY__ */ |
49 | 65 | ||
diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h index b86c31291f0a..94c0ef7a9e03 100644 --- a/arch/parisc/include/asm/pgtable.h +++ b/arch/parisc/include/asm/pgtable.h | |||
@@ -43,8 +43,7 @@ static inline void purge_tlb_entries(struct mm_struct *mm, unsigned long addr) | |||
43 | { | 43 | { |
44 | mtsp(mm->context, 1); | 44 | mtsp(mm->context, 1); |
45 | pdtlb(addr); | 45 | pdtlb(addr); |
46 | if (unlikely(split_tlb)) | 46 | pitlb(addr); |
47 | pitlb(addr); | ||
48 | } | 47 | } |
49 | 48 | ||
50 | /* Certain architectures need to do special things when PTEs | 49 | /* Certain architectures need to do special things when PTEs |
diff --git a/arch/parisc/include/asm/sections.h b/arch/parisc/include/asm/sections.h index 5a40b51df80c..bb52aea0cb21 100644 --- a/arch/parisc/include/asm/sections.h +++ b/arch/parisc/include/asm/sections.h | |||
@@ -5,6 +5,8 @@ | |||
5 | /* nothing to see, move along */ | 5 | /* nothing to see, move along */ |
6 | #include <asm-generic/sections.h> | 6 | #include <asm-generic/sections.h> |
7 | 7 | ||
8 | extern char __alt_instructions[], __alt_instructions_end[]; | ||
9 | |||
8 | #ifdef CONFIG_64BIT | 10 | #ifdef CONFIG_64BIT |
9 | 11 | ||
10 | #define HAVE_DEREFERENCE_FUNCTION_DESCRIPTOR 1 | 12 | #define HAVE_DEREFERENCE_FUNCTION_DESCRIPTOR 1 |
diff --git a/arch/parisc/include/asm/tlbflush.h b/arch/parisc/include/asm/tlbflush.h index 14668bd52d60..6804374efa66 100644 --- a/arch/parisc/include/asm/tlbflush.h +++ b/arch/parisc/include/asm/tlbflush.h | |||
@@ -85,8 +85,7 @@ static inline void flush_tlb_page(struct vm_area_struct *vma, | |||
85 | purge_tlb_start(flags); | 85 | purge_tlb_start(flags); |
86 | mtsp(sid, 1); | 86 | mtsp(sid, 1); |
87 | pdtlb(addr); | 87 | pdtlb(addr); |
88 | if (unlikely(split_tlb)) | 88 | pitlb(addr); |
89 | pitlb(addr); | ||
90 | purge_tlb_end(flags); | 89 | purge_tlb_end(flags); |
91 | } | 90 | } |
92 | #endif | 91 | #endif |
diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c index 9f1c29d06574..56dc9791ee23 100644 --- a/arch/parisc/kernel/cache.c +++ b/arch/parisc/kernel/cache.c | |||
@@ -479,18 +479,6 @@ int __flush_tlb_range(unsigned long sid, unsigned long start, | |||
479 | /* Purge TLB entries for small ranges using the pdtlb and | 479 | /* Purge TLB entries for small ranges using the pdtlb and |
480 | pitlb instructions. These instructions execute locally | 480 | pitlb instructions. These instructions execute locally |
481 | but cause a purge request to be broadcast to other TLBs. */ | 481 | but cause a purge request to be broadcast to other TLBs. */ |
482 | if (likely(!split_tlb)) { | ||
483 | while (start < end) { | ||
484 | purge_tlb_start(flags); | ||
485 | mtsp(sid, 1); | ||
486 | pdtlb(start); | ||
487 | purge_tlb_end(flags); | ||
488 | start += PAGE_SIZE; | ||
489 | } | ||
490 | return 0; | ||
491 | } | ||
492 | |||
493 | /* split TLB case */ | ||
494 | while (start < end) { | 482 | while (start < end) { |
495 | purge_tlb_start(flags); | 483 | purge_tlb_start(flags); |
496 | mtsp(sid, 1); | 484 | mtsp(sid, 1); |
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index 7c85a91b4710..d3e2633cd688 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <asm/ldcw.h> | 38 | #include <asm/ldcw.h> |
39 | #include <asm/traps.h> | 39 | #include <asm/traps.h> |
40 | #include <asm/thread_info.h> | 40 | #include <asm/thread_info.h> |
41 | #include <asm/alternative.h> | ||
41 | 42 | ||
42 | #include <linux/linkage.h> | 43 | #include <linux/linkage.h> |
43 | 44 | ||
@@ -464,7 +465,7 @@ | |||
464 | /* Acquire pa_tlb_lock lock and check page is present. */ | 465 | /* Acquire pa_tlb_lock lock and check page is present. */ |
465 | .macro tlb_lock spc,ptp,pte,tmp,tmp1,fault | 466 | .macro tlb_lock spc,ptp,pte,tmp,tmp1,fault |
466 | #ifdef CONFIG_SMP | 467 | #ifdef CONFIG_SMP |
467 | cmpib,COND(=),n 0,\spc,2f | 468 | 98: cmpib,COND(=),n 0,\spc,2f |
468 | load_pa_tlb_lock \tmp | 469 | load_pa_tlb_lock \tmp |
469 | 1: LDCW 0(\tmp),\tmp1 | 470 | 1: LDCW 0(\tmp),\tmp1 |
470 | cmpib,COND(=) 0,\tmp1,1b | 471 | cmpib,COND(=) 0,\tmp1,1b |
@@ -473,6 +474,7 @@ | |||
473 | bb,<,n \pte,_PAGE_PRESENT_BIT,3f | 474 | bb,<,n \pte,_PAGE_PRESENT_BIT,3f |
474 | b \fault | 475 | b \fault |
475 | stw,ma \spc,0(\tmp) | 476 | stw,ma \spc,0(\tmp) |
477 | 99: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP) | ||
476 | #endif | 478 | #endif |
477 | 2: LDREG 0(\ptp),\pte | 479 | 2: LDREG 0(\ptp),\pte |
478 | bb,>=,n \pte,_PAGE_PRESENT_BIT,\fault | 480 | bb,>=,n \pte,_PAGE_PRESENT_BIT,\fault |
@@ -482,15 +484,17 @@ | |||
482 | /* Release pa_tlb_lock lock without reloading lock address. */ | 484 | /* Release pa_tlb_lock lock without reloading lock address. */ |
483 | .macro tlb_unlock0 spc,tmp | 485 | .macro tlb_unlock0 spc,tmp |
484 | #ifdef CONFIG_SMP | 486 | #ifdef CONFIG_SMP |
485 | or,COND(=) %r0,\spc,%r0 | 487 | 98: or,COND(=) %r0,\spc,%r0 |
486 | stw,ma \spc,0(\tmp) | 488 | stw,ma \spc,0(\tmp) |
489 | 99: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP) | ||
487 | #endif | 490 | #endif |
488 | .endm | 491 | .endm |
489 | 492 | ||
490 | /* Release pa_tlb_lock lock. */ | 493 | /* Release pa_tlb_lock lock. */ |
491 | .macro tlb_unlock1 spc,tmp | 494 | .macro tlb_unlock1 spc,tmp |
492 | #ifdef CONFIG_SMP | 495 | #ifdef CONFIG_SMP |
493 | load_pa_tlb_lock \tmp | 496 | 98: load_pa_tlb_lock \tmp |
497 | 99: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP) | ||
494 | tlb_unlock0 \spc,\tmp | 498 | tlb_unlock0 \spc,\tmp |
495 | #endif | 499 | #endif |
496 | .endm | 500 | .endm |
diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S index f33bf2d306d6..b41c0136a05f 100644 --- a/arch/parisc/kernel/pacache.S +++ b/arch/parisc/kernel/pacache.S | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <asm/pgtable.h> | 37 | #include <asm/pgtable.h> |
38 | #include <asm/cache.h> | 38 | #include <asm/cache.h> |
39 | #include <asm/ldcw.h> | 39 | #include <asm/ldcw.h> |
40 | #include <asm/alternative.h> | ||
40 | #include <linux/linkage.h> | 41 | #include <linux/linkage.h> |
41 | #include <linux/init.h> | 42 | #include <linux/init.h> |
42 | 43 | ||
@@ -190,7 +191,7 @@ ENDPROC_CFI(flush_tlb_all_local) | |||
190 | .import cache_info,data | 191 | .import cache_info,data |
191 | 192 | ||
192 | ENTRY_CFI(flush_instruction_cache_local) | 193 | ENTRY_CFI(flush_instruction_cache_local) |
193 | load32 cache_info, %r1 | 194 | 88: load32 cache_info, %r1 |
194 | 195 | ||
195 | /* Flush Instruction Cache */ | 196 | /* Flush Instruction Cache */ |
196 | 197 | ||
@@ -243,6 +244,7 @@ fioneloop2: | |||
243 | fisync: | 244 | fisync: |
244 | sync | 245 | sync |
245 | mtsm %r22 /* restore I-bit */ | 246 | mtsm %r22 /* restore I-bit */ |
247 | 89: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP) | ||
246 | bv %r0(%r2) | 248 | bv %r0(%r2) |
247 | nop | 249 | nop |
248 | ENDPROC_CFI(flush_instruction_cache_local) | 250 | ENDPROC_CFI(flush_instruction_cache_local) |
@@ -250,7 +252,7 @@ ENDPROC_CFI(flush_instruction_cache_local) | |||
250 | 252 | ||
251 | .import cache_info, data | 253 | .import cache_info, data |
252 | ENTRY_CFI(flush_data_cache_local) | 254 | ENTRY_CFI(flush_data_cache_local) |
253 | load32 cache_info, %r1 | 255 | 88: load32 cache_info, %r1 |
254 | 256 | ||
255 | /* Flush Data Cache */ | 257 | /* Flush Data Cache */ |
256 | 258 | ||
@@ -304,6 +306,7 @@ fdsync: | |||
304 | syncdma | 306 | syncdma |
305 | sync | 307 | sync |
306 | mtsm %r22 /* restore I-bit */ | 308 | mtsm %r22 /* restore I-bit */ |
309 | 89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP) | ||
307 | bv %r0(%r2) | 310 | bv %r0(%r2) |
308 | nop | 311 | nop |
309 | ENDPROC_CFI(flush_data_cache_local) | 312 | ENDPROC_CFI(flush_data_cache_local) |
@@ -312,6 +315,7 @@ ENDPROC_CFI(flush_data_cache_local) | |||
312 | 315 | ||
313 | .macro tlb_lock la,flags,tmp | 316 | .macro tlb_lock la,flags,tmp |
314 | #ifdef CONFIG_SMP | 317 | #ifdef CONFIG_SMP |
318 | 98: | ||
315 | #if __PA_LDCW_ALIGNMENT > 4 | 319 | #if __PA_LDCW_ALIGNMENT > 4 |
316 | load32 pa_tlb_lock + __PA_LDCW_ALIGNMENT-1, \la | 320 | load32 pa_tlb_lock + __PA_LDCW_ALIGNMENT-1, \la |
317 | depi 0,31,__PA_LDCW_ALIGN_ORDER, \la | 321 | depi 0,31,__PA_LDCW_ALIGN_ORDER, \la |
@@ -326,15 +330,17 @@ ENDPROC_CFI(flush_data_cache_local) | |||
326 | nop | 330 | nop |
327 | b,n 2b | 331 | b,n 2b |
328 | 3: | 332 | 3: |
333 | 99: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP) | ||
329 | #endif | 334 | #endif |
330 | .endm | 335 | .endm |
331 | 336 | ||
332 | .macro tlb_unlock la,flags,tmp | 337 | .macro tlb_unlock la,flags,tmp |
333 | #ifdef CONFIG_SMP | 338 | #ifdef CONFIG_SMP |
334 | ldi 1,\tmp | 339 | 98: ldi 1,\tmp |
335 | sync | 340 | sync |
336 | stw \tmp,0(\la) | 341 | stw \tmp,0(\la) |
337 | mtsm \flags | 342 | mtsm \flags |
343 | 99: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP) | ||
338 | #endif | 344 | #endif |
339 | .endm | 345 | .endm |
340 | 346 | ||
@@ -596,9 +602,11 @@ ENTRY_CFI(copy_user_page_asm) | |||
596 | pdtlb,l %r0(%r29) | 602 | pdtlb,l %r0(%r29) |
597 | #else | 603 | #else |
598 | tlb_lock %r20,%r21,%r22 | 604 | tlb_lock %r20,%r21,%r22 |
599 | pdtlb %r0(%r28) | 605 | 0: pdtlb %r0(%r28) |
600 | pdtlb %r0(%r29) | 606 | 1: pdtlb %r0(%r29) |
601 | tlb_unlock %r20,%r21,%r22 | 607 | tlb_unlock %r20,%r21,%r22 |
608 | ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB) | ||
609 | ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SMP, INSN_PxTLB) | ||
602 | #endif | 610 | #endif |
603 | 611 | ||
604 | #ifdef CONFIG_64BIT | 612 | #ifdef CONFIG_64BIT |
@@ -736,8 +744,9 @@ ENTRY_CFI(clear_user_page_asm) | |||
736 | pdtlb,l %r0(%r28) | 744 | pdtlb,l %r0(%r28) |
737 | #else | 745 | #else |
738 | tlb_lock %r20,%r21,%r22 | 746 | tlb_lock %r20,%r21,%r22 |
739 | pdtlb %r0(%r28) | 747 | 0: pdtlb %r0(%r28) |
740 | tlb_unlock %r20,%r21,%r22 | 748 | tlb_unlock %r20,%r21,%r22 |
749 | ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB) | ||
741 | #endif | 750 | #endif |
742 | 751 | ||
743 | #ifdef CONFIG_64BIT | 752 | #ifdef CONFIG_64BIT |
@@ -813,11 +822,12 @@ ENTRY_CFI(flush_dcache_page_asm) | |||
813 | pdtlb,l %r0(%r28) | 822 | pdtlb,l %r0(%r28) |
814 | #else | 823 | #else |
815 | tlb_lock %r20,%r21,%r22 | 824 | tlb_lock %r20,%r21,%r22 |
816 | pdtlb %r0(%r28) | 825 | 0: pdtlb %r0(%r28) |
817 | tlb_unlock %r20,%r21,%r22 | 826 | tlb_unlock %r20,%r21,%r22 |
827 | ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB) | ||
818 | #endif | 828 | #endif |
819 | 829 | ||
820 | ldil L%dcache_stride, %r1 | 830 | 88: ldil L%dcache_stride, %r1 |
821 | ldw R%dcache_stride(%r1), r31 | 831 | ldw R%dcache_stride(%r1), r31 |
822 | 832 | ||
823 | #ifdef CONFIG_64BIT | 833 | #ifdef CONFIG_64BIT |
@@ -847,6 +857,7 @@ ENTRY_CFI(flush_dcache_page_asm) | |||
847 | cmpb,COND(<<) %r28, %r25,1b | 857 | cmpb,COND(<<) %r28, %r25,1b |
848 | fdc,m r31(%r28) | 858 | fdc,m r31(%r28) |
849 | 859 | ||
860 | 89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP) | ||
850 | sync | 861 | sync |
851 | bv %r0(%r2) | 862 | bv %r0(%r2) |
852 | nop | 863 | nop |
@@ -874,15 +885,19 @@ ENTRY_CFI(flush_icache_page_asm) | |||
874 | 885 | ||
875 | #ifdef CONFIG_PA20 | 886 | #ifdef CONFIG_PA20 |
876 | pdtlb,l %r0(%r28) | 887 | pdtlb,l %r0(%r28) |
877 | pitlb,l %r0(%sr4,%r28) | 888 | 1: pitlb,l %r0(%sr4,%r28) |
889 | ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SPLIT_TLB, INSN_NOP) | ||
878 | #else | 890 | #else |
879 | tlb_lock %r20,%r21,%r22 | 891 | tlb_lock %r20,%r21,%r22 |
880 | pdtlb %r0(%r28) | 892 | 0: pdtlb %r0(%r28) |
881 | pitlb %r0(%sr4,%r28) | 893 | 1: pitlb %r0(%sr4,%r28) |
882 | tlb_unlock %r20,%r21,%r22 | 894 | tlb_unlock %r20,%r21,%r22 |
895 | ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB) | ||
896 | ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SMP, INSN_PxTLB) | ||
897 | ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SPLIT_TLB, INSN_NOP) | ||
883 | #endif | 898 | #endif |
884 | 899 | ||
885 | ldil L%icache_stride, %r1 | 900 | 88: ldil L%icache_stride, %r1 |
886 | ldw R%icache_stride(%r1), %r31 | 901 | ldw R%icache_stride(%r1), %r31 |
887 | 902 | ||
888 | #ifdef CONFIG_64BIT | 903 | #ifdef CONFIG_64BIT |
@@ -914,13 +929,14 @@ ENTRY_CFI(flush_icache_page_asm) | |||
914 | cmpb,COND(<<) %r28, %r25,1b | 929 | cmpb,COND(<<) %r28, %r25,1b |
915 | fic,m %r31(%sr4,%r28) | 930 | fic,m %r31(%sr4,%r28) |
916 | 931 | ||
932 | 89: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP) | ||
917 | sync | 933 | sync |
918 | bv %r0(%r2) | 934 | bv %r0(%r2) |
919 | nop | 935 | nop |
920 | ENDPROC_CFI(flush_icache_page_asm) | 936 | ENDPROC_CFI(flush_icache_page_asm) |
921 | 937 | ||
922 | ENTRY_CFI(flush_kernel_dcache_page_asm) | 938 | ENTRY_CFI(flush_kernel_dcache_page_asm) |
923 | ldil L%dcache_stride, %r1 | 939 | 88: ldil L%dcache_stride, %r1 |
924 | ldw R%dcache_stride(%r1), %r23 | 940 | ldw R%dcache_stride(%r1), %r23 |
925 | 941 | ||
926 | #ifdef CONFIG_64BIT | 942 | #ifdef CONFIG_64BIT |
@@ -950,13 +966,14 @@ ENTRY_CFI(flush_kernel_dcache_page_asm) | |||
950 | cmpb,COND(<<) %r26, %r25,1b | 966 | cmpb,COND(<<) %r26, %r25,1b |
951 | fdc,m %r23(%r26) | 967 | fdc,m %r23(%r26) |
952 | 968 | ||
969 | 89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP) | ||
953 | sync | 970 | sync |
954 | bv %r0(%r2) | 971 | bv %r0(%r2) |
955 | nop | 972 | nop |
956 | ENDPROC_CFI(flush_kernel_dcache_page_asm) | 973 | ENDPROC_CFI(flush_kernel_dcache_page_asm) |
957 | 974 | ||
958 | ENTRY_CFI(purge_kernel_dcache_page_asm) | 975 | ENTRY_CFI(purge_kernel_dcache_page_asm) |
959 | ldil L%dcache_stride, %r1 | 976 | 88: ldil L%dcache_stride, %r1 |
960 | ldw R%dcache_stride(%r1), %r23 | 977 | ldw R%dcache_stride(%r1), %r23 |
961 | 978 | ||
962 | #ifdef CONFIG_64BIT | 979 | #ifdef CONFIG_64BIT |
@@ -985,13 +1002,14 @@ ENTRY_CFI(purge_kernel_dcache_page_asm) | |||
985 | cmpb,COND(<<) %r26, %r25, 1b | 1002 | cmpb,COND(<<) %r26, %r25, 1b |
986 | pdc,m %r23(%r26) | 1003 | pdc,m %r23(%r26) |
987 | 1004 | ||
1005 | 89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP) | ||
988 | sync | 1006 | sync |
989 | bv %r0(%r2) | 1007 | bv %r0(%r2) |
990 | nop | 1008 | nop |
991 | ENDPROC_CFI(purge_kernel_dcache_page_asm) | 1009 | ENDPROC_CFI(purge_kernel_dcache_page_asm) |
992 | 1010 | ||
993 | ENTRY_CFI(flush_user_dcache_range_asm) | 1011 | ENTRY_CFI(flush_user_dcache_range_asm) |
994 | ldil L%dcache_stride, %r1 | 1012 | 88: ldil L%dcache_stride, %r1 |
995 | ldw R%dcache_stride(%r1), %r23 | 1013 | ldw R%dcache_stride(%r1), %r23 |
996 | ldo -1(%r23), %r21 | 1014 | ldo -1(%r23), %r21 |
997 | ANDCM %r26, %r21, %r26 | 1015 | ANDCM %r26, %r21, %r26 |
@@ -999,13 +1017,14 @@ ENTRY_CFI(flush_user_dcache_range_asm) | |||
999 | 1: cmpb,COND(<<),n %r26, %r25, 1b | 1017 | 1: cmpb,COND(<<),n %r26, %r25, 1b |
1000 | fdc,m %r23(%sr3, %r26) | 1018 | fdc,m %r23(%sr3, %r26) |
1001 | 1019 | ||
1020 | 89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP) | ||
1002 | sync | 1021 | sync |
1003 | bv %r0(%r2) | 1022 | bv %r0(%r2) |
1004 | nop | 1023 | nop |
1005 | ENDPROC_CFI(flush_user_dcache_range_asm) | 1024 | ENDPROC_CFI(flush_user_dcache_range_asm) |
1006 | 1025 | ||
1007 | ENTRY_CFI(flush_kernel_dcache_range_asm) | 1026 | ENTRY_CFI(flush_kernel_dcache_range_asm) |
1008 | ldil L%dcache_stride, %r1 | 1027 | 88: ldil L%dcache_stride, %r1 |
1009 | ldw R%dcache_stride(%r1), %r23 | 1028 | ldw R%dcache_stride(%r1), %r23 |
1010 | ldo -1(%r23), %r21 | 1029 | ldo -1(%r23), %r21 |
1011 | ANDCM %r26, %r21, %r26 | 1030 | ANDCM %r26, %r21, %r26 |
@@ -1014,13 +1033,14 @@ ENTRY_CFI(flush_kernel_dcache_range_asm) | |||
1014 | fdc,m %r23(%r26) | 1033 | fdc,m %r23(%r26) |
1015 | 1034 | ||
1016 | sync | 1035 | sync |
1036 | 89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP) | ||
1017 | syncdma | 1037 | syncdma |
1018 | bv %r0(%r2) | 1038 | bv %r0(%r2) |
1019 | nop | 1039 | nop |
1020 | ENDPROC_CFI(flush_kernel_dcache_range_asm) | 1040 | ENDPROC_CFI(flush_kernel_dcache_range_asm) |
1021 | 1041 | ||
1022 | ENTRY_CFI(purge_kernel_dcache_range_asm) | 1042 | ENTRY_CFI(purge_kernel_dcache_range_asm) |
1023 | ldil L%dcache_stride, %r1 | 1043 | 88: ldil L%dcache_stride, %r1 |
1024 | ldw R%dcache_stride(%r1), %r23 | 1044 | ldw R%dcache_stride(%r1), %r23 |
1025 | ldo -1(%r23), %r21 | 1045 | ldo -1(%r23), %r21 |
1026 | ANDCM %r26, %r21, %r26 | 1046 | ANDCM %r26, %r21, %r26 |
@@ -1029,13 +1049,14 @@ ENTRY_CFI(purge_kernel_dcache_range_asm) | |||
1029 | pdc,m %r23(%r26) | 1049 | pdc,m %r23(%r26) |
1030 | 1050 | ||
1031 | sync | 1051 | sync |
1052 | 89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP) | ||
1032 | syncdma | 1053 | syncdma |
1033 | bv %r0(%r2) | 1054 | bv %r0(%r2) |
1034 | nop | 1055 | nop |
1035 | ENDPROC_CFI(purge_kernel_dcache_range_asm) | 1056 | ENDPROC_CFI(purge_kernel_dcache_range_asm) |
1036 | 1057 | ||
1037 | ENTRY_CFI(flush_user_icache_range_asm) | 1058 | ENTRY_CFI(flush_user_icache_range_asm) |
1038 | ldil L%icache_stride, %r1 | 1059 | 88: ldil L%icache_stride, %r1 |
1039 | ldw R%icache_stride(%r1), %r23 | 1060 | ldw R%icache_stride(%r1), %r23 |
1040 | ldo -1(%r23), %r21 | 1061 | ldo -1(%r23), %r21 |
1041 | ANDCM %r26, %r21, %r26 | 1062 | ANDCM %r26, %r21, %r26 |
@@ -1043,13 +1064,14 @@ ENTRY_CFI(flush_user_icache_range_asm) | |||
1043 | 1: cmpb,COND(<<),n %r26, %r25,1b | 1064 | 1: cmpb,COND(<<),n %r26, %r25,1b |
1044 | fic,m %r23(%sr3, %r26) | 1065 | fic,m %r23(%sr3, %r26) |
1045 | 1066 | ||
1067 | 89: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP) | ||
1046 | sync | 1068 | sync |
1047 | bv %r0(%r2) | 1069 | bv %r0(%r2) |
1048 | nop | 1070 | nop |
1049 | ENDPROC_CFI(flush_user_icache_range_asm) | 1071 | ENDPROC_CFI(flush_user_icache_range_asm) |
1050 | 1072 | ||
1051 | ENTRY_CFI(flush_kernel_icache_page) | 1073 | ENTRY_CFI(flush_kernel_icache_page) |
1052 | ldil L%icache_stride, %r1 | 1074 | 88: ldil L%icache_stride, %r1 |
1053 | ldw R%icache_stride(%r1), %r23 | 1075 | ldw R%icache_stride(%r1), %r23 |
1054 | 1076 | ||
1055 | #ifdef CONFIG_64BIT | 1077 | #ifdef CONFIG_64BIT |
@@ -1079,13 +1101,14 @@ ENTRY_CFI(flush_kernel_icache_page) | |||
1079 | cmpb,COND(<<) %r26, %r25, 1b | 1101 | cmpb,COND(<<) %r26, %r25, 1b |
1080 | fic,m %r23(%sr4, %r26) | 1102 | fic,m %r23(%sr4, %r26) |
1081 | 1103 | ||
1104 | 89: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP) | ||
1082 | sync | 1105 | sync |
1083 | bv %r0(%r2) | 1106 | bv %r0(%r2) |
1084 | nop | 1107 | nop |
1085 | ENDPROC_CFI(flush_kernel_icache_page) | 1108 | ENDPROC_CFI(flush_kernel_icache_page) |
1086 | 1109 | ||
1087 | ENTRY_CFI(flush_kernel_icache_range_asm) | 1110 | ENTRY_CFI(flush_kernel_icache_range_asm) |
1088 | ldil L%icache_stride, %r1 | 1111 | 88: ldil L%icache_stride, %r1 |
1089 | ldw R%icache_stride(%r1), %r23 | 1112 | ldw R%icache_stride(%r1), %r23 |
1090 | ldo -1(%r23), %r21 | 1113 | ldo -1(%r23), %r21 |
1091 | ANDCM %r26, %r21, %r26 | 1114 | ANDCM %r26, %r21, %r26 |
@@ -1093,6 +1116,7 @@ ENTRY_CFI(flush_kernel_icache_range_asm) | |||
1093 | 1: cmpb,COND(<<),n %r26, %r25, 1b | 1116 | 1: cmpb,COND(<<),n %r26, %r25, 1b |
1094 | fic,m %r23(%sr4, %r26) | 1117 | fic,m %r23(%sr4, %r26) |
1095 | 1118 | ||
1119 | 89: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP) | ||
1096 | sync | 1120 | sync |
1097 | bv %r0(%r2) | 1121 | bv %r0(%r2) |
1098 | nop | 1122 | nop |
diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c index 4e87c35c22b7..db6e7957f9a3 100644 --- a/arch/parisc/kernel/setup.c +++ b/arch/parisc/kernel/setup.c | |||
@@ -305,6 +305,86 @@ static int __init parisc_init_resources(void) | |||
305 | return 0; | 305 | return 0; |
306 | } | 306 | } |
307 | 307 | ||
308 | static int no_alternatives __initdata; | ||
309 | static int __init setup_no_alternatives(char *str) | ||
310 | { | ||
311 | no_alternatives = 1; | ||
312 | return 1; | ||
313 | } | ||
314 | __setup("no-alternatives", setup_no_alternatives); | ||
315 | |||
316 | static void __init apply_alternatives_all(void) | ||
317 | { | ||
318 | struct alt_instr *entry; | ||
319 | int index = 0, applied = 0; | ||
320 | |||
321 | |||
322 | pr_info("alternatives: %spatching kernel code\n", | ||
323 | no_alternatives ? "NOT " : ""); | ||
324 | if (no_alternatives) | ||
325 | return; | ||
326 | |||
327 | set_kernel_text_rw(1); | ||
328 | |||
329 | for (entry = (struct alt_instr *) &__alt_instructions; | ||
330 | entry < (struct alt_instr *) &__alt_instructions_end; | ||
331 | entry++, index++) { | ||
332 | |||
333 | u32 *from, len, cond, replacement; | ||
334 | |||
335 | from = (u32 *)((ulong)&entry->orig_offset + entry->orig_offset); | ||
336 | len = entry->len; | ||
337 | cond = entry->cond; | ||
338 | replacement = entry->replacement; | ||
339 | |||
340 | WARN_ON(!cond); | ||
341 | pr_debug("Check %d: Cond 0x%x, Replace %02d instructions @ 0x%px with 0x%08x\n", | ||
342 | index, cond, len, from, replacement); | ||
343 | |||
344 | if ((cond & ALT_COND_NO_SMP) && (num_online_cpus() != 1)) | ||
345 | continue; | ||
346 | if ((cond & ALT_COND_NO_DCACHE) && (cache_info.dc_size != 0)) | ||
347 | continue; | ||
348 | if ((cond & ALT_COND_NO_ICACHE) && (cache_info.ic_size != 0)) | ||
349 | continue; | ||
350 | |||
351 | /* | ||
352 | * If the PDC_MODEL capabilities has Non-coherent IO-PDIR bit | ||
353 | * set (bit #61, big endian), we have to flush and sync every | ||
354 | * time IO-PDIR is changed in Ike/Astro. | ||
355 | */ | ||
356 | if ((cond & ALT_COND_NO_IOC_FDC) && | ||
357 | (boot_cpu_data.pdc.capabilities & PDC_MODEL_IOPDIR_FDC)) | ||
358 | continue; | ||
359 | |||
360 | /* Want to replace pdtlb by a pdtlb,l instruction? */ | ||
361 | if (replacement == INSN_PxTLB) { | ||
362 | replacement = *from; | ||
363 | if (boot_cpu_data.cpu_type >= pcxu) /* >= pa2.0 ? */ | ||
364 | replacement |= (1 << 10); /* set el bit */ | ||
365 | } | ||
366 | |||
367 | /* | ||
368 | * Replace instruction with NOPs? | ||
369 | * For long distance insert a branch instruction instead. | ||
370 | */ | ||
371 | if (replacement == INSN_NOP && len > 1) | ||
372 | replacement = 0xe8000002 + (len-2)*8; /* "b,n .+8" */ | ||
373 | |||
374 | pr_debug("Do %d: Cond 0x%x, Replace %02d instructions @ 0x%px with 0x%08x\n", | ||
375 | index, cond, len, from, replacement); | ||
376 | |||
377 | /* Replace instruction */ | ||
378 | *from = replacement; | ||
379 | applied++; | ||
380 | } | ||
381 | |||
382 | pr_info("alternatives: applied %d out of %d patches\n", applied, index); | ||
383 | |||
384 | set_kernel_text_rw(0); | ||
385 | } | ||
386 | |||
387 | |||
308 | extern void gsc_init(void); | 388 | extern void gsc_init(void); |
309 | extern void processor_init(void); | 389 | extern void processor_init(void); |
310 | extern void ccio_init(void); | 390 | extern void ccio_init(void); |
@@ -346,6 +426,7 @@ static int __init parisc_init(void) | |||
346 | boot_cpu_data.cpu_hz / 1000000, | 426 | boot_cpu_data.cpu_hz / 1000000, |
347 | boot_cpu_data.cpu_hz % 1000000 ); | 427 | boot_cpu_data.cpu_hz % 1000000 ); |
348 | 428 | ||
429 | apply_alternatives_all(); | ||
349 | parisc_setup_cache_timing(); | 430 | parisc_setup_cache_timing(); |
350 | 431 | ||
351 | /* These are in a non-obvious order, will fix when we have an iotree */ | 432 | /* These are in a non-obvious order, will fix when we have an iotree */ |
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c index 342073f44d3f..848c1934680b 100644 --- a/arch/parisc/kernel/signal.c +++ b/arch/parisc/kernel/signal.c | |||
@@ -65,7 +65,6 @@ | |||
65 | #define INSN_LDI_R25_1 0x34190002 /* ldi 1,%r25 (in_syscall=1) */ | 65 | #define INSN_LDI_R25_1 0x34190002 /* ldi 1,%r25 (in_syscall=1) */ |
66 | #define INSN_LDI_R20 0x3414015a /* ldi __NR_rt_sigreturn,%r20 */ | 66 | #define INSN_LDI_R20 0x3414015a /* ldi __NR_rt_sigreturn,%r20 */ |
67 | #define INSN_BLE_SR2_R0 0xe4008200 /* be,l 0x100(%sr2,%r0),%sr0,%r31 */ | 67 | #define INSN_BLE_SR2_R0 0xe4008200 /* be,l 0x100(%sr2,%r0),%sr0,%r31 */ |
68 | #define INSN_NOP 0x08000240 /* nop */ | ||
69 | /* For debugging */ | 68 | /* For debugging */ |
70 | #define INSN_DIE_HORRIBLY 0x68000ccc /* stw %r0,0x666(%sr0,%r0) */ | 69 | #define INSN_DIE_HORRIBLY 0x68000ccc /* stw %r0,0x666(%sr0,%r0) */ |
71 | 70 | ||
diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S index da2e31190efa..c3b1b9c24ede 100644 --- a/arch/parisc/kernel/vmlinux.lds.S +++ b/arch/parisc/kernel/vmlinux.lds.S | |||
@@ -61,6 +61,12 @@ SECTIONS | |||
61 | EXIT_DATA | 61 | EXIT_DATA |
62 | } | 62 | } |
63 | PERCPU_SECTION(8) | 63 | PERCPU_SECTION(8) |
64 | . = ALIGN(4); | ||
65 | .altinstructions : { | ||
66 | __alt_instructions = .; | ||
67 | *(.altinstructions) | ||
68 | __alt_instructions_end = .; | ||
69 | } | ||
64 | . = ALIGN(HUGEPAGE_SIZE); | 70 | . = ALIGN(HUGEPAGE_SIZE); |
65 | __init_end = .; | 71 | __init_end = .; |
66 | /* freed after init ends here */ | 72 | /* freed after init ends here */ |
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c index aae9b0d71c1e..e7e626bcd0be 100644 --- a/arch/parisc/mm/init.c +++ b/arch/parisc/mm/init.c | |||
@@ -511,6 +511,21 @@ static void __init map_pages(unsigned long start_vaddr, | |||
511 | } | 511 | } |
512 | } | 512 | } |
513 | 513 | ||
514 | void __init set_kernel_text_rw(int enable_read_write) | ||
515 | { | ||
516 | unsigned long start = (unsigned long)_stext; | ||
517 | unsigned long end = (unsigned long)_etext; | ||
518 | |||
519 | map_pages(start, __pa(start), end-start, | ||
520 | PAGE_KERNEL_RWX, enable_read_write ? 1:0); | ||
521 | |||
522 | /* force the kernel to see the new TLB entries */ | ||
523 | __flush_tlb_range(0, start, end); | ||
524 | |||
525 | /* dump old cached instructions */ | ||
526 | flush_icache_range(start, end); | ||
527 | } | ||
528 | |||
514 | void __ref free_initmem(void) | 529 | void __ref free_initmem(void) |
515 | { | 530 | { |
516 | unsigned long init_begin = (unsigned long)__init_begin; | 531 | unsigned long init_begin = (unsigned long)__init_begin; |
diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c index 614823617b8b..701a7d6a74d5 100644 --- a/drivers/parisc/ccio-dma.c +++ b/drivers/parisc/ccio-dma.c | |||
@@ -609,14 +609,13 @@ ccio_io_pdir_entry(u64 *pdir_ptr, space_t sid, unsigned long vba, | |||
609 | ** PCX-T'? Don't know. (eg C110 or similar K-class) | 609 | ** PCX-T'? Don't know. (eg C110 or similar K-class) |
610 | ** | 610 | ** |
611 | ** See PDC_MODEL/option 0/SW_CAP word for "Non-coherent IO-PDIR bit". | 611 | ** See PDC_MODEL/option 0/SW_CAP word for "Non-coherent IO-PDIR bit". |
612 | ** Hopefully we can patch (NOP) these out at boot time somehow. | ||
613 | ** | 612 | ** |
614 | ** "Since PCX-U employs an offset hash that is incompatible with | 613 | ** "Since PCX-U employs an offset hash that is incompatible with |
615 | ** the real mode coherence index generation of U2, the PDIR entry | 614 | ** the real mode coherence index generation of U2, the PDIR entry |
616 | ** must be flushed to memory to retain coherence." | 615 | ** must be flushed to memory to retain coherence." |
617 | */ | 616 | */ |
618 | asm volatile("fdc %%r0(%0)" : : "r" (pdir_ptr)); | 617 | asm_io_fdc(pdir_ptr); |
619 | asm volatile("sync"); | 618 | asm_io_sync(); |
620 | } | 619 | } |
621 | 620 | ||
622 | /** | 621 | /** |
@@ -682,17 +681,14 @@ ccio_mark_invalid(struct ioc *ioc, dma_addr_t iova, size_t byte_cnt) | |||
682 | ** FIXME: PCX_W platforms don't need FDC/SYNC. (eg C360) | 681 | ** FIXME: PCX_W platforms don't need FDC/SYNC. (eg C360) |
683 | ** PCX-U/U+ do. (eg C200/C240) | 682 | ** PCX-U/U+ do. (eg C200/C240) |
684 | ** See PDC_MODEL/option 0/SW_CAP for "Non-coherent IO-PDIR bit". | 683 | ** See PDC_MODEL/option 0/SW_CAP for "Non-coherent IO-PDIR bit". |
685 | ** | ||
686 | ** Hopefully someone figures out how to patch (NOP) the | ||
687 | ** FDC/SYNC out at boot time. | ||
688 | */ | 684 | */ |
689 | asm volatile("fdc %%r0(%0)" : : "r" (pdir_ptr[7])); | 685 | asm_io_fdc(pdir_ptr); |
690 | 686 | ||
691 | iovp += IOVP_SIZE; | 687 | iovp += IOVP_SIZE; |
692 | byte_cnt -= IOVP_SIZE; | 688 | byte_cnt -= IOVP_SIZE; |
693 | } | 689 | } |
694 | 690 | ||
695 | asm volatile("sync"); | 691 | asm_io_sync(); |
696 | ccio_clear_io_tlb(ioc, CCIO_IOVP(iova), saved_byte_cnt); | 692 | ccio_clear_io_tlb(ioc, CCIO_IOVP(iova), saved_byte_cnt); |
697 | } | 693 | } |
698 | 694 | ||
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c index 11de0eccf968..c1e599a429af 100644 --- a/drivers/parisc/sba_iommu.c +++ b/drivers/parisc/sba_iommu.c | |||
@@ -587,8 +587,7 @@ sba_io_pdir_entry(u64 *pdir_ptr, space_t sid, unsigned long vba, | |||
587 | * (bit #61, big endian), we have to flush and sync every time | 587 | * (bit #61, big endian), we have to flush and sync every time |
588 | * IO-PDIR is changed in Ike/Astro. | 588 | * IO-PDIR is changed in Ike/Astro. |
589 | */ | 589 | */ |
590 | if (ioc_needs_fdc) | 590 | asm_io_fdc(pdir_ptr); |
591 | asm volatile("fdc %%r0(%0)" : : "r" (pdir_ptr)); | ||
592 | } | 591 | } |
593 | 592 | ||
594 | 593 | ||
@@ -641,8 +640,8 @@ sba_mark_invalid(struct ioc *ioc, dma_addr_t iova, size_t byte_cnt) | |||
641 | do { | 640 | do { |
642 | /* clear I/O Pdir entry "valid" bit first */ | 641 | /* clear I/O Pdir entry "valid" bit first */ |
643 | ((u8 *) pdir_ptr)[7] = 0; | 642 | ((u8 *) pdir_ptr)[7] = 0; |
643 | asm_io_fdc(pdir_ptr); | ||
644 | if (ioc_needs_fdc) { | 644 | if (ioc_needs_fdc) { |
645 | asm volatile("fdc %%r0(%0)" : : "r" (pdir_ptr)); | ||
646 | #if 0 | 645 | #if 0 |
647 | entries_per_cacheline = L1_CACHE_SHIFT - 3; | 646 | entries_per_cacheline = L1_CACHE_SHIFT - 3; |
648 | #endif | 647 | #endif |
@@ -661,8 +660,7 @@ sba_mark_invalid(struct ioc *ioc, dma_addr_t iova, size_t byte_cnt) | |||
661 | ** could dump core on HPMC. | 660 | ** could dump core on HPMC. |
662 | */ | 661 | */ |
663 | ((u8 *) pdir_ptr)[7] = 0; | 662 | ((u8 *) pdir_ptr)[7] = 0; |
664 | if (ioc_needs_fdc) | 663 | asm_io_fdc(pdir_ptr); |
665 | asm volatile("fdc %%r0(%0)" : : "r" (pdir_ptr)); | ||
666 | 664 | ||
667 | WRITE_REG( SBA_IOVA(ioc, iovp, 0, 0), ioc->ioc_hpa+IOC_PCOM); | 665 | WRITE_REG( SBA_IOVA(ioc, iovp, 0, 0), ioc->ioc_hpa+IOC_PCOM); |
668 | } | 666 | } |
@@ -773,8 +771,7 @@ sba_map_single(struct device *dev, void *addr, size_t size, | |||
773 | } | 771 | } |
774 | 772 | ||
775 | /* force FDC ops in io_pdir_entry() to be visible to IOMMU */ | 773 | /* force FDC ops in io_pdir_entry() to be visible to IOMMU */ |
776 | if (ioc_needs_fdc) | 774 | asm_io_sync(); |
777 | asm volatile("sync" : : ); | ||
778 | 775 | ||
779 | #ifdef ASSERT_PDIR_SANITY | 776 | #ifdef ASSERT_PDIR_SANITY |
780 | sba_check_pdir(ioc,"Check after sba_map_single()"); | 777 | sba_check_pdir(ioc,"Check after sba_map_single()"); |
@@ -858,8 +855,7 @@ sba_unmap_page(struct device *dev, dma_addr_t iova, size_t size, | |||
858 | sba_free_range(ioc, iova, size); | 855 | sba_free_range(ioc, iova, size); |
859 | 856 | ||
860 | /* If fdc's were issued, force fdc's to be visible now */ | 857 | /* If fdc's were issued, force fdc's to be visible now */ |
861 | if (ioc_needs_fdc) | 858 | asm_io_sync(); |
862 | asm volatile("sync" : : ); | ||
863 | 859 | ||
864 | READ_REG(ioc->ioc_hpa+IOC_PCOM); /* flush purges */ | 860 | READ_REG(ioc->ioc_hpa+IOC_PCOM); /* flush purges */ |
865 | #endif /* DELAYED_RESOURCE_CNT == 0 */ | 861 | #endif /* DELAYED_RESOURCE_CNT == 0 */ |
@@ -1008,8 +1004,7 @@ sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents, | |||
1008 | filled = iommu_fill_pdir(ioc, sglist, nents, 0, sba_io_pdir_entry); | 1004 | filled = iommu_fill_pdir(ioc, sglist, nents, 0, sba_io_pdir_entry); |
1009 | 1005 | ||
1010 | /* force FDC ops in io_pdir_entry() to be visible to IOMMU */ | 1006 | /* force FDC ops in io_pdir_entry() to be visible to IOMMU */ |
1011 | if (ioc_needs_fdc) | 1007 | asm_io_sync(); |
1012 | asm volatile("sync" : : ); | ||
1013 | 1008 | ||
1014 | #ifdef ASSERT_PDIR_SANITY | 1009 | #ifdef ASSERT_PDIR_SANITY |
1015 | if (sba_check_pdir(ioc,"Check after sba_map_sg()")) | 1010 | if (sba_check_pdir(ioc,"Check after sba_map_sg()")) |