Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/powerpc Move powerpc to use pcu to manage FPU/AltiV...



details:   https://anonhg.NetBSD.org/src/rev/2191d0d74c97
branches:  trunk
changeset: 764724:2191d0d74c97
user:      matt <matt%NetBSD.org@localhost>
date:      Mon May 02 02:01:32 2011 +0000

description:
Move powerpc to use pcu to manage FPU/AltiVec/SPE.

diffstat:

 sys/arch/powerpc/booke/spe.c                 |  142 ++++-------
 sys/arch/powerpc/booke/trap.c                |    6 +-
 sys/arch/powerpc/conf/files.powerpc          |    4 +-
 sys/arch/powerpc/include/altivec.h           |   34 ++-
 sys/arch/powerpc/include/fpu.h               |   43 ++-
 sys/arch/powerpc/include/proc.h              |   12 +-
 sys/arch/powerpc/include/psl.h               |    6 +-
 sys/arch/powerpc/include/types.h             |    8 +-
 sys/arch/powerpc/include/userret.h           |   53 +----
 sys/arch/powerpc/oea/altivec.c               |  233 ++++++-------------
 sys/arch/powerpc/pic/ipi.c                   |   12 +-
 sys/arch/powerpc/powerpc/compat_16_machdep.c |    9 +-
 sys/arch/powerpc/powerpc/core_machdep.c      |   14 +-
 sys/arch/powerpc/powerpc/fpu.c               |  315 ++++++++++----------------
 sys/arch/powerpc/powerpc/powerpc_machdep.c   |   25 +-
 sys/arch/powerpc/powerpc/process_machdep.c   |   51 ++-
 sys/arch/powerpc/powerpc/trap.c              |   23 +-
 sys/arch/powerpc/powerpc/vm_machdep.c        |   13 +-
 18 files changed, 426 insertions(+), 577 deletions(-)

diffs (truncated from 1693 to 300 lines):

diff -r cf0c3267cdc8 -r 2191d0d74c97 sys/arch/powerpc/booke/spe.c
--- a/sys/arch/powerpc/booke/spe.c      Mon May 02 01:49:23 2011 +0000
+++ b/sys/arch/powerpc/booke/spe.c      Mon May 02 02:01:32 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: spe.c,v 1.2 2011/01/18 01:02:52 matt Exp $     */
+/*     $NetBSD: spe.c,v 1.3 2011/05/02 02:01:32 matt Exp $     */
 
 /*-
  * Copyright (c) 2011 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: spe.c,v 1.2 2011/01/18 01:02:52 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: spe.c,v 1.3 2011/05/02 02:01:32 matt Exp $");
 
 #include "opt_altivec.h"
 
@@ -41,6 +41,7 @@
 #include <sys/systm.h>
 #include <sys/atomic.h>
 #include <sys/siginfo.h>
+#include <sys/pcu.h>
 
 #include <powerpc/altivec.h>
 #include <powerpc/spr.h>
@@ -48,13 +49,33 @@
 #include <powerpc/psl.h>
 #include <powerpc/pcb.h>
 
-void
-vec_enable(void)
+static void vec_state_load(lwp_t *, bool);
+static void vec_state_save(lwp_t *);
+static void vec_state_release(lwp_t *);
+
+const pcu_ops_t vec_ops = {
+       .pcu_id = PCU_VEC,
+       .pcu_state_load = vec_state_load,
+       .pcu_state_save = vec_state_save,
+       .pcu_state_release = vec_state_release,
+};
+
+bool
+vec_used_p(lwp_t *l)
 {
-       struct cpu_info * const ci = curcpu();
-       lwp_t * const l = curlwp;
+       return (l->l_md.md_flags & MDLWP_USEDVEC) != 0;
+}
 
+void
+vec_mark_used(lwp_t *l)
+{
        l->l_md.md_flags |= MDLWP_USEDVEC;
+}
+
+void
+vec_state_load(lwp_t *l, bool used)
+{
+       struct pcb * const pcb = lwp_getpcb(l);
 
        /*
         * Enable SPE temporarily (and disable interrupts).
@@ -63,37 +84,30 @@
        mtmsr((msr & ~PSL_EE) | PSL_SPV);
        __asm volatile ("isync");
 
-       if (ci->ci_veclwp != l) {
-               struct pcb * const pcb = lwp_getpcb(l);
-               /*
-                * Save the existing state (if any).
-                */
-               vec_save_cpu(VEC_SAVE_AND_RELEASE);
+       /*
+        * Call an assembly routine to do load everything.
+        */
+       vec_load_from_vreg(&pcb->pcb_vr);
+       __asm volatile ("sync");
 
