[PATCHv4] Xilinx Virtex 4 FX Soft FPU support

2010-11-22 Thread Sergey Temerkhanov
This patch enables support for Xilinx Virtex 4 FX singe-float FPU. This patch 
enables support for Xilinx Virtex 4 FX singe-float FPU.

Changelog v3-v4
-Added help for CONFIG_XILINX_SOFTFPU option
-Made kernel math emulation dependent on !PPC_FPU.

Changelog v2-v3:
-Fixed whitespaces for SAVE_FPR/REST_FPR.
-Changed description of MSR_AP bit.
-Removed the stub for APU unavailable exception.

Changelog v1-v2:
-Added MSR_AP bit definition
-Renamed CONFIG_XILINX_FPU to CONFIG_XILINX_SOFTFPU, moved it to
 'Platform support' and made it Virtex4-FX-only.
-Changed SAVE_FPR/REST_FPR definition style.

Caveats:
- Hard-float binaries which rely on in-kernel math emulation will
give wrong results since they expect 64-bit double-precision instead
of 32-bit single-precision numbers which Xilinx V4-FX Soft FPU produces.


Signed-off-by: Sergey Temerkhanovtemerkha...@cifronik.ru

diff -r df25ff2b70a4 arch/powerpc/Kconfig
--- a/arch/powerpc/Kconfig  Fri Aug 27 21:10:12 2010 +0400
+++ b/arch/powerpc/Kconfig  Fri Sep 10 13:08:13 2010 +0400
@@ -293,7 +293,7 @@
 
 config MATH_EMULATION
bool Math emulation
-   depends on 4xx || 8xx || E200 || PPC_MPC832x || E500
+   depends on (4xx || 8xx || E200 || PPC_MPC832x || E500)  !PPC_FPU
---help---
  Some PowerPC chips designed for embedded applications do not have
  a floating-point unit and therefore do not implement the
diff -r df25ff2b70a4 arch/powerpc/include/asm/ppc_asm.h
--- a/arch/powerpc/include/asm/ppc_asm.hFri Aug 27 21:10:12 2010 +0400
+++ b/arch/powerpc/include/asm/ppc_asm.hFri Sep 10 13:08:13 2010 +0400
@@ -85,13 +85,21 @@
 #define REST_8GPRS(n, base)REST_4GPRS(n, base); REST_4GPRS(n+4, base)
 #define REST_10GPRS(n, base)   REST_8GPRS(n, base); REST_2GPRS(n+8, base)
 
-#define SAVE_FPR(n, base)  stfdn,THREAD_FPR0+8*TS_FPRWIDTH*(n)(base)
+
+#ifdef CONFIG_XILINX_SOFTFPU
+#define SAVE_FPR(n, base)  stfs n,THREAD_FPR0+8*TS_FPRWIDTH*(n)(base)
+#define REST_FPR(n, base)  lfs n,THREAD_FPR0+8*TS_FPRWIDTH*(n)(base)
+#else
+#define SAVE_FPR(n, base)  stfd n,THREAD_FPR0+8*TS_FPRWIDTH*(n)(base)
+#define REST_FPR(n, base)  lfd n,THREAD_FPR0+8*TS_FPRWIDTH*(n)(base)
+#endif
+
 #define SAVE_2FPRS(n, base)SAVE_FPR(n, base); SAVE_FPR(n+1, base)
 #define SAVE_4FPRS(n, base)SAVE_2FPRS(n, base); SAVE_2FPRS(n+2, base)
 #define SAVE_8FPRS(n, base)SAVE_4FPRS(n, base); SAVE_4FPRS(n+4, base)
 #define SAVE_16FPRS(n, base)   SAVE_8FPRS(n, base); SAVE_8FPRS(n+8, base)
 #define SAVE_32FPRS(n, base)   SAVE_16FPRS(n, base); SAVE_16FPRS(n+16, base)
-#define REST_FPR(n, base)  lfd n,THREAD_FPR0+8*TS_FPRWIDTH*(n)(base)
+
 #define REST_2FPRS(n, base)REST_FPR(n, base); REST_FPR(n+1, base)
 #define REST_4FPRS(n, base)REST_2FPRS(n, base); REST_2FPRS(n+2, base)
 #define REST_8FPRS(n, base)REST_4FPRS(n, base); REST_4FPRS(n+4, base)
diff -r df25ff2b70a4 arch/powerpc/include/asm/reg.h
--- a/arch/powerpc/include/asm/reg.hFri Aug 27 21:10:12 2010 +0400
+++ b/arch/powerpc/include/asm/reg.hFri Sep 10 13:08:13 2010 +0400
@@ -30,6 +30,7 @@
 #define MSR_ISF_LG 61  /* Interrupt 64b mode valid on 630 */
 #define MSR_HV_LG  60  /* Hypervisor state */
 #define MSR_VEC_LG 25  /* Enable AltiVec */
