summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authordrochner <drochner@NetBSD.org>2004-03-04 20:17:01 +0000
committerdrochner <drochner@NetBSD.org>2004-03-04 20:17:01 +0000
commitbb362b40bfbfa4ca443bb3acf14174d96b101196 (patch)
tree6d64f67238cf01c2ac7ffa3b7617060d4c93ee79 /sys
parent162e36abb120325f65fe309dadf319602220c76b (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.mips3
-rw-r--r--sys/arch/mips/mips/locore.S17
-rw-r--r--sys/arch/mips/mips/mips_fputrap.c86
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);
+}