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