summaryrefslogtreecommitdiffstats
path: root/sys/powerpc/aim
diff options
context:
space:
mode:
authornwhitehorn <nwhitehorn@FreeBSD.org>2010-02-22 14:17:23 +0000
committernwhitehorn <nwhitehorn@FreeBSD.org>2010-02-22 14:17:23 +0000
commita9f2786d08ce019d0969b21bb7470742b5e5bad5 (patch)
treec27f698d92061bb3a404250dfa135b059266be48 /sys/powerpc/aim
parent69414838331fba17e430ba1b57b262f7eab2bf22 (diff)
downloadFreeBSD-src-a9f2786d08ce019d0969b21bb7470742b5e5bad5.zip
FreeBSD-src-a9f2786d08ce019d0969b21bb7470742b5e5bad5.tar.gz
Allow user programs to execute mfpvr instructions. Linux allows this, and
some math-related software like GMP expects to be able to use it to pick a target appropriately. MFC after: 1 week
Diffstat (limited to 'sys/powerpc/aim')
-rw-r--r--sys/powerpc/aim/trap.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/sys/powerpc/aim/trap.c b/sys/powerpc/aim/trap.c
index 943e3c6..35f4147 100644
--- a/sys/powerpc/aim/trap.c
+++ b/sys/powerpc/aim/trap.c
@@ -82,6 +82,7 @@ static void printtrap(u_int vector, struct trapframe *frame, int isfatal,
int user);
static int trap_pfault(struct trapframe *frame, int user);
static int fix_unaligned(struct thread *td, struct trapframe *frame);
+static int ppc_instr_emulate(struct trapframe *frame);
static int handle_onfault(struct trapframe *frame);
static void syscall(struct trapframe *frame);
@@ -209,7 +210,9 @@ trap(struct trapframe *frame)
/* Identify the trap reason */
if (frame->srr1 & EXC_PGM_TRAP)
sig = SIGTRAP;
- else
+ else if (ppc_instr_emulate(frame) == 0)
+ frame->srr0 += 4;
+ else
sig = SIGILL;
break;
@@ -615,3 +618,21 @@ fix_unaligned(struct thread *td, struct trapframe *frame)
return -1;
}
+
+static int
+ppc_instr_emulate(struct trapframe *frame)
+{
+ uint32_t instr;
+ int reg;
+
+ instr = fuword32((void *)frame->srr0);
+
+ if ((instr & 0xfc1fffff) == 0x7c1f42a6) { /* mfpvr */
+ reg = (instr & ~0xfc1fffff) >> 21;
+ frame->fixreg[reg] = mfpvr();
+ return (0);
+ }
+
+ return (-1);
+}
+
OpenPOWER on IntegriCloud