diff options
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' |
| 158 | endef | 158 | endef |
| 159 | |||
| 160 | # we require gcc 3.3 or above to compile the kernel | ||
| 161 | archprepare: checkbin | ||
| 162 | checkbin: | ||
| 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 | ||
| 15 | KBUILD_CFLAGS := -D__KERNEL__ -O2 -DBOOTLOADER | 15 | KBUILD_CFLAGS := -D__KERNEL__ -O2 -DBOOTLOADER |
| 16 | KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING | 16 | KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING |
| 17 | KBUILD_CFLAGS += $(cflags-y) -fno-delete-null-pointer-checks | 17 | KBUILD_CFLAGS += $(cflags-y) -fno-delete-null-pointer-checks -fno-builtin-printf |
| 18 | KBUILD_CFLAGS += -fno-PIE -mno-space-regs -mdisable-fpregs -Os | 18 | KBUILD_CFLAGS += -fno-PIE -mno-space-regs -mdisable-fpregs -Os |
| 19 | ifndef CONFIG_64BIT | 19 | ifndef CONFIG_64BIT |
| 20 | KBUILD_CFLAGS += -mfast-indirect-calls | 20 | KBUILD_CFLAGS += -mfast-indirect-calls |
| @@ -22,7 +22,6 @@ endif | |||
| 22 | 22 | ||
| 23 | OBJECTS += $(obj)/head.o $(obj)/real2.o $(obj)/firmware.o $(obj)/misc.o $(obj)/piggy.o | 23 | OBJECTS += $(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 | ||
| 26 | LDFLAGS_vmlinux := -X -e startup --as-needed -T | 25 | LDFLAGS_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 | |||
| 55 | CPPFLAGS_vmlinux.lds += -I$(objtree)/$(obj) -DBOOTLOADER | 54 | CPPFLAGS_vmlinux.lds += -I$(objtree)/$(obj) -DBOOTLOADER |
| 56 | $(obj)/vmlinux.lds: $(obj)/sizes.h | 55 | $(obj)/vmlinux.lds: $(obj)/sizes.h |
| 57 | 56 | ||
| 58 | OBJCOPYFLAGS_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 | ||
| 231 | static 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 | |||
| 230 | unsigned long decompress_kernel(unsigned int started_wide, | 279 | unsigned 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 | |||
| 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/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; | |||
| 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/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; | |||
| 11 | extern int pdc_type; | 11 | extern int pdc_type; |
| 12 | extern unsigned long parisc_cell_num; /* cell number the CPU runs on (PAT) */ | 12 | extern unsigned long parisc_cell_num; /* cell number the CPU runs on (PAT) */ |
| 13 | extern unsigned long parisc_cell_loc; /* cell location of CPU (PAT) */ | 13 | extern unsigned long parisc_cell_loc; /* cell location of CPU (PAT) */ |
| 14 | extern 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 | */ |
| 299 | typedef struct pdc_pat_cell_info_rtn_block { | 317 | typedef 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 | ||
| 327 | extern int pdc_pat_chassis_send_log(unsigned long status, unsigned long data); | 356 | extern int pdc_pat_chassis_send_log(unsigned long status, unsigned long data); |
| 328 | extern int pdc_pat_cell_get_number(struct pdc_pat_cell_num *cell_info); | 357 | extern int pdc_pat_cell_get_number(struct pdc_pat_cell_num *cell_info); |
| 329 | extern int pdc_pat_cell_module(unsigned long *actcnt, unsigned long ploc, unsigned long mod, unsigned long view_type, void *mem_addr); | 358 | extern 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); | ||
| 361 | extern int pdc_pat_cell_module(unsigned long *actcnt, unsigned long ploc, | ||
| 362 | unsigned long mod, unsigned long view_type, void *mem_addr); | ||
| 330 | extern int pdc_pat_cell_num_to_loc(void *, unsigned long); | 363 | extern int pdc_pat_cell_num_to_loc(void *, unsigned long); |
| 331 | 364 | ||
| 332 | extern int pdc_pat_cpu_get_number(struct pdc_pat_cpu_num *cpu_info, unsigned long hpa); | 365 | extern int pdc_pat_cpu_get_number(struct pdc_pat_cpu_num *cpu_info, unsigned long hpa); |
| 333 | 366 | ||
| 334 | extern int pdc_pat_pd_get_addr_map(unsigned long *actual_len, void *mem_addr, unsigned long count, unsigned long offset); | 367 | extern int pdc_pat_pd_get_addr_map(unsigned long *actual_len, void *mem_addr, |
| 368 | unsigned long count, unsigned long offset); | ||
| 369 | extern int pdc_pat_pd_get_pdc_revisions(unsigned long *legacy_rev, | ||
| 370 | unsigned long *pat_rev, unsigned long *pdc_cap); | ||
| 335 | 371 | ||
| 336 | extern int pdc_pat_io_pci_cfg_read(unsigned long pci_addr, int pci_size, u32 *val); | 372 | extern int pdc_pat_io_pci_cfg_read(unsigned long pci_addr, int pci_size, u32 *val); |
| 337 | extern int pdc_pat_io_pci_cfg_write(unsigned long pci_addr, int pci_size, u32 val); | 373 | extern 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 | ||
| 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/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 | ||
| 44 | static inline int arch_spin_trylock(arch_spinlock_t *x) | 44 | static 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 | ||
| 37 | void flush_dcache_page_asm(unsigned long phys_addr, unsigned long vaddr); | 37 | void flush_dcache_page_asm(unsigned long phys_addr, unsigned long vaddr); |
| 38 | EXPORT_SYMBOL(flush_dcache_page_asm); | 38 | EXPORT_SYMBOL(flush_dcache_page_asm); |
| 39 | void purge_dcache_page_asm(unsigned long phys_addr, unsigned long vaddr); | ||
| 39 | void flush_icache_page_asm(unsigned long phys_addr, unsigned long vaddr); | 40 | void 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 | ||
| 307 | static 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 | |||
| 306 | void flush_dcache_page(struct page *page) | 318 | void 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 */ |
| 365 | static unsigned long parisc_cache_flush_threshold __read_mostly = FLUSH_THRESHOLD; | 377 | static 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 */ |
| 368 | static unsigned long parisc_tlb_flush_threshold __read_mostly = FLUSH_TLB_THRESHOLD; | 380 | static unsigned long parisc_tlb_flush_threshold __read_mostly = FLUSH_TLB_THRESHOLD; |
| 369 | 381 | ||
| 370 | void __init parisc_setup_cache_timing(void) | 382 | void __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 | ||
| 426 | set_tlb_threshold: | 440 | set_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 | |||
| 621 | flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long pfn) | 629 | flush_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 | 466 | 98: cmpib,COND(=),n 0,\spc,2f |
| 470 | load_pa_tlb_lock \tmp | 467 | load_pa_tlb_lock \tmp |
| 471 | 1: LDCW 0(\tmp),\tmp1 | 468 | 1: 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) |
| 478 | 2: | 475 | 99: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP) |
| 479 | #endif | 476 | #endif |
| 477 | 2: LDREG 0(\ptp),\pte | ||
| 478 | bb,>=,n \pte,_PAGE_PRESENT_BIT,\fault | ||
| 479 | 3: | ||
| 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 | 485 | 98: or,COND(=) %r0,\spc,%r0 |
| 486 | sync | 486 | stw,ma \spc,0(\tmp) |
| 487 | or,COND(=) %r0,\spc,%r0 | 487 | 99: 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 | 494 | 98: load_pa_tlb_lock \tmp |
| 495 | 99: 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 | ||
| 1659 | itlb_fault: | 1659 | itlb_fault: |
| 1660 | b intr_save | 1660 | b intr_save |
| 1661 | ldi 6,%r8 | 1661 | ldi PARISC_ITLB_TRAP,%r8 |
| 1662 | 1662 | ||
| 1663 | nadtlb_fault: | 1663 | nadtlb_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 | */ | ||
| 1337 | int 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 | */ | ||
| 1452 | int 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 |
| 88 | ENTRY_CFI(os_hpmc) | 88 | ENTRY(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 */ |
| 305 | ENDPROC_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) */ |
| 44 | unsigned long parisc_cell_num __read_mostly; | 44 | unsigned long parisc_cell_num __read_mostly; |
| 45 | unsigned long parisc_cell_loc __read_mostly; | 45 | unsigned long parisc_cell_loc __read_mostly; |
| 46 | unsigned long parisc_pat_pdc_cap __read_mostly; | ||
| 46 | 47 | ||
| 47 | 48 | ||
| 48 | void __init setup_pdc(void) | 49 | void __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 | ||
| 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 |
| @@ -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 | 841 | 1: fdc,m r31(%r28) | |
| 832 | 1: 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 | ||
| 859 | 89: 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 |
| 853 | ENDPROC_CFI(flush_dcache_page_asm) | 863 | ENDPROC_CFI(flush_dcache_page_asm) |
| 854 | 864 | ||
| 865 | ENTRY_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 | ||
| 886 | 0: pdtlb %r0(%r28) | ||
| 887 | tlb_unlock %r20,%r21,%r22 | ||
| 888 | ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB) | ||
| 889 | #endif | ||
| 890 | |||
| 891 | 88: 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 | |||
| 902 | 1: 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 | |||
| 920 | 89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP) | ||
| 921 | sync | ||
| 922 | bv %r0(%r2) | ||
| 923 | nop | ||
| 924 | ENDPROC_CFI(purge_dcache_page_asm) | ||
| 925 | |||
| 855 | ENTRY_CFI(flush_icache_page_asm) | 926 | ENTRY_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) | 948 | 1: 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) | 952 | 0: pdtlb %r0(%r28) |
| 881 | pitlb %r0(%sr4,%r28) | 953 | 1: 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 | 960 | 88: 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 */ |
| 899 | 1: fic,m %r31(%sr4,%r28) | 973 | 1: 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 | ||
| 991 | 89: 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 |
| 920 | ENDPROC_CFI(flush_icache_page_asm) | 995 | ENDPROC_CFI(flush_icache_page_asm) |
| 921 | 996 | ||
| 922 | ENTRY_CFI(flush_kernel_dcache_page_asm) | 997 | ENTRY_CFI(flush_kernel_dcache_page_asm) |
| 923 | ldil L%dcache_stride, %r1 | 998 | 88: 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 | |||
| 935 | 1: fdc,m %r23(%r26) | 1009 | 1: 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 | ||
| 1027 | 89: 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 |
| 956 | ENDPROC_CFI(flush_kernel_dcache_page_asm) | 1031 | ENDPROC_CFI(flush_kernel_dcache_page_asm) |
| 957 | 1032 | ||
| 958 | ENTRY_CFI(purge_kernel_dcache_page_asm) | 1033 | ENTRY_CFI(purge_kernel_dcache_page_asm) |
| 959 | ldil L%dcache_stride, %r1 | 1034 | 88: 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 | ||
| 1063 | 89: 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 |
| 991 | ENDPROC_CFI(purge_kernel_dcache_page_asm) | 1067 | ENDPROC_CFI(purge_kernel_dcache_page_asm) |
| 992 | 1068 | ||
| 993 | ENTRY_CFI(flush_user_dcache_range_asm) | 1069 | ENTRY_CFI(flush_user_dcache_range_asm) |
| 994 | ldil L%dcache_stride, %r1 | 1070 | 88: 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 | ||
| 999 | 1: 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 */ | ||
| 1082 | 1: 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 | ||
| 1101 | 2: cmpb,COND(>>),n %r25, %r26, 2b | ||
| 1102 | fdc,m %r23(%sr3, %r26) | ||
| 1103 | |||
| 1104 | 89: 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 |
| 1005 | ENDPROC_CFI(flush_user_dcache_range_asm) | 1108 | ENDPROC_CFI(flush_user_dcache_range_asm) |
| 1006 | 1109 | ||
| 1007 | ENTRY_CFI(flush_kernel_dcache_range_asm) | 1110 | ENTRY_CFI(flush_kernel_dcache_range_asm) |
| 1008 | ldil L%dcache_stride, %r1 | 1111 | 88: 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 | ||
| 1013 | 1: 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 */ | ||
| 1123 | 1: 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 | |||
| 1142 | 2: cmpb,COND(>>),n %r25, %r26, 2b /* predict taken */ | ||
| 1014 | fdc,m %r23(%r26) | 1143 | fdc,m %r23(%r26) |
| 1015 | 1144 | ||
| 1016 | sync | 1145 | sync |
| 1146 | 89: 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 |
| 1020 | ENDPROC_CFI(flush_kernel_dcache_range_asm) | 1150 | ENDPROC_CFI(flush_kernel_dcache_range_asm) |
| 1021 | 1151 | ||
| 1022 | ENTRY_CFI(purge_kernel_dcache_range_asm) | 1152 | ENTRY_CFI(purge_kernel_dcache_range_asm) |
| 1023 | ldil L%dcache_stride, %r1 | 1153 | 88: 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 | ||
| 1028 | 1: 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 */ | ||
| 1165 | 1: 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 | |||
| 1184 | 2: cmpb,COND(>>),n %r25, %r26, 2b /* predict taken */ | ||
| 1029 | pdc,m %r23(%r26) | 1185 | pdc,m %r23(%r26) |
| 1030 | 1186 | ||
| 1031 | sync | 1187 | sync |
| 1188 | 89: 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 |
| 1035 | ENDPROC_CFI(purge_kernel_dcache_range_asm) | 1192 | ENDPROC_CFI(purge_kernel_dcache_range_asm) |
| 1036 | 1193 | ||
| 1037 | ENTRY_CFI(flush_user_icache_range_asm) | 1194 | ENTRY_CFI(flush_user_icache_range_asm) |
| 1038 | ldil L%icache_stride, %r1 | 1195 | 88: 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 | ||
| 1043 | 1: 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 */ | ||
| 1207 | 1: 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 | |||
| 1226 | 2: cmpb,COND(>>),n %r25, %r26, 2b | ||
| 1044 | fic,m %r23(%sr3, %r26) | 1227 | fic,m %r23(%sr3, %r26) |
| 1045 | 1228 | ||
| 1229 | 89: 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 |
| 1049 | ENDPROC_CFI(flush_user_icache_range_asm) | 1233 | ENDPROC_CFI(flush_user_icache_range_asm) |
| 1050 | 1234 | ||
| 1051 | ENTRY_CFI(flush_kernel_icache_page) | 1235 | ENTRY_CFI(flush_kernel_icache_page) |
| 1052 | ldil L%icache_stride, %r1 | 1236 | 88: 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 | ||
| 1266 | 89: 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 |
| 1085 | ENDPROC_CFI(flush_kernel_icache_page) | 1270 | ENDPROC_CFI(flush_kernel_icache_page) |
| 1086 | 1271 | ||
| 1087 | ENTRY_CFI(flush_kernel_icache_range_asm) | 1272 | ENTRY_CFI(flush_kernel_icache_range_asm) |
| 1088 | ldil L%icache_stride, %r1 | 1273 | 88: 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 | ||
| 1093 | 1: 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 */ | ||
| 1285 | 1: 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 | |||
| 1304 | 2: cmpb,COND(>>),n %r25, %r26, 2b /* predict taken */ | ||
| 1094 | fic,m %r23(%sr4, %r26) | 1305 | fic,m %r23(%sr4, %r26) |
| 1095 | 1306 | ||
| 1307 | 89: 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 | ||
| 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/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 |
| 641 | 2: stw %r24, 0(%r26) | 641 | 2: 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: | |||
| 655 | 3: | 654 | 3: |
| 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 | ||
| 858 | cas2_end: | 856 | cas2_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: | |||
| 868 | 22: | 865 | 22: |
| 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 | ||
| 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 | |||
| 518 | void __ref free_initmem(void) | 529 | void __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 @@ | |||
| 8 | obj-$(CONFIG_IOSAPIC) += iosapic.o | 8 | obj-$(CONFIG_IOSAPIC) += iosapic.o |
| 9 | obj-$(CONFIG_IOMMU_SBA) += sba_iommu.o | 9 | obj-$(CONFIG_IOMMU_SBA) += sba_iommu.o |
| 10 | obj-$(CONFIG_PCI_LBA) += lba_pci.o | 10 | obj-$(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 | ||
| 14 | obj-$(CONFIG_IOMMU_CCIO) += ccio-dma.o | 11 | obj-$(CONFIG_IOMMU_CCIO) += ccio-dma.o |
| 15 | 12 | ||
| 16 | obj-$(CONFIG_GSC) += gsc.o | 13 | obj-$(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 | |||
| 69 | static 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 | |||
| 82 | static 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 | |||
| 96 | static 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 | |||
| 102 | static 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 | |||
| 108 | static 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 | |||
| 115 | static 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 | |||
| 131 | static 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 | |||
| 146 | static 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 | */ | ||
| 166 | static int __init | ||
| 167 | ccio_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 | |||
| 187 | static 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 | |||
| 193 | static struct parisc_driver ccio_driver __refdata = { | ||
| 194 | .name = "U2/Uturn", | ||
| 195 | .id_table = ccio_tbl, | ||
| 196 | .probe = ccio_probe, | ||
| 197 | }; | ||
| 198 | |||
| 199 | void __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 | |||
| 48 | tmp=$(mktemp /tmp/vmlinux-XXX) | 48 | tmp=$(mktemp /tmp/vmlinux-XXX) |
| 49 | trap "rm -f $tmp" 0 | 49 | trap "rm -f $tmp" 0 |
| 50 | 50 | ||
| 51 | # Initial attempt for uncompressed images or objects: | ||
| 52 | check_vmlinux $img | ||
| 53 | |||
| 54 | # That didn't work, so retry after decompression. | 51 | # That didn't work, so retry after decompression. |
| 55 | try_decompress '\037\213\010' xy gunzip | 52 | try_decompress '\037\213\010' xy gunzip |
| 56 | try_decompress '\3757zXZ\000' abcde unxz | 53 | try_decompress '\3757zXZ\000' abcde unxz |
| @@ -60,5 +57,8 @@ try_decompress '\211\114\132' xy 'lzop -d' | |||
| 60 | try_decompress '\002!L\030' xxx 'lz4 -d' | 57 | try_decompress '\002!L\030' xxx 'lz4 -d' |
| 61 | try_decompress '(\265/\375' xxx unzstd | 58 | try_decompress '(\265/\375' xxx unzstd |
| 62 | 59 | ||
| 60 | # Finally check for uncompressed images or objects: | ||
| 61 | check_vmlinux $img | ||
| 62 | |||
| 63 | # Bail out: | 63 | # Bail out: |
| 64 | echo "$me: Cannot find vmlinux." >&2 | 64 | echo "$me: Cannot find vmlinux." >&2 |
