diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2005-12-17 16:08:36 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2005-12-17 16:08:36 +0000 |
commit | 1efabd602581b7ac811d1f628d9d9f1d8bcfa096 (patch) | |
tree | dea8703d6bdfdec9e4254b0014de1d4438429f93 | |
parent | 00f8cc47ebb95c2a6d74080b7ad654e8db039c4a (diff) |
Fix PT_{GET|SET}FPREGS. Make sure we flush the fpu before reading/modifying
the state in the pcb. Make sure we don't thrash the initial fpu state for
(currently unsupported) 32-bit processes.
ok miod@
-rw-r--r-- | sys/arch/sparc64/sparc64/process_machdep.c | 48 |
1 files changed, 26 insertions, 22 deletions
diff --git a/sys/arch/sparc64/sparc64/process_machdep.c b/sys/arch/sparc64/sparc64/process_machdep.c index 2053ff0fb2b..221ba392a41 100644 --- a/sys/arch/sparc64/sparc64/process_machdep.c +++ b/sys/arch/sparc64/sparc64/process_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: process_machdep.c,v 1.8 2005/12/16 21:37:05 miod Exp $ */ +/* $OpenBSD: process_machdep.c,v 1.9 2005/12/17 16:08:35 kettenis Exp $ */ /* $NetBSD: process_machdep.c,v 1.10 2000/09/26 22:05:50 eeh Exp $ */ /* @@ -117,22 +117,24 @@ process_read_fpregs(p, regs) struct fpreg *regs; { extern struct fpstate64 initfpstate; - struct fpstate64 *statep = &initfpstate; - struct fpreg32 *regp = (struct fpreg32 *)regs; + struct fpstate64 *statep = &initfpstate; + struct fpreg32 *regp = (struct fpreg32 *)regs; int i; + /* NOTE: struct fpreg == struct fpstate */ + if (p->p_md.md_fpstate) { + if (p == fpproc) + savefpstate(p->p_md.md_fpstate); + statep = p->p_md.md_fpstate; + } + if (!(curproc->p_flag & P_32)) { /* 64-bit mode -- copy in fregs */ - /* NOTE: struct fpreg == struct fpstate */ - if (p->p_md.md_fpstate) - statep = p->p_md.md_fpstate; bcopy(statep, regs, sizeof(struct fpreg64)); return 0; } /* 32-bit mode -- copy out & convert 32-bit fregs */ - if (p->p_md.md_fpstate) - statep = p->p_md.md_fpstate; - for (i=0; i<32; i++) + for (i = 0; i < 32; i++) regp->fr_regs[i] = statep->fs_regs[i]; return 0; @@ -205,27 +207,29 @@ process_write_fpregs(p, regs) struct proc *p; struct fpreg *regs; { - - extern struct fpstate64 initfpstate; - struct fpstate64 *statep = &initfpstate; - struct fpreg32 *regp = (struct fpreg32 *)regs; + struct fpstate64 *statep; + struct fpreg32 *regp = (struct fpreg32 *)regs; int i; + if (p->p_md.md_fpstate == NULL) + return EINVAL; + else + statep = p->p_md.md_fpstate; + + if (p == fpproc) { + /* Release the fpu. */ + savefpstate(p->p_md.md_fpstate); + fpproc = NULL; + } + if (!(curproc->p_flag & P_32)) { /* 64-bit mode -- copy in fregs */ - if (p->p_md.md_fpstate == NULL) - return EINVAL; - - /* NOTE: struct fpreg == struct fpstate */ - bcopy(regs, p->p_md.md_fpstate, sizeof(struct fpreg64)); - statep = p->p_md.md_fpstate; + bcopy(regs, statep, sizeof(struct fpreg64)); statep->fs_qsize = 0; return 0; } /* 32-bit mode -- copy in & convert 32-bit fregs */ - if (p->p_md.md_fpstate) - statep = p->p_md.md_fpstate; - for (i=0; i<32; i++) + for (i = 0; i < 32; i++) statep->fs_regs[i] = regp->fr_regs[i]; statep->fs_fsr = regp->fr_fsr; statep->fs_qsize = 0; |