diff options
-rw-r--r-- | arch/mips/include/asm/cpu-features.h | 7 | ||||
-rw-r--r-- | arch/mips/kernel/traps.c | 23 | ||||
-rw-r--r-- | arch/mips/math-emu/cp1emu.c | 55 |
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)); |