patch-2.3.48 linux/arch/mips/kernel/ptrace.c

Next file: linux/arch/mips/kernel/r2300_fpu.S
Previous file: linux/arch/mips/kernel/process.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.47/linux/arch/mips/kernel/ptrace.c linux/arch/mips/kernel/ptrace.c
@@ -1,4 +1,4 @@
-/* $Id: ptrace.c,v 1.13 1999/06/17 13:25:46 ralf Exp $
+/* $Id: ptrace.c,v 1.18 1999/10/09 00:00:58 ralf Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -30,6 +30,7 @@
 	struct task_struct *child;
 	unsigned int flags;
 	int res;
+	extern void save_fp(void*);
 
 	lock_kernel();
 #if 0
@@ -136,17 +137,13 @@
 			break;
 		case FPR_BASE ... FPR_BASE + 31:
 			if (child->used_math) {
-				unsigned long long *fregs;
-
 				if (last_task_used_math == child) {
 					enable_cp1();
-					r4xx0_save_fp(child);
+					save_fp(child);
 					disable_cp1();
 					last_task_used_math = NULL;
 				}
-				fregs = (unsigned long long *)
-					&child->tss.fpu.hard.fp_regs[0];
-				tmp = (unsigned long) fregs[(addr - 32)];
+				tmp = child->thread.fpu.hard.fp_regs[addr - 32];
 			} else {
 				tmp = -1;	/* FP not yet used  */
 			}
@@ -167,11 +164,17 @@
 			tmp = regs->lo;
 			break;
 		case FPC_CSR:
-			tmp = child->tss.fpu.hard.control;
+			tmp = child->thread.fpu.hard.control;
 			break;
-		case FPC_EIR:	/* implementation / version register */
-			tmp = 0;	/* XXX */
+		case FPC_EIR: {	/* implementation / version register */
+			unsigned int flags;
+
+			__save_flags(flags);
+			enable_cp1();
+			__asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
+			__restore_flags(flags);
 			break;
+		}
 		default:
 			tmp = 0;
 			res = -EIO;
@@ -191,33 +194,35 @@
 		goto out;
 
 	case PTRACE_POKEUSR: {
-		unsigned long long *fregs;
 		struct pt_regs *regs;
 		int res = 0;
+		regs = (struct pt_regs *) ((unsigned long) child +
+		       KERNEL_STACK_SIZE - 32 - sizeof(struct pt_regs));
 
 		switch (addr) {
 		case 0 ... 31:
-			regs = (struct pt_regs *) ((unsigned long) child +
-			       KERNEL_STACK_SIZE - 32 - sizeof(struct pt_regs));
+			regs->regs[addr] = data;
 			break;
-		case FPR_BASE ... FPR_BASE + 31:
+		case FPR_BASE ... FPR_BASE + 31: {
+			unsigned int *fregs;
 			if (child->used_math) {
 				if (last_task_used_math == child) {
 					enable_cp1();
-					r4xx0_save_fp(child);
+					save_fp(child);
 					disable_cp1();
 					last_task_used_math = NULL;
+					regs->cp0_status &= ~ST0_CU1;
 				}
 			} else {
 				/* FP not yet used  */
-				memset(&child->tss.fpu.hard, ~0,
-				       sizeof(child->tss.fpu.hard));
-				child->tss.fpu.hard.control = 0;
+				memset(&child->thread.fpu.hard, ~0,
+				       sizeof(child->thread.fpu.hard));
+				child->thread.fpu.hard.control = 0;
 			}
-			fregs = (unsigned long long *)
-				&child->tss.fpu.hard.fp_regs[0];
-			fregs[(addr - 32)] = (unsigned long long) data;
+			fregs = child->thread.fpu.hard.fp_regs;
+			fregs[addr - FPR_BASE] = data;
 			break;
+		}
 		case PC:
 			regs->cp0_epc = data;
 			break;
@@ -228,7 +233,7 @@
 			regs->lo = data;
 			break;
 		case FPC_CSR:
-			child->tss.fpu.hard.control = data;
+			child->thread.fpu.hard.control = data;
 			break;
 		default:
 			/* The rest are not allowed. */

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)