Math and AltiVec cleanup
PATCH 1/1 Math and AltiVec cleanup
Hi Dan,
This patch introduces CONFIG_MATH. CONFIG_MATH is set on PPC CPUs which have floating-point or if CONFIG_MATH_EMULATION is selected. Every piece of code in the kernel which depends on floating-point is now in a "#ifdef CONFIG_MATH" / "#endif" pair. Same goes for AltiVec.
Daniel Marmier
arch/ppc/config.in +5 -0
@@ -68,6 +68,11 @@ if [ "$CONFIG_4xx" = "y" -o "$CONFIG_8xx" = "y" ]; then bool 'Math emulation' CONFIG_MATH_EMULATION fi +if [ "$CONFIG_4xx" = "y" -o "$CONFIG_8xx" = "y" ]; then + define_bool CONFIG_MATH $CONFIG_MATH_EMULATION +else + define_bool CONFIG_MATH y +fi endmenu mainmenu_option next_comment
arch/ppc/kernel/align.c +4 -0
@@ -237,8 +237,10 @@return -EFAULT ;/* bad address */ } +#ifdef CONFIG_MATH if ((flags &F ) && (regs->msr &MSR_FP ))giveup_fpu (current); +#endif /* CONFIG_MATH */ if (flags &M )return 0 ;/* too hard for now */
@@ -285,6 +287,7 @@SWAP (data.v[1 ], data.v[2 ]); }break ; +#ifdef CONFIG_MATH case LD +F : current->thread.fpr[reg] = data.d;break ;
@@ -305,6 +308,7 @@cvt_df (¤t->thread.fpr[reg], &data.f, ¤t->thread.fpscr);/* data.f = current->thread.fpr[reg]; */ break ; +#endif /* CONFIG_MATH */ default :printk ("align: can't handle flags=%x\n" , flags);return 0 ;
arch/ppc/kernel/entry.S +11 -4
@@ -209,10 +209,17 @@ mflr r20 /* Return to switch caller */ mfmsr r22 li r0,MSR_FP /* Disable floating-point */ -#ifdef CONFIG_ALTIVEC - oris r0,r0,MSR_VEC@h -#endif /* CONFIG_ALTIVEC */ - andc r22,r22,r0 +#if defined(CONFIG_MATH) && defined(CONFIG_ALTIVEC) + li r0,MSR_FP /* Disable floating-point */ + oris r0,r0,MSR_VEC@h + andc r22,r22,r0 +#elif defined (CONFIG_MATH) + li r0,MSR_FP /* Disable floating-point */ + andc r22,r22,r0 +#elif defined(CONFIG_ALTIVEC) + lis r0,MSR_VEC@h + andc r22,r22,r0 +#endif stw r20,_NIP(r1) stw r22,_MSR(r1) stw r20,_LINK(r1)
arch/ppc/kernel/head_8xx.S +2 -0
@@ -612,9 +612,11 @@ SYNC rfi +#ifdef CONFIG_MATH .globl giveup_fpu giveup_fpu: blr +#endif /* * This code is jumped to from the startup code to copy
arch/ppc/kernel/mk_defs.c +2 -0
@@ -47,8 +47,10 @@DEFINE (PF_TRACESYS ,PF_TRACESYS );DEFINE (TASK_FLAGS , offsetof(struct task_struct , flags));DEFINE (NEED_RESCHED , offsetof(struct task_struct , need_resched)); +#ifdef CONFIG_MATH DEFINE(THREAD_FPR0, offsetof(struct thread_struct, fpr[0]));DEFINE (THREAD_FPSCR , offsetof(struct thread_struct , fpscr)); +#endif /* CONFIG_MATH */ #ifdef CONFIG_ALTIVEC DEFINE(THREAD_VR0, offsetof(struct thread_struct, vr[0]));DEFINE (THREAD_VRSAVE , offsetof(struct thread_struct , vrsave));
arch/ppc/kernel/process.c +42 -8
157 lines not on this page · raw message
arch/ppc/kernel/ptrace.c +4 -0
@@ -383,11 +383,13 @@if (addr <PT_FPR0 ) { tmp =get_reg (child, addr); } +#ifdef CONFIG_MATH else if (addr >= PT_FPR0 && addr <= PT_FPSCR) {if (child->thread.regs->msr &MSR_FP )giveup_fpu (child); tmp = ((long *)child->thread.fpr)[addr -PT_FPR0 ]; } +#endif /* CONFIG_MATH */ else ret = -EIO ;if (!ret)
@@ -418,6 +420,7 @@ ret =0 ; goto out; } +#ifdef CONFIG_MATH if (addr >=PT_FPR0 && addr <PT_FPR0 +64 ) {if (child->thread.regs->msr &MSR_FP )giveup_fpu (child);
@@ -425,6 +428,7 @@ ret =0 ; goto out; } +#endif /* CONFIG_MATH */ goto out;case PTRACE_SYSCALL :/* continue and stop at next (return from) syscall */
arch/ppc/kernel/signal.c +10 -2
@@ -218,8 +218,10 @@if (sc == (struct sigcontext_struct *)(sigctx.regs)) {/* Last stacked signal - restore registers */ sr = (struct sigregs *) sigctx.regs; +#ifdef CONFIG_MATH if (regs->msr &MSR_FP )giveup_fpu (current); +#endif /* CONFIG_MATH */ if (copy_from_user (saved_regs, &sr->gp_regs,sizeof (sr->gp_regs))) goto badframe;
@@ -227,9 +229,11 @@ | (saved_regs[PT_MSR] & MSR_USERCHANGE);memcpy (regs, saved_regs,GP_REGS_SIZE ); +#ifdef CONFIG_MATH if (copy_from_user (current->thread.fpr, &sr->fp_regs,sizeof (sr->fp_regs))) goto badframe; +#endif /* CONFIG_MATH */ ret = regs->result;
@@ -266,11 +270,15 @@if (verify_area (VERIFY_WRITE , frame,sizeof (*frame))) goto badframe; -if (regs->msr &MSR_FP ) -giveup_fpu (current); +#ifdef CONFIG_MATH +if (regs->msr &MSR_FP ) +giveup_fpu (current); +#endif /* CONFIG_MATH */ if (__copy_to_user (&frame->gp_regs, regs,GP_REGS_SIZE ) +#ifdef CONFIG_MATH ||__copy_to_user (&frame->fp_regs, current->thread.fpr,ELF_NFPREG *sizeof (double )) +#endif /* CONFIG_MATH */ ||__put_user (0x38007777UL , &frame->tramp[0 ])/* li r0,0x7777 */ ||__put_user (0x44000002UL , &frame->tramp[1 ]))/* sc */ goto badframe;
arch/ppc/kernel/traps.c +2 -0
@@ -214,8 +214,10 @@ {int fixed; +#ifdef CONFIG_MATH if (regs->msr &MSR_FP )giveup_fpu (current); +#endif /* CONFIG_MATH */ fixed =fix_alignment (regs);if (fixed ==1 ) { regs->nip +=4 ;/* skip over emulated instruction */
arch/ppc/mm/init.c +2 -0
@@ -309,12 +309,14 @@ printk("current"); } +#ifdef CONFIG_MATH if ( p == last_task_used_math ) {if ( iscur )printk ("," );printk ("last math" ); } +#endif /* CONFIG_MATH */ #endif /* __SMP__ */ printk ("\n" ); }
include/asm-ppc/elf.h +9 -0
@@ -4,11 +4,20 @@/* * ELF register definitions.. */ +#include <linux/config.h> #include <asm/ptrace.h> #define ELF_NGREG 48/* includes nip, msr, lr, etc. */ +#ifdef CONFIG_MATH #define ELF_NFPREG 33/* includes fpscr */ +#else +#define ELF_NFPREG 0 +#endif /* CONFIG_MATH */ +#ifdef CONFIG_ALTIVEC #define ELF_NVRREG 33/* includes vscr */ +#else +#define ELF_NVRREG 0 +#endif /* CONFIG_ALTIVEC */ /* * This is used to ensure we don't load something for the wrong architecture.
include/asm-ppc/processor.h +6 -1
@@ -596,8 +596,12 @@#define MCA_bus__is_a_macro/* for versions in ksyms.c */ /* Lazy FPU handling on uni-processor */ +#ifdef CONFIG_MATH extern struct task_struct *last_task_used_math; +#endif /* CONFIG_MATH */ +#ifdef CONFIG_ALTIVEC extern struct task_struct *last_task_used_altivec; +#endif /* CONFIG_ALTIVEC */ /* * this is the minimum allowable io space due to the location
@@ -623,9 +627,11 @@mm_segment_t fs;/* for get_fs() validation */ void *pgdir;/* root of page-table tree */ signed long last_syscall; +#ifdef CONFIG_MATH double fpr[32 ];/* Complete floating point set */ unsigned long fpscr_pad;/* fpr ... fpscr must be contiguous */ unsigned long fpscr;/* Floating point status */ +#endif /* CONFIG_MATH */ #ifdef CONFIG_ALTIVEC vector128 vr[32 ];/* Complete AltiVec set */ vector128 vscr;/* AltiVec status */
@@ -642,7 +648,6 @@KERNEL_DS ,/*fs*/ \ swapper_pg_dir,/* pgdir */ \ 0, /* last_syscall */ \ - {0}, 0, 0 \ }/*
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/