[MIPS] Add basic SMARTMIPS ASE support

This patch adds trivial support for SMARTMIPS extension. This extension
is currently implemented by 4KS[CD] CPUs.

Basically it saves/restores ACX register, which is part of the SMARTMIPS
ASE, when needed. This patch does *not* add any support for Smartmips MMU
features.

Futhermore this patch does not add explicit support for 4KS[CD] CPUs since
they are respectively mips32 and mips32r2 compliant.  So with the current
processor configuration, a platform that has such CPUs needs to select
both configs:

	CPU_HAS_SMARTMIPS
	SYS_HAS_CPU_MIPS32_R[12]

This is due to the processor configuration which is mixing up all the
architecture variants and the processor types.

The drawback of this, is that we currently pass '-march=mips32' option to
gcc when building a kernel instead of '-march=4ksc' for 4KSC case. This
can lead to a kernel image a little bit bigger than required.

Signed-off-by: Franck Bui-Huu <fbuihuu@gmail.com>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
diff --git a/include/asm-mips/ptrace.h b/include/asm-mips/ptrace.h
index 8a1f2b6..1906938 100644
--- a/include/asm-mips/ptrace.h
+++ b/include/asm-mips/ptrace.h
@@ -21,6 +21,7 @@
 #define FPC_EIR		70
 #define DSP_BASE	71		/* 3 more hi / lo register pairs */
 #define DSP_CONTROL	77
+#define ACX		78
 
 /*
  * This struct defines the way the registers are stored on the stack during a
@@ -39,6 +40,9 @@
 	unsigned long cp0_status;
 	unsigned long hi;
 	unsigned long lo;
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+	unsigned long acx;
+#endif
 	unsigned long cp0_badvaddr;
 	unsigned long cp0_cause;
 	unsigned long cp0_epc;
diff --git a/include/asm-mips/sigcontext.h b/include/asm-mips/sigcontext.h
index 9729474..9ce0607 100644
--- a/include/asm-mips/sigcontext.h
+++ b/include/asm-mips/sigcontext.h
@@ -23,7 +23,7 @@
 	unsigned long long	sc_pc;
 	unsigned long long	sc_regs[32];
 	unsigned long long	sc_fpregs[32];
-	unsigned int		sc_ownedfp;	/* Unused */
+	unsigned int		sc_acx;		/* Was sc_ownedfp */
 	unsigned int		sc_fpc_csr;
 	unsigned int		sc_fpc_eir;	/* Unused */
 	unsigned int		sc_used_math;
@@ -79,7 +79,7 @@
 	__u64		sc_pc;
 	__u64		sc_regs[32];
 	__u64		sc_fpregs[32];
-	__u32		sc_ownedfp;	/* Unused */
+	__u32		sc_acx;		/* Only MIPS32; was sc_ownedfp */
 	__u32		sc_fpc_csr;
 	__u32		sc_fpc_eir;	/* Unused */
 	__u32		sc_used_math;
diff --git a/include/asm-mips/stackframe.h b/include/asm-mips/stackframe.h
index 1fae5dc..7afa1fd 100644
--- a/include/asm-mips/stackframe.h
+++ b/include/asm-mips/stackframe.h
@@ -29,16 +29,25 @@
 		.endm
 
 		.macro	SAVE_TEMP
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+		mflhxu	v1
+		LONG_S	v1, PT_LO(sp)
+		mflhxu	v1
+		LONG_S	v1, PT_HI(sp)
+		mflhxu	v1
+		LONG_S	v1, PT_ACX(sp)
+#else
 		mfhi	v1
+		LONG_S	v1, PT_HI(sp)
+		mflo	v1
+		LONG_S	v1, PT_LO(sp)
+#endif
 #ifdef CONFIG_32BIT
 		LONG_S	$8, PT_R8(sp)
 		LONG_S	$9, PT_R9(sp)
 #endif
-		LONG_S	v1, PT_HI(sp)
-		mflo	v1
 		LONG_S	$10, PT_R10(sp)
 		LONG_S	$11, PT_R11(sp)
-		LONG_S	v1,  PT_LO(sp)
 		LONG_S	$12, PT_R12(sp)
 		LONG_S	$13, PT_R13(sp)
 		LONG_S	$14, PT_R14(sp)
@@ -182,16 +191,25 @@
 		.endm
 
 		.macro	RESTORE_TEMP
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+		LONG_L	$24, PT_ACX(sp)
+		mtlhx	$24
+		LONG_L	$24, PT_HI(sp)
+		mtlhx	$24
 		LONG_L	$24, PT_LO(sp)
+		mtlhx	$24
+#else
+		LONG_L	$24, PT_LO(sp)
+		mtlo	$24
+		LONG_L	$24, PT_HI(sp)
+		mthi	$24
+#endif
 #ifdef CONFIG_32BIT
 		LONG_L	$8, PT_R8(sp)
 		LONG_L	$9, PT_R9(sp)
 #endif
-		mtlo	$24
-		LONG_L	$24, PT_HI(sp)
 		LONG_L	$10, PT_R10(sp)
 		LONG_L	$11, PT_R11(sp)
-		mthi	$24
 		LONG_L	$12, PT_R12(sp)
 		LONG_L	$13, PT_R13(sp)
 		LONG_L	$14, PT_R14(sp)