Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 28 Jul 2013 17:54:42 +0000 (UTC)
From:      Andriy Gapon <avg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r253747 - in head/sys: amd64/amd64 amd64/include i386/i386 i386/include x86/include
Message-ID:  <201307281754.r6SHsg1K041487@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: avg
Date: Sun Jul 28 17:54:42 2013
New Revision: 253747
URL: http://svnweb.freebsd.org/changeset/base/253747

Log:
  x86: detect mwait capabilities and extensions, when present
  
  Reviewed by:	kib (earlier amd64-only version)
  MFC after:	2 weeks

Modified:
  head/sys/amd64/amd64/identcpu.c
  head/sys/amd64/amd64/initcpu.c
  head/sys/amd64/include/md_var.h
  head/sys/i386/i386/identcpu.c
  head/sys/i386/i386/initcpu.c
  head/sys/i386/include/md_var.h
  head/sys/x86/include/specialreg.h

Modified: head/sys/amd64/amd64/identcpu.c
==============================================================================
--- head/sys/amd64/amd64/identcpu.c	Sun Jul 28 17:37:30 2013	(r253746)
+++ head/sys/amd64/amd64/identcpu.c	Sun Jul 28 17:54:42 2013	(r253747)
@@ -532,6 +532,13 @@ identify_cpu(void)
 		}
 	}
 
+	if (cpu_high >= 5 && (cpu_feature2 & CPUID2_MON) != 0) {
+		do_cpuid(5, regs);
+		cpu_mon_mwait_flags = regs[2];
+		cpu_mon_min_size = regs[0] &  CPUID5_MON_MIN_SIZE;
+		cpu_mon_max_size = regs[1] &  CPUID5_MON_MAX_SIZE;
+	}
+
 	if (cpu_high >= 7) {
 		cpuid_count(7, 0, regs);
 		cpu_stdext_feature = regs[1];

Modified: head/sys/amd64/amd64/initcpu.c
==============================================================================
--- head/sys/amd64/amd64/initcpu.c	Sun Jul 28 17:37:30 2013	(r253746)
+++ head/sys/amd64/amd64/initcpu.c	Sun Jul 28 17:54:42 2013	(r253747)
@@ -75,6 +75,9 @@ u_int	cpu_mxcsr_mask;		/* Valid bits in 
 u_int	cpu_clflush_line_size = 32;
 u_int	cpu_stdext_feature;
 u_int	cpu_max_ext_state_size;
+u_int	cpu_mon_mwait_flags;	/* MONITOR/MWAIT flags (CPUID.05H.ECX) */
+u_int	cpu_mon_min_size;	/* MONITOR minimum range size, bytes */
+u_int	cpu_mon_max_size;	/* MONITOR minimum range size, bytes */
 
 SYSCTL_UINT(_hw, OID_AUTO, via_feature_rng, CTLFLAG_RD,
 	&via_feature_rng, 0, "VIA RNG feature available in CPU");

Modified: head/sys/amd64/include/md_var.h
==============================================================================
--- head/sys/amd64/include/md_var.h	Sun Jul 28 17:37:30 2013	(r253746)
+++ head/sys/amd64/include/md_var.h	Sun Jul 28 17:54:42 2013	(r253747)
@@ -58,6 +58,9 @@ extern	u_int	cpu_procinfo;
 extern	u_int	cpu_procinfo2;
 extern	char	cpu_vendor[];
 extern	u_int	cpu_vendor_id;
+extern	u_int	cpu_mon_mwait_flags;
+extern	u_int	cpu_mon_min_size;
+extern	u_int	cpu_mon_max_size;
 extern	char	ctx_switch_xsave[];
 extern	char	kstack[];
 extern	char	sigcode[];

Modified: head/sys/i386/i386/identcpu.c
==============================================================================
--- head/sys/i386/i386/identcpu.c	Sun Jul 28 17:37:30 2013	(r253746)
+++ head/sys/i386/i386/identcpu.c	Sun Jul 28 17:54:42 2013	(r253747)
@@ -1121,6 +1121,13 @@ finishidentcpu(void)
 		}
 	}
 
