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)