Unverified Commit ece276de authored by Jiaxun Yang's avatar Jiaxun Yang Committed by Paul Burton
Browse files

MIPS: Add MAC2008 Support



MAC2008 means the processor implemented IEEE754 style Fused MADD
instruction. It was introduced in Release3 but removed in Release5.

The toolchain support of MAC2008 have never landed except for Loongson
processors.

This patch aimed to disabled the MAC2008 if it's optional. For
MAC2008 only processors, we corrected math-emu behavior to align
with actual hardware behavior.

Signed-off-by: default avatarJiaxun Yang <jiaxun.yang@flygoat.com>
[paulburton@kernel.org: Fixup MIPSr2-r5 check in cpu_set_fpu_2008.]
Signed-off-by: default avatarPaul Burton <paulburton@kernel.org>
Cc: linux-mips@vger.kernel.org
Cc: chenhc@lemote.com
Cc: paul.burton@mips.com
Cc: linux-kernel@vger.kernel.org
parent 0a3d5b57
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -555,6 +555,10 @@
# define cpu_has_perf		__opt(MIPS_CPU_PERF)
#endif

#ifndef cpu_has_mac2008_only
# define cpu_has_mac2008_only	__opt(MIPS_CPU_MAC_2008_ONLY)
#endif

#ifdef CONFIG_SMP
/*
 * Some systems share FTLB RAMs between threads within a core (siblings in
+1 −0
Original line number Diff line number Diff line
@@ -416,6 +416,7 @@ enum cpu_type_enum {
#define MIPS_CPU_MT_PER_TC_PERF_COUNTERS \
				BIT_ULL(56)	/* CPU has perf counters implemented per TC (MIPSMT ASE) */
#define MIPS_CPU_MMID		BIT_ULL(57)	/* CPU supports MemoryMapIDs */
#define MIPS_CPU_MAC_2008_ONLY	BIT_ULL(58)	/* CPU Only support MAC2008 Fused multiply-add instruction */

/*
 * CPU ASE encodings
+3 −0
Original line number Diff line number Diff line
@@ -1101,9 +1101,12 @@
/*
 * Bits 22:20 of the FPU Status Register will be read as 0,
 * and should be written as zero.
 * MAC2008 was removed in Release 5 so we still treat it as
 * reserved.
 */
#define FPU_CSR_RSVD	(_ULCAST_(7) << 20)

#define FPU_CSR_MAC2008	(_ULCAST_(1) << 20)
#define FPU_CSR_ABS2008	(_ULCAST_(1) << 19)
#define FPU_CSR_NAN2008	(_ULCAST_(1) << 18)

+15 −1
Original line number Diff line number Diff line
@@ -102,7 +102,12 @@ static void cpu_set_fpu_2008(struct cpuinfo_mips *c)
		if (fir & MIPS_FPIR_HAS2008) {
			fcsr = read_32bit_cp1_register(CP1_STATUS);

			fcsr0 = fcsr & ~(FPU_CSR_ABS2008 | FPU_CSR_NAN2008);
			/*
			 * MAC2008 toolchain never landed in real world, so we're only
			 * testing wether it can be disabled and don't try to enabled
			 * it.
			 */
			fcsr0 = fcsr & ~(FPU_CSR_ABS2008 | FPU_CSR_NAN2008 | FPU_CSR_MAC2008);
			write_32bit_cp1_register(CP1_STATUS, fcsr0);
			fcsr0 = read_32bit_cp1_register(CP1_STATUS);

@@ -112,6 +117,15 @@ static void cpu_set_fpu_2008(struct cpuinfo_mips *c)

			write_32bit_cp1_register(CP1_STATUS, fcsr);

			if (c->isa_level & (MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2)) {
				/*
				 * The bit for MAC2008 might be reused by R6 in future,
				 * so we only test for R2-R5.
				 */
				if (fcsr0 & FPU_CSR_MAC2008)
					c->options |= MIPS_CPU_MAC_2008_ONLY;
			}

			if (!(fcsr0 & FPU_CSR_NAN2008))
				c->options |= MIPS_CPU_NAN_LEGACY;
			if (fcsr1 & FPU_CSR_NAN2008)
+31 −7
Original line number Diff line number Diff line
@@ -1514,15 +1514,27 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
			break;

		case madd_s_op:
			if (cpu_has_mac2008_only)
				handler = ieee754sp_madd;
			else
				handler = fpemu_sp_madd;
			goto scoptop;
		case msub_s_op:
			if (cpu_has_mac2008_only)
				handler = ieee754sp_msub;
			else
				handler = fpemu_sp_msub;
			goto scoptop;
		case nmadd_s_op:
			if (cpu_has_mac2008_only)
				handler = ieee754sp_nmadd;
			else
				handler = fpemu_sp_nmadd;
			goto scoptop;
		case nmsub_s_op:
			if (cpu_has_mac2008_only)
				handler = ieee754sp_nmsub;
			else
				handler = fpemu_sp_nmsub;
			goto scoptop;

@@ -1610,15 +1622,27 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
			break;

		case madd_d_op:
			if (cpu_has_mac2008_only)
				handler = ieee754dp_madd;
			else
				handler = fpemu_dp_madd;
			goto dcoptop;
		case msub_d_op:
			if (cpu_has_mac2008_only)
				handler = ieee754dp_msub;
			else
				handler = fpemu_dp_msub;
			goto dcoptop;
		case nmadd_d_op:
			if (cpu_has_mac2008_only)
				handler = ieee754dp_nmadd;
			else
				handler = fpemu_dp_nmadd;
			goto dcoptop;
		case nmsub_d_op:
			if (cpu_has_mac2008_only)
				handler = ieee754dp_nmsub;
			else
			handler = fpemu_dp_nmsub;
			goto dcoptop;

Loading