aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/mm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/mm')
-rw-r--r--arch/mips/mm/c-r4k.c6
-rw-r--r--arch/mips/mm/fault.c29
-rw-r--r--arch/mips/mm/page.c30
-rw-r--r--arch/mips/mm/sc-mips.c4
-rw-r--r--arch/mips/mm/tlb-r4k.c8
-rw-r--r--arch/mips/mm/tlbex.c7
-rw-r--r--arch/mips/mm/uasm-micromips.c8
-rw-r--r--arch/mips/mm/uasm-mips.c38
-rw-r--r--arch/mips/mm/uasm.c15
9 files changed, 104 insertions, 41 deletions
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index dd261df005c2..3f8059602765 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -794,7 +794,7 @@ static void local_r4k_flush_cache_sigtramp(void * arg)
794 __asm__ __volatile__ ( 794 __asm__ __volatile__ (
795 ".set push\n\t" 795 ".set push\n\t"
796 ".set noat\n\t" 796 ".set noat\n\t"
797 ".set mips3\n\t" 797 ".set "MIPS_ISA_LEVEL"\n\t"
798#ifdef CONFIG_32BIT 798#ifdef CONFIG_32BIT
799 "la $at,1f\n\t" 799 "la $at,1f\n\t"
800#endif 800#endif
@@ -1255,6 +1255,7 @@ static void probe_pcache(void)
1255 case CPU_P5600: 1255 case CPU_P5600:
1256 case CPU_PROAPTIV: 1256 case CPU_PROAPTIV:
1257 case CPU_M5150: 1257 case CPU_M5150:
1258 case CPU_QEMU_GENERIC:
1258 if (!(read_c0_config7() & MIPS_CONF7_IAR) && 1259 if (!(read_c0_config7() & MIPS_CONF7_IAR) &&
1259 (c->icache.waysize > PAGE_SIZE)) 1260 (c->icache.waysize > PAGE_SIZE))
1260 c->icache.flags |= MIPS_CACHE_ALIASES; 1261 c->icache.flags |= MIPS_CACHE_ALIASES;
@@ -1472,7 +1473,8 @@ static void setup_scache(void)
1472 1473
1473 default: 1474 default:
1474 if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M32R2 | 1475 if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M32R2 |
1475 MIPS_CPU_ISA_M64R1 | MIPS_CPU_ISA_M64R2)) { 1476 MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R1 |
1477 MIPS_CPU_ISA_M64R2 | MIPS_CPU_ISA_M64R6)) {
1476#ifdef CONFIG_MIPS_CPU_SCACHE 1478#ifdef CONFIG_MIPS_CPU_SCACHE
1477 if (mips_sc_init ()) { 1479 if (mips_sc_init ()) {
1478 scache_size = c->scache.ways * c->scache.sets * c->scache.linesz; 1480 scache_size = c->scache.ways * c->scache.sets * c->scache.linesz;
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index 70ab5d664332..7ff8637e530d 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c
@@ -14,6 +14,7 @@
14#include <linux/string.h> 14#include <linux/string.h>
15#include <linux/types.h> 15#include <linux/types.h>
16#include <linux/ptrace.h> 16#include <linux/ptrace.h>
17#include <linux/ratelimit.h>
17#include <linux/mman.h> 18#include <linux/mman.h>
18#include <linux/mm.h> 19#include <linux/mm.h>
19#include <linux/smp.h> 20#include <linux/smp.h>
@@ -28,6 +29,8 @@
28#include <asm/highmem.h> /* For VMALLOC_END */ 29#include <asm/highmem.h> /* For VMALLOC_END */
29#include <linux/kdebug.h> 30#include <linux/kdebug.h>
30 31
32int show_unhandled_signals = 1;
33
31/* 34/*
32 * This routine handles page faults. It determines the address, 35 * This routine handles page faults. It determines the address,
33 * and the problem, and then passes it off to one of the appropriate 36 * and the problem, and then passes it off to one of the appropriate
@@ -44,6 +47,8 @@ static void __kprobes __do_page_fault(struct pt_regs *regs, unsigned long write,
44 int fault; 47 int fault;
45 unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; 48 unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
46 49
50 static DEFINE_RATELIMIT_STATE(ratelimit_state, 5 * HZ, 10);
51
47#if 0 52#if 0
48 printk("Cpu%d[%s:%d:%0*lx:%ld:%0*lx]\n", raw_smp_processor_id(), 53 printk("Cpu%d[%s:%d:%0*lx:%ld:%0*lx]\n", raw_smp_processor_id(),
49 current->comm, current->pid, field, address, write, 54 current->comm, current->pid, field, address, write,
@@ -203,15 +208,21 @@ bad_area_nosemaphore:
203 if (user_mode(regs)) { 208 if (user_mode(regs)) {
204 tsk->thread.cp0_badvaddr = address; 209 tsk->thread.cp0_badvaddr = address;
205 tsk->thread.error_code = write; 210 tsk->thread.error_code = write;
206#if 0 211 if (show_unhandled_signals &&
207 printk("do_page_fault() #2: sending SIGSEGV to %s for " 212 unhandled_signal(tsk, SIGSEGV) &&
208 "invalid %s\n%0*lx (epc == %0*lx, ra == %0*lx)\n", 213 __ratelimit(&ratelimit_state)) {
209 tsk->comm, 214 pr_info("\ndo_page_fault(): sending SIGSEGV to %s for invalid %s %0*lx",
210 write ? "write access to" : "read access from", 215 tsk->comm,
211 field, address, 216 write ? "write access to" : "read access from",
212 field, (unsigned long) regs->cp0_epc, 217 field, address);
213 field, (unsigned long) regs->regs[31]); 218 pr_info("epc = %0*lx in", field,
214#endif 219 (unsigned long) regs->cp0_epc);
220 print_vma_addr(" ", regs->cp0_epc);
221 pr_info("ra = %0*lx in", field,
222 (unsigned long) regs->regs[31]);
223 print_vma_addr(" ", regs->regs[31]);
224 pr_info("\n");
225 }
215 info.si_signo = SIGSEGV; 226 info.si_signo = SIGSEGV;
216 info.si_errno = 0; 227 info.si_errno = 0;
217 /* info.si_code has been set above */ 228 /* info.si_code has been set above */
diff --git a/arch/mips/mm/page.c b/arch/mips/mm/page.c
index b611102e23b5..3f85f921801b 100644
--- a/arch/mips/mm/page.c
+++ b/arch/mips/mm/page.c
@@ -72,6 +72,20 @@ static struct uasm_reloc relocs[5];
72#define cpu_is_r4600_v1_x() ((read_c0_prid() & 0xfffffff0) == 0x00002010) 72#define cpu_is_r4600_v1_x() ((read_c0_prid() & 0xfffffff0) == 0x00002010)
73#define cpu_is_r4600_v2_x() ((read_c0_prid() & 0xfffffff0) == 0x00002020) 73#define cpu_is_r4600_v2_x() ((read_c0_prid() & 0xfffffff0) == 0x00002020)
74 74
75/*
76 * R6 has a limited offset of the pref instruction.
77 * Skip it if the offset is more than 9 bits.
78 */
79#define _uasm_i_pref(a, b, c, d) \
80do { \
81 if (cpu_has_mips_r6) { \
82 if (c <= 0xff && c >= -0x100) \
83 uasm_i_pref(a, b, c, d);\
84 } else { \
85 uasm_i_pref(a, b, c, d); \
86 } \
87} while(0)
88
75static int pref_bias_clear_store; 89static int pref_bias_clear_store;
76static int pref_bias_copy_load; 90static int pref_bias_copy_load;
77static int pref_bias_copy_store; 91static int pref_bias_copy_store;
@@ -178,7 +192,15 @@ static void set_prefetch_parameters(void)
178 pref_bias_copy_load = 256; 192 pref_bias_copy_load = 256;
179 pref_bias_copy_store = 128; 193 pref_bias_copy_store = 128;
180 pref_src_mode = Pref_LoadStreamed; 194 pref_src_mode = Pref_LoadStreamed;
181 pref_dst_mode = Pref_PrepareForStore; 195 if (cpu_has_mips_r6)
196 /*
197 * Bit 30 (Pref_PrepareForStore) has been
198 * removed from MIPS R6. Use bit 5
199 * (Pref_StoreStreamed).
200 */
201 pref_dst_mode = Pref_StoreStreamed;
202 else
203 pref_dst_mode = Pref_PrepareForStore;
182 break; 204 break;
183 } 205 }
184 } else { 206 } else {
@@ -214,7 +236,7 @@ static inline void build_clear_pref(u32 **buf, int off)
214 return; 236 return;
215 237
216 if (pref_bias_clear_store) { 238 if (pref_bias_clear_store) {
217 uasm_i_pref(buf, pref_dst_mode, pref_bias_clear_store + off, 239 _uasm_i_pref(buf, pref_dst_mode, pref_bias_clear_store + off,
218 A0); 240 A0);
219 } else if (cache_line_size == (half_clear_loop_size << 1)) { 241 } else if (cache_line_size == (half_clear_loop_size << 1)) {
220 if (cpu_has_cache_cdex_s) { 242 if (cpu_has_cache_cdex_s) {
@@ -357,7 +379,7 @@ static inline void build_copy_load_pref(u32 **buf, int off)
357 return; 379 return;
358 380
359 if (pref_bias_copy_load) 381 if (pref_bias_copy_load)
360 uasm_i_pref(buf, pref_src_mode, pref_bias_copy_load + off, A1); 382 _uasm_i_pref(buf, pref_src_mode, pref_bias_copy_load + off, A1);
361} 383}
362 384
363static inline void build_copy_store_pref(u32 **buf, int off) 385static inline void build_copy_store_pref(u32 **buf, int off)
@@ -366,7 +388,7 @@ static inline void build_copy_store_pref(u32 **buf, int off)
366 return; 388 return;
367 389
368 if (pref_bias_copy_store) { 390 if (pref_bias_copy_store) {
369 uasm_i_pref(buf, pref_dst_mode, pref_bias_copy_store + off, 391 _uasm_i_pref(buf, pref_dst_mode, pref_bias_copy_store + off,
370 A0); 392 A0);
371 } else if (cache_line_size == (half_copy_loop_size << 1)) { 393 } else if (cache_line_size == (half_copy_loop_size << 1)) {
372 if (cpu_has_cache_cdex_s) { 394 if (cpu_has_cache_cdex_s) {
diff --git a/arch/mips/mm/sc-mips.c b/arch/mips/mm/sc-mips.c
index 99eb8fabab60..4ceafd13870c 100644
--- a/arch/mips/mm/sc-mips.c
+++ b/arch/mips/mm/sc-mips.c
@@ -81,6 +81,7 @@ static inline int mips_sc_is_activated(struct cpuinfo_mips *c)
81 case CPU_PROAPTIV: 81 case CPU_PROAPTIV:
82 case CPU_P5600: 82 case CPU_P5600:
83 case CPU_BMIPS5000: 83 case CPU_BMIPS5000:
84 case CPU_QEMU_GENERIC:
84 if (config2 & (1 << 12)) 85 if (config2 & (1 << 12))
85 return 0; 86 return 0;
86 } 87 }
@@ -104,7 +105,8 @@ static inline int __init mips_sc_probe(void)
104 105
105 /* Ignore anything but MIPSxx processors */ 106 /* Ignore anything but MIPSxx processors */
106 if (!(c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M32R2 | 107 if (!(c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M32R2 |
107 MIPS_CPU_ISA_M64R1 | MIPS_CPU_ISA_M64R2))) 108 MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R1 |
109 MIPS_CPU_ISA_M64R2 | MIPS_CPU_ISA_M64R6)))
108 return 0; 110 return 0;
109 111
110 /* Does this MIPS32/MIPS64 CPU have a config2 register? */ 112 /* Does this MIPS32/MIPS64 CPU have a config2 register? */
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
index 30639a6e9b8c..b2afa49beab0 100644
--- a/arch/mips/mm/tlb-r4k.c
+++ b/arch/mips/mm/tlb-r4k.c
@@ -485,13 +485,11 @@ static void r4k_tlb_configure(void)
485 * Enable the no read, no exec bits, and enable large virtual 485 * Enable the no read, no exec bits, and enable large virtual
486 * address. 486 * address.
487 */ 487 */
488 u32 pg = PG_RIE | PG_XIE;
489#ifdef CONFIG_64BIT 488#ifdef CONFIG_64BIT
490 pg |= PG_ELPA; 489 set_c0_pagegrain(PG_RIE | PG_XIE | PG_ELPA);
490#else
491 set_c0_pagegrain(PG_RIE | PG_XIE);
491#endif 492#endif
492 if (cpu_has_rixiex)
493 pg |= PG_IEC;
494 write_c0_pagegrain(pg);
495 } 493 }
496 494
497 temp_tlb_entry = current_cpu_data.tlbsize - 1; 495 temp_tlb_entry = current_cpu_data.tlbsize - 1;
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index 3978a3d81366..d75ff73a2012 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -501,7 +501,7 @@ static void build_tlb_write_entry(u32 **p, struct uasm_label **l,
501 case tlb_indexed: tlbw = uasm_i_tlbwi; break; 501 case tlb_indexed: tlbw = uasm_i_tlbwi; break;
502 } 502 }
503 503
504 if (cpu_has_mips_r2) { 504 if (cpu_has_mips_r2_exec_hazard) {
505 /* 505 /*
506 * The architecture spec says an ehb is required here, 506 * The architecture spec says an ehb is required here,
507 * but a number of cores do not have the hazard and 507 * but a number of cores do not have the hazard and
@@ -514,6 +514,7 @@ static void build_tlb_write_entry(u32 **p, struct uasm_label **l,
514 case CPU_PROAPTIV: 514 case CPU_PROAPTIV:
515 case CPU_P5600: 515 case CPU_P5600:
516 case CPU_M5150: 516 case CPU_M5150:
517 case CPU_QEMU_GENERIC:
517 break; 518 break;
518 519
519 default: 520 default:
@@ -1952,7 +1953,7 @@ static void build_r4000_tlb_load_handler(void)
1952 1953
1953 switch (current_cpu_type()) { 1954 switch (current_cpu_type()) {
1954 default: 1955 default:
1955 if (cpu_has_mips_r2) { 1956 if (cpu_has_mips_r2_exec_hazard) {
1956 uasm_i_ehb(&p); 1957 uasm_i_ehb(&p);
1957 1958
1958 case CPU_CAVIUM_OCTEON: 1959 case CPU_CAVIUM_OCTEON:
@@ -2019,7 +2020,7 @@ static void build_r4000_tlb_load_handler(void)
2019 2020
2020 switch (current_cpu_type()) { 2021 switch (current_cpu_type()) {
2021 default: 2022 default:
2022 if (cpu_has_mips_r2) { 2023 if (cpu_has_mips_r2_exec_hazard) {
2023 uasm_i_ehb(&p); 2024 uasm_i_ehb(&p);
2024 2025
2025 case CPU_CAVIUM_OCTEON: 2026 case CPU_CAVIUM_OCTEON:
diff --git a/arch/mips/mm/uasm-micromips.c b/arch/mips/mm/uasm-micromips.c
index 8399ddf03a02..d78178daea4b 100644
--- a/arch/mips/mm/uasm-micromips.c
+++ b/arch/mips/mm/uasm-micromips.c
@@ -38,14 +38,6 @@
38 | (e) << RE_SH \ 38 | (e) << RE_SH \
39 | (f) << FUNC_SH) 39 | (f) << FUNC_SH)
40 40
41/* Define these when we are not the ISA the kernel is being compiled with. */
42#ifndef CONFIG_CPU_MICROMIPS
43#define MM_uasm_i_b(buf, off) ISAOPC(_beq)(buf, 0, 0, off)
44#define MM_uasm_i_beqz(buf, rs, off) ISAOPC(_beq)(buf, rs, 0, off)
45#define MM_uasm_i_beqzl(buf, rs, off) ISAOPC(_beql)(buf, rs, 0, off)
46#define MM_uasm_i_bnez(buf, rs, off) ISAOPC(_bne)(buf, rs, 0, off)
47#endif
48
49#include "uasm.c" 41#include "uasm.c"
50 42
51static struct insn insn_table_MM[] = { 43static struct insn insn_table_MM[] = {
diff --git a/arch/mips/mm/uasm-mips.c b/arch/mips/mm/uasm-mips.c
index 8e02291cfc0c..b4a837893562 100644
--- a/arch/mips/mm/uasm-mips.c
+++ b/arch/mips/mm/uasm-mips.c
@@ -38,13 +38,13 @@
38 | (e) << RE_SH \ 38 | (e) << RE_SH \
39 | (f) << FUNC_SH) 39 | (f) << FUNC_SH)
40 40
41/* Define these when we are not the ISA the kernel is being compiled with. */ 41/* This macro sets the non-variable bits of an R6 instruction. */
42#ifdef CONFIG_CPU_MICROMIPS 42#define M6(a, b, c, d, e) \
43#define CL_uasm_i_b(buf, off) ISAOPC(_beq)(buf, 0, 0, off) 43 ((a) << OP_SH \
44#define CL_uasm_i_beqz(buf, rs, off) ISAOPC(_beq)(buf, rs, 0, off) 44 | (b) << RS_SH \
45#define CL_uasm_i_beqzl(buf, rs, off) ISAOPC(_beql)(buf, rs, 0, off) 45 | (c) << RT_SH \
46#define CL_uasm_i_bnez(buf, rs, off) ISAOPC(_bne)(buf, rs, 0, off) 46 | (d) << SIMM9_SH \
47#endif 47 | (e) << FUNC_SH)
48 48
49#include "uasm.c" 49#include "uasm.c"
50 50
@@ -62,7 +62,11 @@ static struct insn insn_table[] = {
62 { insn_bltzl, M(bcond_op, 0, bltzl_op, 0, 0, 0), RS | BIMM }, 62 { insn_bltzl, M(bcond_op, 0, bltzl_op, 0, 0, 0), RS | BIMM },
63 { insn_bltz, M(bcond_op, 0, bltz_op, 0, 0, 0), RS | BIMM }, 63 { insn_bltz, M(bcond_op, 0, bltz_op, 0, 0, 0), RS | BIMM },
64 { insn_bne, M(bne_op, 0, 0, 0, 0, 0), RS | RT | BIMM }, 64 { insn_bne, M(bne_op, 0, 0, 0, 0, 0), RS | RT | BIMM },
65#ifndef CONFIG_CPU_MIPSR6
65 { insn_cache, M(cache_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, 66 { insn_cache, M(cache_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
67#else
68 { insn_cache, M6(cache_op, 0, 0, 0, cache6_op), RS | RT | SIMM9 },
69#endif
66 { insn_daddiu, M(daddiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, 70 { insn_daddiu, M(daddiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
67 { insn_daddu, M(spec_op, 0, 0, 0, 0, daddu_op), RS | RT | RD }, 71 { insn_daddu, M(spec_op, 0, 0, 0, 0, daddu_op), RS | RT | RD },
68 { insn_dinsm, M(spec3_op, 0, 0, 0, 0, dinsm_op), RS | RT | RD | RE }, 72 { insn_dinsm, M(spec3_op, 0, 0, 0, 0, dinsm_op), RS | RT | RD | RE },
@@ -85,13 +89,22 @@ static struct insn insn_table[] = {
85 { insn_jal, M(jal_op, 0, 0, 0, 0, 0), JIMM }, 89 { insn_jal, M(jal_op, 0, 0, 0, 0, 0), JIMM },
86 { insn_jalr, M(spec_op, 0, 0, 0, 0, jalr_op), RS | RD }, 90 { insn_jalr, M(spec_op, 0, 0, 0, 0, jalr_op), RS | RD },
87 { insn_j, M(j_op, 0, 0, 0, 0, 0), JIMM }, 91 { insn_j, M(j_op, 0, 0, 0, 0, 0), JIMM },
92#ifndef CONFIG_CPU_MIPSR6
88 { insn_jr, M(spec_op, 0, 0, 0, 0, jr_op), RS }, 93 { insn_jr, M(spec_op, 0, 0, 0, 0, jr_op), RS },
94#else
95 { insn_jr, M(spec_op, 0, 0, 0, 0, jalr_op), RS },
96#endif
89 { insn_lb, M(lb_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, 97 { insn_lb, M(lb_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
90 { insn_ld, M(ld_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, 98 { insn_ld, M(ld_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
91 { insn_ldx, M(spec3_op, 0, 0, 0, ldx_op, lx_op), RS | RT | RD }, 99 { insn_ldx, M(spec3_op, 0, 0, 0, ldx_op, lx_op), RS | RT | RD },
92 { insn_lh, M(lh_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, 100 { insn_lh, M(lh_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
101#ifndef CONFIG_CPU_MIPSR6
93 { insn_lld, M(lld_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, 102 { insn_lld, M(lld_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
94 { insn_ll, M(ll_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, 103 { insn_ll, M(ll_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
104#else
105 { insn_lld, M6(spec3_op, 0, 0, 0, lld6_op), RS | RT | SIMM9 },
106 { insn_ll, M6(spec3_op, 0, 0, 0, ll6_op), RS | RT | SIMM9 },
107#endif
95 { insn_lui, M(lui_op, 0, 0, 0, 0, 0), RT | SIMM }, 108 { insn_lui, M(lui_op, 0, 0, 0, 0, 0), RT | SIMM },
96 { insn_lw, M(lw_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, 109 { insn_lw, M(lw_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
97 { insn_lwx, M(spec3_op, 0, 0, 0, lwx_op, lx_op), RS | RT | RD }, 110 { insn_lwx, M(spec3_op, 0, 0, 0, lwx_op, lx_op), RS | RT | RD },
@@ -104,11 +117,20 @@ static struct insn insn_table[] = {
104 { insn_mul, M(spec2_op, 0, 0, 0, 0, mul_op), RS | RT | RD}, 117 { insn_mul, M(spec2_op, 0, 0, 0, 0, mul_op), RS | RT | RD},
105 { insn_ori, M(ori_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, 118 { insn_ori, M(ori_op, 0, 0, 0, 0, 0), RS | RT | UIMM },
106 { insn_or, M(spec_op, 0, 0, 0, 0, or_op), RS | RT | RD }, 119 { insn_or, M(spec_op, 0, 0, 0, 0, or_op), RS | RT | RD },
120#ifndef CONFIG_CPU_MIPSR6
107 { insn_pref, M(pref_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, 121 { insn_pref, M(pref_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
122#else
123 { insn_pref, M6(spec3_op, 0, 0, 0, pref6_op), RS | RT | SIMM9 },
124#endif
108 { insn_rfe, M(cop0_op, cop_op, 0, 0, 0, rfe_op), 0 }, 125 { insn_rfe, M(cop0_op, cop_op, 0, 0, 0, rfe_op), 0 },
109 { insn_rotr, M(spec_op, 1, 0, 0, 0, srl_op), RT | RD | RE }, 126 { insn_rotr, M(spec_op, 1, 0, 0, 0, srl_op), RT | RD | RE },
127#ifndef CONFIG_CPU_MIPSR6
110 { insn_scd, M(scd_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, 128 { insn_scd, M(scd_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
111 { insn_sc, M(sc_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, 129 { insn_sc, M(sc_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
130#else
131 { insn_scd, M6(spec3_op, 0, 0, 0, scd6_op), RS | RT | SIMM9 },
132 { insn_sc, M6(spec3_op, 0, 0, 0, sc6_op), RS | RT | SIMM9 },
133#endif
112 { insn_sd, M(sd_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, 134 { insn_sd, M(sd_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
113 { insn_sll, M(spec_op, 0, 0, 0, 0, sll_op), RT | RD | RE }, 135 { insn_sll, M(spec_op, 0, 0, 0, 0, sll_op), RT | RD | RE },
114 { insn_sllv, M(spec_op, 0, 0, 0, 0, sllv_op), RS | RT | RD }, 136 { insn_sllv, M(spec_op, 0, 0, 0, 0, sllv_op), RS | RT | RD },
@@ -198,6 +220,8 @@ static void build_insn(u32 **buf, enum opcode opc, ...)
198 op |= build_set(va_arg(ap, u32)); 220 op |= build_set(va_arg(ap, u32));
199 if (ip->fields & SCIMM) 221 if (ip->fields & SCIMM)
200 op |= build_scimm(va_arg(ap, u32)); 222 op |= build_scimm(va_arg(ap, u32));
223 if (ip->fields & SIMM9)
224 op |= build_scimm9(va_arg(ap, u32));
201 va_end(ap); 225 va_end(ap);
202 226
203 **buf = op; 227 **buf = op;
diff --git a/arch/mips/mm/uasm.c b/arch/mips/mm/uasm.c
index 4adf30284813..319051c34343 100644
--- a/arch/mips/mm/uasm.c
+++ b/arch/mips/mm/uasm.c
@@ -24,7 +24,8 @@ enum fields {
24 JIMM = 0x080, 24 JIMM = 0x080,
25 FUNC = 0x100, 25 FUNC = 0x100,
26 SET = 0x200, 26 SET = 0x200,
27 SCIMM = 0x400 27 SCIMM = 0x400,
28 SIMM9 = 0x800,
28}; 29};
29 30
30#define OP_MASK 0x3f 31#define OP_MASK 0x3f
@@ -41,6 +42,8 @@ enum fields {
41#define FUNC_SH 0 42#define FUNC_SH 0
42#define SET_MASK 0x7 43#define SET_MASK 0x7
43#define SET_SH 0 44#define SET_SH 0
45#define SIMM9_SH 7
46#define SIMM9_MASK 0x1ff
44 47
45enum opcode { 48enum opcode {
46 insn_invalid, 49 insn_invalid,
@@ -116,6 +119,14 @@ static inline u32 build_scimm(u32 arg)
116 return (arg & SCIMM_MASK) << SCIMM_SH; 119 return (arg & SCIMM_MASK) << SCIMM_SH;
117} 120}
118 121
122static inline u32 build_scimm9(s32 arg)
123{
124 WARN((arg > 0xff || arg < -0x100),
125 KERN_WARNING "Micro-assembler field overflow\n");
126
127 return (arg & SIMM9_MASK) << SIMM9_SH;
128}
129
119static inline u32 build_func(u32 arg) 130static inline u32 build_func(u32 arg)
120{ 131{
121 WARN(arg & ~FUNC_MASK, KERN_WARNING "Micro-assembler field overflow\n"); 132 WARN(arg & ~FUNC_MASK, KERN_WARNING "Micro-assembler field overflow\n");
@@ -330,7 +341,7 @@ I_u3u1u2(_ldx)
330void ISAFUNC(uasm_i_pref)(u32 **buf, unsigned int a, signed int b, 341void ISAFUNC(uasm_i_pref)(u32 **buf, unsigned int a, signed int b,
331 unsigned int c) 342 unsigned int c)
332{ 343{
333 if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X) && a <= 24 && a != 5) 344 if (CAVIUM_OCTEON_DCACHE_PREFETCH_WAR && a <= 24 && a != 5)
334 /* 345 /*
335 * As per erratum Core-14449, replace prefetches 0-4, 346 * As per erratum Core-14449, replace prefetches 0-4,
336 * 6-24 with 'pref 28'. 347 * 6-24 with 'pref 28'.