-               /*
-                * Call an assembly routine to do load everything.
-                */
-               vec_load_from_vreg(&pcb->pcb_vr);
-
-               /*
-                * Enable SPE when we return to user-mode (we overload the
-                * ALTIVEC flags).  Record the new ownership of the SPE unit.
-                */
-               ci->ci_veclwp = l;
-               l->l_md.md_veccpu = ci;
-       }
-       __asm volatile ("sync");
-       l->l_md.md_flags |= MDLWP_OWNVEC;
 
        /*
         * Restore MSR (turn off SPE)
         */
        mtmsr(msr);
+       __asm volatile ("isync");
+
+       /*
+        * Note that vector has now been used.
+        */
+       l->l_md.md_flags |= MDLWP_USEDVEC;
 }
 
 void
-vec_save_cpu(enum vec_op op)
+vec_state_save(lwp_t *l)
 {
+       struct pcb * const pcb = lwp_getpcb(l);
+
        /*
         * Turn on SPE, turn off interrupts.
         */
@@ -101,71 +115,27 @@
        mtmsr((msr & ~PSL_EE) | PSL_SPV);
        __asm volatile ("isync");
 
-       struct cpu_info * const ci = curcpu();
-       lwp_t * const l = ci->ci_veclwp;
-
-       KASSERTMSG(l->l_md.md_veccpu == ci,
-           ("%s: veccpu (%p) != ci (%p)\n", __func__, l->l_md.md_veccpu, ci));
-       if (l->l_md.md_flags & MDLWP_OWNVEC) {
-               struct pcb * const pcb = lwp_getpcb(l);
-
-               /*
-                * Save the vector state which is best done in assembly.
-                */
-               vec_unload_to_vreg(&pcb->pcb_vr);
-
-               /*
-                * Indicate that VEC unit is unloaded
-                */
-               l->l_md.md_flags &= ~MDLWP_OWNVEC;
-
-               /*
-                * If asked to, give up the VEC unit.
-                */
-               if (op == VEC_SAVE_AND_RELEASE)
-                       ci->ci_veclwp = ci->ci_data.cpu_idlelwp;
-       }
+       /*
+        * Save the vector state which is best done in assembly.
+        */
+       vec_unload_to_vreg(&pcb->pcb_vr);
+       __asm volatile ("sync");
 
        /*
         * Restore MSR (turn off SPE)
         */
        mtmsr(msr);
+       __asm volatile ("isync");
 }
 
-/*
- * Save a lwp's SPE state to its PCB.  The lwp must either be curlwp or traced
- * by curlwp (and stopped).  (The point being that the lwp must not be onproc
- * on another CPU during this function).
- */
 void
-vec_save_lwp(lwp_t *l, enum vec_op op)
+vec_state_release(lwp_t *l)
 {
-       struct cpu_info * const ci = curcpu();
-
-       /*
-        * If it's already in the PCB, there's nothing to do.
-        */
-       if ((l->l_md.md_flags & MDLWP_OWNVEC) == 0)
-               return;
-
        /*
-        * If we simply need to discard the information, then don't
-        * to save anything.
+        * Turn off SPV so the next SPE instruction will cause a
+        * SPE unavailable exception
         */
-       if (op == VEC_DISCARD) {
-               struct cpu_info * const veccpu = l->l_md.md_veccpu;
-#ifndef MULTIPROCESSOR
-               KASSERT(ci == veccpu);
-#endif
-               KASSERT(l == veccpu->ci_veclwp);
-               KASSERT(l == curlwp || ci == veccpu);
-               ci->ci_veclwp = ci->ci_data.cpu_idlelwp;
-               atomic_and_uint(&l->l_md.md_flags, ~MDLWP_OWNVEC);
-               return;
-       }
-
-       KASSERT(l == ci->ci_veclwp);
-       vec_save_cpu(op);
+       l->l_md.md_utf->tf_srr1 &= ~PSL_SPV;
 }
 
 void
@@ -174,7 +144,9 @@
        struct pcb * const pcb = lwp_getpcb(l);
        const union __vr *vr = mcp->__vrf.__vrs;
 
-       vec_save_lwp(l, VEC_DISCARD);
+       KASSERT(l == curlwp);
+
+       vec_save();
 
        /* grab the accumulator */
        pcb->pcb_vr.vreg[8][0] = vr->__vr32[2];
