summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2006-05-15 21:02:45 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2006-05-15 21:02:45 +0000
commit5940aca5d72dfea8a5dcd50b8578c67f6369f380 (patch)
treef1816db5407dd4b1b49b55c19f47a4cc0f7442d3
parent35e8a265b9c183213211836eca2dfdd91922cd67 (diff)
Implement PT_{GET|SET}FPREGS.
"looks good to me" miod@, ok drahn@
-rw-r--r--sys/arch/powerpc/include/ptrace.h5
-rw-r--r--sys/arch/powerpc/powerpc/process_machdep.c38
2 files changed, 38 insertions, 5 deletions
diff --git a/sys/arch/powerpc/include/ptrace.h b/sys/arch/powerpc/include/ptrace.h
index 7190d31d4a2..d1dd1018a33 100644
--- a/sys/arch/powerpc/include/ptrace.h
+++ b/sys/arch/powerpc/include/ptrace.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ptrace.h,v 1.2 1998/08/07 02:22:05 rahnds Exp $ */
+/* $OpenBSD: ptrace.h,v 1.3 2006/05/15 21:02:44 kettenis Exp $ */
/* $NetBSD: ptrace.h,v 1.7 1995/01/26 19:47:10 mycroft Exp $ */
/*
@@ -39,10 +39,7 @@
#define PT_STEP (PT_FIRSTMACH + 0)
#define PT_GETREGS (PT_FIRSTMACH + 1)
#define PT_SETREGS (PT_FIRSTMACH + 2)
-
-#if NOT_SUPPORTED
#define PT_GETFPREGS (PT_FIRSTMACH + 3)
#define PT_SETFPREGS (PT_FIRSTMACH + 4)
-#endif
#endif /* !_POWERPC_PTRACE_H_ */
diff --git a/sys/arch/powerpc/powerpc/process_machdep.c b/sys/arch/powerpc/powerpc/process_machdep.c
index b7815091c3d..bdba319e20f 100644
--- a/sys/arch/powerpc/powerpc/process_machdep.c
+++ b/sys/arch/powerpc/powerpc/process_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: process_machdep.c,v 1.10 2005/10/09 14:52:12 drahn Exp $ */
+/* $OpenBSD: process_machdep.c,v 1.11 2006/05/15 21:02:44 kettenis Exp $ */
/* $NetBSD: process_machdep.c,v 1.1 1996/09/30 16:34:53 ws Exp $ */
/*
@@ -69,6 +69,24 @@ process_read_regs(struct proc *p, struct reg *regs)
return (0);
}
+int
+process_read_fpregs(struct proc *p, struct fpreg *regs)
+{
+ struct pcb *pcb = &p->p_addr->u_pcb;
+
+ if (!(pcb->pcb_flags & PCB_FPU)) {
+ bzero(regs->fpr, sizeof(regs->fpr));
+ regs->fpscr = 0;
+ } else {
+ if (p == fpuproc)
+ save_fpu();
+ bcopy(pcb->pcb_fpu.fpr, regs->fpr, sizeof(regs->fpr));
+ regs->fpscr = *(u_int64_t *)&pcb->pcb_fpu.fpcsr;
+ }
+
+ return (0);
+}
+
#ifdef PTRACE
/*
@@ -125,4 +143,22 @@ process_write_regs(struct proc *p, struct reg *regs)
return (0);
}
+int
+process_write_fpregs(struct proc *p, struct fpreg *regs)
+{
+ struct pcb *pcb = &p->p_addr->u_pcb;
+ u_int64_t fpscr = regs->fpscr;
+
+ if (p == fpuproc) { /* release the fpu */
+ save_fpu();
+ fpuproc = NULL;
+ }
+
+ bcopy(regs->fpr, pcb->pcb_fpu.fpr, sizeof(regs->fpr));
+ pcb->pcb_fpu.fpcsr = *(double *)&fpscr;
+ pcb->pcb_flags |= PCB_FPU;
+
+ return (0);
+}
+
#endif /* PTRACE */