Re: [PATCH v2] MIPS: Add basic R5900 support

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

 



Hi Maciej,

> > For this reason the R5900 patch modifies the __{save,restore}_dsp macros,
> > mips_dsp_state::dspcontrol, DSP_INIT, sigcontext32::sc_dsp, etc. I've seen
> > the cpu_has_dsp macro too, but haven't looked at the details of this yet.
> 
>  Given that the R5900 does not expand DSP support anyhow that sounds 
> suspicious to me.

I've taken a closer look at the R5900 changes to the DSP kernel code now:

The R5900 has four three-operand instructions: MADD, MADDU, MULT and MULTU.
In addition, it has ten instructions for pipeline 1: MULT1, MULTU1, DIV1,
DIVU1, MADD1, MADDU1, MFHI1, MFLO1, MTHI1 and MTLO1. Those are the reason
(parts of) the cpu_has_dsp infrastructure is used, as shown in the patch
below. What are your thoughts on this?

The instructions are specific to the R5900, and notably incompatible with
similar ones in the base MIPS32 architecture. They are also distinct from
the (also R5900 specific) 128-bit multimedia instructions.

By the way, "machine" is set to "Unknown" and "ASEs implemented" is empty
in /proc/cpuinfo. What would be the proper values for the R5900?

Fredrik

diff --git a/arch/mips/include/asm/dsp.h b/arch/mips/include/asm/dsp.h
index 7bfad0520e25..1bf4da622795 100644
--- a/arch/mips/include/asm/dsp.h
+++ b/arch/mips/include/asm/dsp.h
@@ -27,11 +27,13 @@ static inline void __init_dsp(void)
 {
 	mthi1(0);
 	mtlo1(0);
+#ifndef CONFIG_CPU_R5900
 	mthi2(0);
 	mtlo2(0);
 	mthi3(0);
 	mtlo3(0);
 	wrdsp(DSP_DEFAULT, DSP_MASK);
+#endif
 }
 
 static inline void init_dsp(void)
@@ -40,6 +42,13 @@ static inline void init_dsp(void)
 		__init_dsp();
 }
 
