From owner-freebsd-current@FreeBSD.ORG Sun Feb 3 17:45:03 2013 Return-Path: Delivered-To: freebsd-current@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id 72507619; Sun, 3 Feb 2013 17:45:03 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from citadel.icyb.net.ua (citadel.icyb.net.ua [212.40.38.140]) by mx1.freebsd.org (Postfix) with ESMTP id 72E3F2C6; Sun, 3 Feb 2013 17:45:02 +0000 (UTC) Received: from porto.starpoint.kiev.ua (porto-e.starpoint.kiev.ua [212.40.38.100]) by citadel.icyb.net.ua (8.8.8p3/ICyb-2.3exp) with ESMTP id TAA09560; Sun, 03 Feb 2013 19:44:58 +0200 (EET) (envelope-from avg@FreeBSD.org) Received: from localhost ([127.0.0.1]) by porto.starpoint.kiev.ua with esmtp (Exim 4.34 (FreeBSD)) id 1U23cg-0006ph-81; Sun, 03 Feb 2013 19:44:58 +0200 Message-ID: <510EA219.2090504@FreeBSD.org> Date: Sun, 03 Feb 2013 19:44:57 +0200 From: Andriy Gapon User-Agent: Mozilla/5.0 (X11; FreeBSD amd64; rv:17.0) Gecko/20130121 Thunderbird/17.0.2 MIME-Version: 1.0 To: freebsd-current@FreeBSD.org Subject: detect mwait capabilities and extensions X-Enigmail-Version: 1.4.6 Content-Type: text/plain; charset=X-VIET-VPS Content-Transfer-Encoding: 7bit Cc: freebsd-hackers@FreeBSD.org X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 03 Feb 2013 17:45:03 -0000 Guys, could you please the following change? It is amd64-centric now, but obviously I plan equivalent changes for i386. I am mostly concerned about proper header files for various definitions and proper names for them. Especially I am not sure where to put STATE_RUNNING, STATE_MWAIT, STATE_SLEEPING... Thank you. diff --git a/sys/amd64/amd64/identcpu.c b/sys/amd64/amd64/identcpu.c index 2517498..d831f95 100644 --- a/sys/amd64/amd64/identcpu.c +++ b/sys/amd64/amd64/identcpu.c @@ -513,6 +513,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]; diff --git a/sys/amd64/amd64/initcpu.c b/sys/amd64/amd64/initcpu.c index 4abed4c..f7574b1 100644 --- a/sys/amd64/amd64/initcpu.c +++ b/sys/amd64/amd64/initcpu.c @@ -75,6 +75,9 @@ u_int cpu_mxcsr_mask; /* Valid bits in mxcsr */ 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"); diff --git a/sys/amd64/include/md_var.h b/sys/amd64/include/md_var.h index 5d7cb74..ddc5b9f 100644 --- a/sys/amd64/include/md_var.h +++ b/sys/amd64/include/md_var.h @@ -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[]; diff --git a/sys/x86/include/specialreg.h b/sys/x86/include/specialreg.h index dbf9ba0..af64c1b 100644 --- a/sys/x86/include/specialreg.h +++ b/sys/x86/include/specialreg.h @@ -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 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -665,10 +665,6 @@ TUNABLE_INT("machdep.idle_mwait", &idle_mwait); SYSCTL_INT(_machdep, OID_AUTO, idle_mwait, CTLFLAG_RW, &idle_mwait, 0, "Use MONITOR/MWAIT for short idle"); -#define STATE_RUNNING 0x0 -#define STATE_MWAIT 0x1 -#define STATE_SLEEPING 0x2 - static void cpu_idle_acpi(int busy) { diff --git a/sys/amd64/include/cpu.h b/sys/amd64/include/cpu.h index 1c2871f..dc29a37 100644 --- a/sys/amd64/include/cpu.h +++ b/sys/amd64/include/cpu.h @@ -43,8 +43,14 @@ #include #include +/* + * CPU states for the purpose of communication using MONITOR+MWAIT. */ +#define STATE_RUNNING 0x0 +#define STATE_MWAIT 0x1 +#define STATE_SLEEPING 0x2 + #define cpu_exec(p) /* nothing */ #define cpu_swapin(p) /* nothing */ #define cpu_getstack(td) ((td)->td_frame->tf_rsp) #define cpu_setstack(td, ap) ((td)->td_frame->tf_rsp = (ap)) #define cpu_spinwait() ia32_pause() -- Andriy Gapon