Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/x86_64 Fix up the FP code some, and make it deliver...



details:   https://anonhg.NetBSD.org/src/rev/6c44605a950c
branches:  trunk
changeset: 532674:6c44605a950c
user:      fvdl <fvdl%NetBSD.org@localhost>
date:      Wed Jun 12 19:13:27 2002 +0000

description:
Fix up the FP code some, and make it deliver XMM exceptions. Adapt
sigframe a bit.

diffstat:

 sys/arch/x86_64/include/fpu.h             |  27 ++++++++++++++++++----
 sys/arch/x86_64/include/frame.h           |   3 +-
 sys/arch/x86_64/include/pcb.h             |   4 +-
 sys/arch/x86_64/x86_64/fpu.c              |  36 +++++++++++++++++++++++++-----
 sys/arch/x86_64/x86_64/locore.S           |   4 +-
 sys/arch/x86_64/x86_64/machdep.c          |  24 +++++++++++++++-----
 sys/arch/x86_64/x86_64/netbsd32_machdep.c |   7 ++++-
 sys/arch/x86_64/x86_64/process_machdep.c  |   4 +-
 sys/arch/x86_64/x86_64/trap.c             |  11 ++++++--
 sys/arch/x86_64/x86_64/vector.S           |   6 +++-
 10 files changed, 94 insertions(+), 32 deletions(-)

diffs (truncated from 391 to 300 lines):

diff -r 39bc3caaaf5a -r 6c44605a950c sys/arch/x86_64/include/fpu.h
--- a/sys/arch/x86_64/include/fpu.h     Wed Jun 12 19:09:37 2002 +0000
+++ b/sys/arch/x86_64/include/fpu.h     Wed Jun 12 19:13:27 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: fpu.h,v 1.2 2002/01/03 04:28:31 thorpej Exp $  */
+/*     $NetBSD: fpu.h,v 1.3 2002/06/12 19:13:27 fvdl Exp $     */
 
 #ifndef        _X86_64_FPU_H_
 #define        _X86_64_FPU_H_
@@ -12,18 +12,26 @@
 struct fxsave64 {
 /*BITFIELDTYPE*/ u_int64_t     fx_fcw:16;
 /*BITFIELDTYPE*/ u_int64_t     fx_fsw:16;
+/*BITFIELDTYPE*/ u_int64_t     fx_ftw:8;
 /*BITFIELDTYPE*/ u_int64_t     fx_unused1:8;
-/*BITFIELDTYPE*/ u_int64_t     fx_ftw:8;
 /*BITFIELDTYPE*/ u_int64_t     fx_fop:16;
 /*BITFIELDTYPE*/ u_int64_t     fx_rip;
-/*BITFIELDTYPE*/ u_int64_t     fx_dp;
+/*BITFIELDTYPE*/ u_int64_t     fx_rdp;
 /*BITFIELDTYPE*/ u_int64_t     fx_mxcsr:32;
-/*BITFIELDTYPE*/ u_int64_t     fx_unused2:32;
+/*BITFIELDTYPE*/ u_int64_t     fx_mxcsr_mask:32;
 /*BITFIELDTYPE*/ u_int64_t     fx_st[8 * 2];   /* 8 normal FP regs */
 /*BITFIELDTYPE*/ u_int64_t     fx_xmm[16 * 2]; /* 16 SSE2 registers */
 /*BITFIELDTYPE*/ u_int8_t      fx_unused3[96];
 } __attribute__ ((aligned (16)));
 
+#ifdef _KERNEL
+
+struct savefpu {
+       struct fxsave64 fp_fxsave;      /* see above */
+       u_int16_t fp_ex_sw;             /* saved status from last exception */
+       u_int16_t fp_ex_tw;             /* saved tag from last exception */
+};
+
 /*
  * This one only used for backward compat coredumping.
  */
@@ -41,13 +49,17 @@
        u_int16_t       fs_opsel;
 } __attribute__ ((packed));
 
