mwait.h 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. #ifndef _ASM_X86_MWAIT_H
  2. #define _ASM_X86_MWAIT_H
  3. #include <linux/sched.h>
  4. #define MWAIT_SUBSTATE_MASK 0xf
  5. #define MWAIT_CSTATE_MASK 0xf
  6. #define MWAIT_SUBSTATE_SIZE 4
  7. #define MWAIT_HINT2CSTATE(hint) (((hint) >> MWAIT_SUBSTATE_SIZE) & MWAIT_CSTATE_MASK)
  8. #define MWAIT_HINT2SUBSTATE(hint) ((hint) & MWAIT_CSTATE_MASK)
  9. #define CPUID_MWAIT_LEAF 5
  10. #define CPUID5_ECX_EXTENSIONS_SUPPORTED 0x1
  11. #define CPUID5_ECX_INTERRUPT_BREAK 0x2
  12. #define MWAIT_ECX_INTERRUPT_BREAK 0x1
  13. static inline void __monitor(const void *eax, unsigned long ecx,
  14. unsigned long edx)
  15. {
  16. /* "monitor %eax, %ecx, %edx;" */
  17. asm volatile(".byte 0x0f, 0x01, 0xc8;"
  18. :: "a" (eax), "c" (ecx), "d"(edx));
  19. }
  20. static inline void __mwait(unsigned long eax, unsigned long ecx)
  21. {
  22. /* "mwait %eax, %ecx;" */
  23. asm volatile(".byte 0x0f, 0x01, 0xc9;"
  24. :: "a" (eax), "c" (ecx));
  25. }
  26. static inline void __sti_mwait(unsigned long eax, unsigned long ecx)
  27. {
  28. trace_hardirqs_on();
  29. /* "mwait %eax, %ecx;" */
  30. asm volatile("sti; .byte 0x0f, 0x01, 0xc9;"
  31. :: "a" (eax), "c" (ecx));
  32. }
  33. /*
  34. * This uses new MONITOR/MWAIT instructions on P4 processors with PNI,
  35. * which can obviate IPI to trigger checking of need_resched.
  36. * We execute MONITOR against need_resched and enter optimized wait state
  37. * through MWAIT. Whenever someone changes need_resched, we would be woken
  38. * up from MWAIT (without an IPI).
  39. *
  40. * New with Core Duo processors, MWAIT can take some hints based on CPU
  41. * capability.
  42. */
  43. static inline void mwait_idle_with_hints(unsigned long eax, unsigned long ecx)
  44. {
  45. if (!current_set_polling_and_test()) {
  46. if (static_cpu_has_bug(X86_BUG_CLFLUSH_MONITOR)) {
  47. mb();
  48. clflush((void *)&current_thread_info()->flags);
  49. mb();
  50. }
  51. __monitor((void *)&current_thread_info()->flags, 0, 0);
  52. if (!need_resched())
  53. __mwait(eax, ecx);
  54. }
  55. current_clr_polling();
  56. }
  57. #endif /* _ASM_X86_MWAIT_H */