Author: nwhitehorn
Date: Sun Nov 17 14:44:22 2013
New Revision: 258257
URL: http://svnweb.freebsd.org/changeset/base/258257

Log:
  Split the function of the PCB_FPU flags into two: PCB_FPU now indicates that
  the actual FPU is enabled, while PCB_FPREGS indicates that the FPU state
  structure in the PCB is valid. This separation reflects the situation on
  FPU-less systems in which the FP state is used by the emulator but we don't
  actually want to try to turn on the non-existant FPU.
  
  Use this flag to save and restore FP regs properly on both AIM and Book-E.
  As a side effect, this sets up hard-FP and Altivec on Book-E CPUs with such
  abilities except for a trap handler to call enable_fpu()/enable_altivec().

Modified:
  head/sys/conf/files.powerpc
  head/sys/powerpc/booke/trap.c
  head/sys/powerpc/include/pcb.h
  head/sys/powerpc/powerpc/exec_machdep.c
  head/sys/powerpc/powerpc/fpu.c
  head/sys/powerpc/powerpc/swtch32.S

Modified: head/sys/conf/files.powerpc
==============================================================================
--- head/sys/conf/files.powerpc Sun Nov 17 14:07:00 2013        (r258256)
+++ head/sys/conf/files.powerpc Sun Nov 17 14:44:22 2013        (r258257)
@@ -165,7 +165,7 @@ powerpc/powermac/uninorth.c optional        pow
 powerpc/powermac/uninorthpci.c optional        powermac pci
 powerpc/powermac/vcoregpio.c   optional        powermac 
 powerpc/powermac/windtunnel.c  optional        powermac windtunnel
-powerpc/powerpc/altivec.c      optional        aim
+powerpc/powerpc/altivec.c      standard
 powerpc/powerpc/autoconf.c     standard
 powerpc/powerpc/bcopy.c                standard
 powerpc/powerpc/bus_machdep.c  standard
@@ -182,7 +182,7 @@ powerpc/powerpc/dump_machdep.c      standard
 powerpc/powerpc/elf32_machdep.c        optional        powerpc | 
compat_freebsd32
 powerpc/powerpc/elf64_machdep.c        optional        powerpc64
 powerpc/powerpc/exec_machdep.c standard
-powerpc/powerpc/fpu.c          optional        aim
+powerpc/powerpc/fpu.c          standard
 powerpc/powerpc/fuswintr.c     standard
 powerpc/powerpc/gdb_machdep.c  optional        gdb
 powerpc/powerpc/in_cksum.c     optional        inet | inet6

Modified: head/sys/powerpc/booke/trap.c
==============================================================================
--- head/sys/powerpc/booke/trap.c       Sun Nov 17 14:07:00 2013        
(r258256)
+++ head/sys/powerpc/booke/trap.c       Sun Nov 17 14:44:22 2013        
(r258257)
@@ -194,6 +194,11 @@ trap(struct trapframe *frame)
 
                case EXC_PGM:   /* Program exception */
 #ifdef FPU_EMU
+                       if (!(td->td_pcb->pcb_flags & PCB_FPREGS)) {
+                               bzero(&td->td_pcb->pcb_fpu,
+                                   sizeof(td->td_pcb->pcb_fpu));
+                               td->td_pcb->pcb_flags |= PCB_FPREGS;
+                       }
                        sig = fpu_emulate(frame,
                            (struct fpreg *)&td->td_pcb->pcb_fpu);
 #else

