MIPS: math-emu: Set FIR feature flags for full emulation
authorMaciej W. Rozycki <macro@linux-mips.org>
Fri, 3 Apr 2015 22:27:26 +0000 (23:27 +0100)
committerRalf Baechle <ralf@linux-mips.org>
Tue, 7 Apr 2015 23:10:25 +0000 (01:10 +0200)
Implement FIR feature flags in the FPU emulator according to features
supported and architecture level requirements.  The W, L and F64 bits
have only been added at level #2 even though the features they refer to
were also included with the MIPS64r1 ISA and the W fixed-point format
also with the MIPS32r1 ISA.

This is only relevant for the full emulation mode and the emulated CFC1
instruction as well as ptrace(2) accesses.

Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/9707/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
arch/mips/kernel/cpu-probe.c
arch/mips/math-emu/cp1emu.c

index f8481ce7bbb17b281d25cc5e5311f6ffdf9a1e16..ca9b9c62c6eacc675ad75d925f9d3390e1f38976 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <asm/bugs.h>
 #include <asm/cpu.h>
+#include <asm/cpu-features.h>
 #include <asm/cpu-type.h>
 #include <asm/fpu.h>
 #include <asm/mipsregs.h>
 #include <asm/spram.h>
 #include <asm/uaccess.h>
 
+/*
+ * Set the FIR feature flags for the FPU emulator.
+ */
+static void cpu_set_nofpu_id(struct cpuinfo_mips *c)
+{
+       u32 value;
+
+       value = 0;
+       if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1 |
+                           MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
+                           MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6))
+               value |= MIPS_FPIR_D | MIPS_FPIR_S;
+       if (c->isa_level & (MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
+                           MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6))
+               value |= MIPS_FPIR_F64 | MIPS_FPIR_L | MIPS_FPIR_W;
+       c->fpu_id = value;
+}
+
 static int mips_fpu_disabled;
 
 static int __init fpu_disable(char *s)
 {
-       cpu_data[0].options &= ~MIPS_CPU_FPU;
+       boot_cpu_data.options &= ~MIPS_CPU_FPU;
+       cpu_set_nofpu_id(&boot_cpu_data);
        mips_fpu_disabled = 1;
 
        return 1;
@@ -1382,7 +1402,8 @@ void cpu_probe(void)
                        if (c->fpu_id & MIPS_FPIR_FREP)
                                c->options |= MIPS_CPU_FRE;
                }
-       }
+       } else
+               cpu_set_nofpu_id(c);
 
        if (cpu_has_mips_r2_r6) {
                c->srsets = ((read_c0_srsctl() >> 26) & 0x0f) + 1;
index acfef06b83112b88a43d913eced9ac5b1d94659a..7aa42b2caf89d00e95ad62053047bcee1ca7e697 100644 (file)
@@ -45,6 +45,7 @@
 #include <asm/signal.h>
 #include <asm/uaccess.h>
 
+#include <asm/cpu-info.h>
 #include <asm/processor.h>
 #include <asm/fpu_emulator.h>
 #include <asm/fpu.h>
@@ -853,7 +854,7 @@ static inline void cop1_cfc(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
                         (void *)xcp->cp0_epc,
                         MIPSInst_RT(ir), value);
        } else if (MIPSInst_RD(ir) == FPCREG_RID)
-               value = 0;
+               value = current_cpu_data.fpu_id;
        else
                value = 0;
        if (MIPSInst_RT(ir))