diff options
author | Michael Shalayeff <mickey@cvs.openbsd.org> | 2002-09-17 03:51:50 +0000 |
---|---|---|
committer | Michael Shalayeff <mickey@cvs.openbsd.org> | 2002-09-17 03:51:50 +0000 |
commit | 0af5f7d7e417327f279b2e0c39805df2245cb728 (patch) | |
tree | c484672697515b8c7087c7e26a0b0a7fac0e0510 | |
parent | 5ca251874f77e1a0a603d0d99e23ac447553efe6 (diff) |
handle fpu exceptions properly, might use a regress, i guess
-rw-r--r-- | sys/arch/hppa/hppa/machdep.c | 10 | ||||
-rw-r--r-- | sys/arch/hppa/hppa/trap.c | 51 | ||||
-rw-r--r-- | sys/arch/hppa/include/cpu.h | 15 |
3 files changed, 67 insertions, 9 deletions
diff --git a/sys/arch/hppa/hppa/machdep.c b/sys/arch/hppa/hppa/machdep.c index a99b3e167f8..938e1a57eee 100644 --- a/sys/arch/hppa/hppa/machdep.c +++ b/sys/arch/hppa/hppa/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.79 2002/09/11 16:01:37 mickey Exp $ */ +/* $OpenBSD: machdep.c,v 1.80 2002/09/17 03:51:49 mickey Exp $ */ /* * Copyright (c) 1999-2002 Michael Shalayeff @@ -1156,7 +1156,7 @@ setregs(p, pack, stack, retval) register_t *retval; { register struct trapframe *tf = p->p_md.md_regs; - /* register struct pcb *pcb = &p->p_addr->u_pcb; */ + register struct pcb *pcb = &p->p_addr->u_pcb; #ifdef DEBUG /*extern int pmapdebug;*/ /*pmapdebug = 13; @@ -1172,6 +1172,12 @@ setregs(p, pack, stack, retval) tf->tf_arg0 = (u_long)PS_STRINGS; tf->tf_arg1 = tf->tf_arg2 = 0; /* XXX dynload stuff */ + /* reset any of the pending FPU exceptions */ + pcb->pcb_fpregs[0] = HPPA_FPU_INIT; + pcb->pcb_fpregs[1] = 0; + pcb->pcb_fpregs[2] = 0; + pcb->pcb_fpregs[3] = 0; + /* setup terminal stack frame */ stack = hppa_round_page(stack); tf->tf_r3 = stack; diff --git a/sys/arch/hppa/hppa/trap.c b/sys/arch/hppa/hppa/trap.c index 7d0f96e3fb6..effbc7f7fb4 100644 --- a/sys/arch/hppa/hppa/trap.c +++ b/sys/arch/hppa/hppa/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.49 2002/09/12 04:36:19 mickey Exp $ */ +/* $OpenBSD: trap.c,v 1.50 2002/09/17 03:51:49 mickey Exp $ */ /* * Copyright (c) 1998-2001 Michael Shalayeff @@ -131,7 +131,6 @@ trap(type, frame) { extern u_int32_t sir; struct proc *p = curproc; - struct pcb *pcbp; vaddr_t va; struct vm_map *map; struct vmspace *vm; @@ -211,7 +210,7 @@ trap(type, frame) case T_PRIV_REG: /* these just can't make it to the trap() ever */ case T_HPMC: case T_HPMC | T_USER: - case T_EMULATION: case T_EMULATION | T_USER: + case T_EMULATION: #endif case T_IBREAK: case T_DATALIGN: @@ -239,7 +238,48 @@ trap(type, frame) /* pass to user debugger */ break; - case T_EXCEPTION | T_USER: /* co-proc assist trap */ + case T_EXCEPTION | T_USER: { + extern u_int32_t fpu_enable; /* from machdep */ + extern paddr_t fpu_curpcb; + u_int32_t stat, *pex; + int i, flt; + +#ifdef DIAGNOSTIC + if (fpu_curpcb != frame->tf_cr30) + panic("trap: FPU is not owned"); +#endif + mfctl(CR_CCR, stat); + if (stat & fpu_enable) /* net quite there yet */ + fpu_save((vaddr_t)p->p_addr->u_pcb.pcb_fpregs); + /* nobody owns it anymore */ + fpu_curpcb = 0; + mtctl(stat & ~fpu_enable, CR_CCR); + + /* get the exceptions and mask by the enabled mask */ + pex = (u_int32_t *)&p->p_addr->u_pcb.pcb_fpregs[0]; + for (i = 0, pex++; i < 7 && !*pex; i++, pex++); + stat = HPPA_FPU_OP(*pex); + if (stat & HPPA_FPU_V) + flt = FPE_FLTINV; + else if (stat & HPPA_FPU_Z) + flt = FPE_FLTDIV; + else if (stat & HPPA_FPU_O) + flt = FPE_FLTOVF; + else if (stat & HPPA_FPU_U) + flt = FPE_FLTUND; + else if (stat & HPPA_FPU_I) + flt = FPE_FLTRES; + else + flt = 0; + /* still left: under/over-flow and inexact */ + *pex = 0; + + sv.sival_int = va; + trapsignal(p, SIGFPE, type &~ T_USER, flt, sv); + } + break; + + case T_EMULATION | T_USER: /* co-proc assist trap */ sv.sival_int = va; trapsignal(p, SIGFPE, type &~ T_USER, FPE_FLTINV, sv); break; @@ -362,10 +402,9 @@ if (kdb_trap (type, va, frame)) if (kdb_trap (type, va, frame)) return; #endif - pcbp = &p->p_addr->u_pcb; frame->tf_iioq_tail = 4 + (frame->tf_iioq_head = - pcbp->pcb_onfault); + p->p_addr->u_pcb.pcb_onfault); #ifdef DDB frame->tf_iir = 0; #endif diff --git a/sys/arch/hppa/include/cpu.h b/sys/arch/hppa/include/cpu.h index 9c037f18be1..7de30854e37 100644 --- a/sys/arch/hppa/include/cpu.h +++ b/sys/arch/hppa/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.31 2002/08/03 20:56:42 mickey Exp $ */ +/* $OpenBSD: cpu.h,v 1.32 2002/09/17 03:51:49 mickey Exp $ */ /* * Copyright (c) 2000-2001 Michael Shalayeff @@ -81,6 +81,19 @@ extern const char *cpu_typename; */ #define HPPA_FPUS 0xc0 #define HPPA_FPUVER(w) (((w) & 0x003ff800) >> 11) +#define HPPA_FPU_OP(w) ((w) >> 26) +#define HPPA_FPU_I 0x01 +#define HPPA_FPU_U 0x02 +#define HPPA_FPU_O 0x04 +#define HPPA_FPU_Z 0x08 +#define HPPA_FPU_V 0x10 +#define HPPA_FPU_D 0x20 +#define HPPA_FPU_T 0x40 +#define HPPA_FPU_RM 0x00000600 +#define HPPA_FPU_CQ 0x00fff800 +#define HPPA_FPU_C 0x04000000 +#define HPPA_FPU_FLSH 27 +#define HPPA_FPU_INIT (HPPA_FPU_I | HPPA_FPU_U | HPPA_FPU_O | HPPA_FPU_Z | HPPA_FPU_V) #define HPPA_PMSFUS 0x20 /* ??? */ /* |