[PATCH] MIPS: Fix MIPS_O32_FP64_SUPPORT for 64bit CPUs before R2

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



MIPS_O32_FP64_SUPPORT enables possibility of using all 32 FPRs on 32bit
kernel in case CPU implemented FR1. As FR1 is present on all 64bit CPUs
following R4000's priviliged spec, there is no reason to limit such support
to R2+ CPUs.

Fix it by remove architecture reversion conditions in FR1 context switch
code and enable relevant bits in kernel's FIR copy.

Signed-off-by: Jiaxun Yang <jiaxun.yang@xxxxxxxxxxx>
---
 arch/mips/include/asm/asmmacro.h |  6 ++----
 arch/mips/include/asm/fpu.h      |  3 +--
 arch/mips/kernel/elf.c           |  5 ++---
 arch/mips/kernel/fpu-probe.c     | 17 +++++++++++++++++
 arch/mips/kernel/r4k_fpu.S       | 16 ++++++----------
 5 files changed, 28 insertions(+), 19 deletions(-)

diff --git a/arch/mips/include/asm/asmmacro.h b/arch/mips/include/asm/asmmacro.h
index 067a635d3bc8..3e7c19ee6a90 100644
--- a/arch/mips/include/asm/asmmacro.h
+++ b/arch/mips/include/asm/asmmacro.h
@@ -130,8 +130,7 @@
 	.endm
 
 	.macro	fpu_save_double thread status tmp
-#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPSR2) || \
-    defined(CONFIG_CPU_MIPSR5) || defined(CONFIG_CPU_MIPSR6)
+#if defined(CONFIG_64BIT) || defined(CONFIG_MIPS_O32_FP64_SUPPORT)
 	sll	\tmp, \status, 5
 	bgez	\tmp, 10f
 	fpu_save_16odd \thread
@@ -189,8 +188,7 @@
 	.endm
 
 	.macro	fpu_restore_double thread status tmp
-#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPSR2) || \
-    defined(CONFIG_CPU_MIPSR5) || defined(CONFIG_CPU_MIPSR6)
+#if defined(CONFIG_64BIT) || defined(CONFIG_MIPS_O32_FP64_SUPPORT)
 	sll	\tmp, \status, 5
 	bgez	\tmp, 10f				# 16 register mode?
 
diff --git a/arch/mips/include/asm/fpu.h b/arch/mips/include/asm/fpu.h
index 86310d6e1035..1cd820e79f77 100644
--- a/arch/mips/include/asm/fpu.h
+++ b/arch/mips/include/asm/fpu.h
@@ -71,8 +71,7 @@ static inline int __enable_fpu(enum fpu_mode mode)
 		goto fr_common;
 
 	case FPU_64BIT:
-#if !(defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR5) || \
-      defined(CONFIG_CPU_MIPSR6) || defined(CONFIG_64BIT))
+#if !(defined(CONFIG_64BIT) || defined(CONFIG_MIPS_O32_FP64_SUPPORT))
 		/* we only have a 32-bit FPU */
 		return SIGFPE;
 #endif
diff --git a/arch/mips/kernel/elf.c b/arch/mips/kernel/elf.c
index 5582a4ca1e9e..0895bc9b5dd7 100644
--- a/arch/mips/kernel/elf.c
+++ b/arch/mips/kernel/elf.c
@@ -250,9 +250,8 @@ int arch_check_elf(void *_ehdr, bool has_interpreter, void *_interp_ehdr,
 		state->overall_fp_mode = FP_FRE;
 	else if ((prog_req.fr1 && prog_req.frdefault) ||
 		 (prog_req.single && !prog_req.frdefault))
-		/* Make sure 64-bit MIPS III/IV/64R1 will not pick FR1 */
-		state->overall_fp_mode = ((raw_current_cpu_data.fpu_id & MIPS_FPIR_F64) &&
-					  cpu_has_mips_r2_r6) ?
+		/* Make sure CPUs without FR1 will not pick FR1 */
+		state->overall_fp_mode = (raw_current_cpu_data.fpu_id & MIPS_FPIR_F64) ?
 					  FP_FR1 : FP_FR0;
 	else if (prog_req.fr1)
 		state->overall_fp_mode = FP_FR1;
diff --git a/arch/mips/kernel/fpu-probe.c b/arch/mips/kernel/fpu-probe.c
index e689d6a83234..383c43e5c86a 100644
--- a/arch/mips/kernel/fpu-probe.c
+++ b/arch/mips/kernel/fpu-probe.c
@@ -289,6 +289,23 @@ void cpu_set_fpu_opts(struct cpuinfo_mips *c)
 			c->options |= MIPS_CPU_FRE;
 	}
 
