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