+	if (cpu_high >= 5 && (cpu_feature2 & CPUID2_MON) != 0) {
+		do_cpuid(5, regs);
+		cpu_mon_mwait_flags = regs[2];
+		cpu_mon_min_size = regs[0] &  CPUID5_MON_MIN_SIZE;
+		cpu_mon_max_size = regs[1] &  CPUID5_MON_MAX_SIZE;
+	}
+
 	/* Detect AMD features (PTE no-execute bit, 3dnow, 64 bit mode etc) */
 	if (cpu_vendor_id == CPU_VENDOR_INTEL ||
 	    cpu_vendor_id == CPU_VENDOR_AMD) {

Modified: head/sys/i386/i386/initcpu.c
==============================================================================
--- head/sys/i386/i386/initcpu.c	Sun Jul 28 17:37:30 2013	(r253746)
+++ head/sys/i386/i386/initcpu.c	Sun Jul 28 17:54:42 2013	(r253747)
@@ -97,6 +97,9 @@ u_int	cpu_procinfo2 = 0;	/* Multicore in
 char	cpu_vendor[20] = "";	/* CPU Origin code */
 u_int	cpu_vendor_id = 0;	/* CPU vendor ID */
 u_int	cpu_clflush_line_size = 32;
+u_int	cpu_mon_mwait_flags;	/* MONITOR/MWAIT flags (CPUID.05H.ECX) */
+u_int	cpu_mon_min_size;	/* MONITOR minimum range size, bytes */
+u_int	cpu_mon_max_size;	/* MONITOR minimum range size, bytes */
 
 SYSCTL_UINT(_hw, OID_AUTO, via_feature_rng, CTLFLAG_RD,
 	&via_feature_rng, 0, "VIA RNG feature available in CPU");

Modified: head/sys/i386/include/md_var.h
==============================================================================
--- head/sys/i386/include/md_var.h	Sun Jul 28 17:37:30 2013	(r253746)
+++ head/sys/i386/include/md_var.h	Sun Jul 28 17:54:42 2013	(r253747)
@@ -57,6 +57,9 @@ extern	u_int	cpu_procinfo2;
 extern	char	cpu_vendor[];
 extern	u_int	cpu_vendor_id;
 extern	u_int	cyrix_did;
+extern	u_int	cpu_mon_mwait_flags;
+extern	u_int	cpu_mon_min_size;
+extern	u_int	cpu_mon_max_size;
 extern	char	kstack[];
 extern	char	sigcode[];
 extern	int	szsigcode;

Modified: head/sys/x86/include/specialreg.h
==============================================================================
--- head/sys/x86/include/specialreg.h	Sun Jul 28 17:37:30 2013	(r253746)
+++ head/sys/x86/include/specialreg.h	Sun Jul 28 17:54:42 2013	(r253747)
@@ -240,6 +240,29 @@
 #define	CPUID_LOCAL_APIC_ID	0xff000000
 
 /*
+ * CPUID instruction 5 info
+ */
+#define	CPUID5_MON_MIN_SIZE	0x0000ffff	/* eax */
+#define	CPUID5_MON_MAX_SIZE	0x0000ffff	/* ebx */
+#define	CPUID5_MON_MWAIT_EXT	0x00000001	/* ecx */
+#define	CPUID5_MWAIT_INTRBREAK	0x00000002	/* ecx */
+
+/*
+ * MWAIT cpu power states.  Lower 4 bits are sub-states.
+ */
+#define	MWAIT_C0	0xf0
+#define	MWAIT_C1	0x00
+#define	MWAIT_C2	0x10
+#define	MWAIT_C3	0x20
+#define	MWAIT_C4	0x30
+
+/*
+ * MWAIT extensions.
+ */
+/* Interrupt breaks MWAIT even when masked. */
+#define	MWAIT_INTRBREAK		0x00000001
+
+/*
  * CPUID instruction 6 ecx info
  */
 #define	CPUID_PERF_STAT		0x00000001



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201307281754.r6SHsg1K041487>