+	/* Fix up FIR for FPU earlier than R2 */
+	if (!cpu_has_mips_r2_r6) {
+		c->fpu_id |= MIPS_FPIR_S;
+#ifdef CONFIG_CPU_R4K_FPU
+		/* All known R4000 class FPU implemented double */
+		c->fpu_id |= MIPS_FPIR_D;
+#endif
+		if (cpu_has_64bits) {
+			/* Try to enable FR1 */
+			change_c0_status(ST0_FR, ST0_FR);
+			if (read_c0_status() & ST0_FR) {
+				c->fpu_id |= MIPS_FPIR_F64;
+				c->options |= MIPS_CPU_32FPR;
+			}
+		}
+	}
+
 	cpu_set_fpu_fcsr_mask(c);
 	cpu_set_fpu_2008(c);
 	cpu_set_nan_2008(c);
diff --git a/arch/mips/kernel/r4k_fpu.S b/arch/mips/kernel/r4k_fpu.S
index 4e8c98517d9d..eeef115fc39e 100644
--- a/arch/mips/kernel/r4k_fpu.S
+++ b/arch/mips/kernel/r4k_fpu.S
@@ -40,8 +40,7 @@
  */
 LEAF(_save_fp)
 EXPORT_SYMBOL(_save_fp)
-#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPSR2) || \
-    defined(CONFIG_CPU_MIPSR5) || defined(CONFIG_CPU_MIPSR6)
+#if defined(CONFIG_64BIT) || defined(CONFIG_MIPS_O32_FP64_SUPPORT)
 	mfc0	t0, CP0_STATUS
 #endif
 	fpu_save_double a0 t0 t1		# clobbers t1
@@ -52,8 +51,7 @@ EXPORT_SYMBOL(_save_fp)
  * Restore a thread's fp context.
  */
 LEAF(_restore_fp)
-#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPSR2) || \
-    defined(CONFIG_CPU_MIPSR5) || defined(CONFIG_CPU_MIPSR6)
+#if defined(CONFIG_64BIT) || defined(CONFIG_MIPS_O32_FP64_SUPPORT)
 	mfc0	t0, CP0_STATUS
 #endif
 	fpu_restore_double a0 t0 t1		# clobbers t1
@@ -102,11 +100,10 @@ LEAF(_save_fp_context)
 	cfc1	t1, fcr31
 	.set	pop
 
-#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPSR2) || \
-    defined(CONFIG_CPU_MIPSR5) || defined(CONFIG_CPU_MIPSR6)
+#if defined(CONFIG_64BIT) || defined(CONFIG_MIPS_O32_FP64_SUPPORT)
 	.set	push
 	.set	hardfloat
-#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR5)
+#if MIPS_ISA_REV < 6
 	.set	mips32r2
 	.set	fp=64
 	mfc0	t0, CP0_STATUS
@@ -170,11 +167,10 @@ LEAF(_save_fp_context)
 LEAF(_restore_fp_context)
 	EX	lw t1, 0(a1)
 
-#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPSR2) || \
-    defined(CONFIG_CPU_MIPSR5) || defined(CONFIG_CPU_MIPSR6)
+#if defined(CONFIG_64BIT) || defined(CONFIG_MIPS_O32_FP64_SUPPORT)
 	.set	push
 	.set	hardfloat
-#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR5)
+#if MIPS_ISA_REV < 6
 	.set	mips32r2
 	.set	fp=64
 	mfc0	t0, CP0_STATUS
-- 
2.39.2 (Apple Git-143)




[Index of Archives]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux