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