Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/arch/powerpc/powerpc/sig_machdep.c,v rcsdiff: /ftp/cvs/cvsroot/src/sys/arch/powerpc/powerpc/sig_machdep.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.5 retrieving revision 1.5.8.6 diff -u -p -r1.5 -r1.5.8.6 --- src/sys/arch/powerpc/powerpc/sig_machdep.c 2001/05/28 00:12:21 1.5 +++ src/sys/arch/powerpc/powerpc/sig_machdep.c 2002/06/24 22:07:12 1.5.8.6 @@ -1,4 +1,4 @@ -/* $NetBSD: sig_machdep.c,v 1.5 2001/05/28 00:12:21 matt Exp $ */ +/* $NetBSD: sig_machdep.c,v 1.5.8.6 2002/06/24 22:07:12 nathanw Exp $ */ /* * Copyright (C) 1995, 1996 Wolfgang Solfrank. @@ -32,14 +32,21 @@ */ #include "opt_compat_netbsd.h" +#include "opt_ppcarch.h" #include +#include #include #include +#include +#include #include #include +#include #include +#include + /* * Send a signal to process. */ @@ -50,12 +57,13 @@ sendsig(catcher, sig, mask, code) sigset_t *mask; u_long code; { - struct proc *p = curproc; + struct lwp *l = curlwp; + struct proc *p = l->l_proc; struct trapframe *tf; struct sigframe *fp, frame; int onstack; - tf = trapframe(p); + tf = trapframe(l); /* Do we need to jump onto the signal stack? */ onstack = @@ -98,7 +106,7 @@ sendsig(catcher, sig, mask, code) * Process has trashed its stack; give it an illegal * instructoin to halt it in its tracks. */ - sigexit(p, SIGILL); + sigexit(l, SIGILL); /* NOTREACHED */ } @@ -121,14 +129,15 @@ sendsig(catcher, sig, mask, code) * System call to cleanup state after a signal handler returns. */ int -sys___sigreturn14(p, v, retval) - struct proc *p; +sys___sigreturn14(l, v, retval) + struct lwp *l; void *v; register_t *retval; { struct sys___sigreturn14_args /* { syscallarg(struct sigcontext *) sigcntxp; } */ *uap = v; + struct proc *p = l->l_proc; struct sigcontext sc; struct trapframe *tf; int error; @@ -142,7 +151,7 @@ sys___sigreturn14(p, v, retval) return (error); /* Restore the register context. */ - tf = trapframe(p); + tf = trapframe(l); if ((sc.sc_frame.srr1 & PSL_USERSTATIC) != (tf->srr1 & PSL_USERSTATIC)) return (EINVAL); *tf = sc.sc_frame; @@ -158,3 +167,90 @@ sys___sigreturn14(p, v, retval) return (EJUSTRETURN); } + +void +cpu_getmcontext(l, mcp, flagp) + struct lwp *l; + mcontext_t *mcp; + unsigned int *flagp; +{ + const struct trapframe *tf = trapframe(l); + struct __gregs *gr = (struct __gregs *)mcp->__gregs; +#ifndef PPC_IBM4XX + struct pcb *pcb = &l->l_addr->u_pcb; +#endif + + /* Save GPR context. */ + (void)memcpy(gr, &tf->fixreg, 32 * sizeof (gr->__r_r0)); /* GR0-31 */ + gr->__r_cr = tf->cr; + gr->__r_lr = tf->lr; + gr->__r_pc = tf->srr0; + gr->__r_msr = tf->srr1; + gr->__r_ctr = tf->ctr; + gr->__r_xer = tf->xer; + gr->__r_mq = 0; /* For now. */ + *flagp |= _UC_CPU; + +#ifndef PPC_IBM4XX + /* Save FPR context, if any. */ + if ((pcb->pcb_flags & PCB_FPU) != 0) { + /* If we're the FPU owner, dump its context to the PCB first. */ + if (l == fpuproc) + save_fpu(l); + (void)memcpy(mcp->__fpregs.__fpu_regs, pcb->pcb_fpu.fpr, + sizeof (mcp->__fpregs.__fpu_regs)); + mcp->__fpregs.__fpu_fpscr = + ((int *)&pcb->pcb_fpu.fpscr)[_QUAD_LOWWORD]; + mcp->__fpregs.__fpu_valid = 1; + *flagp |= _UC_FPU; + } else +#endif + mcp->__fpregs.__fpu_valid = 0; + + /* No AltiVec support, for now. */ + memset(&mcp->__vrf, 0, sizeof (mcp->__vrf)); +} + +int +cpu_setmcontext(l, mcp, flags) + struct lwp *l; + const mcontext_t *mcp; + unsigned int flags; +{ + struct trapframe *tf = trapframe(l); + struct __gregs *gr = (struct __gregs *)mcp->__gregs; +#ifndef PPC_IBM4XX + struct pcb *pcb = &l->l_addr->u_pcb; +#endif + + /* Restore GPR context, if any. */ + if (flags & _UC_CPU) { + if ((gr->__r_msr & PSL_USERSTATIC) != + (tf->srr1 & PSL_USERSTATIC)) + return (EINVAL); + + (void)memcpy(&tf->fixreg, gr, 32 * sizeof (gr->__r_r0)); + tf->cr = gr->__r_cr; + tf->lr = gr->__r_lr; + tf->srr0 = gr->__r_pc; + tf->srr1 = gr->__r_msr; + tf->ctr = gr->__r_ctr; + tf->xer = gr->__r_xer; + /* unused = gr->__r_mq; */ + } + +#ifndef PPC_IBM4XX + /* Restore FPR context, if any. */ + if ((flags & _UC_FPU) && mcp->__fpregs.__fpu_valid != 0) { + (void)memcpy(&pcb->pcb_fpu.fpr, &mcp->__fpregs.__fpu_regs, + sizeof (pcb->pcb_fpu.fpr)); + pcb->pcb_fpu.fpscr = *(double *)&mcp->__fpregs.__fpu_fpscr; + + /* If we're the FPU owner, force a reload from the PCB. */ + if (l == fpuproc) + enable_fpu(l); + } +#endif + + return (0); +}