+#ifdef CONFIG_CPU_R5900
+#define __save_dsp(tsk)							\
+do {									\
+	tsk->thread.dsp.dspr[0] = mfhi1();				\
+	tsk->thread.dsp.dspr[1] = mflo1();				\
+} while (0)
+#else
 #define __save_dsp(tsk)							\
 do {									\
 	tsk->thread.dsp.dspr[0] = mfhi1();				\
@@ -50,6 +59,7 @@ do {									\
 	tsk->thread.dsp.dspr[5] = mflo3();				\
 	tsk->thread.dsp.dspcontrol = rddsp(DSP_MASK);			\
 } while (0)
+#endif
 
 #define save_dsp(tsk)							\
 do {									\
@@ -57,6 +67,13 @@ do {									\
 		__save_dsp(tsk);					\
 } while (0)
 
+#ifdef CONFIG_CPU_R5900
+#define __restore_dsp(tsk)						\
+do {									\
+	mthi1(tsk->thread.dsp.dspr[0]);					\
+	mtlo1(tsk->thread.dsp.dspr[1]);					\
+} while (0)
+#else
 #define __restore_dsp(tsk)						\
 do {									\
 	mthi1(tsk->thread.dsp.dspr[0]);					\
@@ -67,6 +84,7 @@ do {									\
 	mtlo3(tsk->thread.dsp.dspr[5]);					\
 	wrdsp(tsk->thread.dsp.dspcontrol, DSP_MASK);			\
 } while (0)
+#endif
 
 #define restore_dsp(tsk)						\
 do {									\
diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h
index 95b8c471f572..7330530f31b0 100644
--- a/arch/mips/include/asm/processor.h
+++ b/arch/mips/include/asm/processor.h
@@ -139,13 +139,19 @@ struct mips_fpu_struct {
 	unsigned int	msacsr;
 };
 
+#ifdef CONFIG_CPU_R5900
+#define NUM_DSP_REGS   2
+#else
 #define NUM_DSP_REGS   6
+#endif
 
 typedef __u32 dspreg_t;
 
 struct mips_dsp_state {
 	dspreg_t	dspr[NUM_DSP_REGS];
+#ifndef CONFIG_CPU_R5900
 	unsigned int	dspcontrol;
+#endif
 };
 
 #define INIT_CPUMASK { \
@@ -304,10 +310,20 @@ struct thread_struct {
 #define FPAFF_INIT
 #endif /* CONFIG_MIPS_MT_FPAFF */
 
-#define INIT_THREAD  {						\
-	/*							\
-	 * Saved main processor registers			\
-	 */							\
+#ifdef CONFIG_CPU_R5900
+#define DSP_INIT \
+	.dsp			= {				\
+		.dspr		= {0, },			\
+	},
+#else
+#define DSP_INIT \
+	.dsp			= {				\
+		.dspr		= {0, },			\
+		.dspcontrol	= 0,				\
+	},
+#endif
+
+#define REGS_INIT \
 	.reg16			= 0,				\
 	.reg17			= 0,				\
 	.reg18			= 0,				\
@@ -318,7 +334,13 @@ struct thread_struct {
 	.reg23			= 0,				\
 	.reg29			= 0,				\
 	.reg30			= 0,				\
-	.reg31			= 0,				\
+	.reg31			= 0,
+
+#define INIT_THREAD  {						\
+        /*							\
+         * Saved main processor registers			\
+         */							\
+	REGS_INIT						\
 	/*							\
 	 * Saved cp0 stuff					\
 	 */							\
@@ -342,10 +364,7 @@ struct thread_struct {
 	/*							\
 	 * Saved DSP stuff					\
 	 */							\
-	.dsp			= {				\
-		.dspr		= {0, },			\
-		.dspcontrol	= 0,				\
-	},							\
+	DSP_INIT						\
 	/*							\
 	 * saved watch register stuff				\
 	 */							\
diff --git a/arch/mips/include/asm/sigcontext.h b/arch/mips/include/asm/sigcontext.h
index eeeb0f48c767..4e975a3291f6 100644
--- a/arch/mips/include/asm/sigcontext.h
+++ b/arch/mips/include/asm/sigcontext.h
@@ -23,15 +23,19 @@ struct sigcontext32 {
 	__u32		sc_fpc_csr;
 	__u32		sc_fpc_eir;	/* Unused */
 	__u32		sc_used_math;
+#ifndef CONFIG_CPU_R5900
 	__u32		sc_dsp;		/* dsp status, was sc_ssflags */
+#endif
 	__u64		sc_mdhi;
 	__u64		sc_mdlo;
 	__u32		sc_hi1;		/* Was sc_cause */
 	__u32		sc_lo1;		/* Was sc_badvaddr */
+#ifndef CONFIG_CPU_R5900
 	__u32		sc_hi2;		/* Was sc_sigset[4] */
 	__u32		sc_lo2;
 	__u32		sc_hi3;
 	__u32		sc_lo3;
+#endif
 };
 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32 */
 #endif /* _ASM_SIGCONTEXT_H */
diff --git a/arch/mips/include/uapi/asm/sigcontext.h b/arch/mips/include/uapi/asm/sigcontext.h
index 5cbd9ae6421f..7564ba82425a 100644
--- a/arch/mips/include/uapi/asm/sigcontext.h
+++ b/arch/mips/include/uapi/asm/sigcontext.h
@@ -40,15 +40,26 @@ struct sigcontext {
 	unsigned int		sc_fpc_csr;
 	unsigned int		sc_fpc_eir;	/* Unused */
 	unsigned int		sc_used_math;
+#ifdef CONFIG_CPU_R5900
+	unsigned int		pad0;
+#else
 	unsigned int		sc_dsp;		/* dsp status, was sc_ssflags */
+#endif
 	unsigned long long	sc_mdhi;
 	unsigned long long	sc_mdlo;
 	unsigned long		sc_hi1;		/* Was sc_cause */
 	unsigned long		sc_lo1;		/* Was sc_badvaddr */
+#ifdef CONFIG_CPU_R5900
+	unsigned long		pad1;
+	unsigned long		pad2;
+	unsigned long		pad3;
+	unsigned long		pad4;
+#else
 	unsigned long		sc_hi2;		/* Was sc_sigset[4] */
 	unsigned long		sc_lo2;
 	unsigned long		sc_hi3;
 	unsigned long		sc_lo3;
+#endif
 };
 
 #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
@@ -71,16 +82,22 @@ struct sigcontext {
 	__u64	sc_fpregs[32];
 	__u64	sc_mdhi;
 	__u64	sc_hi1;
+#ifndef CONFIG_CPU_R5900
 	__u64	sc_hi2;
 	__u64	sc_hi3;
+#endif
 	__u64	sc_mdlo;
 	__u64	sc_lo1;
+#ifndef CONFIG_CPU_R5900
 	__u64	sc_lo2;
 	__u64	sc_lo3;
+#endif
 	__u64	sc_pc;
 	__u32	sc_fpc_csr;
 	__u32	sc_used_math;
+#ifndef CONFIG_CPU_R5900
 	__u32	sc_dsp;
+#endif
 	__u32	sc_reserved;
 };
 
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c
index a670c0c11875..041ed07e7910 100644
--- a/arch/mips/kernel/asm-offsets.c
+++ b/arch/mips/kernel/asm-offsets.c
@@ -226,10 +226,12 @@ void output_sc_defines(void)
 	OFFSET(SC_FPC_EIR, sigcontext, sc_fpc_eir);
 	OFFSET(SC_HI1, sigcontext, sc_hi1);
 	OFFSET(SC_LO1, sigcontext, sc_lo1);
+#ifndef CONFIG_CPU_R5900
 	OFFSET(SC_HI2, sigcontext, sc_hi2);
 	OFFSET(SC_LO2, sigcontext, sc_lo2);
 	OFFSET(SC_HI3, sigcontext, sc_hi3);
 	OFFSET(SC_LO3, sigcontext, sc_lo3);
+#endif
 	BLANK();
 }
 #endif
diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c
index f702a459a830..b675c112aac3 100644
--- a/arch/mips/kernel/branch.c
+++ b/arch/mips/kernel/branch.c
@@ -416,9 +416,12 @@ int __MIPS16e_compute_return_epc(struct pt_regs *regs)
 int __compute_return_epc_for_insn(struct pt_regs *regs,
 				   union mips_instruction insn)
 {
-	unsigned int bit, fcr31, dspcontrol, reg;
+	unsigned int bit, fcr31, reg;
 	long epc = regs->cp0_epc;
 	int ret = 0;
+#ifndef CONFIG_CPU_R5900
+	unsigned int dspcontrol;
+#endif
 
 	switch (insn.i_format.opcode) {
 	/*
@@ -539,9 +542,12 @@ int __compute_return_epc_for_insn(struct pt_regs *regs,
 			break;
 
 		case bposge32_op:
+#ifndef CONFIG_CPU_R5900
 			if (!cpu_has_dsp)
+#endif
 				goto sigill_dsp;
 
+#ifndef CONFIG_CPU_R5900
 			dspcontrol = rddsp(0x01);
 
 			if (dspcontrol >= 32) {
@@ -549,6 +555,7 @@ int __compute_return_epc_for_insn(struct pt_regs *regs,
 			} else
 				epc += 8;
 			regs->cp0_epc = epc;
+#endif
 			break;
 		}
 		break;
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index 6931fe722a0b..c1b854542561 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -710,7 +710,7 @@ long arch_ptrace(struct task_struct *child, long request,
 			/* implementation / version register */
 			tmp = boot_cpu_data.fpu_id;
 			break;
-		case DSP_BASE ... DSP_BASE + 5: {
+		case DSP_BASE ... DSP_BASE + NUM_DSP_REGS - 1: {
 			dspreg_t *dregs;
 
 			if (!cpu_has_dsp) {
@@ -722,6 +722,7 @@ long arch_ptrace(struct task_struct *child, long request,
 			tmp = (unsigned long) (dregs[addr - DSP_BASE]);
 			break;
 		}
+#ifndef CONFIG_CPU_R5900
 		case DSP_CONTROL:
 			if (!cpu_has_dsp) {
 				tmp = 0;
@@ -730,6 +731,7 @@ long arch_ptrace(struct task_struct *child, long request,
 			}
 			tmp = child->thread.dsp.dspcontrol;
 			break;
+#endif
 		default:
 			tmp = 0;
 			ret = -EIO;
@@ -791,7 +793,7 @@ long arch_ptrace(struct task_struct *child, long request,
 			init_fp_ctx(child);
 			ptrace_setfcr31(child, data);
 			break;
-		case DSP_BASE ... DSP_BASE + 5: {
+		case DSP_BASE ... DSP_BASE + NUM_DSP_REGS - 1: {
 			dspreg_t *dregs;
 
 			if (!cpu_has_dsp) {
@@ -803,6 +805,7 @@ long arch_ptrace(struct task_struct *child, long request,
 			dregs[addr - DSP_BASE] = data;
 			break;
 		}
+#ifndef CONFIG_CPU_R5900
 		case DSP_CONTROL:
 			if (!cpu_has_dsp) {
 				ret = -EIO;
@@ -810,6 +813,7 @@ long arch_ptrace(struct task_struct *child, long request,
 			}
 			child->thread.dsp.dspcontrol = data;
 			break;
+#endif
 		default:
 			/* The rest are not allowed. */
 			ret = -EIO;
diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c
index 40e212d6b26b..232a28c94cce 100644
--- a/arch/mips/kernel/ptrace32.c
+++ b/arch/mips/kernel/ptrace32.c
@@ -132,7 +132,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 			/* implementation / version register */
 			tmp = boot_cpu_data.fpu_id;
 			break;
-		case DSP_BASE ... DSP_BASE + 5: {
+		case DSP_BASE ... DSP_BASE + NUM_DSP_REGS - 1: {
 			dspreg_t *dregs;
 
 			if (!cpu_has_dsp) {
@@ -144,6 +144,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 			tmp = (unsigned long) (dregs[addr - DSP_BASE]);
 			break;
 		}
+#ifndef CONFIG_CPU_R5900
 		case DSP_CONTROL:
 			if (!cpu_has_dsp) {
 				tmp = 0;
@@ -152,6 +153,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 			}
 			tmp = child->thread.dsp.dspcontrol;
 			break;
+#endif
 		default:
 			tmp = 0;
 			ret = -EIO;
@@ -230,7 +232,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 		case FPC_CSR:
 			child->thread.fpu.fcr31 = data;
 			break;
-		case DSP_BASE ... DSP_BASE + 5: {
+		case DSP_BASE ... DSP_BASE + NUM_DSP_REGS - 1: {
 			dspreg_t *dregs;
 
 			if (!cpu_has_dsp) {
@@ -242,6 +244,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 			dregs[addr - DSP_BASE] = data;
 			break;
 		}
+#ifndef CONFIG_CPU_R5900
 		case DSP_CONTROL:
 			if (!cpu_has_dsp) {
 				ret = -EIO;
@@ -249,6 +252,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 			}
 			child->thread.dsp.dspcontrol = data;
 			break;
+#endif
 		default:
 			/* The rest are not allowed. */
 			ret = -EIO;
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index 9e224469c788..3ca0f424c78b 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -426,11 +426,13 @@ int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
 	if (cpu_has_dsp) {
 		err |= __put_user(mfhi1(), &sc->sc_hi1);
 		err |= __put_user(mflo1(), &sc->sc_lo1);
+#ifndef CONFIG_CPU_R5900
 		err |= __put_user(mfhi2(), &sc->sc_hi2);
 		err |= __put_user(mflo2(), &sc->sc_lo2);
 		err |= __put_user(mfhi3(), &sc->sc_hi3);
 		err |= __put_user(mflo3(), &sc->sc_lo3);
 		err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
+#endif
 	}
 
 
@@ -503,11 +505,13 @@ int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
 	if (cpu_has_dsp) {
 		err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
 		err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
+#ifndef CONFIG_CPU_R5900
 		err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
 		err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
 		err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
 		err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
 		err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
+#endif
 	}
 
 	for (i = 1; i < 32; i++)
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 9979eb78c592..5b63fcc11733 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -1607,8 +1607,10 @@ asmlinkage void do_mt(struct pt_regs *regs)
 
 asmlinkage void do_dsp(struct pt_regs *regs)
 {
+#ifndef CONFIG_CPU_R5900
 	if (cpu_has_dsp)
 		panic("Unexpected DSP exception");
+#endif
 
 	force_sig(SIGILL, current);
 }


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

  Powered by Linux