Source-Changes-HG archive

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

[src/trunk]: src/sys/arch Determine whether the cpu supports xsave (and hence...



details:   https://anonhg.NetBSD.org/src/rev/d318e1717eb4
branches:  trunk
changeset: 326951:d318e1717eb4
user:      dsl <dsl%NetBSD.org@localhost>
date:      Sun Feb 23 12:56:40 2014 +0000

description:
Determine whether the cpu supports xsave (and hence AVX).
The result is only written to sysctl nodes at the moment.
I see:
machdep.fpu_save = 3 (implies xsaveopt)
machdep.xsave_size = 832
machdep.xsave_features = 7
Completely common up the i386 and amd64 machdep sysctl creation.

diffstat:

 sys/arch/amd64/amd64/machdep.c |   25 +------
 sys/arch/i386/i386/machdep.c   |   45 +------------
 sys/arch/x86/include/cpu.h     |   10 ++-
 sys/arch/x86/x86/fpu.c         |   33 +--------
 sys/arch/x86/x86/identcpu.c    |  142 +++++++++++++++++++++++++++++++---------
 sys/arch/x86/x86/x86_machdep.c |   34 ++++++++-
 6 files changed, 156 insertions(+), 133 deletions(-)

diffs (truncated from 472 to 300 lines):

diff -r 8d43e2d4a45f -r d318e1717eb4 sys/arch/amd64/amd64/machdep.c
--- a/sys/arch/amd64/amd64/machdep.c    Sun Feb 23 12:01:51 2014 +0000
+++ b/sys/arch/amd64/amd64/machdep.c    Sun Feb 23 12:56:40 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: machdep.c,v 1.206 2014/02/20 18:19:09 dsl Exp $        */
+/*     $NetBSD: machdep.c,v 1.207 2014/02/23 12:56:40 dsl Exp $        */
 
 /*-
  * Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011
@@ -111,7 +111,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.206 2014/02/20 18:19:09 dsl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.207 2014/02/23 12:56:40 dsl Exp $");
 
 /* #define XENDEBUG_LOW  */
 
@@ -511,27 +511,6 @@
        ci->ci_tss_sel = tss_alloc(tss);
 }
 
