aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/mips/include/asm/cpu-features.h7
-rw-r--r--arch/mips/kernel/traps.c23
-rw-r--r--arch/mips/math-emu/cp1emu.c55
3 files changed, 43 insertions, 42 deletions
diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h
index 62a4730de86a..fc2ad332541c 100644
--- a/arch/mips/include/asm/cpu-features.h
+++ b/arch/mips/include/asm/cpu-features.h
@@ -221,8 +221,11 @@
221#define cpu_has_mips_4_5_r (cpu_has_mips_4 | cpu_has_mips_5_r) 221#define cpu_has_mips_4_5_r (cpu_has_mips_4 | cpu_has_mips_5_r)
222#define cpu_has_mips_5_r (cpu_has_mips_5 | cpu_has_mips_r) 222#define cpu_has_mips_5_r (cpu_has_mips_5 | cpu_has_mips_r)
223 223
224#define cpu_has_mips_4_5_r2_r6 (cpu_has_mips_4_5 | cpu_has_mips_r2 | \ 224#define cpu_has_mips_3_4_5_64_r2_r6 \
225 cpu_has_mips_r6) 225 (cpu_has_mips_3 | cpu_has_mips_4_5_64_r2_r6)
226#define cpu_has_mips_4_5_64_r2_r6 \
227 (cpu_has_mips_4_5 | cpu_has_mips64r1 | \
228 cpu_has_mips_r2 | cpu_has_mips_r6)
226 229
227#define cpu_has_mips32 (cpu_has_mips32r1 | cpu_has_mips32r2 | cpu_has_mips32r6) 230#define cpu_has_mips32 (cpu_has_mips32r1 | cpu_has_mips32r2 | cpu_has_mips32r6)
228#define cpu_has_mips64 (cpu_has_mips64r1 | cpu_has_mips64r2 | cpu_has_mips64r6) 231#define cpu_has_mips64 (cpu_has_mips64r1 | cpu_has_mips64r2 | cpu_has_mips64r6)
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index dc6eaf4d93ea..88f04f0d2d21 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -1349,19 +1349,18 @@ asmlinkage void do_cpu(struct pt_regs *regs)
1349 1349
1350 case 3: 1350 case 3:
1351 /* 1351 /*
1352 * Old (MIPS I and MIPS II) processors will set this code 1352 * The COP3 opcode space and consequently the CP0.Status.CU3
1353 * for COP1X opcode instructions that replaced the original 1353 * bit and the CP0.Cause.CE=3 encoding have been removed as
1354 * COP3 space. We don't limit COP1 space instructions in 1354 * of the MIPS III ISA. From the MIPS IV and MIPS32r2 ISAs
1355 * the emulator according to the CPU ISA, so we want to 1355 * up the space has been reused for COP1X instructions, that
1356 * treat COP1X instructions consistently regardless of which 1356 * are enabled by the CP0.Status.CU1 bit and consequently
1357 * code the CPU chose. Therefore we redirect this trap to 1357 * use the CP0.Cause.CE=1 encoding for Coprocessor Unusable
1358 * the FP emulator too. 1358 * exceptions. Some FPU-less processors that implement one
1359 * 1359 * of these ISAs however use this code erroneously for COP1X
1360 * Then some newer FPU-less processors use this code 1360 * instructions. Therefore we redirect this trap to the FP
1361 * erroneously too, so they are covered by this choice 1361 * emulator too.
1362 * as well.
1363 */ 1362 */
1364 if (raw_cpu_has_fpu) { 1363 if (raw_cpu_has_fpu || !cpu_has_mips_4_5_64_r2_r6) {
1365 force_sig(SIGILL, current); 1364 force_sig(SIGILL, current);
1366 break; 1365 break;
1367 } 1366 }
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c
index be983850eb39..732c3a37d7b9 100644
--- a/arch/mips/math-emu/cp1emu.c
+++ b/arch/mips/math-emu/cp1emu.c
@@ -1115,17 +1115,18 @@ emul:
1115 likely = 0; 1115 likely = 0;
1116 switch (MIPSInst_RT(ir) & 3) { 1116 switch (MIPSInst_RT(ir) & 3) {
1117 case bcfl_op: 1117 case bcfl_op:
1118 likely = 1; 1118 if (cpu_has_mips_2_3_4_5_r)
1119 likely = 1;
1120 /* Fall through */
1119 case bcf_op: 1121 case bcf_op:
1120 cond = !cond; 1122 cond = !cond;
1121 break; 1123 break;
1122 case bctl_op: 1124 case bctl_op:
1123 likely = 1; 1125 if (cpu_has_mips_2_3_4_5_r)
1126 likely = 1;
1127 /* Fall through */
1124 case bct_op: 1128 case bct_op:
1125 break; 1129 break;
1126 default:
1127 /* thats an illegal instruction */
1128 return SIGILL;
1129 } 1130 }
1130 1131
1131 set_delay_slot(xcp); 1132 set_delay_slot(xcp);
@@ -1165,36 +1166,34 @@ emul:
1165 1166
1166 switch (MIPSInst_OPCODE(ir)) { 1167 switch (MIPSInst_OPCODE(ir)) {
1167 case lwc1_op: 1168 case lwc1_op:
1168 goto emul;
1169
1170 case swc1_op: 1169 case swc1_op:
1171 goto emul; 1170 goto emul;
1172 1171
1173 case ldc1_op: 1172 case ldc1_op:
1174 case sdc1_op: 1173 case sdc1_op:
1175 if (cpu_has_mips_2_3_4_5 || 1174 if (cpu_has_mips_2_3_4_5_r)
1176 cpu_has_mips64)
1177 goto emul; 1175 goto emul;
1178 1176
1179 return SIGILL; 1177 return SIGILL;
1180 goto emul;
1181 1178
1182 case cop1_op: 1179 case cop1_op:
1183 goto emul; 1180 goto emul;
1184 1181
1185 case cop1x_op: 1182 case cop1x_op:
1186 if (cpu_has_mips_4_5 || cpu_has_mips64 || cpu_has_mips32r2) 1183 if (cpu_has_mips_4_5_64_r2_r6)
1187 /* its one of ours */ 1184 /* its one of ours */
1188 goto emul; 1185 goto emul;
1189 1186
1190 return SIGILL; 1187 return SIGILL;
1191 1188
1192 case spec_op: 1189 case spec_op:
1193 if (!cpu_has_mips_4_5_r) 1190 switch (MIPSInst_FUNC(ir)) {
1194 return SIGILL; 1191 case movc_op:
1192 if (cpu_has_mips_4_5_r)
1193 goto emul;
1195 1194
1196 if (MIPSInst_FUNC(ir) == movc_op) 1195 return SIGILL;
1197 goto emul; 1196 }
1198 break; 1197 break;
1199 } 1198 }
1200 1199
@@ -1228,7 +1227,7 @@ emul:
1228 break; 1227 break;
1229 1228
1230 case cop1x_op: 1229 case cop1x_op:
1231 if (!cpu_has_mips_4_5 && !cpu_has_mips64 && !cpu_has_mips32r2) 1230 if (!cpu_has_mips_4_5_64_r2_r6)
1232 return SIGILL; 1231 return SIGILL;
1233 1232
1234 sig = fpux_emu(xcp, ctx, ir, fault_addr); 1233 sig = fpux_emu(xcp, ctx, ir, fault_addr);
@@ -1561,7 +1560,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1561 1560
1562 /* unary ops */ 1561 /* unary ops */
1563 case fsqrt_op: 1562 case fsqrt_op:
1564 if (!cpu_has_mips_4_5_r) 1563 if (!cpu_has_mips_2_3_4_5_r)
1565 return SIGILL; 1564 return SIGILL;
1566 1565
1567 handler.u = ieee754sp_sqrt; 1566 handler.u = ieee754sp_sqrt;
@@ -1573,14 +1572,14 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1573 * achieve full IEEE-754 accuracy - however this emulator does. 1572 * achieve full IEEE-754 accuracy - however this emulator does.
1574 */ 1573 */
1575 case frsqrt_op: 1574 case frsqrt_op:
1576 if (!cpu_has_mips_4_5_r2_r6) 1575 if (!cpu_has_mips_4_5_64_r2_r6)
1577 return SIGILL; 1576 return SIGILL;
1578 1577
1579 handler.u = fpemu_sp_rsqrt; 1578 handler.u = fpemu_sp_rsqrt;
1580 goto scopuop; 1579 goto scopuop;
1581 1580
1582 case frecip_op: 1581 case frecip_op:
1583 if (!cpu_has_mips_4_5_r2_r6) 1582 if (!cpu_has_mips_4_5_64_r2_r6)
1584 return SIGILL; 1583 return SIGILL;
1585 1584
1586 handler.u = fpemu_sp_recip; 1585 handler.u = fpemu_sp_recip;
@@ -1682,7 +1681,7 @@ copcsr:
1682 case ftrunc_op: 1681 case ftrunc_op:
1683 case fceil_op: 1682 case fceil_op:
1684 case ffloor_op: 1683 case ffloor_op:
1685 if (!cpu_has_mips_2_3_4_5 && !cpu_has_mips64) 1684 if (!cpu_has_mips_2_3_4_5_r)
1686 return SIGILL; 1685 return SIGILL;
1687 1686
1688 oldrm = ieee754_csr.rm; 1687 oldrm = ieee754_csr.rm;
@@ -1694,7 +1693,7 @@ copcsr:
1694 goto copcsr; 1693 goto copcsr;
1695 1694
1696 case fcvtl_op: 1695 case fcvtl_op:
1697 if (!cpu_has_mips_3_4_5 && !cpu_has_mips64) 1696 if (!cpu_has_mips_3_4_5_64_r2_r6)
1698 return SIGILL; 1697 return SIGILL;
1699 1698
1700 SPFROMREG(fs, MIPSInst_FS(ir)); 1699 SPFROMREG(fs, MIPSInst_FS(ir));
@@ -1706,7 +1705,7 @@ copcsr:
1706 case ftruncl_op: 1705 case ftruncl_op:
1707 case fceill_op: 1706 case fceill_op:
1708 case ffloorl_op: 1707 case ffloorl_op:
1709 if (!cpu_has_mips_3_4_5 && !cpu_has_mips64) 1708 if (!cpu_has_mips_3_4_5_64_r2_r6)
1710 return SIGILL; 1709 return SIGILL;
1711 1710
1712 oldrm = ieee754_csr.rm; 1711 oldrm = ieee754_csr.rm;
@@ -1775,13 +1774,13 @@ copcsr:
1775 * achieve full IEEE-754 accuracy - however this emulator does. 1774 * achieve full IEEE-754 accuracy - however this emulator does.
1776 */ 1775 */
1777 case frsqrt_op: 1776 case frsqrt_op:
1778 if (!cpu_has_mips_4_5_r2_r6) 1777 if (!cpu_has_mips_4_5_64_r2_r6)
1779 return SIGILL; 1778 return SIGILL;
1780 1779
1781 handler.u = fpemu_dp_rsqrt; 1780 handler.u = fpemu_dp_rsqrt;
1782 goto dcopuop; 1781 goto dcopuop;
1783 case frecip_op: 1782 case frecip_op:
1784 if (!cpu_has_mips_4_5_r2_r6) 1783 if (!cpu_has_mips_4_5_64_r2_r6)
1785 return SIGILL; 1784 return SIGILL;
1786 1785
1787 handler.u = fpemu_dp_recip; 1786 handler.u = fpemu_dp_recip;
@@ -1871,7 +1870,7 @@ dcopuop:
1871 goto copcsr; 1870 goto copcsr;
1872 1871
1873 case fcvtl_op: 1872 case fcvtl_op:
1874 if (!cpu_has_mips_3_4_5 && !cpu_has_mips64) 1873 if (!cpu_has_mips_3_4_5_64_r2_r6)
1875 return SIGILL; 1874 return SIGILL;
1876 1875
1877 DPFROMREG(fs, MIPSInst_FS(ir)); 1876 DPFROMREG(fs, MIPSInst_FS(ir));
@@ -1883,7 +1882,7 @@ dcopuop:
1883 case ftruncl_op: 1882 case ftruncl_op:
1884 case fceill_op: 1883 case fceill_op:
1885 case ffloorl_op: 1884 case ffloorl_op:
1886 if (!cpu_has_mips_3_4_5 && !cpu_has_mips64) 1885 if (!cpu_has_mips_3_4_5_64_r2_r6)
1887 return SIGILL; 1886 return SIGILL;
1888 1887
1889 oldrm = ieee754_csr.rm; 1888 oldrm = ieee754_csr.rm;
@@ -1942,7 +1941,7 @@ dcopuop:
1942 1941
1943 case l_fmt: 1942 case l_fmt:
1944 1943
1945 if (!cpu_has_mips_3_4_5 && !cpu_has_mips64) 1944 if (!cpu_has_mips_3_4_5_64_r2_r6)
1946 return SIGILL; 1945 return SIGILL;
1947 1946
1948 DIFROMREG(bits, MIPSInst_FS(ir)); 1947 DIFROMREG(bits, MIPSInst_FS(ir));
@@ -2006,7 +2005,7 @@ dcopuop:
2006 SITOREG(rv.w, MIPSInst_FD(ir)); 2005 SITOREG(rv.w, MIPSInst_FD(ir));
2007 break; 2006 break;
2008 case l_fmt: 2007 case l_fmt:
2009 if (!cpu_has_mips_3_4_5 && !cpu_has_mips64) 2008 if (!cpu_has_mips_3_4_5_64_r2_r6)
2010 return SIGILL; 2009 return SIGILL;
2011 2010
2012 DITOREG(rv.l, MIPSInst_FD(ir)); 2011 DITOREG(rv.l, MIPSInst_FD(ir));