+#define MSR_AP_LG  25  /* Enable APU */
 #define MSR_VSX_LG 23  /* Enable VSX */
 #define MSR_POW_LG 18  /* Enable Power Management */
 #define MSR_WE_LG  18  /* Wait State Enable */
@@ -71,6 +72,7 @@
 #define MSR_HV 0
 #endif
 
+#define MSR_AP __MASK(MSR_AP_LG)   /* Enable APU */
 #define MSR_VEC__MASK(MSR_VEC_LG)  /* Enable AltiVec */
 #define MSR_VSX__MASK(MSR_VSX_LG)  /* Enable VSX */
 #define MSR_POW__MASK(MSR_POW_LG)  /* Enable Power 
Management */
diff -r df25ff2b70a4 arch/powerpc/kernel/fpu.S
--- a/arch/powerpc/kernel/fpu.S Fri Aug 27 21:10:12 2010 +0400
+++ b/arch/powerpc/kernel/fpu.S Fri Sep 10 13:08:13 2010 +0400
@@ -57,6 +57,9 @@
 _GLOBAL(load_up_fpu)
mfmsr   r5
ori r5,r5,MSR_FP
+#ifdef CONFIG_XILINX_SOFTFPU
+   orisr5,r5,msr...@h
+#endif
 #ifdef CONFIG_VSX
 BEGIN_FTR_SECTION
orisr5,r5,msr_...@h
@@ -85,6 +88,9 @@
toreal(r5)
PPC_LL  r4,_MSR-STACK_FRAME_OVERHEAD(r5)
li  r10,MSR_FP|MSR_FE0|MSR_FE1
+#ifdef CONFIG_XILINX_SOFTFPU
+   orisr10,r10,msr...@h
+#endif
andcr4,r4,r10   /* disable FP for previous task */
PPC_STL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
 1:
@@ -94,6 +100,9 @@
mfspr   r5,SPRN_SPRG_THREAD /* current task's THREAD (phys) 
*/
lwz r4,THREAD_FPEXC_MODE(r5)
ori r9,r9,MSR_FP/* enable FP for current */
+#ifdef CONFIG_XILINX_SOFTFPU
+   

[PATCHv4] Xilinx Virtex 4 FX Soft FPU support

2010-09-10 Thread Sergey Temerkhanov
This patch enables support for Xilinx Virtex 4 FX singe-float FPU. This patch 
enables support for Xilinx Virtex 4 FX singe-float FPU.

Changelog v3-v4
-Added help for CONFIG_XILINX_SOFTFPU option
-Made kernel math emulation dependent on !PPC_FPU.

Changelog v2-v3:
-Fixed whitespaces for SAVE_FPR/REST_FPR.
-Changed description of MSR_AP bit.
-Removed the stub for APU unavailable exception.

Changelog v1-v2:
-Added MSR_AP bit definition
-Renamed CONFIG_XILINX_FPU to CONFIG_XILINX_SOFTFPU, moved it to
 'Platform support' and made it Virtex4-FX-only.
-Changed SAVE_FPR/REST_FPR definition style.

Caveats:
- Hard-float binaries which rely on in-kernel math emulation will
give wrong results since they expect 64-bit double-precision instead
of 32-bit single-precision numbers which Xilinx V4-FX Soft FPU produces.


Signed-off-by: Sergey Temerkhanovtemerkha...@cifronik.ru

diff -r df25ff2b70a4 arch/powerpc/Kconfig
--- a/arch/powerpc/Kconfig  Fri Aug 27 21:10:12 2010 +0400
+++ b/arch/powerpc/Kconfig  Fri Sep 10 13:08:13 2010 +0400
@@ -293,7 +293,7 @@
 
 config MATH_EMULATION
bool Math emulation
-   depends on 4xx || 8xx || E200 || PPC_MPC832x || E500
+   depends on (4xx || 8xx || E200 || PPC_MPC832x || E500)  !PPC_FPU
---help---
  Some PowerPC chips designed for embedded applications do not have
  a floating-point unit and therefore do not implement the
diff -r df25ff2b70a4 arch/powerpc/include/asm/ppc_asm.h
--- a/arch/powerpc/include/asm/ppc_asm.hFri Aug 27 21:10:12 2010 +0400
+++ b/arch/powerpc/include/asm/ppc_asm.hFri Sep 10 13:08:13 2010 +0400
@@ -85,13 +85,21 @@
 #define REST_8GPRS(n, base)REST_4GPRS(n, base); REST_4GPRS(n+4, base)
 #define REST_10GPRS(n, base)   REST_8GPRS(n, base); REST_2GPRS(n+8, base)
 