+#endif
+
 
 /*
  * The i387 defaults to Intel extended precision mode and round to nearest,
  * with all exceptions masked.
- * XXXfvdl check this. This stuff is probably invalid.
  */
 #define        __INITIAL_NPXCW__       0x037f
+#define __INITIAL_MXCSR__      0x1f80
+#define __INITIAL_MXCSR_MASK__ 0xffbf
+
 /* NetBSD uses IEEE double precision. */
 #define        __NetBSD_NPXCW__        0x127f
 /* Linux just uses the default control word. */
@@ -69,6 +81,8 @@
  * because it makes the results of calculations depend on whether
  * intermediate values are stored in memory or in FPU registers.
  */
+
+#ifdef _KERNEL
 /*
  * XXX
  */
@@ -77,8 +91,11 @@
 extern void fpuinit(void);
 extern void fpudrop(void);
 extern void fpusave(void);
+extern void fpudiscard(struct proc *);
 extern void fputrap(struct trapframe *);
 
 extern struct proc *fpuproc;
 
+#endif
+
 #endif /* _X86_64_FPU_H_ */
diff -r 39bc3caaaf5a -r 6c44605a950c sys/arch/x86_64/include/frame.h
--- a/sys/arch/x86_64/include/frame.h   Wed Jun 12 19:09:37 2002 +0000
+++ b/sys/arch/x86_64/include/frame.h   Wed Jun 12 19:13:27 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: frame.h,v 1.2 2002/05/28 23:11:38 fvdl Exp $   */
+/*     $NetBSD: frame.h,v 1.3 2002/06/12 19:13:27 fvdl Exp $   */
 
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -172,7 +172,6 @@
        struct  sigcontext *sf_scp;
        sig_t   sf_handler;
        struct  sigcontext sf_sc;
-       struct  fxsave64 *sf_fpp;
        struct  fxsave64 sf_fp;
 };
 
diff -r 39bc3caaaf5a -r 6c44605a950c sys/arch/x86_64/include/pcb.h
--- a/sys/arch/x86_64/include/pcb.h     Wed Jun 12 19:09:37 2002 +0000
+++ b/sys/arch/x86_64/include/pcb.h     Wed Jun 12 19:13:27 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pcb.h,v 1.3 2002/06/03 18:23:16 fvdl Exp $     */
+/*     $NetBSD: pcb.h,v 1.4 2002/06/12 19:13:27 fvdl Exp $     */
 
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -106,7 +106,7 @@
        u_int64_t pcb_usersp;
        u_int64_t pcb_ldt_sel;
        int     pcb_cr0;                /* saved image of CR0 */
-       struct  fxsave64 pcb_savefpu;   /* floating point state */
+       struct  savefpu pcb_savefpu;    /* floating point state */
        int     pcb_flags;
 #define        PCB_USER_LDT    0x01            /* has user-set LDT */
        caddr_t pcb_onfault;            /* copyin/out fault recovery */
diff -r 39bc3caaaf5a -r 6c44605a950c sys/arch/x86_64/x86_64/fpu.c
--- a/sys/arch/x86_64/x86_64/fpu.c      Wed Jun 12 19:09:37 2002 +0000
+++ b/sys/arch/x86_64/x86_64/fpu.c      Wed Jun 12 19:13:27 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: fpu.c,v 1.1 2001/06/19 00:21:16 fvdl Exp $     */
+/*     $NetBSD: fpu.c,v 1.2 2002/06/12 19:13:27 fvdl Exp $     */
 
 /*-
  * Copyright (c) 1994, 1995, 1998 Charles M. Hannum.  All rights reserved.
@@ -89,6 +89,7 @@
 #define fwait()                        __asm("fwait")
 #define        fxsave(addr)            __asm("fxsave %0" : "=m" (*addr))
 #define        fxrstor(addr)           __asm("fxrstor %0" : : "m" (*addr))
+#define fldcw(addr)            __asm("fldcw %0" : : "m" (*addr))
 #define        clts()                  __asm("clts")
 #define        stts()                  lcr0(rcr0() | CR0_TS)
 
@@ -116,11 +117,14 @@
  * Reinitializing the state allows naive SIGFPE handlers to longjmp without
  * doing any fixups.
  */
