[BACK]Return to vfp_init.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / arm / vfp

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/arch/arm/vfp/vfp_init.c between version 1.41.4.5 and 1.42

version 1.41.4.5, 2017/08/28 17:51:32 version 1.42, 2015/02/09 07:55:52
Line 95  load_vfpregs(const struct vfpreg *fregs)
Line 95  load_vfpregs(const struct vfpreg *fregs)
         case FPU_VFP_CORTEXA9:          case FPU_VFP_CORTEXA9:
         case FPU_VFP_CORTEXA15:          case FPU_VFP_CORTEXA15:
         case FPU_VFP_CORTEXA15_QEMU:          case FPU_VFP_CORTEXA15_QEMU:
         case FPU_VFP_CORTEXA53:  
         case FPU_VFP_CORTEXA57:  
 #endif  #endif
                 load_vfpregs_hi(fregs->vfp_regs);                  load_vfpregs_hi(fregs->vfp_regs);
 #ifdef CPU_ARM11  #ifdef CPU_ARM11
Line 119  save_vfpregs(struct vfpreg *fregs)
Line 117  save_vfpregs(struct vfpreg *fregs)
         case FPU_VFP_CORTEXA9:          case FPU_VFP_CORTEXA9:
         case FPU_VFP_CORTEXA15:          case FPU_VFP_CORTEXA15:
         case FPU_VFP_CORTEXA15_QEMU:          case FPU_VFP_CORTEXA15_QEMU:
         case FPU_VFP_CORTEXA53:  
         case FPU_VFP_CORTEXA57:  
 #endif  #endif
                 save_vfpregs_hi(fregs->vfp_regs);                  save_vfpregs_hi(fregs->vfp_regs);
 #ifdef CPU_ARM11  #ifdef CPU_ARM11
Line 198  vfp_fpscr_handler(u_int address, u_int i
Line 194  vfp_fpscr_handler(u_int address, u_int i
         if (pcb->pcb_vfp.vfp_fpexc & VFP_FPEXC_EN)          if (pcb->pcb_vfp.vfp_fpexc & VFP_FPEXC_EN)
                 return 1;                  return 1;
   
         if (__predict_false(!vfp_used_p(l))) {          if (__predict_false(!vfp_used_p())) {
                 pcb->pcb_vfp.vfp_fpscr = vfp_fpscr_default;                  pcb->pcb_vfp.vfp_fpscr = vfp_fpscr_default;
         }          }
 #endif  #endif
Line 215  vfp_fpscr_handler(u_int address, u_int i
Line 211  vfp_fpscr_handler(u_int address, u_int i
         }          }
   
         curcpu()->ci_vfp_evs[0].ev_count++;          curcpu()->ci_vfp_evs[0].ev_count++;
   
         frame->tf_pc += INSN_SIZE;          frame->tf_pc += INSN_SIZE;
         return 0;          return 0;
 }  }
Line 269  vfp_attach(struct cpu_info *ci)
Line 265  vfp_attach(struct cpu_info *ci)
                 cpacr |= __SHIFTIN(CPACR_ALL, cpacr_vfp2);                  cpacr |= __SHIFTIN(CPACR_ALL, cpacr_vfp2);
                 armreg_cpacr_write(cpacr);                  armreg_cpacr_write(cpacr);
   
                 arm_isb();  
   
                 /*                  /*
                  * If we could enable them, then they exist.                   * If we could enable them, then they exist.
                  */                   */