-#define SAVE_FPR(n, base)  stfdn,THREAD_FPR0+8*TS_FPRWIDTH*(n)(base)
+
+#ifdef CONFIG_XILINX_SOFTFPU
+#define SAVE_FPR(n, base)  stfs n,THREAD_FPR0+8*TS_FPRWIDTH*(n)(base)
+#define REST_FPR(n, base)  lfs n,THREAD_FPR0+8*TS_FPRWIDTH*(n)(base)
+#else
+#define SAVE_FPR(n, base)  stfd n,THREAD_FPR0+8*TS_FPRWIDTH*(n)(base)
+#define REST_FPR(n, base)  lfd n,THREAD_FPR0+8*TS_FPRWIDTH*(n)(base)
+#endif
+
 #define SAVE_2FPRS(n, base)SAVE_FPR(n, base); SAVE_FPR(n+1, base)
 #define SAVE_4FPRS(n, base)SAVE_2FPRS(n, base); SAVE_2FPRS(n+2, base)
 #define SAVE_8FPRS(n, base)SAVE_4FPRS(n, base); SAVE_4FPRS(n+4, base)
 #define SAVE_16FPRS(n, base)   SAVE_8FPRS(n, base); SAVE_8FPRS(n+8, base)
 #define SAVE_32FPRS(n, base)   SAVE_16FPRS(n, base); SAVE_16FPRS(n+16, base)
-#define REST_FPR(n, base)  lfd n,THREAD_FPR0+8*TS_FPRWIDTH*(n)(base)
+
 #define REST_2FPRS(n, base)REST_FPR(n, base); REST_FPR(n+1, base)
 #define REST_4FPRS(n, base)REST_2FPRS(n, base); REST_2FPRS(n+2, base)
 #define REST_8FPRS(n, base)REST_4FPRS(n, base); REST_4FPRS(n+4, base)
diff -r df25ff2b70a4 arch/powerpc/include/asm/reg.h
--- a/arch/powerpc/include/asm/reg.hFri Aug 27 21:10:12 2010 +0400
+++ b/arch/powerpc/include/asm/reg.hFri Sep 10 13:08:13 2010 +0400
@@ -30,6 +30,7 @@
 #define MSR_ISF_LG 61  /* Interrupt 64b mode valid on 630 */
 #define MSR_HV_LG  60  /* Hypervisor state */
 #define MSR_VEC_LG 25  /* Enable AltiVec */
+#define MSR_AP_LG  25  /* Enable APU */
 #define MSR_VSX_LG 23  /* Enable VSX */
 #define MSR_POW_LG 18  /* Enable Power Management */
 #define MSR_WE_LG  18  /* Wait State Enable */
@@ -71,6 +72,7 @@
 #define MSR_HV 0
 #endif
 
+#define MSR_AP __MASK(MSR_AP_LG)   /* Enable APU */
 #define MSR_VEC__MASK(MSR_VEC_LG)  /* Enable AltiVec */
 #define MSR_VSX__MASK(MSR_VSX_LG)  /* Enable VSX */
 #define MSR_POW__MASK(MSR_POW_LG)  /* Enable Power 
Management */
diff -r df25ff2b70a4 arch/powerpc/kernel/fpu.S
--- a/arch/powerpc/kernel/fpu.S Fri Aug 27 21:10:12 2010 +0400
+++ b/arch/powerpc/kernel/fpu.S Fri Sep 10 13:08:13 2010 +0400
@@ -57,6 +57,9 @@
 _GLOBAL(load_up_fpu)
mfmsr   r5
ori r5,r5,MSR_FP
+#ifdef CONFIG_XILINX_SOFTFPU
+   orisr5,r5,msr...@h
+#endif
 #ifdef CONFIG_VSX
 BEGIN_FTR_SECTION
orisr5,r5,msr_...@h
@@ -85,6 +88,9 @@
toreal(r5)
PPC_LL  r4,_MSR-STACK_FRAME_OVERHEAD(r5)
li  r10,MSR_FP|MSR_FE0|MSR_FE1
+#ifdef CONFIG_XILINX_SOFTFPU
+   orisr10,r10,msr...@h
+#endif
andcr4,r4,r10   /* disable FP for previous task */
PPC_STL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
 1:
@@ -94,6 +100,9 @@
mfspr   r5,SPRN_SPRG_THREAD /* current task's THREAD (phys) 
*/
lwz r4,THREAD_FPEXC_MODE(r5)
ori r9,r9,MSR_FP/* enable FP for current */
+#ifdef CONFIG_XILINX_SOFTFPU
+