summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorMichael Shalayeff <mickey@cvs.openbsd.org>2003-05-18 15:57:48 +0000
committerMichael Shalayeff <mickey@cvs.openbsd.org>2003-05-18 15:57:48 +0000
commit0104529bd466688238c5b5bc13cc1adcf0a5a682 (patch)
treef392f92ae34f837ee797809733c172fad912bdc4 /sys/arch
parent2445b5bb89a257c9aec8e304a44845476b289008 (diff)
save the fpu state for the signal handler. this is essential
as the fpu regs can be used by the gcc even for non-fpu means and data copying. rearrange the sigcontext a bit to include only the general registers that are needed restoring upon return and thus less waste of space and make up some space for the fpu regs. ALL software that used the signal context on the stack needs at least rebuilding now. a new snap has bin built as well.
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/hppa/hppa/machdep.c142
-rw-r--r--sys/arch/hppa/include/signal.h8
2 files changed, 93 insertions, 57 deletions
diff --git a/sys/arch/hppa/hppa/machdep.c b/sys/arch/hppa/hppa/machdep.c
index 9e01828a49a..d860fc9feec 100644
--- a/sys/arch/hppa/hppa/machdep.c
+++ b/sys/arch/hppa/hppa/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.104 2003/05/11 19:41:09 deraadt Exp $ */
+/* $OpenBSD: machdep.c,v 1.105 2003/05/18 15:57:46 mickey Exp $ */
/*
* Copyright (c) 1999-2002 Michael Shalayeff
@@ -1173,7 +1173,7 @@ setregs(p, pack, stack, retval)
#ifdef DEBUG
/*extern int pmapdebug;*/
/*pmapdebug = 13;
- printf("setregs(%p, %p, %x, %p), ep=%x, cr30=%x\n",
+ printf("setregs(%p, %p, 0x%x, %p), ep=0x%x, cr30=0x%x\n",
p, pack, stack, retval, pack->ep_entry, tf->tf_cr30);
*/
#endif
@@ -1218,6 +1218,7 @@ sendsig(catcher, sig, mask, code, type, val)
int type;
union sigval val;
{
+ extern paddr_t fpu_curpcb; /* from locore.S */
struct proc *p = curproc;
struct trapframe *tf = p->p_md.md_regs;
struct sigacts *psp = p->p_sigacts;
@@ -1232,6 +1233,12 @@ sendsig(catcher, sig, mask, code, type, val)
p->p_comm, p->p_pid, sig, catcher);
#endif
+ /* flush the FPU ctx first */
+ if (tf->tf_cr30 == fpu_curpcb) {
+ fpu_save(fpu_curpcb);
+ fpu_curpcb = 0;
+ }
+
ksc.sc_onstack = psp->ps_sigstk.ss_flags & SS_ONSTACK;
/*
@@ -1255,12 +1262,44 @@ sendsig(catcher, sig, mask, code, type, val)
}
ksc.sc_mask = mask;
- ksc.sc_sp = tf->tf_sp;
ksc.sc_fp = (register_t)scp + sss;
ksc.sc_ps = tf->tf_ipsw;
ksc.sc_pcoqh = tf->tf_iioq_head;
ksc.sc_pcoqt = tf->tf_iioq_tail;
- bcopy(tf, &ksc.sc_tf, sizeof(ksc.sc_tf));
+ ksc.sc_regs[0] = tf->tf_t1;
+ ksc.sc_regs[1] = tf->tf_t2;
+ ksc.sc_regs[2] = tf->tf_sp;
+ ksc.sc_regs[3] = tf->tf_t3;
+ ksc.sc_regs[4] = tf->tf_sar;
+ ksc.sc_regs[5] = tf->tf_r1;
+ ksc.sc_regs[6] = tf->tf_rp;
+ ksc.sc_regs[7] = tf->tf_r3;
+ ksc.sc_regs[8] = tf->tf_r4;
+ ksc.sc_regs[9] = tf->tf_r5;
+ ksc.sc_regs[10] = tf->tf_r6;
+ ksc.sc_regs[11] = tf->tf_r7;
+ ksc.sc_regs[12] = tf->tf_r8;
+ ksc.sc_regs[13] = tf->tf_r9;
+ ksc.sc_regs[14] = tf->tf_r10;
+ ksc.sc_regs[15] = tf->tf_r11;
+ ksc.sc_regs[16] = tf->tf_r12;
+ ksc.sc_regs[17] = tf->tf_r13;
+ ksc.sc_regs[18] = tf->tf_r14;
+ ksc.sc_regs[19] = tf->tf_r15;
+ ksc.sc_regs[20] = tf->tf_r16;
+ ksc.sc_regs[21] = tf->tf_r17;
+ ksc.sc_regs[22] = tf->tf_r18;
+ ksc.sc_regs[23] = tf->tf_t4;
+ ksc.sc_regs[24] = tf->tf_arg3;
+ ksc.sc_regs[25] = tf->tf_arg2;
+ ksc.sc_regs[26] = tf->tf_arg1;
+ ksc.sc_regs[27] = tf->tf_arg0;
+ ksc.sc_regs[28] = tf->tf_dp;
+ ksc.sc_regs[29] = tf->tf_ret0;
+ ksc.sc_regs[30] = tf->tf_ret1;
+ ksc.sc_regs[31] = tf->tf_r31;
+ bcopy(p->p_addr->u_pcb.pcb_fpregs, ksc.sc_fpregs,
+ sizeof(ksc.sc_fpregs));
if (copyout((caddr_t)&ksc, scp, sizeof(*scp)))
sigexit(p, SIGILL);
@@ -1274,8 +1313,8 @@ sendsig(catcher, sig, mask, code, type, val)
#ifdef DEBUG
if ((sigdebug & SDB_FOLLOW) && (!sigpid || p->p_pid == sigpid))
- printf("sendsig(%d): sig %d scp %p fp %p sp %x\n",
- p->p_pid, sig, scp, ksc.sc_fp, ksc.sc_sp);
+ printf("sendsig(%d): sig %d scp %p fp %p sp 0x%x\n",
+ p->p_pid, sig, scp, ksc.sc_fp, (register_t)scp + sss);
#endif
tf->tf_arg0 = sig;
@@ -1287,11 +1326,9 @@ sendsig(catcher, sig, mask, code, type, val)
tf->tf_iioq_tail = tf->tf_iioq_head + 4;
/* disable tracing in the trapframe */
- /* TODO FPU */
-
#ifdef DEBUG
if ((sigdebug & SDB_FOLLOW) && (!sigpid || p->p_pid == sigpid))
- printf("sendsig(%d): pc %x, catcher %x\n", p->p_pid,
+ printf("sendsig(%d): pc 0x%x, catcher 0x%x\n", p->p_pid,
tf->tf_iioq_head, tf->tf_arg3);
#endif
}
@@ -1302,6 +1339,7 @@ sys_sigreturn(p, v, retval)
void *v;
register_t *retval;
{
+ extern paddr_t fpu_curpcb; /* from locore.S */
struct sys_sigreturn_args /* {
syscallarg(struct sigcontext *) sigcntxp;
} */ *uap = v;
@@ -1315,6 +1353,12 @@ sys_sigreturn(p, v, retval)
printf("sigreturn: pid %d, scp %p\n", p->p_pid, scp);
#endif
+ /* flush the FPU ctx first */
+ if (tf->tf_cr30 == fpu_curpcb) {
+ fpu_save(fpu_curpcb);
+ fpu_curpcb = 0;
+ }
+
if ((error = copyin((caddr_t)scp, (caddr_t)&ksc, sizeof ksc)))
return (error);
@@ -1329,15 +1373,47 @@ sys_sigreturn(p, v, retval)
p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
p->p_sigmask = ksc.sc_mask &~ sigcantmask;
- hppa_user2frame((struct trapframe *)&ksc.sc_tf, tf);
+ tf->tf_t1 = ksc.sc_regs[0]; /* r22 */
+ tf->tf_t2 = ksc.sc_regs[1]; /* r21 */
+ tf->tf_sp = ksc.sc_regs[2];
+ tf->tf_t3 = ksc.sc_regs[3]; /* r20 */
+ tf->tf_sar = ksc.sc_regs[4];
+ tf->tf_r1 = ksc.sc_regs[5];
+ tf->tf_rp = ksc.sc_regs[6];
+ tf->tf_r3 = ksc.sc_regs[7];
+ tf->tf_r4 = ksc.sc_regs[8];
+ tf->tf_r5 = ksc.sc_regs[9];
+ tf->tf_r6 = ksc.sc_regs[10];
+ tf->tf_r7 = ksc.sc_regs[11];
+ tf->tf_r8 = ksc.sc_regs[12];
+ tf->tf_r9 = ksc.sc_regs[13];
+ tf->tf_r10 = ksc.sc_regs[14];
+ tf->tf_r11 = ksc.sc_regs[15];
+ tf->tf_r12 = ksc.sc_regs[16];
+ tf->tf_r13 = ksc.sc_regs[17];
+ tf->tf_r14 = ksc.sc_regs[18];
+ tf->tf_r15 = ksc.sc_regs[19];
+ tf->tf_r16 = ksc.sc_regs[20];
+ tf->tf_r17 = ksc.sc_regs[21];
+ tf->tf_r18 = ksc.sc_regs[22];
+ tf->tf_t4 = ksc.sc_regs[23]; /* r19 */
+ tf->tf_arg3 = ksc.sc_regs[24]; /* r23 */
+ tf->tf_arg2 = ksc.sc_regs[25]; /* r24 */
+ tf->tf_arg1 = ksc.sc_regs[26]; /* r25 */
+ tf->tf_arg0 = ksc.sc_regs[27]; /* r26 */
+ tf->tf_dp = ksc.sc_regs[28];
+ tf->tf_ret0 = ksc.sc_regs[29];
+ tf->tf_ret1 = ksc.sc_regs[30];
+ tf->tf_r31 = ksc.sc_regs[31];
+ bcopy(ksc.sc_fpregs, p->p_addr->u_pcb.pcb_fpregs,
+ sizeof(ksc.sc_fpregs));
+ fdcache(HPPA_SID_KERNEL, (vaddr_t)p->p_addr->u_pcb.pcb_fpregs,
+ sizeof(ksc.sc_fpregs));
- tf->tf_sp = ksc.sc_sp;
tf->tf_iioq_head = ksc.sc_pcoqh | HPPA_PC_PRIV_USER;
tf->tf_iioq_tail = ksc.sc_pcoqt | HPPA_PC_PRIV_USER;
tf->tf_ipsw = ksc.sc_ps;
- /* TODO FPU */
-
#ifdef DEBUG
if ((sigdebug & SDB_FOLLOW) && (!sigpid || p->p_pid == sigpid))
printf("sigreturn(%d): returns\n", p->p_pid);
@@ -1345,46 +1421,6 @@ sys_sigreturn(p, v, retval)
return (EJUSTRETURN);
}
-void
-hppa_user2frame(sf, tf)
- struct trapframe *sf, *tf;
-{
- /* only restore r1-r31, sar */
- tf->tf_t1 = sf->tf_t1; /* r22 */
- tf->tf_t2 = sf->tf_t2; /* r21 */
- tf->tf_sp = sf->tf_sp;
- tf->tf_t3 = sf->tf_t3; /* r20 */
-
- tf->tf_sar = sf->tf_sar;
- tf->tf_r1 = sf->tf_r1;
- tf->tf_rp = sf->tf_rp;
- tf->tf_r3 = sf->tf_r3;
- tf->tf_r4 = sf->tf_r4;
- tf->tf_r5 = sf->tf_r5;
- tf->tf_r6 = sf->tf_r6;
- tf->tf_r7 = sf->tf_r7;
- tf->tf_r8 = sf->tf_r8;
- tf->tf_r9 = sf->tf_r9;
- tf->tf_r10 = sf->tf_r10;
- tf->tf_r11 = sf->tf_r11;
- tf->tf_r12 = sf->tf_r12;
- tf->tf_r13 = sf->tf_r13;
- tf->tf_r14 = sf->tf_r14;
- tf->tf_r15 = sf->tf_r15;
- tf->tf_r16 = sf->tf_r16;
- tf->tf_r17 = sf->tf_r17;
- tf->tf_r18 = sf->tf_r18;
- tf->tf_t4 = sf->tf_t4; /* r19 */
- tf->tf_arg3 = sf->tf_arg3; /* r23 */
- tf->tf_arg2 = sf->tf_arg2; /* r24 */
- tf->tf_arg1 = sf->tf_arg1; /* r25 */
- tf->tf_arg0 = sf->tf_arg0; /* r26 */
- tf->tf_dp = sf->tf_dp;
- tf->tf_ret0 = sf->tf_ret0;
- tf->tf_ret1 = sf->tf_ret1;
- tf->tf_r31 = sf->tf_r31;
-}
-
/*
* machine dependent system variables.
*/
diff --git a/sys/arch/hppa/include/signal.h b/sys/arch/hppa/include/signal.h
index 875a6b7b3b2..fb6635c9dd2 100644
--- a/sys/arch/hppa/include/signal.h
+++ b/sys/arch/hppa/include/signal.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: signal.h,v 1.2 2002/02/06 19:39:20 mickey Exp $ */
+/* $OpenBSD: signal.h,v 1.3 2003/05/18 15:57:47 mickey Exp $ */
/*
* Copyright (c) 1994, The University of Utah and
@@ -44,10 +44,10 @@ struct sigcontext {
int sc_onstack; /* sigstack state to restore */
int sc_mask; /* signal mask to restore */
int sc_ps; /* psl to restore */
- int sc_sp; /* sp to restore */
int sc_fp; /* fp to restore */
int sc_pcoqh; /* pc offset queue (head) to restore */
int sc_pcoqt; /* pc offset queue (tail) to restore */
- int sc_resv[5];
- int sc_tf[64];
+ int sc_resv[2];
+ int sc_regs[32];
+ int sc_fpregs[64];
};