Line 321  vfp_attach(struct cpu_info *ci)
Line 315  vfp_attach(struct cpu_info *ci)
         case FPU_VFP_CORTEXA9:          case FPU_VFP_CORTEXA9:
         case FPU_VFP_CORTEXA15:          case FPU_VFP_CORTEXA15:
         case FPU_VFP_CORTEXA15_QEMU:          case FPU_VFP_CORTEXA15_QEMU:
         case FPU_VFP_CORTEXA53:  
         case FPU_VFP_CORTEXA57:  
                 if (armreg_cpacr_read() & CPACR_V7_ASEDIS) {                  if (armreg_cpacr_read() & CPACR_V7_ASEDIS) {
                         model = "VFP 4.0+";                          model = "VFP 4.0+";
                 } else {                  } else {
Line 354  vfp_attach(struct cpu_info *ci)
Line 346  vfp_attach(struct cpu_info *ci)
                     ((f0 & ARM_MVFR0_EXCEPT_MASK) ? ", exceptions" : ""),                      ((f0 & ARM_MVFR0_EXCEPT_MASK) ? ", exceptions" : ""),
                     ((f1 & ARM_MVFR1_D_NAN_MASK) ? ", NaN propagation" : ""),                      ((f1 & ARM_MVFR1_D_NAN_MASK) ? ", NaN propagation" : ""),
                     ((f1 & ARM_MVFR1_FTZ_MASK) ? ", denormals" : ""));                      ((f1 & ARM_MVFR1_FTZ_MASK) ? ", denormals" : ""));
                 aprint_debug("vfp%d: mvfr: [0]=%#x [1]=%#x\n",                  aprint_verbose("vfp%d: mvfr: [0]=%#x [1]=%#x\n",
                     device_unit(ci->ci_dev), f0, f1);                      device_unit(ci->ci_dev), f0, f1);
                 if (CPU_IS_PRIMARY(ci)) {                  if (CPU_IS_PRIMARY(ci)) {
                         if (f0 & ARM_MVFR0_ROUNDING_MASK) {                          if (f0 & ARM_MVFR0_ROUNDING_MASK) {
Line 384  vfp_attach(struct cpu_info *ci)
Line 376  vfp_attach(struct cpu_info *ci)
         install_coproc_handler(VFP_COPROC, vfp_handler);          install_coproc_handler(VFP_COPROC, vfp_handler);
         install_coproc_handler(VFP_COPROC2, vfp_handler);          install_coproc_handler(VFP_COPROC2, vfp_handler);
 #ifdef CPU_CORTEX  #ifdef CPU_CORTEX
         if (cpu_neon_present)          install_coproc_handler(CORE_UNKNOWN_HANDLER, neon_handler);
                 install_coproc_handler(CORE_UNKNOWN_HANDLER, neon_handler);  
 #endif  #endif
 }  }
   
Line 405  vfp_handler(u_int address, u_int insn, t
Line 396  vfp_handler(u_int address, u_int insn, t
         }          }
   
         /*          /*
          * If we are just changing/fetching FPSCR, don't bother loading it           * If we are just changing/fetching FPSCR, don't bother loading it.
          * just emulate the instruction.  
          */           */
         if (!vfp_fpscr_handler(address, insn, frame, fault_code))          if (!vfp_fpscr_handler(address, insn, frame, fault_code))
                 return 0;                  return 0;
   
         /*          /*
          * If we already own the FPU and it's enabled (and no exception), raise  
          * SIGILL.  If there is an exception, drop through to raise a SIGFPE.  
          */  
         if (curcpu()->ci_pcu_curlwp[PCU_FPU] == curlwp  
             && (armreg_fpexc_read() & (VFP_FPEXC_EX|VFP_FPEXC_EN)) == VFP_FPEXC_EN)  
                 return 1;  
   
         /*  
          * Make sure we own the FP.           * Make sure we own the FP.
          */           */
         pcu_load(&arm_vfp_ops);          pcu_load(&arm_vfp_ops);
Line 437  vfp_handler(u_int address, u_int insn, t
Line 419  vfp_handler(u_int address, u_int insn, t
                  */                   */
                 armreg_fpexc_write(fpexc & ~(VFP_FPEXC_EX|VFP_FPEXC_FSUM));                  armreg_fpexc_write(fpexc & ~(VFP_FPEXC_EX|VFP_FPEXC_FSUM));
   
                 pcu_save(&arm_vfp_ops, curlwp);                  pcu_save(&arm_vfp_ops);
   
                 /*                  /*
                  * XXX Need to emulate bounce instructions here to get correct                   * XXX Need to emulate bounce instructions here to get correct
Line 486  neon_handler(u_int address, u_int insn, 
Line 468  neon_handler(u_int address, u_int insn, 
         if (fault_code != FAULT_USER)          if (fault_code != FAULT_USER)
                 panic("NEON fault in non-user mode");                  panic("NEON fault in non-user mode");
   
         /* if we already own the FPU and it's enabled, raise SIGILL */  
         if (curcpu()->ci_pcu_curlwp[PCU_FPU] == curlwp  
             && (armreg_fpexc_read() & VFP_FPEXC_EN) != 0)  
                 return 1;  
   
         pcu_load(&arm_vfp_ops);          pcu_load(&arm_vfp_ops);
   
         /* Need to restart the faulted instruction.  */          /* Need to restart the faulted instruction.  */
Line 549  vfp_state_load(lwp_t *l, u_int flags)
Line 526  vfp_state_load(lwp_t *l, u_int flags)
   
         if (fregs->vfp_fpexc & VFP_FPEXC_EX) {          if (fregs->vfp_fpexc & VFP_FPEXC_EX) {
                 /* Need to restore the exception handling state.  */                  /* Need to restore the exception handling state.  */
                 armreg_fpinst_write(fregs->vfp_fpinst);                  armreg_fpinst2_write(fregs->vfp_fpinst2);
                 if (fregs->vfp_fpexc & VFP_FPEXC_FP2V)                  if (fregs->vfp_fpexc & VFP_FPEXC_FP2V)
                         armreg_fpinst2_write(fregs->vfp_fpinst2);                          armreg_fpinst_write(fregs->vfp_fpinst);
         }          }
 }  }
   
Line 606  vfp_state_release(lwp_t *l)
Line 583  vfp_state_release(lwp_t *l)
 }  }
   
 void  void
 vfp_savecontext(lwp_t *l)  vfp_savecontext(void)
 {  {
         pcu_save(&arm_vfp_ops, l);          pcu_save(&arm_vfp_ops);
 }  }
   
 void  void
 vfp_discardcontext(lwp_t *l, bool used_p)  vfp_discardcontext(bool used_p)
 {  {
         pcu_discard(&arm_vfp_ops, l, used_p);          pcu_discard(&arm_vfp_ops, used_p);
 }  }
   
 bool  bool
 vfp_used_p(const lwp_t *l)  vfp_used_p(void)
 {  {
         return pcu_valid_p(&arm_vfp_ops, l);          return pcu_valid_p(&arm_vfp_ops);
 }  }
   
 void  void
 vfp_getcontext(struct lwp *l, mcontext_t *mcp, int *flagsp)  vfp_getcontext(struct lwp *l, mcontext_t *mcp, int *flagsp)
 {  {
         if (vfp_used_p(l)) {          if (vfp_used_p()) {
                 const struct pcb * const pcb = lwp_getpcb(l);                  const struct pcb * const pcb = lwp_getpcb(l);
                   pcu_save(&arm_vfp_ops);
                 pcu_save(&arm_vfp_ops, l);  
                 mcp->__fpu.__vfpregs.__vfp_fpscr = pcb->pcb_vfp.vfp_fpscr;                  mcp->__fpu.__vfpregs.__vfp_fpscr = pcb->pcb_vfp.vfp_fpscr;
                 memcpy(mcp->__fpu.__vfpregs.__vfp_fstmx, pcb->pcb_vfp.vfp_regs,                  memcpy(mcp->__fpu.__vfpregs.__vfp_fstmx, pcb->pcb_vfp.vfp_regs,
                     sizeof(mcp->__fpu.__vfpregs.__vfp_fstmx));                      sizeof(mcp->__fpu.__vfpregs.__vfp_fstmx));
Line 640  vfp_getcontext(struct lwp *l, mcontext_t
Line 616  vfp_getcontext(struct lwp *l, mcontext_t
 void  void
 vfp_setcontext(struct lwp *l, const mcontext_t *mcp)  vfp_setcontext(struct lwp *l, const mcontext_t *mcp)
 {  {
           pcu_discard(&arm_vfp_ops, true);
         struct pcb * const pcb = lwp_getpcb(l);          struct pcb * const pcb = lwp_getpcb(l);
   
         pcu_discard(&arm_vfp_ops, l, true);  
         pcb->pcb_vfp.vfp_fpscr = mcp->__fpu.__vfpregs.__vfp_fpscr;          pcb->pcb_vfp.vfp_fpscr = mcp->__fpu.__vfpregs.__vfp_fpscr;
         memcpy(pcb->pcb_vfp.vfp_regs, mcp->__fpu.__vfpregs.__vfp_fstmx,          memcpy(pcb->pcb_vfp.vfp_regs, mcp->__fpu.__vfpregs.__vfp_fstmx,
             sizeof(mcp->__fpu.__vfpregs.__vfp_fstmx));              sizeof(mcp->__fpu.__vfpregs.__vfp_fstmx));

Legend:
Removed from v.1.41.4.5  
changed lines
  Added in v.1.42

CVSweb <webmaster@jp.NetBSD.org>