svn commit: r284926 - in head/sys/i386: i386 include isa

Konstantin Belousov kib at FreeBSD.org
Mon Jun 29 12:06:38 UTC 2015


Author: kib
Date: Mon Jun 29 12:06:36 2015
New Revision: 284926
URL: https://svnweb.freebsd.org/changeset/base/284926

Log:
  Provide npx_get_fsave(9) and npx_set_fsave(9) functions to obtain and
  restore the FPU state from the format of machine FSAVE area.  The
  intended use is for ABI emulators to provide FSAVE-formatted FPU state
  to usermode requiring it, while kernel could use FXSAVE due to
  XMM/XSAVE.
  
  The core functionality to convert from/to FXSAVE format is shared with
  the fill_fpregs_xmm() and set_fpregs_xmm().  Move the later functions
  to npx.c and rename them to npx_fill_fpregs_xmm() and
  npx_set_fpregs_xmm().  They differ from nptx_get/set_fsave(9) since
  our mcontext contains padding to be zeroed or ignored.
  
  fill_fpregs() and set_fpregs() could be converted to use the new
  interface, but there are small differences to handle.
  
  Sponsored by:	The FreeBSD Foundation
  MFC after:	1 week

Modified:
  head/sys/i386/i386/machdep.c
  head/sys/i386/include/npx.h
  head/sys/i386/isa/npx.c

Modified: head/sys/i386/i386/machdep.c
==============================================================================
--- head/sys/i386/i386/machdep.c	Mon Jun 29 10:35:00 2015	(r284925)
+++ head/sys/i386/i386/machdep.c	Mon Jun 29 12:06:36 2015	(r284926)
@@ -176,10 +176,6 @@ static void get_fpcontext(struct thread 
     char *xfpusave, size_t xfpusave_len);
 static int  set_fpcontext(struct thread *td, mcontext_t *mcp,
     char *xfpustate, size_t xfpustate_len);
-#ifdef CPU_ENABLE_SSE
-static void set_fpregs_xmm(struct save87 *, struct savexmm *);
-static void fill_fpregs_xmm(struct savexmm *, struct save87 *);
-#endif /* CPU_ENABLE_SSE */
 SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL);
 
 /* Intel ICH registers */
@@ -2952,58 +2948,6 @@ set_regs(struct thread *td, struct reg *
 	return (0);
 }
 
