diff options
Diffstat (limited to 'arch/x86/include/asm/mwait.h')
| -rw-r--r-- | arch/x86/include/asm/mwait.h | 45 | 
1 files changed, 45 insertions, 0 deletions
diff --git a/arch/x86/include/asm/mwait.h b/arch/x86/include/asm/mwait.h index 653dfa7662e1..c70689b5e5aa 100644 --- a/arch/x86/include/asm/mwait.h +++ b/arch/x86/include/asm/mwait.h @@ -14,6 +14,9 @@  #define CPUID5_ECX_INTERRUPT_BREAK	0x2  #define MWAIT_ECX_INTERRUPT_BREAK	0x1 +#define MWAITX_ECX_TIMER_ENABLE		BIT(1) +#define MWAITX_MAX_LOOPS		((u32)-1) +#define MWAITX_DISABLE_CSTATES		0xf  static inline void __monitor(const void *eax, unsigned long ecx,  			     unsigned long edx) @@ -23,6 +26,14 @@ static inline void __monitor(const void *eax, unsigned long ecx,  		     :: "a" (eax), "c" (ecx), "d"(edx));  } +static inline void __monitorx(const void *eax, unsigned long ecx, +			      unsigned long edx) +{ +	/* "monitorx %eax, %ecx, %edx;" */ +	asm volatile(".byte 0x0f, 0x01, 0xfa;" +		     :: "a" (eax), "c" (ecx), "d"(edx)); +} +  static inline void __mwait(unsigned long eax, unsigned long ecx)  {  	/* "mwait %eax, %ecx;" */ @@ -30,6 +41,40 @@ static inline void __mwait(unsigned long eax, unsigned long ecx)  		     :: "a" (eax), "c" (ecx));  } +/* + * MWAITX allows for a timer expiration to get the core out a wait state in + * addition to the default MWAIT exit condition of a store appearing at a + * monitored virtual address. + * + * Registers: + * + * MWAITX ECX[1]: enable timer if set + * MWAITX EBX[31:0]: max wait time expressed in SW P0 clocks. The software P0 + * frequency is the same as the TSC frequency. + * + * Below is a comparison between MWAIT and MWAITX on AMD processors: + * + *                 MWAIT                           MWAITX + * opcode          0f 01 c9           |            0f 01 fb + * ECX[0]                  value of RFLAGS.IF seen by instruction + * ECX[1]          unused/#GP if set  |            enable timer if set + * ECX[31:2]                     unused/#GP if set + * EAX                           unused (reserve for hint) + * EBX[31:0]       unused             |            max wait time (P0 clocks) + * + *                 MONITOR                         MONITORX + * opcode          0f 01 c8           |            0f 01 fa + * EAX                     (logical) address to monitor + * ECX                     #GP if not zero + */ +static inline void __mwaitx(unsigned long eax, unsigned long ebx, +			    unsigned long ecx) +{ +	/* "mwaitx %eax, %ebx, %ecx;" */ +	asm volatile(".byte 0x0f, 0x01, 0xfb;" +		     :: "a" (eax), "b" (ebx), "c" (ecx)); +} +  static inline void __sti_mwait(unsigned long eax, unsigned long ecx)  {  	trace_hardirqs_on();  |