patch-2.4.19 linux-2.4.19/arch/mips64/kernel/ptrace.c
Next file: linux-2.4.19/arch/mips64/kernel/r4k_genex.S
Previous file: linux-2.4.19/arch/mips64/kernel/process.c
Back to the patch index
Back to the overall index
- Lines: 234
- Date:
Fri Aug 2 17:39:43 2002
- Orig file:
linux-2.4.18/arch/mips64/kernel/ptrace.c
- Orig date:
Tue Sep 18 16:56:19 2001
diff -urN linux-2.4.18/arch/mips64/kernel/ptrace.c linux-2.4.19/arch/mips64/kernel/ptrace.c
@@ -22,11 +22,13 @@
#include <linux/smp_lock.h>
#include <linux/user.h>
+#include <asm/cpu.h>
#include <asm/mipsregs.h>
#include <asm/pgtable.h>
#include <asm/page.h>
#include <asm/system.h>
#include <asm/uaccess.h>
+#include <asm/bootinfo.h>
/*
* Called by kernel/ptrace.c when detaching..
@@ -75,15 +77,11 @@
ret = ptrace_attach(child);
goto out_tsk;
}
- ret = -ESRCH;
- if (!(child->ptrace & PT_PTRACED))
- goto out_tsk;
- if (child->state != TASK_STOPPED) {
- if (request != PTRACE_KILL)
- goto out_tsk;
- }
- if (child->p_pptr != current)
+
+ ret = ptrace_check_attach(child, request == PTRACE_KILL);
+ if (ret < 0)
goto out_tsk;
+
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -114,17 +112,23 @@
break;
case FPR_BASE ... FPR_BASE + 31:
if (child->used_math) {
- unsigned long *fregs =
- (void *) child->thread.fpu.hard.fp_regs;
-
+ 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) {
- set_cp0_status(ST0_CU1, ST0_CU1);
- save_fp(child);
- set_cp0_status(ST0_CU1, 0);
- last_task_used_math = NULL;
- }
+ 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
@@ -154,12 +158,15 @@
tmp = regs->lo;
break;
case FPC_CSR:
- tmp = child->thread.fpu.hard.control;
+ if (mips_cpu.options & MIPS_CPU_FPU)
+ tmp = child->thread.fpu.hard.control;
+ else
+ tmp = child->thread.fpu.soft.sr;
break;
case FPC_EIR: { /* implementation / version register */
unsigned int flags;
__save_flags(flags);
- set_cp0_status(ST0_CU1, ST0_CU1);
+ __enable_fpu();
__asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
__restore_flags(flags);
break;
@@ -192,17 +199,21 @@
regs->regs[addr] = data;
break;
case FPR_BASE ... FPR_BASE + 31: {
- unsigned long *fregs =
- (void *) child->thread.fpu.hard.fp_regs;
+ 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) {
- set_cp0_status(ST0_CU1, ST0_CU1);
- save_fp(child);
- set_cp0_status(ST0_CU1, 0);
- last_task_used_math = NULL;
- regs->cp0_status &= ~ST0_CU1;
- }
+ 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 {
/* FP not yet used */
@@ -234,7 +245,10 @@
regs->lo = data;
break;
case FPC_CSR:
- child->thread.fpu.hard.control = data;
+ if (mips_cpu.options & MIPS_CPU_FPU)
+ child->thread.fpu.hard.control = data;
+ else
+ child->thread.fpu.soft.sr = data;
break;
default:
/* The rest are not allowed. */
@@ -334,14 +348,9 @@
ret = ptrace_attach(child);
goto out_tsk;
}
- ret = -ESRCH;
- if (!(child->ptrace & PT_PTRACED))
- goto out_tsk;
- if (child->state != TASK_STOPPED) {
- if (request != PTRACE_KILL)
- goto out_tsk;
- }
- if (child->p_pptr != current)
+
+ ret = ptrace_check_attach(child, request == PTRACE_KILL);
+ if (ret < 0)
goto out_tsk;
switch (request) {
@@ -377,14 +386,20 @@
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) {
- set_cp0_status(ST0_CU1, ST0_CU1);
- save_fp(child);
- set_cp0_status(ST0_CU1, 0);
- last_task_used_math = NULL;
- }
+ 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
@@ -414,12 +429,15 @@
tmp = regs->lo;
break;
case FPC_CSR:
- tmp = child->thread.fpu.hard.control;
+ if (mips_cpu.options & MIPS_CPU_FPU)
+ tmp = child->thread.fpu.hard.control;
+ else
+ tmp = child->thread.fpu.soft.sr;
break;
case FPC_EIR: { /* implementation / version register */
unsigned int flags;
__save_flags(flags);
- set_cp0_status(ST0_CU1, ST0_CU1);
+ __enable_fpu();
__asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
__restore_flags(flags);
break;
@@ -452,16 +470,22 @@
regs->regs[addr] = data;
break;
case FPR_BASE ... FPR_BASE + 31: {
- unsigned long *fregs =
- (void *) child->thread.fpu.hard.fp_regs;
+ unsigned long long *fregs = (unsigned long long *)
+ &child->thread.fpu.hard.fp_regs[0];
+
if (child->used_math) {
#ifndef CONFIG_SMP
- if (last_task_used_math == child) {
- set_cp0_status(ST0_CU1, ST0_CU1);
- save_fp(child);
- set_cp0_status(ST0_CU1, 0);
- last_task_used_math = NULL;
- regs->cp0_status &= ~ST0_CU1;
+ 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 {
@@ -494,7 +518,10 @@
regs->lo = data;
break;
case FPC_CSR:
- child->thread.fpu.hard.control = data;
+ if (mips_cpu.options & MIPS_CPU_FPU)
+ child->thread.fpu.hard.control = data;
+ else
+ child->thread.fpu.soft.sr = 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)