patch-2.4.22 linux-2.4.22/arch/mips64/kernel/ptrace.c
Next file: linux-2.4.22/arch/mips64/kernel/r4k_fpu.S
Previous file: linux-2.4.22/arch/mips64/kernel/process.c
Back to the patch index
Back to the overall index
- Lines: 245
- Date:
2003-08-25 04:44:40.000000000 -0700
- Orig file:
linux-2.4.21/arch/mips64/kernel/ptrace.c
- Orig date:
2002-11-28 15:53:10.000000000 -0800
diff -urN linux-2.4.21/arch/mips64/kernel/ptrace.c linux-2.4.22/arch/mips64/kernel/ptrace.c
@@ -23,6 +23,7 @@
#include <linux/user.h>
#include <asm/cpu.h>
+#include <asm/fpu.h>
#include <asm/mipsregs.h>
#include <asm/pgtable.h>
#include <asm/page.h>
@@ -112,34 +113,19 @@
break;
case FPR_BASE ... FPR_BASE + 31:
if (child->used_math) {
- unsigned long long *fregs
- = (unsigned long long *)
- &child->thread.fpu.hard.fp_regs[0];
- if (mips_cpu.options & MIPS_CPU_FPU) {
-#ifndef CONFIG_SMP
- if (last_task_used_math == child) {
- __enable_fpu();
- save_fp(child);
- __disable_fpu();
- last_task_used_math = NULL;
- }
-#endif
- } else {
- fregs = (unsigned long long *)
- child->thread.fpu.soft.regs;
- }
-
+ unsigned long long *fregs;
+ fregs = (unsigned long long *)get_fpu_regs(child);
/*
* The odd registers are actually the high
* order bits of the values stored in the even
- * registers.
+ * registers - unless we're using r2k_switch.S.
*/
if (addr & 1)
tmp = (unsigned long) (fregs[((addr & ~1) - 32)] >> 32);
else
tmp = (unsigned long) (fregs[(addr - 32)] & 0xffffffff);
} else {
- tmp = -EIO;
+ tmp = -1; /* FP not yet used */
}
break;
case PC:
@@ -158,13 +144,13 @@
tmp = regs->lo;
break;
case FPC_CSR:
- if (mips_cpu.options & MIPS_CPU_FPU)
+ if (cpu_has_fpu)
tmp = child->thread.fpu.hard.control;
else
tmp = child->thread.fpu.soft.sr;
break;
case FPC_EIR: { /* implementation / version register */
- unsigned int flags;
+ unsigned long flags;
__save_flags(flags);
__enable_fpu();
__asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
@@ -200,22 +186,8 @@
break;
case FPR_BASE ... FPR_BASE + 31: {
unsigned long long *fregs;
- fregs = (unsigned long long *)&child->thread.fpu.hard.fp_regs[0];
- if (child->used_math) {
-#ifndef CONFIG_SMP
- if (last_task_used_math == child)
- if (mips_cpu.options & MIPS_CPU_FPU) {
- __enable_fpu();
- save_fp(child);
- __disable_fpu();
- last_task_used_math = NULL;
- regs->cp0_status &= ~ST0_CU1;
- } else {
- fregs = (unsigned long long *)
- child->thread.fpu.soft.regs;
- }
-#endif
- } else {
+ fregs = (unsigned long long *)get_fpu_regs(child);
+ if (!child->used_math) {
/* FP not yet used */
memset(&child->thread.fpu.hard, ~0,
sizeof(child->thread.fpu.hard));
@@ -228,10 +200,12 @@
*/
if (addr & 1) {
fregs[(addr & ~1) - FPR_BASE] &= 0xffffffff;
- fregs[(addr & ~1) - FPR_BASE] |= ((unsigned long) data) << 32;
+ fregs[(addr & ~1) - FPR_BASE] |= ((unsigned long long) data) << 32;
} else {
fregs[addr - FPR_BASE] &= ~0xffffffffLL;
- fregs[addr - FPR_BASE] |= data;
+ /* Must cast, lest sign extension fill upper
+ bits! */
+ fregs[addr - FPR_BASE] |= (unsigned int)data;
}
break;
}
@@ -245,7 +219,7 @@
regs->lo = data;
break;
case FPC_CSR:
- if (mips_cpu.options & MIPS_CPU_FPU)
+ if (cpu_has_fpu)
child->thread.fpu.hard.control = data;
else
child->thread.fpu.soft.sr = data;
@@ -255,7 +229,7 @@
ret = -EIO;
break;
}
- goto out;
+ break;
}
case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
case PTRACE_CONT: { /* restart after signal. */
@@ -342,7 +316,7 @@
ret = -EPERM;
if (pid == 1) /* you may not mess with init */
- goto out;
+ goto out_tsk;
if (request == PTRACE_ATTACH) {
ret = ptrace_attach(child);
@@ -383,32 +357,8 @@
break;
case FPR_BASE ... FPR_BASE + 31:
if (child->used_math) {
- unsigned long long *fregs
- = (unsigned long long *)
- &child->thread.fpu.hard.fp_regs[0];
- if (mips_cpu.options & MIPS_CPU_FPU) {
-#ifndef CONFIG_SMP
- if (last_task_used_math == child) {
- __enable_fpu();
- save_fp(child);
- __disable_fpu();
- last_task_used_math = NULL;
- }
-#endif
- } else {
- fregs = (unsigned long long *)
- child->thread.fpu.soft.regs;
- }
-
- /*
- * The odd registers are actually the high
- * order bits of the values stored in the even
- * registers.
- */
- if (addr & 1)
- tmp = (unsigned long) (fregs[((addr & ~1) - 32)] >> 32);
- else
- tmp = (unsigned long) (fregs[(addr - 32)] & 0xffffffff);
+ unsigned long *fregs = get_fpu_regs(child);
+ tmp = fregs[addr - FPR_BASE];
} else {
tmp = -EIO;
}
@@ -429,13 +379,13 @@
tmp = regs->lo;
break;
case FPC_CSR:
- if (mips_cpu.options & MIPS_CPU_FPU)
+ if (cpu_has_fpu)
tmp = child->thread.fpu.hard.control;
else
tmp = child->thread.fpu.soft.sr;
break;
case FPC_EIR: { /* implementation / version register */
- unsigned int flags;
+ unsigned long flags;
__save_flags(flags);
__enable_fpu();
__asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
@@ -470,42 +420,14 @@
regs->regs[addr] = data;
break;
case FPR_BASE ... FPR_BASE + 31: {
- unsigned long long *fregs = (unsigned long long *)
- &child->thread.fpu.hard.fp_regs[0];
-
- if (child->used_math) {
-#ifndef CONFIG_SMP
- if (mips_cpu.options & MIPS_CPU_FPU) {
- if (last_task_used_math == child) {
- __enable_fpu();
- save_fp(child);
- __disable_fpu();
- last_task_used_math = NULL;
- regs->cp0_status &= ~ST0_CU1;
- } else {
- fregs = (unsigned long long *)
- child->thread.fpu.soft.regs;
- }
- }
-#endif
- } else {
+ unsigned long *fregs = get_fpu_regs(child);
+ if (!child->used_math) {
/* FP not yet used */
memset(&child->thread.fpu.hard, ~0,
sizeof(child->thread.fpu.hard));
child->thread.fpu.hard.control = 0;
}
- /*
- * The odd registers are actually the high order bits
- * of the values stored in the even registers - unless
- * we're using r2k_switch.S.
- */
- if (addr & 1) {
- fregs[(addr & ~1) - FPR_BASE] &= 0xffffffff;
- fregs[(addr & ~1) - FPR_BASE] |= ((unsigned long) data) << 32;
- } else {
- fregs[addr - FPR_BASE] &= ~0xffffffffLL;
- fregs[addr - FPR_BASE] |= data;
- }
+ fregs[addr - FPR_BASE] = data;
break;
}
case PC:
@@ -518,7 +440,7 @@
regs->lo = data;
break;
case FPC_CSR:
- if (mips_cpu.options & MIPS_CPU_FPU)
+ if (cpu_has_fpu)
child->thread.fpu.hard.control = data;
else
child->thread.fpu.soft.sr = data;
@@ -528,7 +450,7 @@
ret = -EIO;
break;
}
- goto out;
+ break;
}
case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
case PTRACE_CONT: { /* restart after signal. */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)