diff options
| author | drochner <drochner@NetBSD.org> | 2004-03-04 20:17:01 +0000 |
|---|---|---|
| committer | drochner <drochner@NetBSD.org> | 2004-03-04 20:17:01 +0000 |
| commit | bb362b40bfbfa4ca443bb3acf14174d96b101196 (patch) | |
| tree | 6d64f67238cf01c2ac7ffa3b7617060d4c93ee79 /sys | |
| parent | 162e36abb120325f65fe309dadf319602220c76b (diff) | |
fix some problems with FPU exception signaling:
-The MachFPTrap did generate pre-siginfo arguments to trapsignal(),
leading to an immediate crash.
Put the siginfo generation into a separate .c file for simplicity.
-The exception bits in MIPS_FPU_CSR didn't get cleared, leading to
trouble later ("kernel used FPU" on pmax).
XXX This should probably be done for the "unimplemented fpu instruction"
case as well, but I don't know how to test this. Or, even better -
centralize the CSR clearing before the branch in MachFPTrap.
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/arch/mips/conf/files.mips | 3 | ||||
| -rw-r--r-- | sys/arch/mips/mips/locore.S | 17 | ||||
| -rw-r--r-- | sys/arch/mips/mips/mips_fputrap.c | 86 |
3 files changed, 98 insertions, 8 deletions
diff --git a/sys/arch/mips/conf/files.mips b/sys/arch/mips/conf/files.mips index cf9ec9afce0..ae5eb5846b6 100644 --- a/sys/arch/mips/conf/files.mips +++ b/sys/arch/mips/conf/files.mips @@ -1,4 +1,4 @@ -# $NetBSD: files.mips,v 1.49 2003/12/12 14:55:58 sekiya Exp $ +# $NetBSD: files.mips,v 1.50 2004/03/04 20:17:01 drochner Exp $ # defflag opt_cputype.h NOFPU @@ -53,6 +53,7 @@ file arch/mips/mips/cache_mipsNN.c mips32 | mips64 file arch/mips/mips/in_cksum.c inet file netns/ns_cksum.c ns +file arch/mips/mips/mips_fputrap.c !softfloat & !nofpu file arch/mips/mips/mips_emul.c file arch/mips/mips/fp.S softfloat | !nofpu diff --git a/sys/arch/mips/mips/locore.S b/sys/arch/mips/mips/locore.S index e801b33b17e..cc86155fad4 100644 --- a/sys/arch/mips/mips/locore.S +++ b/sys/arch/mips/mips/locore.S @@ -1,4 +1,4 @@ -/* $NetBSD: locore.S,v 1.157 2003/11/04 10:33:15 dsl Exp $ */ +/* $NetBSD: locore.S,v 1.158 2004/03/04 20:17:01 drochner Exp $ */ /* * Copyright (c) 1992, 1993 @@ -936,10 +936,10 @@ XNESTED(MachFPTrap) REG_S a1, FRAME_CAUSE(a3) REG_EPILOGUE - move a2, a0 # code = instruction + move a1, a0 # code = instruction lw a0, _C_LABEL(curlwp) # get current process - jal _C_LABEL(trapsignal) - li a1, SIGILL + jal _C_LABEL(mips_fpuillinst) + nop b FPReturn nop @@ -953,10 +953,13 @@ XNESTED(MachFPTrap) REG_S a1, FRAME_CAUSE(a3) REG_EPILOGUE - move a2, a0 # code = instruction + and a0, t0, ~MIPS_FPU_EXCEPTION_BITS + ctc1 a0, MIPS_FPU_CSR + + move a1, t0 # FPU status lw a0, _C_LABEL(curlwp) # get current process - jal _C_LABEL(trapsignal) - li a1, SIGFPE # BDSLOT + jal _C_LABEL(mips_fpuexcept) + nop b FPReturn nop diff --git a/sys/arch/mips/mips/mips_fputrap.c b/sys/arch/mips/mips/mips_fputrap.c new file mode 100644 index 00000000000..983113af6da --- /dev/null +++ b/sys/arch/mips/mips/mips_fputrap.c @@ -0,0 +1,86 @@ +/* $NetBSD: mips_fputrap.c,v 1.1 2004/03/04 20:17:01 drochner Exp $ */ + +/* + * Copyright (c) 2004 + * Matthias Drochner. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/proc.h> +#include <sys/signal.h> +#include <sys/siginfo.h> +#include <mips/cpuregs.h> + +void mips_fpuexcept(struct lwp *, unsigned int); +void mips_fpuillinst(struct lwp *, unsigned int, unsigned long); +static int fpustat2sicode(unsigned int); + +void +mips_fpuexcept(struct lwp *l, unsigned int fpustat) +{ + ksiginfo_t ksi; + + KSI_INIT_TRAP(&ksi); + ksi.ksi_signo = SIGFPE; + ksi.ksi_code = fpustat2sicode(fpustat); + ksi.ksi_trap = fpustat; + (*l->l_proc->p_emul->e_trapsignal)(l, &ksi); +} + +void +mips_fpuillinst(struct lwp *l, unsigned int opcode, unsigned long vaddr) +{ + ksiginfo_t ksi; + + KSI_INIT_TRAP(&ksi); + ksi.ksi_signo = SIGILL; + ksi.ksi_code = ILL_ILLOPC; + ksi.ksi_trap = opcode; + ksi.ksi_addr = (void *)vaddr; + (*l->l_proc->p_emul->e_trapsignal)(l, &ksi); +} + +static struct { + unsigned int bit; + int code; +} fpecodes[] = { + { MIPS_FPU_EXCEPTION_INEXACT, FPE_FLTRES }, + { MIPS_FPU_EXCEPTION_UNDERFLOW, FPE_FLTUND }, + { MIPS_FPU_EXCEPTION_OVERFLOW, FPE_FLTOVF }, + { MIPS_FPU_EXCEPTION_DIV0, FPE_FLTDIV }, + { MIPS_FPU_EXCEPTION_INVALID, FPE_FLTINV }, + { MIPS_FPU_EXCEPTION_UNIMPL, FPE_FLTINV } +}; + +static int +fpustat2sicode(unsigned int fpustat) +{ + int i; + + for (i = 0; i < 6; i++) + if (fpustat & fpecodes[i].bit) + return (fpecodes[i].code); + return (FPE_FLTINV); +} |
