alt_irq.h 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. #ifndef __ALT_IRQ_H__
  2. #define __ALT_IRQ_H__
  3. /******************************************************************************
  4. * *
  5. * License Agreement *
  6. * *
  7. * Copyright (c) 2009 Altera Corporation, San Jose, California, USA. *
  8. * All rights reserved. *
  9. * *
  10. * Permission is hereby granted, free of charge, to any person obtaining a *
  11. * copy of this software and associated documentation files (the "Software"), *
  12. * to deal in the Software without restriction, including without limitation *
  13. * the rights to use, copy, modify, merge, publish, distribute, sublicense, *
  14. * and/or sell copies of the Software, and to permit persons to whom the *
  15. * Software is furnished to do so, subject to the following conditions: *
  16. * *
  17. * The above copyright notice and this permission notice shall be included in *
  18. * all copies or substantial portions of the Software. *
  19. * *
  20. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
  21. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
  22. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
  23. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
  24. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *
  25. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *
  26. * DEALINGS IN THE SOFTWARE. *
  27. * *
  28. * This agreement shall be governed in all respects by the laws of the State *
  29. * of California and by the laws of the United States of America. *
  30. * *
  31. ******************************************************************************/
  32. /*
  33. * alt_irq.h is the Nios II specific implementation of the interrupt controller
  34. * interface.
  35. *
  36. * Nios II includes optional support for an external interrupt controller.
  37. * When an external controller is present, the "Enhanced" interrupt API
  38. * must be used to manage individual interrupts. The enhanced API also
  39. * supports the processor's internal interrupt controller. Certain API
  40. * members are accessible from either the "legacy" or "enhanced" interrpt
  41. * API.
  42. *
  43. * Regardless of which API is in use, this file should be included by
  44. * application code and device drivers that register ISRs or manage interrpts.
  45. */
  46. #include <errno.h>
  47. #include "nios2.h"
  48. #include "alt_types.h"
  49. #include "system.h"
  50. #ifdef __cplusplus
  51. extern "C"
  52. {
  53. #endif /* __cplusplus */
  54. /*
  55. * Macros used by alt_irq_enabled
  56. */
  57. #define ALT_IRQ_ENABLED 1
  58. #define ALT_IRQ_DISABLED 0
  59. /*
  60. * Number of available interrupts in internal interrupt controller.
  61. */
  62. #define ALT_NIRQ NIOS2_NIRQ
  63. /*
  64. * Used by alt_irq_disable_all() and alt_irq_enable_all().
  65. */
  66. typedef int alt_irq_context;
  67. /* ISR Prototype */
  68. #ifdef ALT_ENHANCED_INTERRUPT_API_PRESENT
  69. typedef void (*alt_isr_func)(void* isr_context);
  70. #else
  71. typedef void (*alt_isr_func)(void* isr_context, alt_u32 id);
  72. #endif
  73. /*
  74. * The following protypes and routines are supported by both
  75. * the enhanced and legacy interrupt APIs
  76. */
  77. /*
  78. * alt_irq_enabled can be called to determine if the processor's global
  79. * interrupt enable is asserted. The return value is zero if interrupts
  80. * are disabled, and non-zero otherwise.
  81. *
  82. * Whether the internal or external interrupt controller is present,
  83. * individual interrupts may still be disabled. Use the other API to query
  84. * a specific interrupt.
  85. */
  86. static ALT_INLINE int ALT_ALWAYS_INLINE alt_irq_enabled (void)
  87. {
  88. int status;
  89. NIOS2_READ_STATUS (status);
  90. return status & NIOS2_STATUS_PIE_MSK;
  91. }
  92. /*
  93. * alt_irq_disable_all()
  94. *
  95. * This routine inhibits all interrupts by negating the status register PIE
  96. * bit. It returns the previous contents of the CPU status register (IRQ
  97. * context) which can be used to restore the status register PIE bit to its
  98. * state before this routine was called.
  99. */
  100. static ALT_INLINE alt_irq_context ALT_ALWAYS_INLINE
  101. alt_irq_disable_all (void)
  102. {
  103. alt_irq_context context;
  104. NIOS2_READ_STATUS (context);
  105. NIOS2_WRITE_STATUS (context & ~NIOS2_STATUS_PIE_MSK);
  106. return context;
  107. }
  108. /*
  109. * alt_irq_enable_all()
  110. *
  111. * Enable all interrupts that were previously disabled by alt_irq_disable_all()
  112. *
  113. * This routine accepts a context to restore the CPU status register PIE bit
  114. * to the state prior to a call to alt_irq_disable_all().
  115. * In the case of nested calls to alt_irq_disable_all()/alt_irq_enable_all(),
  116. * this means that alt_irq_enable_all() does not necessarily re-enable
  117. * interrupts.
  118. *
  119. * This routine will perform a read-modify-write sequence to restore only
  120. * status.PIE if the processor is configured with options that add additional
  121. * writeable status register bits. These include the MMU, MPU, the enhanced
  122. * interrupt controller port, and shadow registers. Otherwise, as a performance
  123. * enhancement, status is overwritten with the prior context.
  124. */
  125. static ALT_INLINE void ALT_ALWAYS_INLINE
  126. alt_irq_enable_all (alt_irq_context context)
  127. {
  128. #if (NIOS2_NUM_OF_SHADOW_REG_SETS > 0) || (defined NIOS2_EIC_PRESENT) || \
  129. (defined NIOS2_MMU_PRESENT) || (defined NIOS2_MPU_PRESENT)
  130. alt_irq_context status;
  131. NIOS2_READ_STATUS (status);
  132. status &= ~NIOS2_STATUS_PIE_MSK;
  133. status |= (context & NIOS2_STATUS_PIE_MSK);
  134. NIOS2_WRITE_STATUS (status);
  135. #else
  136. NIOS2_WRITE_STATUS (context);
  137. #endif
  138. }
  139. /*
  140. * The function alt_irq_init() is defined within the auto-generated file
  141. * alt_sys_init.c. This function calls the initilization macros for all
  142. * interrupt controllers in the system at config time, before any other
  143. * non-interrupt controller driver is initialized.
  144. *
  145. * The "base" parameter is ignored and only present for backwards-compatibility.
  146. * It is recommended that NULL is passed in for the "base" parameter.
  147. */
  148. extern void alt_irq_init (const void* base);
  149. /*
  150. * alt_irq_cpu_enable_interrupts() enables the CPU to start taking interrupts.
  151. */
  152. static ALT_INLINE void ALT_ALWAYS_INLINE
  153. alt_irq_cpu_enable_interrupts (void)
  154. {
  155. NIOS2_WRITE_STATUS(NIOS2_STATUS_PIE_MSK
  156. #if defined(NIOS2_EIC_PRESENT) && (NIOS2_NUM_OF_SHADOW_REG_SETS > 0)
  157. | NIOS2_STATUS_RSIE_MSK
  158. #endif
  159. );
  160. }
  161. /*
  162. * Prototypes for the enhanced interrupt API.
  163. */
  164. #ifdef ALT_ENHANCED_INTERRUPT_API_PRESENT
  165. /*
  166. * alt_ic_isr_register() can be used to register an interrupt handler. If the
  167. * function is succesful, then the requested interrupt will be enabled upon
  168. * return.
  169. */
  170. extern int alt_ic_isr_register(alt_u32 ic_id,
  171. alt_u32 irq,
  172. alt_isr_func isr,
  173. void *isr_context,
  174. void *flags);
  175. /*
  176. * alt_ic_irq_enable() and alt_ic_irq_disable() enable/disable a specific
  177. * interrupt by using IRQ port and interrupt controller instance.
  178. */
  179. int alt_ic_irq_enable (alt_u32 ic_id, alt_u32 irq);
  180. int alt_ic_irq_disable(alt_u32 ic_id, alt_u32 irq);
  181. /*
  182. * alt_ic_irq_enabled() indicates whether a specific interrupt, as
  183. * specified by IRQ port and interrupt controller instance is enabled.
  184. */
  185. alt_u32 alt_ic_irq_enabled(alt_u32 ic_id, alt_u32 irq);
  186. #else
  187. /*
  188. * Prototypes for the legacy interrupt API.
  189. */
  190. #include "priv/alt_legacy_irq.h"
  191. #endif
  192. /*
  193. * alt_irq_pending() returns a bit list of the current pending interrupts.
  194. * This is used by alt_irq_handler() to determine which registered interrupt
  195. * handlers should be called.
  196. *
  197. * This routine is only available for the Nios II internal interrupt
  198. * controller.
  199. */
  200. #ifndef NIOS2_EIC_PRESENT
  201. static ALT_INLINE alt_u32 ALT_ALWAYS_INLINE alt_irq_pending (void)
  202. {
  203. alt_u32 active;
  204. NIOS2_READ_IPENDING (active);
  205. return active;
  206. }
  207. #endif
  208. #ifdef __cplusplus
  209. }
  210. #endif /* __cplusplus */
  211. #endif /* __ALT_IRQ_H__ */