Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/powerpc Add support for PPC FP emulation to BookE.
details: https://anonhg.NetBSD.org/src/rev/271cc755eda6
branches: trunk
changeset: 780423:271cc755eda6
user: matt <matt%NetBSD.org@localhost>
date: Mon Jul 23 04:13:06 2012 +0000
description:
Add support for PPC FP emulation to BookE.
Pass a ksiginfo_t to fpu_emulation so it can give more detailed
info on signals.
diffstat:
sys/arch/powerpc/booke/trap.c | 33 +++++++++++++++-
sys/arch/powerpc/conf/files.booke | 4 +-
sys/arch/powerpc/fpu/fpu_emu.c | 78 ++++++++++++++++++++++++--------------
sys/arch/powerpc/fpu/fpu_emu.h | 3 +-
sys/arch/powerpc/fpu/fpu_extern.h | 12 +++++-
sys/arch/powerpc/ibm4xx/trap.c | 16 +++++---
6 files changed, 104 insertions(+), 42 deletions(-)
diffs (truncated from 360 to 300 lines):
diff -r e3b0f9151590 -r 271cc755eda6 sys/arch/powerpc/booke/trap.c
--- a/sys/arch/powerpc/booke/trap.c Mon Jul 23 03:32:30 2012 +0000
+++ b/sys/arch/powerpc/booke/trap.c Mon Jul 23 04:13:06 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: trap.c,v 1.17 2012/07/09 17:45:22 matt Exp $ */
+/* $NetBSD: trap.c,v 1.18 2012/07/23 04:13:06 matt Exp $ */
/*-
* Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -38,7 +38,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: trap.c,v 1.17 2012/07/09 17:45:22 matt Exp $");
+__KERNEL_RCSID(1, "$NetBSD: trap.c,v 1.18 2012/07/23 04:13:06 matt Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -61,6 +61,8 @@
#include <powerpc/booke/spr.h>
#include <powerpc/booke/cpuvar.h>
+#include <powerpc/fpu/fpu_extern.h>
+
#include <powerpc/db_machdep.h>
#include <ddb/db_interface.h>
@@ -426,6 +428,18 @@
return true;
}
+ if (OPC_MFSPR_P(opcode, SPR_PIR)) {
+ __asm ("mfpir %0" : "=r"(tf->tf_fixreg[OPC_MFSPR_REG(opcode)]));
+ return true;
+ }
+
+ if (OPC_MFSPR_P(opcode, SPR_SVR)) {
+ __asm ("mfspr %0,%1"
+ : "=r"(tf->tf_fixreg[OPC_MFSPR_REG(opcode)])
+ : "n"(SPR_SVR));
+ return true;
+ }
+
/*
* If we bothered to emulate FP, we would try to do so here.
*/
@@ -465,6 +479,21 @@
}
}
+ if (tf->tf_esr & ESR_PIL) {
+ struct pcb * const pcb = lwp_getpcb(curlwp);
+ if (__predict_false(!(curlwp->l_md.md_flags & MDLWP_USEDFPU))) {
+ memset(&pcb->pcb_fpu, 0, sizeof(pcb->pcb_fpu));
+ curlwp->l_md.md_flags |= MDLWP_USEDFPU;
+ }
+ if (fpu_emulate(tf, &pcb->pcb_fpu, ksi)) {
+ if (ksi->ksi_signo == 0) {
+ ci->ci_ev_fpu.ev_count++;
+ return 0;
+ }
+ return EFAULT;
+ }
+ }
+
KSI_INIT_TRAP(ksi);
ksi->ksi_signo = SIGILL;
ksi->ksi_trap = EXC_PGM;
diff -r e3b0f9151590 -r 271cc755eda6 sys/arch/powerpc/conf/files.booke
--- a/sys/arch/powerpc/conf/files.booke Mon Jul 23 03:32:30 2012 +0000
+++ b/sys/arch/powerpc/conf/files.booke Mon Jul 23 04:13:06 2012 +0000
@@ -1,8 +1,8 @@
-# $NetBSD: files.booke,v 1.7 2012/07/22 23:46:10 matt Exp $
+# $NetBSD: files.booke,v 1.8 2012/07/23 04:13:06 matt Exp $
#
# PPC BookE specific configuration info
-#include "arch/powerpc/fpu/files.fpu"
+include "arch/powerpc/fpu/files.fpu"
# Board Properties
file arch/powerpc/booke/board_prop.c
diff -r e3b0f9151590 -r 271cc755eda6 sys/arch/powerpc/fpu/fpu_emu.c
--- a/sys/arch/powerpc/fpu/fpu_emu.c Mon Jul 23 03:32:30 2012 +0000
+++ b/sys/arch/powerpc/fpu/fpu_emu.c Mon Jul 23 04:13:06 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: fpu_emu.c,v 1.15 2011/01/18 01:02:53 matt Exp $ */
+/* $NetBSD: fpu_emu.c,v 1.16 2012/07/23 04:13:06 matt Exp $ */
/*
* Copyright 2001 Wasabi Systems, Inc.
@@ -76,21 +76,23 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fpu_emu.c,v 1.15 2011/01/18 01:02:53 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fpu_emu.c,v 1.16 2012/07/23 04:13:06 matt Exp $");
#include "opt_ddb.h"
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/signal.h>
+#include <sys/signalvar.h>
+#include <sys/siginfo.h>
#include <sys/systm.h>
#include <sys/syslog.h>
-#include <sys/signalvar.h>
-#include <sys/device.h> /* for evcnt */
+#include <sys/evcnt.h>
#include <powerpc/instr.h>
#include <machine/reg.h>
#include <machine/fpu.h>
+#include <machine/trap.h>
#include <powerpc/fpu/fpu_emu.h>
#include <powerpc/fpu/fpu_extern.h>
@@ -182,13 +184,15 @@
* Return zero for success, else signal number.
* (Typically: zero, SIGFPE, SIGILL, SIGSEGV)
*/
-int
-fpu_emulate(struct trapframe *tf, struct fpreg *fpf)
+bool
+fpu_emulate(struct trapframe *tf, struct fpreg *fpf, ksiginfo_t *ksi)
{
- static union instr insn;
- static struct fpemu fe;
- static int lastill = 0;
- int sig;
+ union instr insn;
+ struct fpemu fe;
+
+ KSI_INIT_TRAP(ksi);
+ ksi->ksi_signo = 0;
+ ksi->ksi_addr = (void *)tf->tf_srr0;
/* initialize insn.is_datasize to tell it is *not* initialized */
fe.fe_fpstate = fpf;
@@ -200,36 +204,46 @@
#ifdef DEBUG
printf("fpu_emulate: fault reading opcode\n");
#endif
- return SIGSEGV;
+ ksi->ksi_signo = SIGSEGV;
+ ksi->ksi_trap = EXC_ISI;
+ ksi->ksi_code = SEGV_MAPERR;
+ ksi->ksi_addr = (void *)tf->tf_srr0;
+ return true;
}
DPRINTF(FPE_EX, ("fpu_emulate: emulating insn %x at %p\n",
insn.i_int, (void *)tf->tf_srr0));
-
if ((insn.i_any.i_opcd == OPC_TWI) ||
((insn.i_any.i_opcd == OPC_integer_31) &&
(insn.i_x.i_xo == OPC31_TW))) {
/* Check for the two trap insns. */
DPRINTF(FPE_EX, ("fpu_emulate: SIGTRAP\n"));
- return (SIGTRAP);
+ ksi->ksi_signo = SIGTRAP;
+ ksi->ksi_trap = EXC_PGM;
+ ksi->ksi_code = TRAP_TRACE;
+ ksi->ksi_addr = (void *)tf->tf_srr0;
+ return true;
}
- sig = 0;
switch (fpu_execute(tf, &fe, &insn)) {
case 0:
DPRINTF(FPE_EX, ("fpu_emulate: success\n"));
tf->tf_srr0 += 4;
- break;
+ return true;
case FPE:
DPRINTF(FPE_EX, ("fpu_emulate: SIGFPE\n"));
- sig = SIGFPE;
- break;
+ ksi->ksi_signo = SIGFPE;
+ ksi->ksi_trap = EXC_PGM;
+ return true;
case FAULT:
DPRINTF(FPE_EX, ("fpu_emulate: SIGSEGV\n"));
- sig = SIGSEGV;
- break;
+ ksi->ksi_signo = SIGSEGV;
+ ksi->ksi_trap = EXC_DSI;
+ ksi->ksi_code = SEGV_MAPERR;
+ ksi->ksi_addr = (void *)fe.fe_addr;
+ return true;
case NOTFPU:
default:
@@ -241,21 +255,19 @@
opc_disasm((vaddr_t)(tf->tf_srr0), insn.i_int);
}
#endif
+#if defined(PPC_IBM4XX) && defined(DEBUG)
/*
* XXXX retry an illegal insn once due to cache issues.
*/
+ static int lastill = 0;
if (lastill == tf->tf_srr0) {
- sig = SIGILL;
-#ifdef DEBUG
if (fpe_debug & FPE_EX)
Debugger();
-#endif
}
lastill = tf->tf_srr0;
- break;
+#endif /* PPC_IBM4XX && DEBUG */
+ return false;
}
-
- return (sig);
}
/*
@@ -337,8 +349,10 @@
DPRINTF(FPE_INSN,
("fpu_execute: Store INT %x at %p\n",
a[1], (void *)addr));
- if (copyout(&a[1], (void *)addr, sizeof(int)))
+ if (copyout(&a[1], (void *)addr, sizeof(int))) {
+ fe->fe_addr = addr;
return (FAULT);
+ }
return (0);
}
@@ -392,22 +406,28 @@
(void *)addr));
fpu_explode(fe, fp = &fe->fe_f1, FTYPE_DBL, rt);
fpu_implode(fe, fp, type, (void *)&buf);
- if (copyout(&buf, (void *)addr, size))
+ if (copyout(&buf, (void *)addr, size)) {
+ fe->fe_addr = addr;
return (FAULT);
+ }
} else {
DPRINTF(FPE_INSN,
("fpu_execute: Store DBL at %p\n",
(void *)addr));
- if (copyout(&fs->fpreg[rt], (void *)addr, size))
+ if (copyout(&fs->fpreg[rt], (void *)addr, size)) {
+ fe->fe_addr = addr;
return (FAULT);
+ }
}
} else {
/* Load */
FPU_EMU_EVCNT_INCR(fpload);
DPRINTF(FPE_INSN, ("fpu_execute: Load from %p\n",
(void *)addr));
- if (copyin((const void *)addr, &fs->fpreg[rt], size))
+ if (copyin((const void *)addr, &fs->fpreg[rt], size)) {
+ fe->fe_addr = addr;
return (FAULT);
+ }
if (type != FTYPE_DBL) {
fpu_explode(fe, fp = &fe->fe_f1, type, rt);
fpu_implode(fe, fp, FTYPE_DBL,
diff -r e3b0f9151590 -r 271cc755eda6 sys/arch/powerpc/fpu/fpu_emu.h
--- a/sys/arch/powerpc/fpu/fpu_emu.h Mon Jul 23 03:32:30 2012 +0000
+++ b/sys/arch/powerpc/fpu/fpu_emu.h Mon Jul 23 04:13:06 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: fpu_emu.h,v 1.3 2005/12/11 12:18:42 christos Exp $ */
+/* $NetBSD: fpu_emu.h,v 1.4 2012/07/23 04:13:06 matt Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -143,6 +143,7 @@
struct fpn fe_f1; /* operand 1 */
struct fpn fe_f2; /* operand 2, if required */
struct fpn fe_f3; /* available storage for result */
+ vaddr_t fe_addr; /* last address accessed */
};
/*
diff -r e3b0f9151590 -r 271cc755eda6 sys/arch/powerpc/fpu/fpu_extern.h
--- a/sys/arch/powerpc/fpu/fpu_extern.h Mon Jul 23 03:32:30 2012 +0000
+++ b/sys/arch/powerpc/fpu/fpu_extern.h Mon Jul 23 04:13:06 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: fpu_extern.h,v 1.4 2008/04/28 20:23:32 martin Exp $ */
+/* $NetBSD: fpu_extern.h,v 1.5 2012/07/23 04:13:06 matt Exp $ */
/*-
* Copyright (c) 1995 The NetBSD Foundation, Inc.
@@ -29,6 +29,12 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#ifndef _POWERPC_FPU_FPU_EXTERN_H_
+#define _POWERPC_FPU_FPU_EXTERN_H_
+
+#include <sys/signal.h>
Home |
Main Index |
Thread Index |
Old Index