irqflags.h 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /*
  2. * include/asm-i386/irqflags.h
  3. *
  4. * IRQ flags handling
  5. *
  6. * This file gets included from lowlevel asm headers too, to provide
  7. * wrapped versions of the local_irq_*() APIs, based on the
  8. * raw_local_irq_*() functions from the lowlevel headers.
  9. */
  10. #ifndef _ASM_IRQFLAGS_H
  11. #define _ASM_IRQFLAGS_H
  12. #ifndef __ASSEMBLY__
  13. static inline unsigned long __raw_local_save_flags(void)
  14. {
  15. unsigned long flags;
  16. __asm__ __volatile__(
  17. "pushfl ; popl %0"
  18. : "=g" (flags)
  19. : /* no input */
  20. );
  21. return flags;
  22. }
  23. #define raw_local_save_flags(flags) \
  24. do { (flags) = __raw_local_save_flags(); } while (0)
  25. static inline void raw_local_irq_restore(unsigned long flags)
  26. {
  27. __asm__ __volatile__(
  28. "pushl %0 ; popfl"
  29. : /* no output */
  30. :"g" (flags)
  31. :"memory", "cc"
  32. );
  33. }
  34. static inline void raw_local_irq_disable(void)
  35. {
  36. __asm__ __volatile__("cli" : : : "memory");
  37. }
  38. static inline void raw_local_irq_enable(void)
  39. {
  40. __asm__ __volatile__("sti" : : : "memory");
  41. }
  42. /*
  43. * Used in the idle loop; sti takes one instruction cycle
  44. * to complete:
  45. */
  46. static inline void raw_safe_halt(void)
  47. {
  48. __asm__ __volatile__("sti; hlt" : : : "memory");
  49. }
  50. /*
  51. * Used when interrupts are already enabled or to
  52. * shutdown the processor:
  53. */
  54. static inline void halt(void)
  55. {
  56. __asm__ __volatile__("hlt": : :"memory");
  57. }
  58. static inline int raw_irqs_disabled_flags(unsigned long flags)
  59. {
  60. return !(flags & (1 << 9));
  61. }
  62. static inline int raw_irqs_disabled(void)
  63. {
  64. unsigned long flags = __raw_local_save_flags();
  65. return raw_irqs_disabled_flags(flags);
  66. }
  67. /*
  68. * For spinlocks, etc:
  69. */
  70. static inline unsigned long __raw_local_irq_save(void)
  71. {
  72. unsigned long flags = __raw_local_save_flags();
  73. raw_local_irq_disable();
  74. return flags;
  75. }
  76. #define raw_local_irq_save(flags) \
  77. do { (flags) = __raw_local_irq_save(); } while (0)
  78. #endif /* __ASSEMBLY__ */
  79. /*
  80. * Do the CPU's IRQ-state tracing from assembly code. We call a
  81. * C function, so save all the C-clobbered registers:
  82. */
  83. #ifdef CONFIG_TRACE_IRQFLAGS
  84. # define TRACE_IRQS_ON \
  85. pushl %eax; \
  86. pushl %ecx; \
  87. pushl %edx; \
  88. call trace_hardirqs_on; \
  89. popl %edx; \
  90. popl %ecx; \
  91. popl %eax;
  92. # define TRACE_IRQS_OFF \
  93. pushl %eax; \
  94. pushl %ecx; \
  95. pushl %edx; \
  96. call trace_hardirqs_off; \
  97. popl %edx; \
  98. popl %ecx; \
  99. popl %eax;
  100. #else
  101. # define TRACE_IRQS_ON
  102. # define TRACE_IRQS_OFF
  103. #endif
  104. #endif