Modified: head/sys/powerpc/include/pcb.h
==============================================================================
--- head/sys/powerpc/include/pcb.h      Sun Nov 17 14:07:00 2013        
(r258256)
+++ head/sys/powerpc/include/pcb.h      Sun Nov 17 14:44:22 2013        
(r258257)
@@ -47,8 +47,9 @@ struct pcb {
        faultbuf        *pcb_onfault;           /* For use during
                                                    copyin/copyout */
        int             pcb_flags;
-#define        PCB_FPU         1       /* Process had FPU initialized */
-#define        PCB_VEC         2       /* Process had Altivec initialized */
+#define        PCB_FPU         1       /* Process uses FPU */
+#define        PCB_FPREGS      2       /* Process had FPU registers 
initialized */
+#define        PCB_VEC         4       /* Process had Altivec initialized */
        struct fpu {
                double  fpr[32];
                double  fpscr;  /* FPSCR stored as double for easier access */

Modified: head/sys/powerpc/powerpc/exec_machdep.c
==============================================================================
--- head/sys/powerpc/powerpc/exec_machdep.c     Sun Nov 17 14:07:00 2013        
(r258256)
+++ head/sys/powerpc/powerpc/exec_machdep.c     Sun Nov 17 14:44:22 2013        
(r258257)
@@ -381,19 +381,20 @@ grab_mcontext(struct thread *td, mcontex
                mcp->mc_gpr[4] = 0;
        }
 
-#ifdef AIM
        /*
         * This assumes that floating-point context is *not* lazy,
         * so if the thread has used FP there would have been a
         * FP-unavailable exception that would have set things up
         * correctly.
         */
-       if (pcb->pcb_flags & PCB_FPU) {
-               KASSERT(td == curthread,
-                       ("get_mcontext: fp save not curthread"));
-               critical_enter();
-               save_fpu(td);
-               critical_exit();
+       if (pcb->pcb_flags & PCB_FPREGS) {
+               if (pcb->pcb_flags & PCB_FPU) {
+                       KASSERT(td == curthread,
+                               ("get_mcontext: fp save not curthread"));
+                       critical_enter();
+                       save_fpu(td);
+                       critical_exit();
+               }
                mcp->mc_flags |= _MC_FP_VALID;
                memcpy(&mcp->mc_fpscr, &pcb->pcb_fpu.fpscr, sizeof(double));
                memcpy(mcp->mc_fpreg, pcb->pcb_fpu.fpr, 32*sizeof(double));
@@ -414,7 +415,6 @@ grab_mcontext(struct thread *td, mcontex
                mcp->mc_vrsave =  pcb->pcb_vec.vrsave;
                memcpy(mcp->mc_avec, pcb->pcb_vec.vr, sizeof(mcp->mc_avec));
        }
-#endif
 
        mcp->mc_len = sizeof(*mcp);
 
@@ -467,13 +467,9 @@ set_mcontext(struct thread *td, const mc
        else
                tf->fixreg[2] = tls;
 
-#ifdef AIM
        if (mcp->mc_flags & _MC_FP_VALID) {
-               if ((pcb->pcb_flags & PCB_FPU) != PCB_FPU) {
-                       critical_enter();
-                       enable_fpu(td);
-                       critical_exit();
-               }
+               /* enable_fpu() will happen lazily on a fault */
+               pcb->pcb_flags |= PCB_FPREGS;
                memcpy(&pcb->pcb_fpu.fpscr, &mcp->mc_fpscr, sizeof(double));
                memcpy(pcb->pcb_fpu.fpr, mcp->mc_fpreg, 32*sizeof(double));
        }
@@ -488,7 +484,6 @@ set_mcontext(struct thread *td, const mc
                pcb->pcb_vec.vrsave = mcp->mc_vrsave;
                memcpy(pcb->pcb_vec.vr, mcp->mc_avec, sizeof(mcp->mc_avec));
        }
-#endif
 
        return (0);
 }
@@ -625,7 +620,7 @@ fill_fpregs(struct thread *td, struct fp
 
        pcb = td->td_pcb;
 
-       if ((pcb->pcb_flags & PCB_FPU) == 0)
+       if ((pcb->pcb_flags & PCB_FPREGS) == 0)
                memset(fpregs, 0, sizeof(struct fpreg));
        else
                memcpy(fpregs, &pcb->pcb_fpu, sizeof(struct fpreg));
@@ -654,14 +649,11 @@ set_dbregs(struct thread *td, struct dbr
 int
 set_fpregs(struct thread *td, struct fpreg *fpregs)
 {
-#ifdef AIM
        struct pcb *pcb;
 
        pcb = td->td_pcb;
-       if ((pcb->pcb_flags & PCB_FPU) == 0)
-               enable_fpu(td);
+       pcb->pcb_flags |= PCB_FPREGS;
        memcpy(&pcb->pcb_fpu, fpregs, sizeof(struct fpreg));
-#endif
 
        return (0);
 }
@@ -1021,14 +1013,10 @@ cpu_set_upcall_kse(struct thread *td, vo
        tf->fixreg[3] = (register_t)arg;
        if (SV_PROC_FLAG(td->td_proc, SV_ILP32)) {
                tf->srr0 = (register_t)entry;
-           #ifdef AIM
                tf->srr1 = PSL_USERSET | PSL_FE_DFLT;
                #ifdef __powerpc64__
                tf->srr1 &= ~PSL_SF;
                #endif
-           #else
-               tf->srr1 = PSL_USERSET;
-           #endif
        } else {
            #ifdef __powerpc64__
                register_t entry_desc[3];

Modified: head/sys/powerpc/powerpc/fpu.c
==============================================================================
--- head/sys/powerpc/powerpc/fpu.c      Sun Nov 17 14:07:00 2013        
(r258256)
+++ head/sys/powerpc/powerpc/fpu.c      Sun Nov 17 14:44:22 2013        
(r258257)
@@ -66,10 +66,11 @@ enable_fpu(struct thread *td)
         * initialise the FPU registers and FPSCR to 0, and set the flag
         * to indicate that the FPU is in use.
         */
+       pcb->pcb_flags |= PCB_FPU;
        tf->srr1 |= PSL_FP;
-       if (!(pcb->pcb_flags & PCB_FPU)) {
+       if (!(pcb->pcb_flags & PCB_FPREGS)) {
                memset(&pcb->pcb_fpu, 0, sizeof pcb->pcb_fpu);
-               pcb->pcb_flags |= PCB_FPU;
+               pcb->pcb_flags |= PCB_FPREGS;
        }
 
        /*

Modified: head/sys/powerpc/powerpc/swtch32.S
==============================================================================
--- head/sys/powerpc/powerpc/swtch32.S  Sun Nov 17 14:07:00 2013        
(r258256)
+++ head/sys/powerpc/powerpc/swtch32.S  Sun Nov 17 14:44:22 2013        
(r258257)
@@ -100,7 +100,6 @@ ENTRY(cpu_switch)
        mr      %r16,%r5                /* and the new lock */
        mr      %r17,%r6                /* and the PCB */
        
-#ifdef AIM
        lwz     %r7,PCB_FLAGS(%r17)
        /* Save FPU context if needed */
        andi.   %r7, %r7, PCB_FPU
@@ -116,7 +115,6 @@ ENTRY(cpu_switch)
        bl      save_vec
        
 .L2:
-#endif
        mr      %r3,%r14                /* restore old thread ptr */
        bl      pmap_deactivate         /* Deactivate the current pmap */
 
@@ -143,7 +141,6 @@ blocked_loop:
        mr      %r3,%r2                 /* Get new thread ptr */
        bl      pmap_activate           /* Activate the new address space */
 
-#ifdef AIM
        lwz     %r6, PCB_FLAGS(%r17)
        /* Restore FPU context if needed */
        andi.   %r6, %r6, PCB_FPU
@@ -160,7 +157,6 @@ blocked_loop:
        bl      enable_vec
 
 .L4:
-#endif
        /* thread to restore is in r3 */
        mr      %r3,%r17                /* Recover PCB ptr */
        lmw     %r12,PCB_CONTEXT(%r3)   /* Load the non-volatile GP regs */
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to