Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/powerpc Factor out emulation code for m[ft]msr in u...
details: https://anonhg.NetBSD.org/src/rev/87818d94ebb1
branches: trunk
changeset: 935988:87818d94ebb1
user: rin <rin%NetBSD.org@localhost>
date: Wed Jul 15 08:58:51 2020 +0000
description:
Factor out emulation code for m[ft]msr in user mode from oea, and
adjust it for systems without FPU.
Now, it can be used from booke and ibm4xx in order to support fenv(3).
diffstat:
sys/arch/powerpc/include/cpu.h | 4 +-
sys/arch/powerpc/include/instr.h | 8 +--
sys/arch/powerpc/powerpc/powerpc_machdep.c | 80 +++++++++++++++++++++++++++++-
sys/arch/powerpc/powerpc/trap.c | 64 +----------------------
4 files changed, 85 insertions(+), 71 deletions(-)
diffs (226 lines):
diff -r 6539ad60a48f -r 87818d94ebb1 sys/arch/powerpc/include/cpu.h
--- a/sys/arch/powerpc/include/cpu.h Wed Jul 15 08:56:05 2020 +0000
+++ b/sys/arch/powerpc/include/cpu.h Wed Jul 15 08:58:51 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.h,v 1.114 2020/07/07 01:39:23 rin Exp $ */
+/* $NetBSD: cpu.h,v 1.115 2020/07/15 08:58:51 rin Exp $ */
/*
* Copyright (C) 1999 Wolfgang Solfrank.
@@ -391,6 +391,8 @@
void * mapiodev(paddr_t, psize_t, bool);
void unmapiodev(vaddr_t, vsize_t);
+int emulate_mxmsr(struct lwp *, struct trapframe *, uint32_t);
+
#ifdef MULTIPROCESSOR
int md_setup_trampoline(volatile struct cpu_hatch_data *,
struct cpu_info *);
diff -r 6539ad60a48f -r 87818d94ebb1 sys/arch/powerpc/include/instr.h
--- a/sys/arch/powerpc/include/instr.h Wed Jul 15 08:56:05 2020 +0000
+++ b/sys/arch/powerpc/include/instr.h Wed Jul 15 08:58:51 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: instr.h,v 1.8 2017/02/27 06:54:00 chs Exp $ */
+/* $NetBSD: instr.h,v 1.9 2020/07/15 08:58:51 rin Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -405,12 +405,6 @@
#define OPC_MFSPR_REG(o) (((o) >> 21) & 0x1f)
#define OPC_MFSPR_P(o, spr) (((o) & OPC_MFSPR_MASK) == OPC_MFSPR(spr))
-#define OPC_MFMSR_CODE 0x7c0000a6
-#define OPC_MFMSR_MASK 0xfc1fffff
-#define OPC_MFMSR OPC_MFMSR_CODE
-#define OPC_MFMSR_REG(o) (((o) >> 21) & 0x1f)
-#define OPC_MFMSR_P(o) (((o) & OPC_MFMSR_MASK) == OPC_MFMSR_CODE)
-
/*
* booke doesn't have lwsync even though gcc emits it so we have to emulate it.
*/
diff -r 6539ad60a48f -r 87818d94ebb1 sys/arch/powerpc/powerpc/powerpc_machdep.c
--- a/sys/arch/powerpc/powerpc/powerpc_machdep.c Wed Jul 15 08:56:05 2020 +0000
+++ b/sys/arch/powerpc/powerpc/powerpc_machdep.c Wed Jul 15 08:58:51 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: powerpc_machdep.c,v 1.79 2020/07/07 01:39:23 rin Exp $ */
+/* $NetBSD: powerpc_machdep.c,v 1.80 2020/07/15 08:58:52 rin Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: powerpc_machdep.c,v 1.79 2020/07/07 01:39:23 rin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: powerpc_machdep.c,v 1.80 2020/07/15 08:58:52 rin Exp $");
#ifdef _KERNEL_OPT
#include "opt_altivec.h"
@@ -738,6 +738,82 @@
#endif /* DDB */
#endif /* MULTIPROCESSOR */
+int
+emulate_mxmsr(struct lwp *l, struct trapframe *tf, uint32_t opcode)
+{
+
+#define OPC_MFMSR_CODE 0x7c0000a6
+#define OPC_MFMSR_MASK 0xfc1fffff
+#define OPC_MFMSR_P(o) (((o) & OPC_MFMSR_MASK) == OPC_MFMSR_CODE)
+
+#define OPC_MTMSR_CODE 0x7c000124
+#define OPC_MTMSR_MASK 0xfc1fffff
+#define OPC_MTMSR_P(o) (((o) & OPC_MTMSR_MASK) == OPC_MTMSR_CODE)
+
+#define OPC_MXMSR_REG(o) (((o) >> 21) & 0x1f)
+
+ if (OPC_MFMSR_P(opcode)) {
+ struct pcb * const pcb = lwp_getpcb(l);
+ register_t msr = tf->tf_srr1 & PSL_USERSRR1;
+
+ if (fpu_used_p(l))
+ msr |= PSL_FP;
+#ifdef ALTIVEC
+ if (vec_used_p(l))
+ msr |= PSL_VEC;
+#endif
+
+ msr |= (pcb->pcb_flags & PSL_FE_PREC);
+ tf->tf_fixreg[OPC_MXMSR_REG(opcode)] = msr;
+ return 1;
+ }
+
+ if (OPC_MTMSR_P(opcode)) {
+ struct pcb * const pcb = lwp_getpcb(l);
+ register_t msr = tf->tf_fixreg[OPC_MXMSR_REG(opcode)];
+
+ /*
+ * Ignore the FP enable bit in the requested MSR.
+ * It might be set in the thread's actual MSR but the
+ * user code isn't allowed to change it.
+ */
+ msr &= ~PSL_FP;
+#ifdef ALTIVEC
+ msr &= ~PSL_VEC;
+#endif
+
+ /*
+ * Don't let the user muck with bits he's not allowed to.
+ */
+#ifdef PPC_HAVE_FPU
+ if (!PSL_USEROK_P(msr))
+#else
+ if (!PSL_USEROK_P(msr & ~PSL_FE_PREC))
+#endif
+ return 0;
+
+ /*
+ * For now, only update the FP exception mode.
+ */
+ pcb->pcb_flags &= ~PSL_FE_PREC;
+ pcb->pcb_flags |= msr & PSL_FE_PREC;
+
+#ifdef PPC_HAVE_FPU
+ /*
+ * If we think we have the FPU, update SRR1 too. If we're
+ * wrong userret() will take care of it.
+ */
+ if (tf->tf_srr1 & PSL_FP) {
+ tf->tf_srr1 &= ~(PSL_FE0|PSL_FE1);
+ tf->tf_srr1 |= msr & (PSL_FE0|PSL_FE1);
+ }
+#endif
+ return 1;
+ }
+
+ return 0;
+}
+
#ifdef MODULAR
/*
* Push any modules loaded by the boot loader.
diff -r 6539ad60a48f -r 87818d94ebb1 sys/arch/powerpc/powerpc/trap.c
--- a/sys/arch/powerpc/powerpc/trap.c Wed Jul 15 08:56:05 2020 +0000
+++ b/sys/arch/powerpc/powerpc/trap.c Wed Jul 15 08:58:51 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: trap.c,v 1.162 2020/07/15 07:58:26 rin Exp $ */
+/* $NetBSD: trap.c,v 1.163 2020/07/15 08:58:52 rin Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -35,7 +35,7 @@
#define __UCAS_PRIVATE
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.162 2020/07/15 07:58:26 rin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.163 2020/07/15 08:58:52 rin Exp $");
#ifdef _KERNEL_OPT
#include "opt_altivec.h"
@@ -1089,65 +1089,7 @@
return 1;
}
- if (OPC_MFMSR_P(opcode)) {
- struct pcb * const pcb = lwp_getpcb(l);
- register_t msr = tf->tf_srr1 & PSL_USERSRR1;
-
- if (fpu_used_p(l))
- msr |= PSL_FP;
- msr |= (pcb->pcb_flags & (PCB_FE0|PCB_FE1));
-#ifdef ALTIVEC
- if (vec_used_p(l))
- msr |= PSL_VEC;
-#endif
- tf->tf_fixreg[OPC_MFMSR_REG(opcode)] = msr;
- return 1;
- }
-
-#define OPC_MTMSR_CODE 0x7c000124
-#define OPC_MTMSR_MASK 0xfc1fffff
-#define OPC_MTMSR OPC_MTMSR_CODE
-#define OPC_MTMSR_REG(o) (((o) >> 21) & 0x1f)
-#define OPC_MTMSR_P(o) (((o) & OPC_MTMSR_MASK) == OPC_MTMSR_CODE)
-
- if (OPC_MTMSR_P(opcode)) {
- struct pcb * const pcb = lwp_getpcb(l);
- register_t msr = tf->tf_fixreg[OPC_MTMSR_REG(opcode)];
-
- /*
- * Ignore the FP enable bit in the requested MSR.
- * It might be set in the thread's actual MSR but the
- * user code isn't allowed to change it.
- */
- msr &= ~PSL_FP;
-#ifdef ALTIVEC
- msr &= ~PSL_VEC;
-#endif
-
- /*
- * Don't let the user muck with bits he's not allowed to.
- */
- if (!PSL_USEROK_P(msr))
- return 0;
-
- /*
- * For now, only update the FP exception mode.
- */
- pcb->pcb_flags &= ~(PSL_FE0|PSL_FE1);
- pcb->pcb_flags |= msr & (PSL_FE0|PSL_FE1);
-
- /*
- * If we think we have the FPU, update SRR1 too. If we're
- * wrong userret() will take care of it.
- */
- if (tf->tf_srr1 & PSL_FP) {
- tf->tf_srr1 &= ~(PSL_FE0|PSL_FE1);
- tf->tf_srr1 |= msr & (PSL_FE0|PSL_FE1);
- }
- return 1;
- }
-
- return 0;
+ return emulate_mxmsr(l, tf, opcode);
}
int
Home |
Main Index |
Thread Index |
Old Index