interrupt.h 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /*
  2. * This file is subject to the terms and conditions of the GNU General Public
  3. * License. See the file "COPYING" in the main directory of this archive
  4. * for more details.
  5. *
  6. * Copyright (C) 1994, 95, 96, 97, 98, 99, 2003 by Ralf Baechle
  7. * Copyright (C) 1996 by Paul M. Antoine
  8. * Copyright (C) 1999 Silicon Graphics
  9. * Copyright (C) 2000 MIPS Technologies, Inc.
  10. */
  11. #ifndef _ASM_INTERRUPT_H
  12. #define _ASM_INTERRUPT_H
  13. #include <asm/hazards.h>
  14. __asm__ (
  15. ".macro\tlocal_irq_enable\n\t"
  16. ".set\tpush\n\t"
  17. ".set\treorder\n\t"
  18. ".set\tnoat\n\t"
  19. "mfc0\t$1,$12\n\t"
  20. "ori\t$1,0x1f\n\t"
  21. "xori\t$1,0x1e\n\t"
  22. "mtc0\t$1,$12\n\t"
  23. "irq_enable_hazard\n\t"
  24. ".set\tpop\n\t"
  25. ".endm");
  26. static inline void local_irq_enable(void)
  27. {
  28. __asm__ __volatile__(
  29. "local_irq_enable"
  30. : /* no outputs */
  31. : /* no inputs */
  32. : "memory");
  33. }
  34. /*
  35. * For cli() we have to insert nops to make sure that the new value
  36. * has actually arrived in the status register before the end of this
  37. * macro.
  38. * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs
  39. * no nops at all.
  40. */
  41. __asm__ (
  42. ".macro\tlocal_irq_disable\n\t"
  43. ".set\tpush\n\t"
  44. ".set\tnoat\n\t"
  45. "mfc0\t$1,$12\n\t"
  46. "ori\t$1,1\n\t"
  47. "xori\t$1,1\n\t"
  48. ".set\tnoreorder\n\t"
  49. "mtc0\t$1,$12\n\t"
  50. "irq_disable_hazard\n\t"
  51. ".set\tpop\n\t"
  52. ".endm");
  53. static inline void local_irq_disable(void)
  54. {
  55. __asm__ __volatile__(
  56. "local_irq_disable"
  57. : /* no outputs */
  58. : /* no inputs */
  59. : "memory");
  60. }
  61. __asm__ (
  62. ".macro\tlocal_save_flags flags\n\t"
  63. ".set\tpush\n\t"
  64. ".set\treorder\n\t"
  65. "mfc0\t\\flags, $12\n\t"
  66. ".set\tpop\n\t"
  67. ".endm");
  68. #define local_save_flags(x) \
  69. __asm__ __volatile__( \
  70. "local_save_flags %0" \
  71. : "=r" (x))
  72. __asm__ (
  73. ".macro\tlocal_irq_save result\n\t"
  74. ".set\tpush\n\t"
  75. ".set\treorder\n\t"
  76. ".set\tnoat\n\t"
  77. "mfc0\t\\result, $12\n\t"
  78. "ori\t$1, \\result, 1\n\t"
  79. "xori\t$1, 1\n\t"
  80. ".set\tnoreorder\n\t"
  81. "mtc0\t$1, $12\n\t"
  82. "irq_disable_hazard\n\t"
  83. ".set\tpop\n\t"
  84. ".endm");
  85. #define local_irq_save(x) \
  86. __asm__ __volatile__( \
  87. "local_irq_save\t%0" \
  88. : "=r" (x) \
  89. : /* no inputs */ \
  90. : "memory")
  91. __asm__ (
  92. ".macro\tlocal_irq_restore flags\n\t"
  93. ".set\tnoreorder\n\t"
  94. ".set\tnoat\n\t"
  95. "mfc0\t$1, $12\n\t"
  96. "andi\t\\flags, 1\n\t"
  97. "ori\t$1, 1\n\t"
  98. "xori\t$1, 1\n\t"
  99. "or\t\\flags, $1\n\t"
  100. "mtc0\t\\flags, $12\n\t"
  101. "irq_disable_hazard\n\t"
  102. ".set\tat\n\t"
  103. ".set\treorder\n\t"
  104. ".endm");
  105. #define local_irq_restore(flags) \
  106. do { \
  107. unsigned long __tmp1; \
  108. \
  109. __asm__ __volatile__( \
  110. "local_irq_restore\t%0" \
  111. : "=r" (__tmp1) \
  112. : "0" (flags) \
  113. : "memory"); \
  114. } while(0)
  115. #define irqs_disabled() \
  116. ({ \
  117. unsigned long flags; \
  118. local_save_flags(flags); \
  119. !(flags & 1); \
  120. })
  121. #endif /* _ASM_INTERRUPT_H */