aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/parisc/Makefile9
-rw-r--r--arch/parisc/boot/compressed/Makefile4
-rw-r--r--arch/parisc/boot/compressed/misc.c95
-rw-r--r--arch/parisc/boot/compressed/vmlinux.lds.S10
-rw-r--r--arch/parisc/include/asm/alternative.h47
-rw-r--r--arch/parisc/include/asm/assembly.h9
-rw-r--r--arch/parisc/include/asm/cache.h22
-rw-r--r--arch/parisc/include/asm/page.h12
-rw-r--r--arch/parisc/include/asm/pdc.h1
-rw-r--r--arch/parisc/include/asm/pdcpat.h62
-rw-r--r--arch/parisc/include/asm/pgtable.h33
-rw-r--r--arch/parisc/include/asm/sections.h2
-rw-r--r--arch/parisc/include/asm/spinlock.h4
-rw-r--r--arch/parisc/include/asm/tlbflush.h3
-rw-r--r--arch/parisc/kernel/cache.c63
-rw-r--r--arch/parisc/kernel/entry.S34
-rw-r--r--arch/parisc/kernel/firmware.c57
-rw-r--r--arch/parisc/kernel/hpmc.S3
-rw-r--r--arch/parisc/kernel/inventory.c10
-rw-r--r--arch/parisc/kernel/pacache.S280
-rw-r--r--arch/parisc/kernel/setup.c81
-rw-r--r--arch/parisc/kernel/signal.c1
-rw-r--r--arch/parisc/kernel/syscall.S12
-rw-r--r--arch/parisc/kernel/traps.c7
-rw-r--r--arch/parisc/kernel/vmlinux.lds.S6
-rw-r--r--arch/parisc/mm/init.c23
-rw-r--r--drivers/parisc/Makefile3
-rw-r--r--drivers/parisc/ccio-dma.c12
-rw-r--r--drivers/parisc/ccio-rm-dma.c202
-rw-r--r--drivers/parisc/dino.c5
-rw-r--r--drivers/parisc/sba_iommu.c17
-rwxr-xr-xscripts/extract-vmlinux6
32 files changed, 721 insertions, 414 deletions
diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile
index 5ce030266e7d..d047a09d660f 100644
--- a/arch/parisc/Makefile
+++ b/arch/parisc/Makefile
@@ -156,12 +156,3 @@ define archhelp
156 @echo ' copy to $$(INSTALL_PATH)' 156 @echo ' copy to $$(INSTALL_PATH)'
157 @echo ' zinstall - Install compressed vmlinuz kernel' 157 @echo ' zinstall - Install compressed vmlinuz kernel'
158endef 158endef
159
160# we require gcc 3.3 or above to compile the kernel
161archprepare: checkbin
162checkbin:
163 @if test "$(cc-version)" -lt "0303"; then \
164 echo -n "Sorry, GCC v3.3 or above is required to build " ; \
165 echo "the kernel." ; \
166 false ; \
167 fi
diff --git a/arch/parisc/boot/compressed/Makefile b/arch/parisc/boot/compressed/Makefile
index 7d7e594bda36..777533cdea31 100644
--- a/arch/parisc/boot/compressed/Makefile
+++ b/arch/parisc/boot/compressed/Makefile
@@ -14,7 +14,7 @@ targets += misc.o piggy.o sizes.h head.o real2.o firmware.o
14 14
15KBUILD_CFLAGS := -D__KERNEL__ -O2 -DBOOTLOADER 15KBUILD_CFLAGS := -D__KERNEL__ -O2 -DBOOTLOADER
16KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING 16KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING
17KBUILD_CFLAGS += $(cflags-y) -fno-delete-null-pointer-checks 17KBUILD_CFLAGS += $(cflags-y) -fno-delete-null-pointer-checks -fno-builtin-printf
18KBUILD_CFLAGS += -fno-PIE -mno-space-regs -mdisable-fpregs -Os 18KBUILD_CFLAGS += -fno-PIE -mno-space-regs -mdisable-fpregs -Os
19ifndef CONFIG_64BIT 19ifndef CONFIG_64BIT
20KBUILD_CFLAGS += -mfast-indirect-calls 20KBUILD_CFLAGS += -mfast-indirect-calls
@@ -22,7 +22,6 @@ endif
22 22
23OBJECTS += $(obj)/head.o $(obj)/real2.o $(obj)/firmware.o $(obj)/misc.o $(obj)/piggy.o 23OBJECTS += $(obj)/head.o $(obj)/real2.o $(obj)/firmware.o $(obj)/misc.o $(obj)/piggy.o
24 24
25# LDFLAGS_vmlinux := -X --whole-archive -e startup -T
26LDFLAGS_vmlinux := -X -e startup --as-needed -T 25LDFLAGS_vmlinux := -X -e startup --as-needed -T
27$(obj)/vmlinux: $(obj)/vmlinux.lds $(OBJECTS) $(LIBGCC) 26$(obj)/vmlinux: $(obj)/vmlinux.lds $(OBJECTS) $(LIBGCC)
28 $(call if_changed,ld) 27 $(call if_changed,ld)
@@ -55,7 +54,6 @@ $(obj)/misc.o: $(obj)/sizes.h
55CPPFLAGS_vmlinux.lds += -I$(objtree)/$(obj) -DBOOTLOADER 54CPPFLAGS_vmlinux.lds += -I$(objtree)/$(obj) -DBOOTLOADER
56$(obj)/vmlinux.lds: $(obj)/sizes.h 55$(obj)/vmlinux.lds: $(obj)/sizes.h
57 56
58OBJCOPYFLAGS_vmlinux.bin := -O binary -R .comment -S
59$(obj)/vmlinux.bin: vmlinux 57$(obj)/vmlinux.bin: vmlinux
60 $(call if_changed,objcopy) 58 $(call if_changed,objcopy)
61 59
diff --git a/arch/parisc/boot/compressed/misc.c b/arch/parisc/boot/compressed/misc.c
index f57118e1f6b4..2556bb181813 100644
--- a/arch/parisc/boot/compressed/misc.c
+++ b/arch/parisc/boot/compressed/misc.c
@@ -5,6 +5,7 @@
5 */ 5 */
6 6
7#include <linux/uaccess.h> 7#include <linux/uaccess.h>
8#include <linux/elf.h>
8#include <asm/unaligned.h> 9#include <asm/unaligned.h>
9#include <asm/page.h> 10#include <asm/page.h>
10#include "sizes.h" 11#include "sizes.h"
@@ -227,13 +228,62 @@ static void flush_data_cache(char *start, unsigned long length)
227 asm ("sync"); 228 asm ("sync");
228} 229}
229 230
231static void parse_elf(void *output)
232{
233#ifdef CONFIG_64BIT
234 Elf64_Ehdr ehdr;
235 Elf64_Phdr *phdrs, *phdr;
236#else
237 Elf32_Ehdr ehdr;
238 Elf32_Phdr *phdrs, *phdr;
239#endif
240 void *dest;
241 int i;
242
243 memcpy(&ehdr, output, sizeof(ehdr));
244 if (ehdr.e_ident[EI_MAG0] != ELFMAG0 ||
245 ehdr.e_ident[EI_MAG1] != ELFMAG1 ||
246 ehdr.e_ident[EI_MAG2] != ELFMAG2 ||
247 ehdr.e_ident[EI_MAG3] != ELFMAG3) {
248 error("Kernel is not a valid ELF file");
249 return;
250 }
251
252#ifdef DEBUG
253 printf("Parsing ELF... ");
254#endif
255
256 phdrs = malloc(sizeof(*phdrs) * ehdr.e_phnum);
257 if (!phdrs)
258 error("Failed to allocate space for phdrs");
259
260 memcpy(phdrs, output + ehdr.e_phoff, sizeof(*phdrs) * ehdr.e_phnum);
261
262 for (i = 0; i < ehdr.e_phnum; i++) {
263 phdr = &phdrs[i];
264
265 switch (phdr->p_type) {
266 case PT_LOAD:
267 dest = (void *)((unsigned long) phdr->p_paddr &
268 (__PAGE_OFFSET_DEFAULT-1));
269 memmove(dest, output + phdr->p_offset, phdr->p_filesz);
270 break;
271 default:
272 break;
273 }
274 }
275
276 free(phdrs);
277}
278
230unsigned long decompress_kernel(unsigned int started_wide, 279unsigned long decompress_kernel(unsigned int started_wide,
231 unsigned int command_line, 280 unsigned int command_line,
232 const unsigned int rd_start, 281 const unsigned int rd_start,
233 const unsigned int rd_end) 282 const unsigned int rd_end)
234{ 283{
235 char *output; 284 char *output;
236 unsigned long len, len_all; 285 unsigned long vmlinux_addr, vmlinux_len;
286 unsigned long kernel_addr, kernel_len;
237 287
238#ifdef CONFIG_64BIT 288#ifdef CONFIG_64BIT
239 parisc_narrow_firmware = 0; 289 parisc_narrow_firmware = 0;
@@ -241,27 +291,29 @@ unsigned long decompress_kernel(unsigned int started_wide,
241 291
242 set_firmware_width_unlocked(); 292 set_firmware_width_unlocked();
243 293
244 putchar('U'); /* if you get this p and no more, string storage */ 294 putchar('D'); /* if you get this D and no more, string storage */
245 /* in $GLOBAL$ is wrong or %dp is wrong */ 295 /* in $GLOBAL$ is wrong or %dp is wrong */
246 puts("ncompressing ...\n"); 296 puts("ecompressing Linux... ");
247
248 output = (char *) KERNEL_BINARY_TEXT_START;
249 len_all = __pa(SZ_end) - __pa(SZparisc_kernel_start);
250 297
251 if ((unsigned long) &_startcode_end > (unsigned long) output) 298 /* where the final bits are stored */
299 kernel_addr = KERNEL_BINARY_TEXT_START;
300 kernel_len = __pa(SZ_end) - __pa(SZparisc_kernel_start);
301 if ((unsigned long) &_startcode_end > kernel_addr)
252 error("Bootcode overlaps kernel code"); 302 error("Bootcode overlaps kernel code");
253 303
254 len = get_unaligned_le32(&output_len); 304 /*
255 if (len > len_all) 305 * Calculate addr to where the vmlinux ELF file shall be decompressed.
256 error("Output len too big."); 306 * Assembly code in head.S positioned the stack directly behind bss, so
257 else 307 * leave 2 MB for the stack.
258 memset(&output[len], 0, len_all - len); 308 */
309 vmlinux_addr = (unsigned long) &_ebss + 2*1024*1024;
310 vmlinux_len = get_unaligned_le32(&output_len);
311 output = (char *) vmlinux_addr;
259 312
260 /* 313 /*
261 * Initialize free_mem_ptr and free_mem_end_ptr. 314 * Initialize free_mem_ptr and free_mem_end_ptr.
262 */ 315 */
263 free_mem_ptr = (unsigned long) &_ebss; 316 free_mem_ptr = vmlinux_addr + vmlinux_len;
264 free_mem_ptr += 2*1024*1024; /* leave 2 MB for stack */
265 317
266 /* Limit memory for bootoader to 1GB */ 318 /* Limit memory for bootoader to 1GB */
267 #define ARTIFICIAL_LIMIT (1*1024*1024*1024) 319 #define ARTIFICIAL_LIMIT (1*1024*1024*1024)
@@ -275,7 +327,11 @@ unsigned long decompress_kernel(unsigned int started_wide,
275 free_mem_end_ptr = rd_start; 327 free_mem_end_ptr = rd_start;
276#endif 328#endif
277 329
330 if (free_mem_ptr >= free_mem_end_ptr)
331 error("Kernel too big for machine.");
332
278#ifdef DEBUG 333#ifdef DEBUG
334 printf("\n");
279 printf("startcode_end = %x\n", &_startcode_end); 335 printf("startcode_end = %x\n", &_startcode_end);
280 printf("commandline = %x\n", command_line); 336 printf("commandline = %x\n", command_line);
281 printf("rd_start = %x\n", rd_start); 337 printf("rd_start = %x\n", rd_start);
@@ -287,16 +343,19 @@ unsigned long decompress_kernel(unsigned int started_wide,
287 printf("input_data = %x\n", input_data); 343 printf("input_data = %x\n", input_data);
288 printf("input_len = %x\n", input_len); 344 printf("input_len = %x\n", input_len);
289 printf("output = %x\n", output); 345 printf("output = %x\n", output);
290 printf("output_len = %x\n", len); 346 printf("output_len = %x\n", vmlinux_len);
291 printf("output_max = %x\n", len_all); 347 printf("kernel_addr = %x\n", kernel_addr);
348 printf("kernel_len = %x\n", kernel_len);
292#endif 349#endif
293 350
294 __decompress(input_data, input_len, NULL, NULL, 351 __decompress(input_data, input_len, NULL, NULL,
295 output, 0, NULL, error); 352 output, 0, NULL, error);
353 parse_elf(output);
296 354
297 flush_data_cache(output, len); 355 output = (char *) kernel_addr;
356 flush_data_cache(output, kernel_len);
298 357
299 printf("Booting kernel ...\n\n"); 358 printf("done.\nBooting the kernel.\n");
300 359
301 return (unsigned long) output; 360 return (unsigned long) output;
302} 361}
diff --git a/arch/parisc/boot/compressed/vmlinux.lds.S b/arch/parisc/boot/compressed/vmlinux.lds.S
index 4ebd4e65524c..bfd7872739a3 100644
--- a/arch/parisc/boot/compressed/vmlinux.lds.S
+++ b/arch/parisc/boot/compressed/vmlinux.lds.S
@@ -42,6 +42,12 @@ SECTIONS
42#endif 42#endif
43 _startcode_end = .; 43 _startcode_end = .;
44 44
45 /* vmlinux.bin.gz is here */
46 . = ALIGN(8);
47 .rodata.compressed : {
48 *(.rodata.compressed)
49 }
50
45 /* bootloader code and data starts behind area of extracted kernel */ 51 /* bootloader code and data starts behind area of extracted kernel */
46 . = (SZ_end - SZparisc_kernel_start + KERNEL_BINARY_TEXT_START); 52 . = (SZ_end - SZparisc_kernel_start + KERNEL_BINARY_TEXT_START);
47 53
@@ -68,10 +74,6 @@ SECTIONS
68 _erodata = . ; 74 _erodata = . ;
69 } 75 }
70 . = ALIGN(8); 76 . = ALIGN(8);
71 .rodata.compressed : {
72 *(.rodata.compressed)
73 }
74 . = ALIGN(8);
75 .bss : { 77 .bss : {
76 _bss = . ; 78 _bss = . ;
77 *(.bss) 79 *(.bss)
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
21struct 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
28void 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/assembly.h b/arch/parisc/include/asm/assembly.h
index e9c6385ef0d1..c17ec0ee6e7c 100644
--- a/arch/parisc/include/asm/assembly.h
+++ b/arch/parisc/include/asm/assembly.h
@@ -129,15 +129,8 @@
129 .macro debug value 129 .macro debug value
130 .endm 130 .endm
131 131
132
133 /* Shift Left - note the r and t can NOT be the same! */
134 .macro shl r, sa, t
135 dep,z \r, 31-(\sa), 32-(\sa), \t
136 .endm
137
138 /* The PA 2.0 shift left */
139 .macro shlw r, sa, t 132 .macro shlw r, sa, t
140 depw,z \r, 31-(\sa), 32-(\sa), \t 133 zdep \r, 31-(\sa), 32-(\sa), \t
141 .endm 134 .endm
142 135
143 /* And the PA 2.0W shift left */ 136 /* And the PA 2.0W shift left */
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;
41extern struct pdc_cache_info cache_info; 42extern struct pdc_cache_info cache_info;
42void parisc_setup_cache_timing(void); 43void 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/page.h b/arch/parisc/include/asm/page.h
index af00fe9bf846..b77f49ce6220 100644
--- a/arch/parisc/include/asm/page.h
+++ b/arch/parisc/include/asm/page.h
@@ -117,14 +117,16 @@ extern int npmem_ranges;
117/* This governs the relationship between virtual and physical addresses. 117/* This governs the relationship between virtual and physical addresses.
118 * If you alter it, make sure to take care of our various fixed mapping 118 * If you alter it, make sure to take care of our various fixed mapping
119 * segments in fixmap.h */ 119 * segments in fixmap.h */
120#if defined(BOOTLOADER)
121#define __PAGE_OFFSET (0) /* bootloader uses physical addresses */
122#else
123#ifdef CONFIG_64BIT 120#ifdef CONFIG_64BIT
124#define __PAGE_OFFSET (0x40000000) /* 1GB */ 121#define __PAGE_OFFSET_DEFAULT (0x40000000) /* 1GB */
125#else 122#else
126#define __PAGE_OFFSET (0x10000000) /* 256MB */ 123#define __PAGE_OFFSET_DEFAULT (0x10000000) /* 256MB */
127#endif 124#endif
125
126#if defined(BOOTLOADER)
127#define __PAGE_OFFSET (0) /* bootloader uses physical addresses */
128#else
129#define __PAGE_OFFSET __PAGE_OFFSET_DEFAULT
128#endif /* BOOTLOADER */ 130#endif /* BOOTLOADER */
129 131
130#define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET) 132#define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET)
diff --git a/arch/parisc/include/asm/pdc.h b/arch/parisc/include/asm/pdc.h
index 339e83ddb39e..5b187d40d604 100644
--- a/arch/parisc/include/asm/pdc.h
+++ b/arch/parisc/include/asm/pdc.h
@@ -11,6 +11,7 @@ extern int parisc_narrow_firmware;
11extern int pdc_type; 11extern int pdc_type;
12extern unsigned long parisc_cell_num; /* cell number the CPU runs on (PAT) */ 12extern unsigned long parisc_cell_num; /* cell number the CPU runs on (PAT) */
13extern unsigned long parisc_cell_loc; /* cell location of CPU (PAT) */ 13extern unsigned long parisc_cell_loc; /* cell location of CPU (PAT) */
14extern unsigned long parisc_pat_pdc_cap; /* PDC capabilities (PAT) */
14 15
15/* Values for pdc_type */ 16/* Values for pdc_type */
16#define PDC_TYPE_ILLEGAL -1 17#define PDC_TYPE_ILLEGAL -1
diff --git a/arch/parisc/include/asm/pdcpat.h b/arch/parisc/include/asm/pdcpat.h
index a468a172ee33..bce9ee1c1c99 100644
--- a/arch/parisc/include/asm/pdcpat.h
+++ b/arch/parisc/include/asm/pdcpat.h
@@ -173,6 +173,16 @@
173/* PDC PAT PD */ 173/* PDC PAT PD */
174#define PDC_PAT_PD 74L /* Protection Domain Info */ 174#define PDC_PAT_PD 74L /* Protection Domain Info */
175#define PDC_PAT_PD_GET_ADDR_MAP 0L /* Get Address Map */ 175#define PDC_PAT_PD_GET_ADDR_MAP 0L /* Get Address Map */
176#define PDC_PAT_PD_GET_PDC_INTERF_REV 1L /* Get PDC Interface Revisions */
177
178#define PDC_PAT_CAPABILITY_BIT_PDC_SERIALIZE (1UL << 0)
179#define PDC_PAT_CAPABILITY_BIT_PDC_POLLING (1UL << 1)
180#define PDC_PAT_CAPABILITY_BIT_PDC_NBC (1UL << 2) /* non-blocking calls */
181#define PDC_PAT_CAPABILITY_BIT_PDC_UFO (1UL << 3)
182#define PDC_PAT_CAPABILITY_BIT_PDC_IODC_32 (1UL << 4)
183#define PDC_PAT_CAPABILITY_BIT_PDC_IODC_64 (1UL << 5)
184#define PDC_PAT_CAPABILITY_BIT_PDC_HPMC_RENDEZ (1UL << 6)
185#define PDC_PAT_CAPABILITY_BIT_SIMULTANEOUS_PTLB (1UL << 7)
176 186
177/* PDC_PAT_PD_GET_ADDR_MAP entry types */ 187/* PDC_PAT_PD_GET_ADDR_MAP entry types */
178#define PAT_MEMORY_DESCRIPTOR 1 188#define PAT_MEMORY_DESCRIPTOR 1
@@ -186,6 +196,14 @@
186#define PAT_MEMUSE_GI 128 196#define PAT_MEMUSE_GI 128
187#define PAT_MEMUSE_GNI 129 197#define PAT_MEMUSE_GNI 129
188 198
199/* PDC PAT REGISTER TOC */
200#define PDC_PAT_REGISTER_TOC 75L
201#define PDC_PAT_TOC_REGISTER_VECTOR 0L /* Register TOC Vector */
202#define PDC_PAT_TOC_READ_VECTOR 1L /* Read TOC Vector */
203
204/* PDC PAT SYSTEM_INFO */
205#define PDC_PAT_SYSTEM_INFO 76L
206/* PDC_PAT_SYSTEM_INFO uses the same options as PDC_SYSTEM_INFO function. */
189 207
190#ifndef __ASSEMBLY__ 208#ifndef __ASSEMBLY__
191#include <linux/types.h> 209#include <linux/types.h>
@@ -297,18 +315,29 @@ struct pdc_pat_pd_addr_map_entry {
297** PDC_PAT_CELL_GET_INFO return block 315** PDC_PAT_CELL_GET_INFO return block
298*/ 316*/
299typedef struct pdc_pat_cell_info_rtn_block { 317typedef struct pdc_pat_cell_info_rtn_block {
300 unsigned long cpu_info;
301 unsigned long cell_info;
302 unsigned long cell_location;
303 unsigned long reo_location;
304 unsigned long mem_size;
305 unsigned long dimm_status;
306 unsigned long pdc_rev; 318 unsigned long pdc_rev;
307 unsigned long fabric_info0; 319 unsigned long capabilities; /* see PDC_PAT_CAPABILITY_BIT_* */
308 unsigned long fabric_info1; 320 unsigned long reserved0[2];
309 unsigned long fabric_info2; 321 unsigned long cell_info; /* 0x20 */
310 unsigned long fabric_info3; 322 unsigned long cell_phys_location;
311 unsigned long reserved[21]; 323 unsigned long cpu_info;
324 unsigned long cpu_speed;
325 unsigned long io_chassis_phys_location;
326 unsigned long cell_io_information;
327 unsigned long reserved1[2];
328 unsigned long io_slot_info_size; /* 0x60 */
329 struct {
330 unsigned long header, info0, info1;
331 unsigned long phys_loc, hw_path;
332 } io_slot[16];
333 unsigned long cell_mem_size; /* 0x2e8 */
334 unsigned long cell_dimm_info_size;
335 unsigned long dimm_info[16];
336 unsigned long fabric_info_size; /* 0x3f8 */
337 struct { /* 0x380 */
338 unsigned long fabric_info_xbc_port;
339 unsigned long rc_attached_to_xbc;
340 } xbc[8*4];
312} pdc_pat_cell_info_rtn_block_t; 341} pdc_pat_cell_info_rtn_block_t;
313 342
314 343
@@ -326,12 +355,19 @@ typedef struct pdc_pat_cell_mod_maddr_block pdc_pat_cell_mod_maddr_block_t;
326 355
327extern int pdc_pat_chassis_send_log(unsigned long status, unsigned long data); 356extern int pdc_pat_chassis_send_log(unsigned long status, unsigned long data);
328extern int pdc_pat_cell_get_number(struct pdc_pat_cell_num *cell_info); 357extern int pdc_pat_cell_get_number(struct pdc_pat_cell_num *cell_info);
329extern int pdc_pat_cell_module(unsigned long *actcnt, unsigned long ploc, unsigned long mod, unsigned long view_type, void *mem_addr); 358extern int pdc_pat_cell_info(struct pdc_pat_cell_info_rtn_block *info,
359 unsigned long *actcnt, unsigned long offset,
360 unsigned long cell_number);
361extern int pdc_pat_cell_module(unsigned long *actcnt, unsigned long ploc,
362 unsigned long mod, unsigned long view_type, void *mem_addr);
330extern int pdc_pat_cell_num_to_loc(void *, unsigned long); 363extern int pdc_pat_cell_num_to_loc(void *, unsigned long);
331 364
332extern int pdc_pat_cpu_get_number(struct pdc_pat_cpu_num *cpu_info, unsigned long hpa); 365extern int pdc_pat_cpu_get_number(struct pdc_pat_cpu_num *cpu_info, unsigned long hpa);
333 366
334extern int pdc_pat_pd_get_addr_map(unsigned long *actual_len, void *mem_addr, unsigned long count, unsigned long offset); 367extern int pdc_pat_pd_get_addr_map(unsigned long *actual_len, void *mem_addr,
368 unsigned long count, unsigned long offset);
369extern int pdc_pat_pd_get_pdc_revisions(unsigned long *legacy_rev,
370 unsigned long *pat_rev, unsigned long *pdc_cap);
335 371
336extern int pdc_pat_io_pci_cfg_read(unsigned long pci_addr, int pci_size, u32 *val); 372extern int pdc_pat_io_pci_cfg_read(unsigned long pci_addr, int pci_size, u32 *val);
337extern int pdc_pat_io_pci_cfg_write(unsigned long pci_addr, int pci_size, u32 val); 373extern int pdc_pat_io_pci_cfg_write(unsigned long pci_addr, int pci_size, u32 val);
diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h
index fa6b7c78f18a..b941ac7d4e70 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
@@ -56,19 +55,14 @@ static inline void purge_tlb_entries(struct mm_struct *mm, unsigned long addr)
56 *(pteptr) = (pteval); \ 55 *(pteptr) = (pteval); \
57 } while(0) 56 } while(0)
58 57
59#define pte_inserted(x) \
60 ((pte_val(x) & (_PAGE_PRESENT|_PAGE_ACCESSED)) \
61 == (_PAGE_PRESENT|_PAGE_ACCESSED))
62
63#define set_pte_at(mm, addr, ptep, pteval) \ 58#define set_pte_at(mm, addr, ptep, pteval) \
64 do { \ 59 do { \
65 pte_t old_pte; \ 60 pte_t old_pte; \
66 unsigned long flags; \ 61 unsigned long flags; \
67 spin_lock_irqsave(&pa_tlb_lock, flags); \ 62 spin_lock_irqsave(&pa_tlb_lock, flags); \
68 old_pte = *ptep; \ 63 old_pte = *ptep; \
69 if (pte_inserted(old_pte)) \
70 purge_tlb_entries(mm, addr); \
71 set_pte(ptep, pteval); \ 64 set_pte(ptep, pteval); \
65 purge_tlb_entries(mm, addr); \
72 spin_unlock_irqrestore(&pa_tlb_lock, flags); \ 66 spin_unlock_irqrestore(&pa_tlb_lock, flags); \
73 } while (0) 67 } while (0)
74 68
@@ -202,7 +196,7 @@ static inline void purge_tlb_entries(struct mm_struct *mm, unsigned long addr)
202#define _PAGE_HUGE (1 << xlate_pabit(_PAGE_HPAGE_BIT)) 196#define _PAGE_HUGE (1 << xlate_pabit(_PAGE_HPAGE_BIT))
203#define _PAGE_USER (1 << xlate_pabit(_PAGE_USER_BIT)) 197#define _PAGE_USER (1 << xlate_pabit(_PAGE_USER_BIT))
204 198
205#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | _PAGE_DIRTY | _PAGE_ACCESSED) 199#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | _PAGE_DIRTY | _PAGE_ACCESSED)
206#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY) 200#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
207#define _PAGE_KERNEL_RO (_PAGE_PRESENT | _PAGE_READ | _PAGE_DIRTY | _PAGE_ACCESSED) 201#define _PAGE_KERNEL_RO (_PAGE_PRESENT | _PAGE_READ | _PAGE_DIRTY | _PAGE_ACCESSED)
208#define _PAGE_KERNEL_EXEC (_PAGE_KERNEL_RO | _PAGE_EXEC) 202#define _PAGE_KERNEL_EXEC (_PAGE_KERNEL_RO | _PAGE_EXEC)
@@ -227,22 +221,22 @@ static inline void purge_tlb_entries(struct mm_struct *mm, unsigned long addr)
227 221
228#ifndef __ASSEMBLY__ 222#ifndef __ASSEMBLY__
229 223
230#define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) 224#define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_USER)
231#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED) 225#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE)
232/* Others seem to make this executable, I don't know if that's correct 226/* Others seem to make this executable, I don't know if that's correct
233 or not. The stack is mapped this way though so this is necessary 227 or not. The stack is mapped this way though so this is necessary
234 in the short term - dhd@linuxcare.com, 2000-08-08 */ 228 in the short term - dhd@linuxcare.com, 2000-08-08 */
235#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED) 229#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ)
236#define PAGE_WRITEONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_WRITE | _PAGE_ACCESSED) 230#define PAGE_WRITEONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_WRITE)
237#define PAGE_EXECREAD __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED) 231#define PAGE_EXECREAD __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC)
238#define PAGE_COPY PAGE_EXECREAD 232#define PAGE_COPY PAGE_EXECREAD
239#define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED) 233#define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC)
240#define PAGE_KERNEL __pgprot(_PAGE_KERNEL) 234#define PAGE_KERNEL __pgprot(_PAGE_KERNEL)
241#define PAGE_KERNEL_EXEC __pgprot(_PAGE_KERNEL_EXEC) 235#define PAGE_KERNEL_EXEC __pgprot(_PAGE_KERNEL_EXEC)
242#define PAGE_KERNEL_RWX __pgprot(_PAGE_KERNEL_RWX) 236#define PAGE_KERNEL_RWX __pgprot(_PAGE_KERNEL_RWX)
243#define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL_RO) 237#define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL_RO)
244#define PAGE_KERNEL_UNC __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE) 238#define PAGE_KERNEL_UNC __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
245#define PAGE_GATEWAY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_GATEWAY| _PAGE_READ) 239#define PAGE_GATEWAY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_GATEWAY| _PAGE_READ)
246 240
247 241
248/* 242/*
@@ -479,8 +473,8 @@ static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned
479 spin_unlock_irqrestore(&pa_tlb_lock, flags); 473 spin_unlock_irqrestore(&pa_tlb_lock, flags);
480 return 0; 474 return 0;
481 } 475 }
482 purge_tlb_entries(vma->vm_mm, addr);
483 set_pte(ptep, pte_mkold(pte)); 476 set_pte(ptep, pte_mkold(pte));
477 purge_tlb_entries(vma->vm_mm, addr);
484 spin_unlock_irqrestore(&pa_tlb_lock, flags); 478 spin_unlock_irqrestore(&pa_tlb_lock, flags);
485 return 1; 479 return 1;
486} 480}
@@ -493,9 +487,8 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
493 487
494 spin_lock_irqsave(&pa_tlb_lock, flags); 488 spin_lock_irqsave(&pa_tlb_lock, flags);
495 old_pte = *ptep; 489 old_pte = *ptep;
496 if (pte_inserted(old_pte))
497 purge_tlb_entries(mm, addr);
498 set_pte(ptep, __pte(0)); 490 set_pte(ptep, __pte(0));
491 purge_tlb_entries(mm, addr);
499 spin_unlock_irqrestore(&pa_tlb_lock, flags); 492 spin_unlock_irqrestore(&pa_tlb_lock, flags);
500 493
501 return old_pte; 494 return old_pte;
@@ -505,8 +498,8 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
505{ 498{
506 unsigned long flags; 499 unsigned long flags;
507 spin_lock_irqsave(&pa_tlb_lock, flags); 500 spin_lock_irqsave(&pa_tlb_lock, flags);
508 purge_tlb_entries(mm, addr);
509 set_pte(ptep, pte_wrprotect(*ptep)); 501 set_pte(ptep, pte_wrprotect(*ptep));
502 purge_tlb_entries(mm, addr);
510 spin_unlock_irqrestore(&pa_tlb_lock, flags); 503 spin_unlock_irqrestore(&pa_tlb_lock, flags);
511} 504}
512 505
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
8extern 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/spinlock.h b/arch/parisc/include/asm/spinlock.h
index 8a63515f03bf..16aec9ba2580 100644
--- a/arch/parisc/include/asm/spinlock.h
+++ b/arch/parisc/include/asm/spinlock.h
@@ -37,8 +37,8 @@ static inline void arch_spin_unlock(arch_spinlock_t *x)
37 volatile unsigned int *a; 37 volatile unsigned int *a;
38 38
39 a = __ldcw_align(x); 39 a = __ldcw_align(x);
40 mb(); 40 /* Release with ordered store. */
41 *a = 1; 41 __asm__ __volatile__("stw,ma %0,0(%1)" : : "r"(1), "r"(a) : "memory");
42} 42}
43 43
44static inline int arch_spin_trylock(arch_spinlock_t *x) 44static inline int arch_spin_trylock(arch_spinlock_t *x)
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 bddd2acebdcc..804880efa11e 100644
--- a/arch/parisc/kernel/cache.c
+++ b/arch/parisc/kernel/cache.c
@@ -36,6 +36,7 @@ EXPORT_SYMBOL(dcache_stride);
36 36
37void flush_dcache_page_asm(unsigned long phys_addr, unsigned long vaddr); 37void flush_dcache_page_asm(unsigned long phys_addr, unsigned long vaddr);
38EXPORT_SYMBOL(flush_dcache_page_asm); 38EXPORT_SYMBOL(flush_dcache_page_asm);
39void purge_dcache_page_asm(unsigned long phys_addr, unsigned long vaddr);
39void flush_icache_page_asm(unsigned long phys_addr, unsigned long vaddr); 40void flush_icache_page_asm(unsigned long phys_addr, unsigned long vaddr);
40 41
41 42
@@ -303,6 +304,17 @@ __flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr,
303 preempt_enable(); 304 preempt_enable();
304} 305}
305 306
307static inline void
308__purge_cache_page(struct vm_area_struct *vma, unsigned long vmaddr,
309 unsigned long physaddr)
310{
311 preempt_disable();
312 purge_dcache_page_asm(physaddr, vmaddr);
313 if (vma->vm_flags & VM_EXEC)
314 flush_icache_page_asm(physaddr, vmaddr);
315 preempt_enable();
316}
317
306void flush_dcache_page(struct page *page) 318void flush_dcache_page(struct page *page)
307{ 319{
308 struct address_space *mapping = page_mapping_file(page); 320 struct address_space *mapping = page_mapping_file(page);
@@ -364,7 +376,7 @@ EXPORT_SYMBOL(flush_kernel_icache_range_asm);
364#define FLUSH_THRESHOLD 0x80000 /* 0.5MB */ 376#define FLUSH_THRESHOLD 0x80000 /* 0.5MB */
365static unsigned long parisc_cache_flush_threshold __read_mostly = FLUSH_THRESHOLD; 377static unsigned long parisc_cache_flush_threshold __read_mostly = FLUSH_THRESHOLD;
366 378
367#define FLUSH_TLB_THRESHOLD (2*1024*1024) /* 2MB initial TLB threshold */ 379#define FLUSH_TLB_THRESHOLD (16*1024) /* 16 KiB minimum TLB threshold */
368static unsigned long parisc_tlb_flush_threshold __read_mostly = FLUSH_TLB_THRESHOLD; 380static unsigned long parisc_tlb_flush_threshold __read_mostly = FLUSH_TLB_THRESHOLD;
369 381
370void __init parisc_setup_cache_timing(void) 382void __init parisc_setup_cache_timing(void)
@@ -404,10 +416,6 @@ void __init parisc_setup_cache_timing(void)
404 goto set_tlb_threshold; 416 goto set_tlb_threshold;
405 } 417 }
406 418
407 alltime = mfctl(16);
408 flush_tlb_all();
409 alltime = mfctl(16) - alltime;
410
411 size = 0; 419 size = 0;
412 start = (unsigned long) _text; 420 start = (unsigned long) _text;
413 rangetime = mfctl(16); 421 rangetime = mfctl(16);
@@ -418,13 +426,19 @@ void __init parisc_setup_cache_timing(void)
418 } 426 }
419 rangetime = mfctl(16) - rangetime; 427 rangetime = mfctl(16) - rangetime;
420 428
421 printk(KERN_DEBUG "Whole TLB flush %lu cycles, flushing %lu bytes %lu cycles\n", 429 alltime = mfctl(16);
430 flush_tlb_all();
431 alltime = mfctl(16) - alltime;
432
433 printk(KERN_INFO "Whole TLB flush %lu cycles, Range flush %lu bytes %lu cycles\n",
422 alltime, size, rangetime); 434 alltime, size, rangetime);
423 435
424 threshold = PAGE_ALIGN(num_online_cpus() * size * alltime / rangetime); 436 threshold = PAGE_ALIGN((num_online_cpus() * size * alltime) / rangetime);
437 printk(KERN_INFO "Calculated TLB flush threshold %lu KiB\n",
438 threshold/1024);
425 439
426set_tlb_threshold: 440set_tlb_threshold:
427 if (threshold) 441 if (threshold > parisc_tlb_flush_threshold)
428 parisc_tlb_flush_threshold = threshold; 442 parisc_tlb_flush_threshold = threshold;
429 printk(KERN_INFO "TLB flush threshold set to %lu KiB\n", 443 printk(KERN_INFO "TLB flush threshold set to %lu KiB\n",
430 parisc_tlb_flush_threshold/1024); 444 parisc_tlb_flush_threshold/1024);
@@ -477,18 +491,6 @@ int __flush_tlb_range(unsigned long sid, unsigned long start,
477 /* Purge TLB entries for small ranges using the pdtlb and 491 /* Purge TLB entries for small ranges using the pdtlb and
478 pitlb instructions. These instructions execute locally 492 pitlb instructions. These instructions execute locally
479 but cause a purge request to be broadcast to other TLBs. */ 493 but cause a purge request to be broadcast to other TLBs. */
480 if (likely(!split_tlb)) {
481 while (start < end) {
482 purge_tlb_start(flags);
483 mtsp(sid, 1);
484 pdtlb(start);
485 purge_tlb_end(flags);
486 start += PAGE_SIZE;
487 }
488 return 0;
489 }
490
491 /* split TLB case */
492 while (start < end) { 494 while (start < end) {
493 purge_tlb_start(flags); 495 purge_tlb_start(flags);
494 mtsp(sid, 1); 496 mtsp(sid, 1);
@@ -573,9 +575,12 @@ void flush_cache_mm(struct mm_struct *mm)
573 pfn = pte_pfn(*ptep); 575 pfn = pte_pfn(*ptep);
574 if (!pfn_valid(pfn)) 576 if (!pfn_valid(pfn))
575 continue; 577 continue;
576 if (unlikely(mm->context)) 578 if (unlikely(mm->context)) {
577 flush_tlb_page(vma, addr); 579 flush_tlb_page(vma, addr);
578 __flush_cache_page(vma, addr, PFN_PHYS(pfn)); 580 __flush_cache_page(vma, addr, PFN_PHYS(pfn));
581 } else {
582 __purge_cache_page(vma, addr, PFN_PHYS(pfn));
583 }
579 } 584 }
580 } 585 }
581} 586}
@@ -610,9 +615,12 @@ void flush_cache_range(struct vm_area_struct *vma,
610 continue; 615 continue;
611 pfn = pte_pfn(*ptep); 616 pfn = pte_pfn(*ptep);
612 if (pfn_valid(pfn)) { 617 if (pfn_valid(pfn)) {
613 if (unlikely(vma->vm_mm->context)) 618 if (unlikely(vma->vm_mm->context)) {
614 flush_tlb_page(vma, addr); 619 flush_tlb_page(vma, addr);
615 __flush_cache_page(vma, addr, PFN_PHYS(pfn)); 620 __flush_cache_page(vma, addr, PFN_PHYS(pfn));
621 } else {
622 __purge_cache_page(vma, addr, PFN_PHYS(pfn));
623 }
616 } 624 }
617 } 625 }
618} 626}
@@ -621,9 +629,12 @@ void
621flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long pfn) 629flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long pfn)
622{ 630{
623 if (pfn_valid(pfn)) { 631 if (pfn_valid(pfn)) {
624 if (likely(vma->vm_mm->context)) 632 if (likely(vma->vm_mm->context)) {
625 flush_tlb_page(vma, vmaddr); 633 flush_tlb_page(vma, vmaddr);
626 __flush_cache_page(vma, vmaddr, PFN_PHYS(pfn)); 634 __flush_cache_page(vma, vmaddr, PFN_PHYS(pfn));
635 } else {
636 __purge_cache_page(vma, vmaddr, PFN_PHYS(pfn));
637 }
627 } 638 }
628} 639}
629 640
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
index 242c5ab65611..1c60408a64ad 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
@@ -186,7 +187,7 @@
186 bv,n 0(%r3) 187 bv,n 0(%r3)
187 nop 188 nop
188 .word 0 /* checksum (will be patched) */ 189 .word 0 /* checksum (will be patched) */
189 .word PA(os_hpmc) /* address of handler */ 190 .word 0 /* address of handler */
190 .word 0 /* length of handler */ 191 .word 0 /* length of handler */
191 .endm 192 .endm
192 193
@@ -426,13 +427,10 @@
426 ldw,s \index(\pmd),\pmd 427 ldw,s \index(\pmd),\pmd
427 bb,>=,n \pmd,_PxD_PRESENT_BIT,\fault 428 bb,>=,n \pmd,_PxD_PRESENT_BIT,\fault
428 dep %r0,31,PxD_FLAG_SHIFT,\pmd /* clear flags */ 429 dep %r0,31,PxD_FLAG_SHIFT,\pmd /* clear flags */
429 copy \pmd,%r9 430 SHLREG \pmd,PxD_VALUE_SHIFT,\pmd
430 SHLREG %r9,PxD_VALUE_SHIFT,\pmd
431 extru \va,31-PAGE_SHIFT,ASM_BITS_PER_PTE,\index 431 extru \va,31-PAGE_SHIFT,ASM_BITS_PER_PTE,\index
432 dep %r0,31,PAGE_SHIFT,\pmd /* clear offset */ 432 dep %r0,31,PAGE_SHIFT,\pmd /* clear offset */
433 shladd \index,BITS_PER_PTE_ENTRY,\pmd,\pmd /* pmd is now pte */ 433 shladd \index,BITS_PER_PTE_ENTRY,\pmd,\pmd /* pmd is now pte */
434 LDREG %r0(\pmd),\pte
435 bb,>=,n \pte,_PAGE_PRESENT_BIT,\fault
436 .endm 434 .endm
437 435
438 /* Look up PTE in a 3-Level scheme. 436 /* Look up PTE in a 3-Level scheme.
@@ -448,7 +446,6 @@
448 .macro L3_ptep pgd,pte,index,va,fault 446 .macro L3_ptep pgd,pte,index,va,fault
449#if CONFIG_PGTABLE_LEVELS == 3 /* we might have a 2-Level scheme, e.g. with 16kb page size */ 447#if CONFIG_PGTABLE_LEVELS == 3 /* we might have a 2-Level scheme, e.g. with 16kb page size */
450 extrd,u \va,63-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index 448 extrd,u \va,63-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index
451 copy %r0,\pte
452 extrd,u,*= \va,63-ASM_PGDIR_SHIFT,64-ASM_PGDIR_SHIFT,%r0 449 extrd,u,*= \va,63-ASM_PGDIR_SHIFT,64-ASM_PGDIR_SHIFT,%r0
453 ldw,s \index(\pgd),\pgd 450 ldw,s \index(\pgd),\pgd
454 extrd,u,*= \va,63-ASM_PGDIR_SHIFT,64-ASM_PGDIR_SHIFT,%r0 451 extrd,u,*= \va,63-ASM_PGDIR_SHIFT,64-ASM_PGDIR_SHIFT,%r0
@@ -463,36 +460,39 @@
463 L2_ptep \pgd,\pte,\index,\va,\fault 460 L2_ptep \pgd,\pte,\index,\va,\fault
464 .endm 461 .endm
465 462
466 /* Acquire pa_tlb_lock lock and recheck page is still present. */ 463 /* Acquire pa_tlb_lock lock and check page is present. */
467 .macro tlb_lock spc,ptp,pte,tmp,tmp1,fault 464 .macro tlb_lock spc,ptp,pte,tmp,tmp1,fault
468#ifdef CONFIG_SMP 465#ifdef CONFIG_SMP
469 cmpib,COND(=),n 0,\spc,2f 46698: cmpib,COND(=),n 0,\spc,2f
470 load_pa_tlb_lock \tmp 467 load_pa_tlb_lock \tmp
4711: LDCW 0(\tmp),\tmp1 4681: LDCW 0(\tmp),\tmp1
472 cmpib,COND(=) 0,\tmp1,1b 469 cmpib,COND(=) 0,\tmp1,1b
473 nop 470 nop
474 LDREG 0(\ptp),\pte 471 LDREG 0(\ptp),\pte
475 bb,<,n \pte,_PAGE_PRESENT_BIT,2f 472 bb,<,n \pte,_PAGE_PRESENT_BIT,3f
476 b \fault 473 b \fault
477 stw \spc,0(\tmp) 474 stw,ma \spc,0(\tmp)
4782: 47599: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP)
479#endif 476#endif
4772: LDREG 0(\ptp),\pte
478 bb,>=,n \pte,_PAGE_PRESENT_BIT,\fault
4793:
480 .endm 480 .endm
481 481
482 /* Release pa_tlb_lock lock without reloading lock address. */ 482 /* Release pa_tlb_lock lock without reloading lock address. */
483 .macro tlb_unlock0 spc,tmp 483 .macro tlb_unlock0 spc,tmp
484#ifdef CONFIG_SMP 484#ifdef CONFIG_SMP
485 or,COND(=) %r0,\spc,%r0 48598: or,COND(=) %r0,\spc,%r0
486 sync 486 stw,ma \spc,0(\tmp)
487 or,COND(=) %r0,\spc,%r0 48799: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP)
488 stw \spc,0(\tmp)
489#endif 488#endif
490 .endm 489 .endm
491 490
492 /* Release pa_tlb_lock lock. */ 491 /* Release pa_tlb_lock lock. */
493 .macro tlb_unlock1 spc,tmp 492 .macro tlb_unlock1 spc,tmp
494#ifdef CONFIG_SMP 493#ifdef CONFIG_SMP
495 load_pa_tlb_lock \tmp 49498: load_pa_tlb_lock \tmp
49599: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP)
496 tlb_unlock0 \spc,\tmp 496 tlb_unlock0 \spc,\tmp
497#endif 497#endif
498 .endm 498 .endm
@@ -1658,7 +1658,7 @@ dbit_fault:
1658 1658
1659itlb_fault: 1659itlb_fault:
1660 b intr_save 1660 b intr_save
1661 ldi 6,%r8 1661 ldi PARISC_ITLB_TRAP,%r8
1662 1662
1663nadtlb_fault: 1663nadtlb_fault:
1664 b intr_save 1664 b intr_save
diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c
index 6d471c00c71a..e6f3b49f2fd7 100644
--- a/arch/parisc/kernel/firmware.c
+++ b/arch/parisc/kernel/firmware.c
@@ -1326,6 +1326,36 @@ int pdc_pat_cell_module(unsigned long *actcnt, unsigned long ploc, unsigned long
1326} 1326}
1327 1327
1328/** 1328/**
1329 * pdc_pat_cell_info - Retrieve the cell's information.
1330 * @info: The pointer to a struct pdc_pat_cell_info_rtn_block.
1331 * @actcnt: The number of bytes which should be written to info.
1332 * @offset: offset of the structure.
1333 * @cell_number: The cell number which should be asked, or -1 for current cell.
1334 *
1335 * This PDC call returns information about the given cell (or all cells).
1336 */
1337int pdc_pat_cell_info(struct pdc_pat_cell_info_rtn_block *info,
1338 unsigned long *actcnt, unsigned long offset,
1339 unsigned long cell_number)
1340{
1341 int retval;
1342 unsigned long flags;
1343 struct pdc_pat_cell_info_rtn_block result;
1344
1345 spin_lock_irqsave(&pdc_lock, flags);
1346 retval = mem_pdc_call(PDC_PAT_CELL, PDC_PAT_CELL_GET_INFO,
1347 __pa(pdc_result), __pa(&result), *actcnt,
1348 offset, cell_number);
1349 if (!retval) {
1350 *actcnt = pdc_result[0];
1351 memcpy(info, &result, *actcnt);
1352 }
1353 spin_unlock_irqrestore(&pdc_lock, flags);
1354
1355 return retval;
1356}
1357
1358/**
1329 * pdc_pat_cpu_get_number - Retrieve the cpu number. 1359 * pdc_pat_cpu_get_number - Retrieve the cpu number.
1330 * @cpu_info: The return buffer. 1360 * @cpu_info: The return buffer.
1331 * @hpa: The Hard Physical Address of the CPU. 1361 * @hpa: The Hard Physical Address of the CPU.
@@ -1413,6 +1443,33 @@ int pdc_pat_pd_get_addr_map(unsigned long *actual_len, void *mem_addr,
1413} 1443}
1414 1444
1415/** 1445/**
1446 * pdc_pat_pd_get_PDC_interface_revisions - Retrieve PDC interface revisions.
1447 * @legacy_rev: The legacy revision.
1448 * @pat_rev: The PAT revision.
1449 * @pdc_cap: The PDC capabilities.
1450 *
1451 */
1452int pdc_pat_pd_get_pdc_revisions(unsigned long *legacy_rev,
1453 unsigned long *pat_rev, unsigned long *pdc_cap)
1454{
1455 int retval;
1456 unsigned long flags;
1457
1458 spin_lock_irqsave(&pdc_lock, flags);
1459 retval = mem_pdc_call(PDC_PAT_PD, PDC_PAT_PD_GET_PDC_INTERF_REV,
1460 __pa(pdc_result));
1461 if (retval == PDC_OK) {
1462 *legacy_rev = pdc_result[0];
1463 *pat_rev = pdc_result[1];
1464 *pdc_cap = pdc_result[2];
1465 }
1466 spin_unlock_irqrestore(&pdc_lock, flags);
1467
1468 return retval;
1469}
1470
1471
1472/**
1416 * pdc_pat_io_pci_cfg_read - Read PCI configuration space. 1473 * pdc_pat_io_pci_cfg_read - Read PCI configuration space.
1417 * @pci_addr: PCI configuration space address for which the read request is being made. 1474 * @pci_addr: PCI configuration space address for which the read request is being made.
1418 * @pci_size: Size of read in bytes. Valid values are 1, 2, and 4. 1475 * @pci_size: Size of read in bytes. Valid values are 1, 2, and 4.
diff --git a/arch/parisc/kernel/hpmc.S b/arch/parisc/kernel/hpmc.S
index 781c3b9a3e46..fde654115564 100644
--- a/arch/parisc/kernel/hpmc.S
+++ b/arch/parisc/kernel/hpmc.S
@@ -85,7 +85,7 @@ END(hpmc_pim_data)
85 85
86 .import intr_save, code 86 .import intr_save, code
87 .align 16 87 .align 16
88ENTRY_CFI(os_hpmc) 88ENTRY(os_hpmc)
89.os_hpmc: 89.os_hpmc:
90 90
91 /* 91 /*
@@ -302,7 +302,6 @@ os_hpmc_6:
302 b . 302 b .
303 nop 303 nop
304 .align 16 /* make function length multiple of 16 bytes */ 304 .align 16 /* make function length multiple of 16 bytes */
305ENDPROC_CFI(os_hpmc)
306.os_hpmc_end: 305.os_hpmc_end:
307 306
308 307
diff --git a/arch/parisc/kernel/inventory.c b/arch/parisc/kernel/inventory.c
index b0fe19ac4d78..35d05fdd7483 100644
--- a/arch/parisc/kernel/inventory.c
+++ b/arch/parisc/kernel/inventory.c
@@ -43,6 +43,7 @@ int pdc_type __read_mostly = PDC_TYPE_ILLEGAL;
43/* cell number and location (PAT firmware only) */ 43/* cell number and location (PAT firmware only) */
44unsigned long parisc_cell_num __read_mostly; 44unsigned long parisc_cell_num __read_mostly;
45unsigned long parisc_cell_loc __read_mostly; 45unsigned long parisc_cell_loc __read_mostly;
46unsigned long parisc_pat_pdc_cap __read_mostly;
46 47
47 48
48void __init setup_pdc(void) 49void __init setup_pdc(void)
@@ -81,12 +82,21 @@ void __init setup_pdc(void)
81#ifdef CONFIG_64BIT 82#ifdef CONFIG_64BIT
82 status = pdc_pat_cell_get_number(&cell_info); 83 status = pdc_pat_cell_get_number(&cell_info);
83 if (status == PDC_OK) { 84 if (status == PDC_OK) {
85 unsigned long legacy_rev, pat_rev;
84 pdc_type = PDC_TYPE_PAT; 86 pdc_type = PDC_TYPE_PAT;
85 pr_cont("64 bit PAT.\n"); 87 pr_cont("64 bit PAT.\n");
86 parisc_cell_num = cell_info.cell_num; 88 parisc_cell_num = cell_info.cell_num;
87 parisc_cell_loc = cell_info.cell_loc; 89 parisc_cell_loc = cell_info.cell_loc;
88 pr_info("PAT: Running on cell %lu and location %lu.\n", 90 pr_info("PAT: Running on cell %lu and location %lu.\n",
89 parisc_cell_num, parisc_cell_loc); 91 parisc_cell_num, parisc_cell_loc);
92 status = pdc_pat_pd_get_pdc_revisions(&legacy_rev,
93 &pat_rev, &parisc_pat_pdc_cap);
94 pr_info("PAT: legacy revision 0x%lx, pat_rev 0x%lx, pdc_cap 0x%lx, S-PTLB %d, HPMC_RENDEZ %d.\n",
95 legacy_rev, pat_rev, parisc_pat_pdc_cap,
96 parisc_pat_pdc_cap
97 & PDC_PAT_CAPABILITY_BIT_SIMULTANEOUS_PTLB ? 1:0,
98 parisc_pat_pdc_cap
99 & PDC_PAT_CAPABILITY_BIT_PDC_HPMC_RENDEZ ? 1:0);
90 return; 100 return;
91 } 101 }
92#endif 102#endif
diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S
index f33bf2d306d6..187f032c9dd8 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
192ENTRY_CFI(flush_instruction_cache_local) 193ENTRY_CFI(flush_instruction_cache_local)
193 load32 cache_info, %r1 19488: load32 cache_info, %r1
194 195
195 /* Flush Instruction Cache */ 196 /* Flush Instruction Cache */
196 197
@@ -243,6 +244,7 @@ fioneloop2:
243fisync: 244fisync:
244 sync 245 sync
245 mtsm %r22 /* restore I-bit */ 246 mtsm %r22 /* restore I-bit */
24789: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP)
246 bv %r0(%r2) 248 bv %r0(%r2)
247 nop 249 nop
248ENDPROC_CFI(flush_instruction_cache_local) 250ENDPROC_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
252ENTRY_CFI(flush_data_cache_local) 254ENTRY_CFI(flush_data_cache_local)
253 load32 cache_info, %r1 25588: 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 */
30989: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
307 bv %r0(%r2) 310 bv %r0(%r2)
308 nop 311 nop
309ENDPROC_CFI(flush_data_cache_local) 312ENDPROC_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
31898:
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
3283: 3323:
33399: 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 33998: ldi 1,\tmp
335 sync 340 sync
336 stw \tmp,0(\la) 341 stw \tmp,0(\la)
337 mtsm \flags 342 mtsm \flags
34399: 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) 6050: pdtlb %r0(%r28)
600 pdtlb %r0(%r29) 6061: 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) 7470: 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) 8250: 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 83088: 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
@@ -828,8 +838,7 @@ ENTRY_CFI(flush_dcache_page_asm)
828 add %r28, %r25, %r25 838 add %r28, %r25, %r25
829 sub %r25, r31, %r25 839 sub %r25, r31, %r25
830 840
831 8411: fdc,m r31(%r28)
8321: fdc,m r31(%r28)
833 fdc,m r31(%r28) 842 fdc,m r31(%r28)
834 fdc,m r31(%r28) 843 fdc,m r31(%r28)
835 fdc,m r31(%r28) 844 fdc,m r31(%r28)
@@ -844,14 +853,76 @@ ENTRY_CFI(flush_dcache_page_asm)
844 fdc,m r31(%r28) 853 fdc,m r31(%r28)
845 fdc,m r31(%r28) 854 fdc,m r31(%r28)
846 fdc,m r31(%r28) 855 fdc,m r31(%r28)
847 cmpb,COND(<<) %r28, %r25,1b 856 cmpb,COND(>>) %r25, %r28, 1b /* predict taken */
848 fdc,m r31(%r28) 857 fdc,m r31(%r28)
849 858
85989: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
850 sync 860 sync
851 bv %r0(%r2) 861 bv %r0(%r2)
852 nop 862 nop
853ENDPROC_CFI(flush_dcache_page_asm) 863ENDPROC_CFI(flush_dcache_page_asm)
854 864
865ENTRY_CFI(purge_dcache_page_asm)
866 ldil L%(TMPALIAS_MAP_START), %r28
867#ifdef CONFIG_64BIT
868#if (TMPALIAS_MAP_START >= 0x80000000)
869 depdi 0, 31,32, %r28 /* clear any sign extension */
870#endif
871 convert_phys_for_tlb_insert20 %r26 /* convert phys addr to tlb insert format */
872 depd %r25, 63,22, %r28 /* Form aliased virtual address 'to' */
873 depdi 0, 63,PAGE_SHIFT, %r28 /* Clear any offset bits */
874#else
875 extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */
876 depw %r25, 31,22, %r28 /* Form aliased virtual address 'to' */
877 depwi 0, 31,PAGE_SHIFT, %r28 /* Clear any offset bits */
878#endif
879
880 /* Purge any old translation */
881
882#ifdef CONFIG_PA20
883 pdtlb,l %r0(%r28)
884#else
885 tlb_lock %r20,%r21,%r22
8860: pdtlb %r0(%r28)
887 tlb_unlock %r20,%r21,%r22
888 ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB)
889#endif
890
89188: ldil L%dcache_stride, %r1
892 ldw R%dcache_stride(%r1), r31
893
894#ifdef CONFIG_64BIT
895 depdi,z 1, 63-PAGE_SHIFT,1, %r25
896#else
897 depwi,z 1, 31-PAGE_SHIFT,1, %r25
898#endif
899 add %r28, %r25, %r25
900 sub %r25, r31, %r25
901
9021: pdc,m r31(%r28)
903 pdc,m r31(%r28)
904 pdc,m r31(%r28)
905 pdc,m r31(%r28)
906 pdc,m r31(%r28)
907 pdc,m r31(%r28)
908 pdc,m r31(%r28)
909 pdc,m r31(%r28)
910 pdc,m r31(%r28)
911 pdc,m r31(%r28)
912 pdc,m r31(%r28)
913 pdc,m r31(%r28)
914 pdc,m r31(%r28)
915 pdc,m r31(%r28)
916 pdc,m r31(%r28)
917 cmpb,COND(>>) %r25, %r28, 1b /* predict taken */
918 pdc,m r31(%r28)
919
92089: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
921 sync
922 bv %r0(%r2)
923 nop
924ENDPROC_CFI(purge_dcache_page_asm)
925
855ENTRY_CFI(flush_icache_page_asm) 926ENTRY_CFI(flush_icache_page_asm)
856 ldil L%(TMPALIAS_MAP_START), %r28 927 ldil L%(TMPALIAS_MAP_START), %r28
857#ifdef CONFIG_64BIT 928#ifdef CONFIG_64BIT
@@ -874,15 +945,19 @@ ENTRY_CFI(flush_icache_page_asm)
874 945
875#ifdef CONFIG_PA20 946#ifdef CONFIG_PA20
876 pdtlb,l %r0(%r28) 947 pdtlb,l %r0(%r28)
877 pitlb,l %r0(%sr4,%r28) 9481: pitlb,l %r0(%sr4,%r28)
949 ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SPLIT_TLB, INSN_NOP)
878#else 950#else
879 tlb_lock %r20,%r21,%r22 951 tlb_lock %r20,%r21,%r22
880 pdtlb %r0(%r28) 9520: pdtlb %r0(%r28)
881 pitlb %r0(%sr4,%r28) 9531: pitlb %r0(%sr4,%r28)
882 tlb_unlock %r20,%r21,%r22 954 tlb_unlock %r20,%r21,%r22
955 ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB)
956 ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SMP, INSN_PxTLB)
957 ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SPLIT_TLB, INSN_NOP)
883#endif 958#endif
884 959
885 ldil L%icache_stride, %r1 96088: ldil L%icache_stride, %r1
886 ldw R%icache_stride(%r1), %r31 961 ldw R%icache_stride(%r1), %r31
887 962
888#ifdef CONFIG_64BIT 963#ifdef CONFIG_64BIT
@@ -893,7 +968,6 @@ ENTRY_CFI(flush_icache_page_asm)
893 add %r28, %r25, %r25 968 add %r28, %r25, %r25
894 sub %r25, %r31, %r25 969 sub %r25, %r31, %r25
895 970
896
897 /* fic only has the type 26 form on PA1.1, requiring an 971 /* fic only has the type 26 form on PA1.1, requiring an
898 * explicit space specification, so use %sr4 */ 972 * explicit space specification, so use %sr4 */
8991: fic,m %r31(%sr4,%r28) 9731: fic,m %r31(%sr4,%r28)
@@ -911,16 +985,17 @@ ENTRY_CFI(flush_icache_page_asm)
911 fic,m %r31(%sr4,%r28) 985 fic,m %r31(%sr4,%r28)
912 fic,m %r31(%sr4,%r28) 986 fic,m %r31(%sr4,%r28)
913 fic,m %r31(%sr4,%r28) 987 fic,m %r31(%sr4,%r28)
914 cmpb,COND(<<) %r28, %r25,1b 988 cmpb,COND(>>) %r25, %r28, 1b /* predict taken */
915 fic,m %r31(%sr4,%r28) 989 fic,m %r31(%sr4,%r28)
916 990
99189: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP)
917 sync 992 sync
918 bv %r0(%r2) 993 bv %r0(%r2)
919 nop 994 nop
920ENDPROC_CFI(flush_icache_page_asm) 995ENDPROC_CFI(flush_icache_page_asm)
921 996
922ENTRY_CFI(flush_kernel_dcache_page_asm) 997ENTRY_CFI(flush_kernel_dcache_page_asm)
923 ldil L%dcache_stride, %r1 99888: ldil L%dcache_stride, %r1
924 ldw R%dcache_stride(%r1), %r23 999 ldw R%dcache_stride(%r1), %r23
925 1000
926#ifdef CONFIG_64BIT 1001#ifdef CONFIG_64BIT
@@ -931,7 +1006,6 @@ ENTRY_CFI(flush_kernel_dcache_page_asm)
931 add %r26, %r25, %r25 1006 add %r26, %r25, %r25
932 sub %r25, %r23, %r25 1007 sub %r25, %r23, %r25
933 1008
934
9351: fdc,m %r23(%r26) 10091: fdc,m %r23(%r26)
936 fdc,m %r23(%r26) 1010 fdc,m %r23(%r26)
937 fdc,m %r23(%r26) 1011 fdc,m %r23(%r26)
@@ -947,16 +1021,17 @@ ENTRY_CFI(flush_kernel_dcache_page_asm)
947 fdc,m %r23(%r26) 1021 fdc,m %r23(%r26)
948 fdc,m %r23(%r26) 1022 fdc,m %r23(%r26)
949 fdc,m %r23(%r26) 1023 fdc,m %r23(%r26)
950 cmpb,COND(<<) %r26, %r25,1b 1024 cmpb,COND(>>) %r25, %r26, 1b /* predict taken */
951 fdc,m %r23(%r26) 1025 fdc,m %r23(%r26)
952 1026
102789: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
953 sync 1028 sync
954 bv %r0(%r2) 1029 bv %r0(%r2)
955 nop 1030 nop
956ENDPROC_CFI(flush_kernel_dcache_page_asm) 1031ENDPROC_CFI(flush_kernel_dcache_page_asm)
957 1032
958ENTRY_CFI(purge_kernel_dcache_page_asm) 1033ENTRY_CFI(purge_kernel_dcache_page_asm)
959 ldil L%dcache_stride, %r1 103488: ldil L%dcache_stride, %r1
960 ldw R%dcache_stride(%r1), %r23 1035 ldw R%dcache_stride(%r1), %r23
961 1036
962#ifdef CONFIG_64BIT 1037#ifdef CONFIG_64BIT
@@ -982,74 +1057,183 @@ ENTRY_CFI(purge_kernel_dcache_page_asm)
982 pdc,m %r23(%r26) 1057 pdc,m %r23(%r26)
983 pdc,m %r23(%r26) 1058 pdc,m %r23(%r26)
984 pdc,m %r23(%r26) 1059 pdc,m %r23(%r26)
985 cmpb,COND(<<) %r26, %r25, 1b 1060 cmpb,COND(>>) %r25, %r26, 1b /* predict taken */
986 pdc,m %r23(%r26) 1061 pdc,m %r23(%r26)
987 1062
106389: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
988 sync 1064 sync
989 bv %r0(%r2) 1065 bv %r0(%r2)
990 nop 1066 nop
991ENDPROC_CFI(purge_kernel_dcache_page_asm) 1067ENDPROC_CFI(purge_kernel_dcache_page_asm)
992 1068
993ENTRY_CFI(flush_user_dcache_range_asm) 1069ENTRY_CFI(flush_user_dcache_range_asm)
994 ldil L%dcache_stride, %r1 107088: ldil L%dcache_stride, %r1
995 ldw R%dcache_stride(%r1), %r23 1071 ldw R%dcache_stride(%r1), %r23
996 ldo -1(%r23), %r21 1072 ldo -1(%r23), %r21
997 ANDCM %r26, %r21, %r26 1073 ANDCM %r26, %r21, %r26
998 1074
9991: cmpb,COND(<<),n %r26, %r25, 1b 1075#ifdef CONFIG_64BIT
1076 depd,z %r23, 59, 60, %r21
1077#else
1078 depw,z %r23, 27, 28, %r21
1079#endif
1080 add %r26, %r21, %r22
1081 cmpb,COND(>>),n %r22, %r25, 2f /* predict not taken */
10821: add %r22, %r21, %r22
1083 fdc,m %r23(%sr3, %r26)
1084 fdc,m %r23(%sr3, %r26)
1085 fdc,m %r23(%sr3, %r26)
1086 fdc,m %r23(%sr3, %r26)
1087 fdc,m %r23(%sr3, %r26)
1088 fdc,m %r23(%sr3, %r26)
1089 fdc,m %r23(%sr3, %r26)
1090 fdc,m %r23(%sr3, %r26)
1091 fdc,m %r23(%sr3, %r26)
1092 fdc,m %r23(%sr3, %r26)
1093 fdc,m %r23(%sr3, %r26)
1094 fdc,m %r23(%sr3, %r26)
1095 fdc,m %r23(%sr3, %r26)
1096 fdc,m %r23(%sr3, %r26)
1097 fdc,m %r23(%sr3, %r26)
1098 cmpb,COND(<<=) %r22, %r25, 1b /* predict taken */
1000 fdc,m %r23(%sr3, %r26) 1099 fdc,m %r23(%sr3, %r26)
1001 1100
11012: cmpb,COND(>>),n %r25, %r26, 2b
1102 fdc,m %r23(%sr3, %r26)
1103
110489: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
1002 sync 1105 sync
1003 bv %r0(%r2) 1106 bv %r0(%r2)
1004 nop 1107 nop
1005ENDPROC_CFI(flush_user_dcache_range_asm) 1108ENDPROC_CFI(flush_user_dcache_range_asm)
1006 1109
1007ENTRY_CFI(flush_kernel_dcache_range_asm) 1110ENTRY_CFI(flush_kernel_dcache_range_asm)
1008 ldil L%dcache_stride, %r1 111188: ldil L%dcache_stride, %r1
1009 ldw R%dcache_stride(%r1), %r23 1112 ldw R%dcache_stride(%r1), %r23
1010 ldo -1(%r23), %r21 1113 ldo -1(%r23), %r21
1011 ANDCM %r26, %r21, %r26 1114 ANDCM %r26, %r21, %r26
1012 1115
10131: cmpb,COND(<<),n %r26, %r25,1b 1116#ifdef CONFIG_64BIT
1117 depd,z %r23, 59, 60, %r21
1118#else
1119 depw,z %r23, 27, 28, %r21
1120#endif
1121 add %r26, %r21, %r22
1122 cmpb,COND(>>),n %r22, %r25, 2f /* predict not taken */
11231: add %r22, %r21, %r22
1124 fdc,m %r23(%r26)
1125 fdc,m %r23(%r26)
1126 fdc,m %r23(%r26)
1127 fdc,m %r23(%r26)
1128 fdc,m %r23(%r26)
1129 fdc,m %r23(%r26)
1130 fdc,m %r23(%r26)
1131 fdc,m %r23(%r26)
1132 fdc,m %r23(%r26)
1133 fdc,m %r23(%r26)
1134 fdc,m %r23(%r26)
1135 fdc,m %r23(%r26)
1136 fdc,m %r23(%r26)
1137 fdc,m %r23(%r26)
1138 fdc,m %r23(%r26)
1139 cmpb,COND(<<=) %r22, %r25, 1b /* predict taken */
1140 fdc,m %r23(%r26)
1141
11422: cmpb,COND(>>),n %r25, %r26, 2b /* predict taken */
1014 fdc,m %r23(%r26) 1143 fdc,m %r23(%r26)
1015 1144
1016 sync 1145 sync
114689: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
1017 syncdma 1147 syncdma
1018 bv %r0(%r2) 1148 bv %r0(%r2)
1019 nop 1149 nop
1020ENDPROC_CFI(flush_kernel_dcache_range_asm) 1150ENDPROC_CFI(flush_kernel_dcache_range_asm)
1021 1151
1022ENTRY_CFI(purge_kernel_dcache_range_asm) 1152ENTRY_CFI(purge_kernel_dcache_range_asm)
1023 ldil L%dcache_stride, %r1 115388: ldil L%dcache_stride, %r1
1024 ldw R%dcache_stride(%r1), %r23 1154 ldw R%dcache_stride(%r1), %r23
1025 ldo -1(%r23), %r21 1155 ldo -1(%r23), %r21
1026 ANDCM %r26, %r21, %r26 1156 ANDCM %r26, %r21, %r26
1027 1157
10281: cmpb,COND(<<),n %r26, %r25,1b 1158#ifdef CONFIG_64BIT
1159 depd,z %r23, 59, 60, %r21
1160#else
1161 depw,z %r23, 27, 28, %r21
1162#endif
1163 add %r26, %r21, %r22
1164 cmpb,COND(>>),n %r22, %r25, 2f /* predict not taken */
11651: add %r22, %r21, %r22
1166 pdc,m %r23(%r26)
1167 pdc,m %r23(%r26)
1168 pdc,m %r23(%r26)
1169 pdc,m %r23(%r26)
1170 pdc,m %r23(%r26)
1171 pdc,m %r23(%r26)
1172 pdc,m %r23(%r26)
1173 pdc,m %r23(%r26)
1174 pdc,m %r23(%r26)
1175 pdc,m %r23(%r26)
1176 pdc,m %r23(%r26)
1177 pdc,m %r23(%r26)
1178 pdc,m %r23(%r26)
1179 pdc,m %r23(%r26)
1180 pdc,m %r23(%r26)
1181 cmpb,COND(<<=) %r22, %r25, 1b /* predict taken */
1182 pdc,m %r23(%r26)
1183
11842: cmpb,COND(>>),n %r25, %r26, 2b /* predict taken */
1029 pdc,m %r23(%r26) 1185 pdc,m %r23(%r26)
1030 1186
1031 sync 1187 sync
118889: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
1032 syncdma 1189 syncdma
1033 bv %r0(%r2) 1190 bv %r0(%r2)
1034 nop 1191 nop
1035ENDPROC_CFI(purge_kernel_dcache_range_asm) 1192ENDPROC_CFI(purge_kernel_dcache_range_asm)
1036 1193
1037ENTRY_CFI(flush_user_icache_range_asm) 1194ENTRY_CFI(flush_user_icache_range_asm)
1038 ldil L%icache_stride, %r1 119588: ldil L%icache_stride, %r1
1039 ldw R%icache_stride(%r1), %r23 1196 ldw R%icache_stride(%r1), %r23
1040 ldo -1(%r23), %r21 1197 ldo -1(%r23), %r21
1041 ANDCM %r26, %r21, %r26 1198 ANDCM %r26, %r21, %r26
1042 1199
10431: cmpb,COND(<<),n %r26, %r25,1b 1200#ifdef CONFIG_64BIT
1201 depd,z %r23, 59, 60, %r21
1202#else
1203 depw,z %r23, 27, 28, %r21
1204#endif
1205 add %r26, %r21, %r22
1206 cmpb,COND(>>),n %r22, %r25, 2f /* predict not taken */
12071: add %r22, %r21, %r22
1208 fic,m %r23(%sr3, %r26)
1209 fic,m %r23(%sr3, %r26)
1210 fic,m %r23(%sr3, %r26)
1211 fic,m %r23(%sr3, %r26)
1212 fic,m %r23(%sr3, %r26)
1213 fic,m %r23(%sr3, %r26)
1214 fic,m %r23(%sr3, %r26)
1215 fic,m %r23(%sr3, %r26)
1216 fic,m %r23(%sr3, %r26)
1217 fic,m %r23(%sr3, %r26)
1218 fic,m %r23(%sr3, %r26)
1219 fic,m %r23(%sr3, %r26)
1220 fic,m %r23(%sr3, %r26)
1221 fic,m %r23(%sr3, %r26)
1222 fic,m %r23(%sr3, %r26)
1223 cmpb,COND(<<=) %r22, %r25, 1b /* predict taken */
1224 fic,m %r23(%sr3, %r26)
1225
12262: cmpb,COND(>>),n %r25, %r26, 2b
1044 fic,m %r23(%sr3, %r26) 1227 fic,m %r23(%sr3, %r26)
1045 1228
122989: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP)
1046 sync 1230 sync
1047 bv %r0(%r2) 1231 bv %r0(%r2)
1048 nop 1232 nop
1049ENDPROC_CFI(flush_user_icache_range_asm) 1233ENDPROC_CFI(flush_user_icache_range_asm)
1050 1234
1051ENTRY_CFI(flush_kernel_icache_page) 1235ENTRY_CFI(flush_kernel_icache_page)
1052 ldil L%icache_stride, %r1 123688: ldil L%icache_stride, %r1
1053 ldw R%icache_stride(%r1), %r23 1237 ldw R%icache_stride(%r1), %r23
1054 1238
1055#ifdef CONFIG_64BIT 1239#ifdef CONFIG_64BIT
@@ -1076,23 +1260,51 @@ ENTRY_CFI(flush_kernel_icache_page)
1076 fic,m %r23(%sr4, %r26) 1260 fic,m %r23(%sr4, %r26)
1077 fic,m %r23(%sr4, %r26) 1261 fic,m %r23(%sr4, %r26)
1078 fic,m %r23(%sr4, %r26) 1262 fic,m %r23(%sr4, %r26)
1079 cmpb,COND(<<) %r26, %r25, 1b 1263 cmpb,COND(>>) %r25, %r26, 1b /* predict taken */
1080 fic,m %r23(%sr4, %r26) 1264 fic,m %r23(%sr4, %r26)
1081 1265
126689: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP)
1082 sync 1267 sync
1083 bv %r0(%r2) 1268 bv %r0(%r2)
1084 nop 1269 nop
1085ENDPROC_CFI(flush_kernel_icache_page) 1270ENDPROC_CFI(flush_kernel_icache_page)
1086 1271
1087ENTRY_CFI(flush_kernel_icache_range_asm) 1272ENTRY_CFI(flush_kernel_icache_range_asm)
1088 ldil L%icache_stride, %r1 127388: ldil L%icache_stride, %r1
1089 ldw R%icache_stride(%r1), %r23 1274 ldw R%icache_stride(%r1), %r23
1090 ldo -1(%r23), %r21 1275 ldo -1(%r23), %r21
1091 ANDCM %r26, %r21, %r26 1276 ANDCM %r26, %r21, %r26
1092 1277
10931: cmpb,COND(<<),n %r26, %r25, 1b 1278#ifdef CONFIG_64BIT
1279 depd,z %r23, 59, 60, %r21
1280#else
1281 depw,z %r23, 27, 28, %r21
1282#endif
1283 add %r26, %r21, %r22
1284 cmpb,COND(>>),n %r22, %r25, 2f /* predict not taken */
12851: add %r22, %r21, %r22
1286 fic,m %r23(%sr4, %r26)
1287 fic,m %r23(%sr4, %r26)
1288 fic,m %r23(%sr4, %r26)
1289 fic,m %r23(%sr4, %r26)
1290 fic,m %r23(%sr4, %r26)
1291 fic,m %r23(%sr4, %r26)
1292 fic,m %r23(%sr4, %r26)
1293 fic,m %r23(%sr4, %r26)
1294 fic,m %r23(%sr4, %r26)
1295 fic,m %r23(%sr4, %r26)
1296 fic,m %r23(%sr4, %r26)
1297 fic,m %r23(%sr4, %r26)
1298 fic,m %r23(%sr4, %r26)
1299 fic,m %r23(%sr4, %r26)
1300 fic,m %r23(%sr4, %r26)
1301 cmpb,COND(<<=) %r22, %r25, 1b /* predict taken */
1302 fic,m %r23(%sr4, %r26)
1303
13042: cmpb,COND(>>),n %r25, %r26, 2b /* predict taken */
1094 fic,m %r23(%sr4, %r26) 1305 fic,m %r23(%sr4, %r26)
1095 1306
130789: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP)
1096 sync 1308 sync
1097 bv %r0(%r2) 1309 bv %r0(%r2)
1098 nop 1310 nop
diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c
index 755e89ec828a..cd227f1cf629 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
308static int no_alternatives __initdata;
309static int __init setup_no_alternatives(char *str)
310{
311 no_alternatives = 1;
312 return 1;
313}
314__setup("no-alternatives", setup_no_alternatives);
315
316static 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
308extern void gsc_init(void); 388extern void gsc_init(void);
309extern void processor_init(void); 389extern void processor_init(void);
310extern void ccio_init(void); 390extern 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/syscall.S b/arch/parisc/kernel/syscall.S
index f453997a7b8f..f5f22ea9b97e 100644
--- a/arch/parisc/kernel/syscall.S
+++ b/arch/parisc/kernel/syscall.S
@@ -640,8 +640,7 @@ cas_action:
640 sub,<> %r28, %r25, %r0 640 sub,<> %r28, %r25, %r0
6412: stw %r24, 0(%r26) 6412: stw %r24, 0(%r26)
642 /* Free lock */ 642 /* Free lock */
643 sync 643 stw,ma %r20, 0(%sr2,%r20)
644 stw %r20, 0(%sr2,%r20)
645#if ENABLE_LWS_DEBUG 644#if ENABLE_LWS_DEBUG
646 /* Clear thread register indicator */ 645 /* Clear thread register indicator */
647 stw %r0, 4(%sr2,%r20) 646 stw %r0, 4(%sr2,%r20)
@@ -655,8 +654,7 @@ cas_action:
6553: 6543:
656 /* Error occurred on load or store */ 655 /* Error occurred on load or store */
657 /* Free lock */ 656 /* Free lock */
658 sync 657 stw,ma %r20, 0(%sr2,%r20)
659 stw %r20, 0(%sr2,%r20)
660#if ENABLE_LWS_DEBUG 658#if ENABLE_LWS_DEBUG
661 stw %r0, 4(%sr2,%r20) 659 stw %r0, 4(%sr2,%r20)
662#endif 660#endif
@@ -857,8 +855,7 @@ cas2_action:
857 855
858cas2_end: 856cas2_end:
859 /* Free lock */ 857 /* Free lock */
860 sync 858 stw,ma %r20, 0(%sr2,%r20)
861 stw %r20, 0(%sr2,%r20)
862 /* Enable interrupts */ 859 /* Enable interrupts */
863 ssm PSW_SM_I, %r0 860 ssm PSW_SM_I, %r0
864 /* Return to userspace, set no error */ 861 /* Return to userspace, set no error */
@@ -868,8 +865,7 @@ cas2_end:
86822: 86522:
869 /* Error occurred on load or store */ 866 /* Error occurred on load or store */
870 /* Free lock */ 867 /* Free lock */
871 sync 868 stw,ma %r20, 0(%sr2,%r20)
872 stw %r20, 0(%sr2,%r20)
873 ssm PSW_SM_I, %r0 869 ssm PSW_SM_I, %r0
874 ldo 1(%r0),%r28 870 ldo 1(%r0),%r28
875 b lws_exit 871 b lws_exit
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
index 68f10f87073d..472a818e8c17 100644
--- a/arch/parisc/kernel/traps.c
+++ b/arch/parisc/kernel/traps.c
@@ -430,8 +430,8 @@ void parisc_terminate(char *msg, struct pt_regs *regs, int code, unsigned long o
430 } 430 }
431 431
432 printk("\n"); 432 printk("\n");
433 pr_crit("%s: Code=%d (%s) regs=%p (Addr=" RFMT ")\n", 433 pr_crit("%s: Code=%d (%s) at addr " RFMT "\n",
434 msg, code, trap_name(code), regs, offset); 434 msg, code, trap_name(code), offset);
435 show_regs(regs); 435 show_regs(regs);
436 436
437 spin_unlock(&terminate_lock); 437 spin_unlock(&terminate_lock);
@@ -802,7 +802,8 @@ void __init initialize_ivt(const void *iva)
802 * the Length/4 words starting at Address is zero. 802 * the Length/4 words starting at Address is zero.
803 */ 803 */
804 804
805 /* Compute Checksum for HPMC handler */ 805 /* Setup IVA and compute checksum for HPMC handler */
806 ivap[6] = (u32)__pa(os_hpmc);
806 length = os_hpmc_size; 807 length = os_hpmc_size;
807 ivap[7] = length; 808 ivap[7] = length;
808 809
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 74842d28a7a1..e7e626bcd0be 100644
--- a/arch/parisc/mm/init.c
+++ b/arch/parisc/mm/init.c
@@ -494,12 +494,8 @@ static void __init map_pages(unsigned long start_vaddr,
494 pte = pte_mkhuge(pte); 494 pte = pte_mkhuge(pte);
495 } 495 }
496 496
497 if (address >= end_paddr) { 497 if (address >= end_paddr)
498 if (force) 498 break;
499 break;
500 else
501 pte_val(pte) = 0;
502 }
503 499
504 set_pte(pg_table, pte); 500 set_pte(pg_table, pte);
505 501
@@ -515,6 +511,21 @@ static void __init map_pages(unsigned long start_vaddr,
515 } 511 }
516} 512}
517 513
514void __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
518void __ref free_initmem(void) 529void __ref free_initmem(void)
519{ 530{
520 unsigned long init_begin = (unsigned long)__init_begin; 531 unsigned long init_begin = (unsigned long)__init_begin;
diff --git a/drivers/parisc/Makefile b/drivers/parisc/Makefile
index 3cd5e6cb8478..99fa6a89e0b9 100644
--- a/drivers/parisc/Makefile
+++ b/drivers/parisc/Makefile
@@ -8,9 +8,6 @@
8obj-$(CONFIG_IOSAPIC) += iosapic.o 8obj-$(CONFIG_IOSAPIC) += iosapic.o
9obj-$(CONFIG_IOMMU_SBA) += sba_iommu.o 9obj-$(CONFIG_IOMMU_SBA) += sba_iommu.o
10obj-$(CONFIG_PCI_LBA) += lba_pci.o 10obj-$(CONFIG_PCI_LBA) += lba_pci.o
11
12# Only use one of them: ccio-rm-dma is for PCX-W systems *only*
13# obj-$(CONFIG_IOMMU_CCIO) += ccio-rm-dma.o
14obj-$(CONFIG_IOMMU_CCIO) += ccio-dma.o 11obj-$(CONFIG_IOMMU_CCIO) += ccio-dma.o
15 12
16obj-$(CONFIG_GSC) += gsc.o 13obj-$(CONFIG_GSC) += gsc.o
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/ccio-rm-dma.c b/drivers/parisc/ccio-rm-dma.c
deleted file mode 100644
index df7932af48b7..000000000000
--- a/drivers/parisc/ccio-rm-dma.c
+++ /dev/null
@@ -1,202 +0,0 @@
1/*
2 * ccio-rm-dma.c:
3 * DMA management routines for first generation cache-coherent machines.
4 * "Real Mode" operation refers to U2/Uturn chip operation. The chip
5 * can perform coherency checks w/o using the I/O MMU. That's all we
6 * need until support for more than 4GB phys mem is needed.
7 *
8 * This is the trivial case - basically what x86 does.
9 *
10 * Drawbacks of using Real Mode are:
11 * o outbound DMA is slower since one isn't using the prefetching
12 * U2 can do for outbound DMA.
13 * o Ability to do scatter/gather in HW is also lost.
14 * o only known to work with PCX-W processor. (eg C360)
15 * (PCX-U/U+ are not coherent with U2 in real mode.)
16 *
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
22 *
23 *
24 * Original version/author:
25 * CVSROOT=:pserver:anonymous@198.186.203.37:/cvsroot/linux-parisc
26 * cvs -z3 co linux/arch/parisc/kernel/dma-rm.c
27 *
28 * (C) Copyright 2000 Philipp Rumpf <prumpf@tux.org>
29 *
30 *
31 * Adopted for The Puffin Group's parisc-linux port by Grant Grundler.
32 * (C) Copyright 2000 Grant Grundler <grundler@puffin.external.hp.com>
33 *
34 */
35
36#include <linux/types.h>
37#include <linux/init.h>
38#include <linux/mm.h>
39#include <linux/string.h>
40#include <linux/pci.h>
41#include <linux/gfp.h>
42
43#include <linux/uaccess.h>
44
45#include <asm/io.h>
46#include <asm/hardware.h>
47#include <asm/page.h>
48
49/* Only chose "ccio" since that's what HP-UX calls it....
50** Make it easier for folks to migrate from one to the other :^)
51*/
52#define MODULE_NAME "ccio"
53
54#define U2_IOA_RUNWAY 0x580
55#define U2_BC_GSC 0x501
56#define UTURN_IOA_RUNWAY 0x581
57#define UTURN_BC_GSC 0x502
58
59#define IS_U2(id) ( \
60 (((id)->hw_type == HPHW_IOA) && ((id)->hversion == U2_IOA_RUNWAY)) || \
61 (((id)->hw_type == HPHW_BCPORT) && ((id)->hversion == U2_BC_GSC)) \
62)
63
64#define IS_UTURN(id) ( \
65 (((id)->hw_type == HPHW_IOA) && ((id)->hversion == UTURN_IOA_RUNWAY)) || \
66 (((id)->hw_type == HPHW_BCPORT) && ((id)->hversion == UTURN_BC_GSC)) \
67)
68
69static int ccio_dma_supported( struct pci_dev *dev, u64 mask)
70{
71 if (dev == NULL) {
72 printk(KERN_ERR MODULE_NAME ": EISA/ISA/et al not supported\n");
73 BUG();
74 return(0);
75 }
76
77 /* only support 32-bit devices (ie PCI/GSC) */
78 return((int) (mask >= 0xffffffffUL));
79}
80
81
82static void *ccio_alloc_consistent(struct pci_dev *dev, size_t size,
83 dma_addr_t *handle)
84{
85 void *ret;
86
87 ret = (void *)__get_free_pages(GFP_ATOMIC, get_order(size));
88
89 if (ret != NULL) {
90 memset(ret, 0, size);
91 *handle = virt_to_phys(ret);
92 }
93 return ret;
94}
95
96static void ccio_free_consistent(struct pci_dev *dev, size_t size,
97 void *vaddr, dma_addr_t handle)
98{
99 free_pages((unsigned long)vaddr, get_order(size));
100}
101
102static dma_addr_t ccio_map_single(struct pci_dev *dev, void *ptr, size_t size,
103 int direction)
104{
105 return virt_to_phys(ptr);
106}
107
108static void ccio_unmap_single(struct pci_dev *dev, dma_addr_t dma_addr,
109 size_t size, int direction)
110{
111 /* Nothing to do */
112}
113
114
115static int ccio_map_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, int direction)
116{
117 int tmp = nents;
118
119 /* KISS: map each buffer separately. */
120 while (nents) {
121 sg_dma_address(sglist) = ccio_map_single(dev, sglist->address, sglist->length, direction);
122 sg_dma_len(sglist) = sglist->length;
123 nents--;
124 sglist++;
125 }
126
127 return tmp;
128}
129
130
131static void ccio_unmap_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, int direction)
132{
133#if 0
134 while (nents) {
135 ccio_unmap_single(dev, sg_dma_address(sglist), sg_dma_len(sglist), direction);
136 nents--;
137 sglist++;
138 }
139 return;
140#else
141 /* Do nothing (copied from current ccio_unmap_single() :^) */
142#endif
143}
144
145
146static struct pci_dma_ops ccio_ops = {
147 ccio_dma_supported,
148 ccio_alloc_consistent,
149 ccio_free_consistent,
150 ccio_map_single,
151 ccio_unmap_single,
152 ccio_map_sg,
153 ccio_unmap_sg,
154 NULL, /* dma_sync_single_for_cpu : NOP for U2 */
155 NULL, /* dma_sync_single_for_device : NOP for U2 */
156 NULL, /* dma_sync_sg_for_cpu : ditto */
157 NULL, /* dma_sync_sg_for_device : ditto */
158};
159
160
161/*
162** Determine if u2 should claim this chip (return 0) or not (return 1).
163** If so, initialize the chip and tell other partners in crime they
164** have work to do.
165*/
166static int __init
167ccio_probe(struct parisc_device *dev)
168{
169 printk(KERN_INFO "%s found %s at 0x%lx\n", MODULE_NAME,
170 dev->id.hversion == U2_BC_GSC ? "U2" : "UTurn",
171 dev->hpa.start);
172
173/*
174** FIXME - should check U2 registers to verify it's really running
175** in "Real Mode".
176*/
177
178#if 0
179/* will need this for "Virtual Mode" operation */
180 ccio_hw_init(ccio_dev);
181 ccio_common_init(ccio_dev);
182#endif
183 hppa_dma_ops = &ccio_ops;
184 return 0;
185}
186
187static const struct parisc_device_id ccio_tbl[] __initconst = {
188 { HPHW_BCPORT, HVERSION_REV_ANY_ID, U2_BC_GSC, 0xc },
189 { HPHW_BCPORT, HVERSION_REV_ANY_ID, UTURN_BC_GSC, 0xc },
190 { 0, }
191};
192
193static struct parisc_driver ccio_driver __refdata = {
194 .name = "U2/Uturn",
195 .id_table = ccio_tbl,
196 .probe = ccio_probe,
197};
198
199void __init ccio_init(void)
200{
201 register_parisc_driver(&ccio_driver);
202}
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c
index 7390fb8ca9d1..dfeea458a789 100644
--- a/drivers/parisc/dino.c
+++ b/drivers/parisc/dino.c
@@ -382,7 +382,7 @@ ilr_again:
382 DBG(KERN_DEBUG "%s(%d, %p) mask 0x%x\n", 382 DBG(KERN_DEBUG "%s(%d, %p) mask 0x%x\n",
383 __func__, irq, intr_dev, mask); 383 __func__, irq, intr_dev, mask);
384 generic_handle_irq(irq); 384 generic_handle_irq(irq);
385 mask &= ~(1 << local_irq); 385 mask &= ~DINO_MASK_IRQ(local_irq);
386 } while (mask); 386 } while (mask);
387 387
388 /* Support for level triggered IRQ lines. 388 /* Support for level triggered IRQ lines.
@@ -396,9 +396,8 @@ ilr_again:
396 if (mask) { 396 if (mask) {
397 if (--ilr_loop > 0) 397 if (--ilr_loop > 0)
398 goto ilr_again; 398 goto ilr_again;
399 printk(KERN_ERR "Dino 0x%px: stuck interrupt %d\n", 399 pr_warn_ratelimited("Dino 0x%px: stuck interrupt %d\n",
400 dino_dev->hba.base_addr, mask); 400 dino_dev->hba.base_addr, mask);
401 return IRQ_NONE;
402 } 401 }
403 return IRQ_HANDLED; 402 return IRQ_HANDLED;
404} 403}
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()"))
diff --git a/scripts/extract-vmlinux b/scripts/extract-vmlinux
index e6239f39abad..85e1f32fb4a0 100755
--- a/scripts/extract-vmlinux
+++ b/scripts/extract-vmlinux
@@ -48,9 +48,6 @@ fi
48tmp=$(mktemp /tmp/vmlinux-XXX) 48tmp=$(mktemp /tmp/vmlinux-XXX)
49trap "rm -f $tmp" 0 49trap "rm -f $tmp" 0
50 50
51# Initial attempt for uncompressed images or objects:
52check_vmlinux $img
53
54# That didn't work, so retry after decompression. 51# That didn't work, so retry after decompression.
55try_decompress '\037\213\010' xy gunzip 52try_decompress '\037\213\010' xy gunzip
56try_decompress '\3757zXZ\000' abcde unxz 53try_decompress '\3757zXZ\000' abcde unxz
@@ -60,5 +57,8 @@ try_decompress '\211\114\132' xy 'lzop -d'
60try_decompress '\002!L\030' xxx 'lz4 -d' 57try_decompress '\002!L\030' xxx 'lz4 -d'
61try_decompress '(\265/\375' xxx unzstd 58try_decompress '(\265/\375' xxx unzstd
62 59
60# Finally check for uncompressed images or objects:
61check_vmlinux $img
62
63# Bail out: 63# Bail out:
64echo "$me: Cannot find vmlinux." >&2 64echo "$me: Cannot find vmlinux." >&2