+
 void
 fputrap(frame)
        struct trapframe *frame;
 {
        register struct proc *p = fpuproc;
+       struct savefpu *sfp = &p->p_addr->u_pcb.pcb_savefpu;
+       u_int16_t cw;
 
 #ifdef DIAGNOSTIC
        /*
@@ -131,9 +135,17 @@
                panic("fputrap: wrong process");
 #endif
 
-       fxsave(&p->p_addr->u_pcb.pcb_savefpu);
-       fninit();
-       fwait();
+       fxsave(sfp);
+       if (frame->tf_trapno == T_XMM) {
+       } else {
+               fninit();
+               fwait();
+               cw = sfp->fp_fxsave.fx_fcw;
+               fldcw(&cw);
+               fwait();
+       }
+       sfp->fp_ex_tw = sfp->fp_fxsave.fx_ftw;
+       sfp->fp_ex_sw = sfp->fp_fxsave.fx_fsw;
        trapsignal(p, SIGFPE, frame->tf_err);
 }
 
@@ -166,6 +178,7 @@
        if (cpl != 0)
                panic("fpudna: masked");
 #endif
+       u_int16_t cw;
 
        p->p_addr->u_pcb.pcb_cr0 &= ~CR0_TS;
        clts();
@@ -182,9 +195,11 @@
 
        fpuproc = p;
 
-       if ((p->p_md.md_flags & MDP_USEDFPU) == 0)
+       if ((p->p_md.md_flags & MDP_USEDFPU) == 0) {
+               cw = p->p_addr->u_pcb.pcb_savefpu.fp_fxsave.fx_fcw;
+               fldcw(&cw);
                p->p_md.md_flags |= MDP_USEDFPU;
-       else
+       } else
                fxrstor(&p->p_addr->u_pcb.pcb_savefpu);
 }
 
@@ -223,3 +238,12 @@
        fpuproc = 0;
        stts();
 }
+
+void
+fpudiscard(struct proc *p)
+{
+       if (p == fpuproc) {
+               fpuproc = 0;
+               stts();
+       }
+}
diff -r 39bc3caaaf5a -r 6c44605a950c sys/arch/x86_64/x86_64/locore.S
--- a/sys/arch/x86_64/x86_64/locore.S   Wed Jun 12 19:09:37 2002 +0000
+++ b/sys/arch/x86_64/x86_64/locore.S   Wed Jun 12 19:13:27 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: locore.S,v 1.5 2002/06/03 18:23:17 fvdl Exp $  */
+/*     $NetBSD: locore.S,v 1.6 2002/06/12 19:13:27 fvdl Exp $  */
 
 /*
  * Copyright-o-rama!
@@ -546,7 +546,7 @@
         * 1. Enable PAE (and SSE while here).
         */
        movl    %cr4,%eax
-       orl     $(CR4_PAE|CR4_OSFXSR),%eax
+       orl     $(CR4_PAE|CR4_OSFXSR|CR4_OSXMMEXCPT),%eax
        movl    %eax,%cr4
 
        /*
diff -r 39bc3caaaf5a -r 6c44605a950c sys/arch/x86_64/x86_64/machdep.c
--- a/sys/arch/x86_64/x86_64/machdep.c  Wed Jun 12 19:09:37 2002 +0000
+++ b/sys/arch/x86_64/x86_64/machdep.c  Wed Jun 12 19:13:27 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: machdep.c,v 1.9 2002/06/04 15:44:34 fvdl Exp $ */
+/*     $NetBSD: machdep.c,v 1.10 2002/06/12 19:13:27 fvdl Exp $        */
 
 /*-
  * Copyright (c) 1996, 1997, 1998, 2000 The NetBSD Foundation, Inc.
@@ -493,16 +493,17 @@
         * fxsave and the ABI.
         */
        sp = (char *)((unsigned long)sp & ~15);
+       fp = (struct sigframe *)sp - 1;
+
        if (p->p_md.md_flags & MDP_USEDFPU) {
-               frame.sf_fpp = &frame.sf_fp;
-               memcpy(frame.sf_fpp, &p->p_addr->u_pcb.pcb_savefpu,     
+               frame.sf_sc.sc_fpstate = &fp->sf_fp;
+               memcpy(&frame.sf_fp, &p->p_addr->u_pcb.pcb_savefpu.fp_fxsave,
                    sizeof (struct fxsave64));
                tocopy = sizeof (struct sigframe);
        } else {
-               frame.sf_fpp = NULL;
+               frame.sf_sc.sc_fpstate = NULL;
                tocopy = sizeof (struct sigframe) - sizeof (struct fxsave64);
        }
-       fp = (struct sigframe *)sp - 1;
 
        /* Build stack frame for signal trampoline. */
        frame.sf_signum = sig;
@@ -636,6 +637,15 @@
        tf->tf_rsp = context.sc_rsp;
        tf->tf_ss = context.sc_ss;
 
+       /* Restore (possibly fixed up) FP state and force it to be reloaded */
+       if (p->p_md.md_flags & MDP_USEDFPU) {
+               if (copyin(context.sc_fpstate,
+                   &p->p_addr->u_pcb.pcb_savefpu.fp_fxsave,
+                   sizeof (struct fxsave64)) != 0)
+                       return EFAULT;
+               fpudiscard(p);
+       }
+
        /* Restore signal stack. */
        if (context.sc_onstack & SS_ONSTACK)
                p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK;
@@ -982,7 +992,9 @@
 
        p->p_md.md_flags &= ~MDP_USEDFPU;
        pcb->pcb_flags = 0;
-       pcb->pcb_savefpu.fx_fcw = __NetBSD_NPXCW__;
+       pcb->pcb_savefpu.fp_fxsave.fx_fcw = __NetBSD_NPXCW__;
+       pcb->pcb_savefpu.fp_fxsave.fx_mxcsr = __INITIAL_MXCSR__;
+       pcb->pcb_savefpu.fp_fxsave.fx_mxcsr_mask = __INITIAL_MXCSR_MASK__;
 
        p->p_flag &= ~P_32;
 
diff -r 39bc3caaaf5a -r 6c44605a950c sys/arch/x86_64/x86_64/netbsd32_machdep.c
--- a/sys/arch/x86_64/x86_64/netbsd32_machdep.c Wed Jun 12 19:09:37 2002 +0000
+++ b/sys/arch/x86_64/x86_64/netbsd32_machdep.c Wed Jun 12 19:13:27 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: netbsd32_machdep.c,v 1.5 2002/06/04 11:14:22 fvdl Exp $        */
+/*     $NetBSD: netbsd32_machdep.c,v 1.6 2002/06/12 19:13:28 fvdl Exp $        */
 
 /*
  * Copyright (c) 2001 Wasabi Systems, Inc.
@@ -81,7 +81,10 @@
 
        p->p_md.md_flags &= ~MDP_USEDFPU;
        pcb->pcb_flags = 0;
-       pcb->pcb_savefpu.fx_fcw = __NetBSD_NPXCW__;
+        pcb->pcb_savefpu.fp_fxsave.fx_fcw = __NetBSD_NPXCW__;
+        pcb->pcb_savefpu.fp_fxsave.fx_mxcsr = __INITIAL_MXCSR__;  
+       pcb->pcb_savefpu.fp_fxsave.fx_mxcsr_mask = __INITIAL_MXCSR_MASK__;
+
 
        p->p_flag |= P_32;
 
diff -r 39bc3caaaf5a -r 6c44605a950c sys/arch/x86_64/x86_64/process_machdep.c



Home | Main Index | Thread Index | Old Index