aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@codesourcery.com>2012-03-06 15:28:54 -0500
committerRalf Baechle <ralf@linux-mips.org>2012-12-13 12:15:27 -0500
commit051ff44a8b508f8e8e342db3220d5ad8296c19ce (patch)
treef020ebd1df039717f5fe5fd7c5932d0df07a0f4a /arch/mips/kernel
parent8add1ecb81f541ef2fcb0b85a5470ad9ecfb4a84 (diff)
MIPS: Handle COP3 Unusable exception as COP1X for FP emulation
Our FP emulator is hardcoded for the MIPS IV FP instruction set and does not match the FP ISA with the general ISA. However for the few MIPS IV FP instructions that use the COP1X major opcode it relies on the Coprocessor Unusable exception to be delivered as a COP1 rather than COP3 exception. This includes indexed transfer (LDXC1, etc.) and FP multiply-accumulate (MADD.D, etc.) instructions. All the MIPS I, II, III and IV processors and some newer chips that do not implement the FPU use the COP3 exception however. Therefore I believe the kernel should follow and redirect any COP3 Unusable traps to the emulator unless an actual FPU part or core is present. This is a change that implements it. Any minor opcode encodings that are not recognised as valid FP instructions are rejected by the emulator and will result in a SIGILL signal being delivered as they currently do. We do not support vendor-specific coprocessor 3 implementations supported with MIPS I and MIPS II ISA processors; we never set CP0.Status.CU3. [Ralf: On MIPS IV processors the kernel always enables the XX bit which replaces the CU3 bit off earlier architecture revisions.] If matching between the CPU and the FPU ISA is considered required one day, this can still be done in the emulator itself. I think the CpU exception dispatcher is not the right place to do this anyway, as there are further differences between MIPS I, MIPS II, MIPS III, MIPS IV and MIPS32 FP ISAs. Corresponding explanation of this implementation is included within the change itself. Signed-off-by: Maciej W. Rozycki <macro@codesourcery.com> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/project/linux-mips/list/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/kernel')
-rw-r--r--arch/mips/kernel/traps.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index da0c29422cf2..cf7ac5483f53 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -1025,6 +1025,24 @@ asmlinkage void do_cpu(struct pt_regs *regs)
1025 1025
1026 return; 1026 return;
1027 1027
1028 case 3:
1029 /*
1030 * Old (MIPS I and MIPS II) processors will set this code
1031 * for COP1X opcode instructions that replaced the original
1032 * COP3 space. We don't limit COP1 space instructions in
1033 * the emulator according to the CPU ISA, so we want to
1034 * treat COP1X instructions consistently regardless of which
1035 * code the CPU chose. Therefore we redirect this trap to
1036 * the FP emulator too.
1037 *
1038 * Then some newer FPU-less processors use this code
1039 * erroneously too, so they are covered by this choice
1040 * as well.
1041 */
1042 if (raw_cpu_has_fpu)
1043 break;
1044 /* Fall through. */
1045
1028 case 1: 1046 case 1:
1029 if (used_math()) /* Using the FPU again. */ 1047 if (used_math()) /* Using the FPU again. */
1030 own_fpu(1); 1048 own_fpu(1);
@@ -1048,9 +1066,6 @@ asmlinkage void do_cpu(struct pt_regs *regs)
1048 case 2: 1066 case 2:
1049 raw_notifier_call_chain(&cu2_chain, CU2_EXCEPTION, regs); 1067 raw_notifier_call_chain(&cu2_chain, CU2_EXCEPTION, regs);
1050 return; 1068 return;
1051
1052 case 3:
1053 break;
1054 } 1069 }
1055 1070
1056 force_sig(SIGILL, current); 1071 force_sig(SIGILL, current);