-SYSCTL_SETUP(sysctl_machdep_setup, "sysctl machdep subtree setup")
-{
-       x86_sysctl_machdep_setup(clog);
-
-       sysctl_createv(clog, 0, NULL, NULL,
-                      CTLFLAG_PERMANENT | CTLFLAG_IMMEDIATE,
-                      CTLTYPE_INT, "fpu_present", NULL,
-                      NULL, 1, NULL, 0,
-                      CTL_MACHDEP, CPU_FPU_PRESENT, CTL_EOL);
-       sysctl_createv(clog, 0, NULL, NULL,
-                      CTLFLAG_PERMANENT | CTLFLAG_IMMEDIATE,
-                      CTLTYPE_INT, "sse", NULL,
-                      NULL, 1, NULL, 0,
-                      CTL_MACHDEP, CPU_SSE, CTL_EOL);
-       sysctl_createv(clog, 0, NULL, NULL,
-                      CTLFLAG_PERMANENT | CTLFLAG_IMMEDIATE,
-                      CTLTYPE_INT, "sse2", NULL,
-                      NULL, 1, NULL, 0,
-                      CTL_MACHDEP, CPU_SSE2, CTL_EOL);
-}
-
 void
 buildcontext(struct lwp *l, void *catcher, void *f)
 {
diff -r 8d43e2d4a45f -r d318e1717eb4 sys/arch/i386/i386/machdep.c
--- a/sys/arch/i386/i386/machdep.c      Sun Feb 23 12:01:51 2014 +0000
+++ b/sys/arch/i386/i386/machdep.c      Sun Feb 23 12:56:40 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: machdep.c,v 1.750 2014/02/20 18:19:10 dsl Exp $        */
+/*     $NetBSD: machdep.c,v 1.751 2014/02/23 12:56:40 dsl Exp $        */
 
 /*-
  * Copyright (c) 1996, 1997, 1998, 2000, 2004, 2006, 2008, 2009
@@ -67,7 +67,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.750 2014/02/20 18:19:10 dsl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.751 2014/02/23 12:56:40 dsl Exp $");
 
 #include "opt_beep.h"
 #include "opt_compat_ibcs2.h"
@@ -590,47 +590,6 @@
 }
 #endif /* XEN */
 
-/*
- * machine dependent system variables.
- */
-SYSCTL_SETUP(sysctl_machdep_setup, "sysctl machdep subtree setup")
-{
-       x86_sysctl_machdep_setup(clog);
-
-#ifndef XEN
-       sysctl_createv(clog, 0, NULL, NULL,
-                      CTLFLAG_PERMANENT,
-                      CTLTYPE_INT, "biosbasemem", NULL,
-                      NULL, 0, &biosbasemem, 0,
-                      CTL_MACHDEP, CPU_BIOSBASEMEM, CTL_EOL);
-       sysctl_createv(clog, 0, NULL, NULL,
-                      CTLFLAG_PERMANENT,
-                      CTLTYPE_INT, "biosextmem", NULL,
-                      NULL, 0, &biosextmem, 0,
-                      CTL_MACHDEP, CPU_BIOSEXTMEM, CTL_EOL);
-#endif /* XEN */
-       sysctl_createv(clog, 0, NULL, NULL,
-                      CTLFLAG_PERMANENT,
-                      CTLTYPE_INT, "osfxsr", NULL,
-                      NULL, 0, &i386_use_fxsave, 0,
-                      CTL_MACHDEP, CPU_OSFXSR, CTL_EOL);
-       sysctl_createv(clog, 0, NULL, NULL,
-                      CTLFLAG_PERMANENT,
-                      CTLTYPE_INT, "fpu_present", NULL,
-                      NULL, 0, &i386_fpu_present, 0,
-                      CTL_MACHDEP, CPU_FPU_PRESENT, CTL_EOL);
-       sysctl_createv(clog, 0, NULL, NULL,
-                      CTLFLAG_PERMANENT,
-                      CTLTYPE_INT, "sse", NULL,
-                      NULL, 0, &i386_has_sse, 0,
-                      CTL_MACHDEP, CPU_SSE, CTL_EOL);
-       sysctl_createv(clog, 0, NULL, NULL,
-                      CTLFLAG_PERMANENT,
-                      CTLTYPE_INT, "sse2", NULL,
-                      NULL, 0, &i386_has_sse2, 0,
-                      CTL_MACHDEP, CPU_SSE2, CTL_EOL);
-}
-
 void *
 getframe(struct lwp *l, int sig, int *onstack)
 {
diff -r 8d43e2d4a45f -r d318e1717eb4 sys/arch/x86/include/cpu.h
--- a/sys/arch/x86/include/cpu.h        Sun Feb 23 12:01:51 2014 +0000
+++ b/sys/arch/x86/include/cpu.h        Sun Feb 23 12:56:40 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cpu.h,v 1.64 2014/02/22 17:48:08 dsl Exp $     */
+/*     $NetBSD: cpu.h,v 1.65 2014/02/23 12:56:40 dsl Exp $     */
 
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
@@ -382,6 +382,14 @@
 #define        i386_has_sse2           1
 #endif
 
+extern int x86_fpu_save;
+#define        FPU_SAVE_FSAVE          0
+#define        FPU_SAVE_FXSAVE         1
+#define        FPU_SAVE_XSAVE          2
+#define        FPU_SAVE_XSAVEOPT       3
+extern unsigned int x86_xsave_size;
+extern uint64_t x86_xsave_features;
+
 extern void (*x86_cpu_idle)(void);
 #define        cpu_idle() (*x86_cpu_idle)()
 
diff -r 8d43e2d4a45f -r d318e1717eb4 sys/arch/x86/x86/fpu.c
--- a/sys/arch/x86/x86/fpu.c    Sun Feb 23 12:01:51 2014 +0000
+++ b/sys/arch/x86/x86/fpu.c    Sun Feb 23 12:56:40 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: fpu.c,v 1.6 2014/02/15 22:20:42 dsl Exp $      */
+/*     $NetBSD: fpu.c,v 1.7 2014/02/23 12:56:40 dsl Exp $      */
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.  All
@@ -100,7 +100,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.6 2014/02/15 22:20:42 dsl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.7 2014/02/23 12:56:40 dsl Exp $");
 
 #include "opt_multiprocessor.h"
 
@@ -241,34 +241,11 @@
 void
 fpuinit(struct cpu_info *ci)
 {
+       if (!i386_fpu_present)
+               return;
+
        clts();
        fninit();
-
-#if defined(__i386__) && !defined(XEN)
-       {
-               uint16_t control;
-
-               /* Read the default control word */
-               fnstcw(&control); 
-
-               if (control != __INITIAL_NPXCW__) {
-                       /* Must be a 486SX, trap FP instructions */
-                       lcr0((rcr0() & ~CR0_MP) | CR0_EM);
-                       aprint_normal_dev(ci->ci_dev, "no fpu (control %x)\n",
-                           control);
-                       i386_fpu_present = 0;
-                       return;
-               }
-
-               if (npx586bug1(4195835, 3145727) != 0) {
-                       /* NB 120+MHz cpus are not affected */
-                       i386_fpu_fdivbug = 1;
-                       aprint_normal_dev(ci->ci_dev,
-                           "WARNING: Pentium FDIV bug detected!\n");
-               }
-       }
-#endif
-
        stts();
 }
 
diff -r 8d43e2d4a45f -r d318e1717eb4 sys/arch/x86/x86/identcpu.c
--- a/sys/arch/x86/x86/identcpu.c       Sun Feb 23 12:01:51 2014 +0000
+++ b/sys/arch/x86/x86/identcpu.c       Sun Feb 23 12:56:40 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: identcpu.c,v 1.40 2014/02/22 17:48:08 dsl Exp $        */
+/*     $NetBSD: identcpu.c,v 1.41 2014/02/23 12:56:40 dsl Exp $        */
 
 /*-
  * Copyright (c) 1999, 2000, 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.40 2014/02/22 17:48:08 dsl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.41 2014/02/23 12:56:40 dsl Exp $");
 
 #include "opt_xen.h"
 
@@ -60,6 +60,10 @@
 int cpu_vendor;
 char cpu_brand_string[49];
 
+int x86_fpu_save = FPU_SAVE_FSAVE;
+unsigned int x86_xsave_size = 0;
+uint64_t x86_xsave_features = 0;
+
 /*
  * Info for CTL_HW
  */
@@ -677,6 +681,85 @@
 #undef PCI_MODE1_DATA_REG
 }
 
+#if !defined(__i386__) || defined(XEN)
+#define cpu_probe_old_fpu(ci)
+#else
+static void
+cpu_probe_old_fpu(struct cpu_info *ci)
+{
+       uint16_t control;
+
+       /* Check that there really is an fpu (496SX) */
+       clts();
+       fninit();
+       /* Read default control word */
+       fnstcw(&control);
+       if (control != __INITIAL_NPXCW__) {
+               /* Must be a 486SX, trap FP instructions */
+               lcr0((rcr0() & ~CR0_MP) | CR0_EM);
+               i386_fpu_present = 0;
+               return;
+       }
+
+       /* Check for 'FDIV' bug on the original Pentium */
+       if (npx586bug1(4195835, 3145727) != 0)
+               /* NB 120+MHz cpus are not affected */
+               i386_fpu_fdivbug = 1;
+
+       stts();
+}
+#endif
+
+static void
+cpu_probe_fpu(struct cpu_info *ci)
+{
+       u_int descs[4];
+
+#ifdef i386 /* amd64 always has fxsave, sse and sse2 */
+       /* If we have FXSAVE/FXRESTOR, use them. */
+       if ((ci->ci_feat_val[0] & CPUID_FXSR) == 0) {
+               i386_use_fxsave = 0;
+               /* Allow for no fpu even if cpuid is supported */
+               cpu_probe_old_fpu(ci);
+               return;
+       }
+
+       i386_use_fxsave = 1;
+       /*
+        * If we have SSE/SSE2, enable XMM exceptions, and
+        * notify userland.
+        */
+       if (ci->ci_feat_val[0] & CPUID_SSE)
+               i386_has_sse = 1;
+       if (ci->ci_feat_val[0] & CPUID_SSE2)
+               i386_has_sse2 = 1;
+#else
+       /*
+        * For amd64 i386_use_fxsave, i386_has_sse and i386_has_sse2 are
+        * #defined to 1.
+        */
+#endif /* i386 */
+
+       x86_fpu_save = FPU_SAVE_FXSAVE;
+
+       /* See if xsave (for AVX is supported) */
+       if ((ci->ci_feat_val[1] & CPUID2_XSAVE) == 0)
+               return;
+
+       x86_fpu_save = FPU_SAVE_XSAVE;
+
+       /* xsaveopt ought to be faster than xsave */
+       x86_cpuid2(0xd, 1, descs);
+       if (descs[0] & CPUID_PES1_XSAVEOPT)
+               x86_fpu_save = FPU_SAVE_XSAVEOPT;
+
+       /* Get features and maximum size of the save area */
+       x86_cpuid(0xd, descs);
+       /* XXX these probably ought to be per-cpu */



Home | Main Index | Thread Index | Old Index