-#ifdef CPU_ENABLE_SSE
-static void
-fill_fpregs_xmm(sv_xmm, sv_87)
-	struct savexmm *sv_xmm;
-	struct save87 *sv_87;
-{
-	register struct env87 *penv_87 = &sv_87->sv_env;
-	register struct envxmm *penv_xmm = &sv_xmm->sv_env;
-	int i;
-
-	bzero(sv_87, sizeof(*sv_87));
-
-	/* FPU control/status */
-	penv_87->en_cw = penv_xmm->en_cw;
-	penv_87->en_sw = penv_xmm->en_sw;
-	penv_87->en_tw = penv_xmm->en_tw;
-	penv_87->en_fip = penv_xmm->en_fip;
-	penv_87->en_fcs = penv_xmm->en_fcs;
-	penv_87->en_opcode = penv_xmm->en_opcode;
-	penv_87->en_foo = penv_xmm->en_foo;
-	penv_87->en_fos = penv_xmm->en_fos;
-
-	/* FPU registers */
-	for (i = 0; i < 8; ++i)
-		sv_87->sv_ac[i] = sv_xmm->sv_fp[i].fp_acc;
-}
-
-static void
-set_fpregs_xmm(sv_87, sv_xmm)
-	struct save87 *sv_87;
-	struct savexmm *sv_xmm;
-{
-	register struct env87 *penv_87 = &sv_87->sv_env;
-	register struct envxmm *penv_xmm = &sv_xmm->sv_env;
-	int i;
-
-	/* FPU control/status */
-	penv_xmm->en_cw = penv_87->en_cw;
-	penv_xmm->en_sw = penv_87->en_sw;
-	penv_xmm->en_tw = penv_87->en_tw;
-	penv_xmm->en_fip = penv_87->en_fip;
-	penv_xmm->en_fcs = penv_87->en_fcs;
-	penv_xmm->en_opcode = penv_87->en_opcode;
-	penv_xmm->en_foo = penv_87->en_foo;
-	penv_xmm->en_fos = penv_87->en_fos;
-
-	/* FPU registers */
-	for (i = 0; i < 8; ++i)
-		sv_xmm->sv_fp[i].fp_acc = sv_87->sv_ac[i];
-}
-#endif /* CPU_ENABLE_SSE */
-
 int
 fill_fpregs(struct thread *td, struct fpreg *fpregs)
 {
@@ -3018,7 +2962,7 @@ fill_fpregs(struct thread *td, struct fp
 #endif
 #ifdef CPU_ENABLE_SSE
 	if (cpu_fxsr)
-		fill_fpregs_xmm(&get_pcb_user_save_td(td)->sv_xmm,
+		npx_fill_fpregs_xmm(&get_pcb_user_save_td(td)->sv_xmm,
 		    (struct save87 *)fpregs);
 	else
 #endif /* CPU_ENABLE_SSE */
@@ -3033,7 +2977,7 @@ set_fpregs(struct thread *td, struct fpr
 
 #ifdef CPU_ENABLE_SSE
 	if (cpu_fxsr)
-		set_fpregs_xmm((struct save87 *)fpregs,
+		npx_set_fpregs_xmm((struct save87 *)fpregs,
 		    &get_pcb_user_save_td(td)->sv_xmm);
 	else
 #endif /* CPU_ENABLE_SSE */

Modified: head/sys/i386/include/npx.h
==============================================================================
--- head/sys/i386/include/npx.h	Mon Jun 29 10:35:00 2015	(r284925)
+++ head/sys/i386/include/npx.h	Mon Jun 29 12:06:36 2015	(r284926)
@@ -67,6 +67,11 @@ void	npxsuspend(union savefpu *addr);
 int	npxtrap_x87(void);
 int	npxtrap_sse(void);
 void	npxuserinited(struct thread *);
+void	npx_get_fsave(void *);
+int	npx_set_fsave(void *);
+void	npx_fill_fpregs_xmm(struct savexmm *, struct save87 *);
+void	npx_set_fpregs_xmm(struct save87 *, struct savexmm *);
+
 struct fpu_kern_ctx *fpu_kern_alloc_ctx(u_int flags);
 void	fpu_kern_free_ctx(struct fpu_kern_ctx *ctx);
 int	fpu_kern_enter(struct thread *td, struct fpu_kern_ctx *ctx,

Modified: head/sys/i386/isa/npx.c
==============================================================================
--- head/sys/i386/isa/npx.c	Mon Jun 29 10:35:00 2015	(r284925)
+++ head/sys/i386/isa/npx.c	Mon Jun 29 12:06:36 2015	(r284926)
@@ -1160,6 +1160,102 @@ fpusave(addr)
 }
 
 #ifdef CPU_ENABLE_SSE
+static void
+npx_fill_fpregs_xmm1(struct savexmm *sv_xmm, struct save87 *sv_87)
+{
+	struct env87 *penv_87;
+	struct envxmm *penv_xmm;
+	int i;
+
+	penv_87 = &sv_87->sv_env;
+	penv_xmm = &sv_xmm->sv_env;
+
+	/* FPU control/status */
+	penv_87->en_cw = penv_xmm->en_cw;
+	penv_87->en_sw = penv_xmm->en_sw;
+	penv_87->en_tw = penv_xmm->en_tw;
+	penv_87->en_fip = penv_xmm->en_fip;
+	penv_87->en_fcs = penv_xmm->en_fcs;
+	penv_87->en_opcode = penv_xmm->en_opcode;
+	penv_87->en_foo = penv_xmm->en_foo;
+	penv_87->en_fos = penv_xmm->en_fos;
+
+	/* FPU registers */
+	for (i = 0; i < 8; ++i)
+		sv_87->sv_ac[i] = sv_xmm->sv_fp[i].fp_acc;
+}
+
+void
+npx_fill_fpregs_xmm(struct savexmm *sv_xmm, struct save87 *sv_87)
+{
+
+	bzero(sv_87, sizeof(*sv_87));
+	npx_fill_fpregs_xmm1(sv_xmm, sv_87);
+}
+
+void
+npx_set_fpregs_xmm(struct save87 *sv_87, struct savexmm *sv_xmm)
+{
+	struct env87 *penv_87;
+	struct envxmm *penv_xmm;
+	int i;
+
+	penv_87 = &sv_87->sv_env;
+	penv_xmm = &sv_xmm->sv_env;
+
+	/* FPU control/status */
+	penv_xmm->en_cw = penv_87->en_cw;
+	penv_xmm->en_sw = penv_87->en_sw;
+	penv_xmm->en_tw = penv_87->en_tw;
+	penv_xmm->en_fip = penv_87->en_fip;
+	penv_xmm->en_fcs = penv_87->en_fcs;
+	penv_xmm->en_opcode = penv_87->en_opcode;
+	penv_xmm->en_foo = penv_87->en_foo;
+	penv_xmm->en_fos = penv_87->en_fos;
+
+	/* FPU registers */
+	for (i = 0; i < 8; ++i)
+		sv_xmm->sv_fp[i].fp_acc = sv_87->sv_ac[i];
+}
+#endif /* CPU_ENABLE_SSE */
+
+void
+npx_get_fsave(void *addr)
+{
+	struct thread *td;
+	union savefpu *sv;
+
+	td = curthread;
+	npxgetregs(td);
+	sv = get_pcb_user_save_td(td);
+#ifdef CPU_ENABLE_SSE
+	if (cpu_fxsr)
+		npx_fill_fpregs_xmm1(&sv->sv_xmm, addr);
+	else
+#endif
+		bcopy(sv, addr, sizeof(struct env87) +
+		    sizeof(struct fpacc87[8]));
+}
+
+int
+npx_set_fsave(void *addr)
+{
+	union savefpu sv;
+	int error;
+
+	bzero(&sv, sizeof(sv));
+#ifdef CPU_ENABLE_SSE
+	if (cpu_fxsr)
+		npx_set_fpregs_xmm(addr, &sv.sv_xmm);
+	else
+#endif
+		bcopy(addr, &sv, sizeof(struct env87) +
+		    sizeof(struct fpacc87[8]));
+	error = npxsetregs(curthread, &sv, NULL, 0);
+	return (error);
+}
+
+#ifdef CPU_ENABLE_SSE
 /*
  * On AuthenticAMD processors, the fxrstor instruction does not restore
  * the x87's stored last instruction pointer, last data pointer, and last


More information about the svn-src-head mailing list