@@ -198,10 +170,12 @@
 {
        struct pcb * const pcb = lwp_getpcb(l);
 
-       if ((l->l_md.md_flags & MDLWP_USEDVEC) == 0)
+       KASSERT(l == curlwp);
+
+       if (!vec_used_p(l))
                return false;
 
-       vec_save_lwp(l, VEC_SAVE);
+       vec_save();
 
        mcp->__gregs[_REG_MSR] |= PSL_SPV;
 
diff -r cf0c3267cdc8 -r 2191d0d74c97 sys/arch/powerpc/booke/trap.c
--- a/sys/arch/powerpc/booke/trap.c     Mon May 02 01:49:23 2011 +0000
+++ b/sys/arch/powerpc/booke/trap.c     Mon May 02 02:01:32 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: trap.c,v 1.5 2011/02/17 13:53:32 matt Exp $    */
+/*     $NetBSD: trap.c,v 1.6 2011/05/02 02:01:32 matt Exp $    */
 /*-
  * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -39,7 +39,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(1, "$NetBSD: trap.c,v 1.5 2011/02/17 13:53:32 matt Exp $");
+__KERNEL_RCSID(1, "$NetBSD: trap.c,v 1.6 2011/05/02 02:01:32 matt Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -400,7 +400,7 @@
        ci->ci_ev_vec.ev_count++;
 
 #ifdef PPC_HAVE_SPE
-       vec_enable();
+       vec_load();
        return 0;
 #else
        KSI_INIT_TRAP(ksi);
diff -r cf0c3267cdc8 -r 2191d0d74c97 sys/arch/powerpc/conf/files.powerpc
--- a/sys/arch/powerpc/conf/files.powerpc       Mon May 02 01:49:23 2011 +0000
+++ b/sys/arch/powerpc/conf/files.powerpc       Mon May 02 02:01:32 2011 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files.powerpc,v 1.75 2011/04/26 15:51:24 joerg Exp $
+#      $NetBSD: files.powerpc,v 1.76 2011/05/02 02:01:32 matt Exp $
 
 defflag        opt_altivec.h   ALTIVEC K_ALTIVEC PPC_HAVE_SPE
 defflag        opt_openpic.h   OPENPIC OPENPIC_SERIAL_MODE
@@ -35,6 +35,7 @@
 file   arch/powerpc/powerpc/db_disasm.c                ddb
 file   arch/powerpc/powerpc/db_interface.c             ddb | kgdb
 file   arch/powerpc/powerpc/db_trace.c                 ddb
+file   arch/powerpc/powerpc/fpu.c
 
 # IBM 4xx Family files (40x)
 file   arch/powerpc/ibm4xx/pmap.c                      ppc_ibm4xx
@@ -53,7 +54,6 @@
 file   arch/powerpc/oea/pmap64.c                       ppc_oea64
 file   arch/powerpc/oea/pmap64_bridge.c                ppc_oea64_bridge
 file   arch/powerpc/oea/pmap_kernel.c                  ppc_oea | ppc_oea64 | ppc_oea64_bridge | ppc_oea601
-file   arch/powerpc/powerpc/fpu.c                      ppc_oea | ppc_oea64 | ppc_oea64_bridge | ppc_oea601
 file   arch/powerpc/powerpc/trap.c                     ppc_oea | ppc_oea64 | ppc_oea64_bridge | ppc_oea601
 
 # PPC BookE (MPC85xx) Family files
diff -r cf0c3267cdc8 -r 2191d0d74c97 sys/arch/powerpc/include/altivec.h
--- a/sys/arch/powerpc/include/altivec.h        Mon May 02 01:49:23 2011 +0000
+++ b/sys/arch/powerpc/include/altivec.h        Mon May 02 02:01:32 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: altivec.h,v 1.13 2011/01/18 01:02:54 matt Exp $        */
+/*     $NetBSD: altivec.h,v 1.14 2011/05/02 02:01:32 matt Exp $        */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -36,24 +36,44 @@
 #define        VSCR_NJ         0x00010000      /* Non Java-IEEE-C9X FP mode */
 
 #ifdef _KERNEL
+#include <sys/pcu.h>
 #include <powerpc/mcontext.h>
 
-enum vec_op { VEC_SAVE, VEC_DISCARD, VEC_SAVE_AND_RELEASE };
 struct lwp;
 struct vreg;
 struct trapframe;
 
-void   vec_enable(void);
-void   vec_save_cpu(enum vec_op);
-void   vec_save_lwp(struct lwp *, enum vec_op);



Home | Main Index | Thread Index | Old Index