Skip to contentSkip to conversation

Math and AltiVec cleanup

PATCH New Daniel Marmier 1 participant 1 message Apr 18, 2000 ptrace support

lore
Share & tools
lore
#0 lore raw

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
diff -urN linux-2.3.99-pre5/arch/ppc/config.in linux-2.3.99-pre5-dm/arch/ppc/config.in
@@ -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
diff -urN linux-2.3.99-pre5/arch/ppc/kernel/align.c linux-2.3.99-pre5-dm/arch/ppc/kernel/align.c
@@ -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(&current->thread.fpr[reg], &data.f, &current->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
diff -urN linux-2.3.99-pre5/arch/ppc/kernel/entry.S linux-2.3.99-pre5-dm/arch/ppc/kernel/entry.S
@@ -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
diff -urN linux-2.3.99-pre5/arch/ppc/kernel/head_8xx.S linux-2.3.99-pre5-dm/arch/ppc/kernel/head_8xx.S
@@ -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
diff -urN linux-2.3.99-pre5/arch/ppc/kernel/mk_defs.c linux-2.3.99-pre5-dm/arch/ppc/kernel/mk_defs.c
@@ -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
diff -urN linux-2.3.99-pre5/arch/ppc/kernel/ptrace.c linux-2.3.99-pre5-dm/arch/ppc/kernel/ptrace.c
@@ -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
diff -urN linux-2.3.99-pre5/arch/ppc/kernel/signal.c linux-2.3.99-pre5-dm/arch/ppc/kernel/signal.c
@@ -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
diff -urN linux-2.3.99-pre5/arch/ppc/kernel/traps.c linux-2.3.99-pre5-dm/arch/ppc/kernel/traps.c
@@ -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
diff -urN linux-2.3.99-pre5/arch/ppc/mm/init.c linux-2.3.99-pre5-dm/arch/ppc/mm/init.c
@@ -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
diff -urN linux-2.3.99-pre5/include/asm-ppc/elf.h linux-2.3.99-pre5-dm/include/asm-ppc/elf.h
@@ -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
diff -urN linux-2.3.99-pre5/include/asm-ppc/processor.h linux-2.3.99-pre5-dm/include/asm-ppc/processor.h
@@ -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/