[PATCHv4] Xilinx Virtex 4 FX Soft FPU support
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
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 +