interrupt.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. /*
  2. * Copyright (c) 2006-2020, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2020-04-05 bigmagic Initial version
  9. */
  10. /**
  11. * @addtogroup ls2k
  12. */
  13. /*@{*/
  14. #include <rtthread.h>
  15. #include <rthw.h>
  16. #include <exception.h>
  17. #include <drivers/pin.h>
  18. #include "ls2k1000.h"
  19. #include "interrupt.h"
  20. static struct rt_irq_desc irq_handle_table[MAX_INTR];
  21. static void rt_hw_interrupt_handler(int vector, void *param)
  22. {
  23. rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
  24. }
  25. static void liointc_init(void)
  26. {
  27. int i;
  28. /* Router for LIOINTC0, to Core 0, INT0 (CPU IP2) */
  29. for (i = 0; i < 32; i ++)
  30. {
  31. HWREG8(LIOINTC0_BASE + i) = LIOINTC_COREx_INTy(0, 0);
  32. }
  33. /* Router for LIOINTC1, to Core 0, INT1 (CPU IP3) */
  34. for (i = 0; i < 32; i ++)
  35. {
  36. HWREG8(LIOINTC1_BASE + i) = LIOINTC_COREx_INTy(0, 1);
  37. }
  38. /* Disable all IRQs */
  39. HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_DISABLE) = 0xffffffff;
  40. HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_DISABLE) = 0xffffffff;
  41. /* Set all IRQs to low level triggered (Default?) */
  42. HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_POL) = 0x0;
  43. HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_EDGE) = 0x0;
  44. HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_POL) = 0x0;
  45. HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_EDGE) = 0x0;
  46. }
  47. //set irq mode
  48. void liointc_set_irq_mode(int irq, int mode)
  49. {
  50. if(irq < 32)
  51. {
  52. if(mode == PIN_IRQ_MODE_RISING)
  53. {
  54. HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_POL) |= (0x0 << (irq));
  55. HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_EDGE) |= (0x1 << (irq));
  56. }
  57. else if(mode == PIN_IRQ_MODE_FALLING)
  58. {
  59. HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_POL) |= (0x1 << (irq));
  60. HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_EDGE) |= (0x1 << (irq));
  61. }
  62. else if(mode == PIN_IRQ_MODE_HIGH_LEVEL)
  63. {
  64. HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_POL) |= (0x1 << (irq));
  65. HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_EDGE) |= (0x0 << (irq));
  66. }
  67. else if(mode == PIN_IRQ_MODE_LOW_LEVEL)
  68. {
  69. HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_POL) |= (0x0 << (irq));
  70. HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_EDGE) |= (0x0 << (irq));
  71. }
  72. else
  73. {
  74. HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_POL) |= (0x1 << (irq));
  75. HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_EDGE) |= (0x1 << (irq));
  76. }
  77. }
  78. else
  79. {
  80. if(mode == PIN_IRQ_MODE_RISING)
  81. {
  82. HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_POL) |= (0x0 << (irq - 32));
  83. HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_EDGE) |= (0x1 << (irq - 32));
  84. }
  85. else if(mode == PIN_IRQ_MODE_FALLING)
  86. {
  87. HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_POL) |= (0x1 << (irq - 32));
  88. HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_EDGE) |= (0x1 << (irq - 32));
  89. }
  90. else if(mode == PIN_IRQ_MODE_HIGH_LEVEL)
  91. {
  92. HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_POL) |= (0x1 << (irq - 32));
  93. HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_EDGE) |= (0x0 << (irq - 32));
  94. }
  95. else if(mode == PIN_IRQ_MODE_LOW_LEVEL)
  96. {
  97. HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_POL) |= (0x0 << (irq - 32));
  98. HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_EDGE) |= (0x0 << (irq - 32));
  99. }
  100. else
  101. {
  102. HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_POL) |= (0x1 << (irq - 32));
  103. HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_EDGE) |= (0x1 << (irq - 32));
  104. }
  105. }
  106. }
  107. static void liointc_isr(rt_ubase_t reg_base, rt_ubase_t isr_base,
  108. int irq_base)
  109. {
  110. rt_uint32_t isr, tmp;
  111. int intx;
  112. /* Mask to clear ISR */
  113. isr = HWREG32(isr_base);
  114. tmp = isr;
  115. /* Handle each of them */
  116. while (tmp)
  117. {
  118. rt_isr_handler_t irq_func;
  119. void *param;
  120. int irq;
  121. intx = __rt_ffs(isr) - 1;
  122. tmp &= ~(1 << intx);
  123. irq = intx + irq_base;
  124. irq_func = irq_handle_table[irq].handler;
  125. param = irq_handle_table[irq].param;
  126. irq_func(irq, param);
  127. #ifdef RT_USING_INTERRUPT_INFO
  128. irq_handle_table[irq].counter++;
  129. #endif
  130. }
  131. /* Enable them again */
  132. HWREG32(reg_base + LIOINTC_REG_INTC_ENABLE) = isr;
  133. }
  134. /**
  135. * This function will initialize hardware interrupt
  136. */
  137. void rt_hw_interrupt_init(void)
  138. {
  139. rt_uint32_t idx;
  140. rt_memset(irq_handle_table, 0x00, sizeof(irq_handle_table));
  141. for (idx = 0; idx < MAX_INTR; idx ++)
  142. {
  143. irq_handle_table[idx].handler = rt_hw_interrupt_handler;
  144. }
  145. liointc_init();
  146. }
  147. rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
  148. void *param, const char *name)
  149. {
  150. rt_isr_handler_t old_handler = RT_NULL;
  151. if (vector >= 0 && vector < MAX_INTR)
  152. {
  153. old_handler = irq_handle_table[vector].handler;
  154. #ifdef RT_USING_INTERRUPT_INFO
  155. rt_strncpy(irq_handle_table[vector].name, name, RT_NAME_MAX);
  156. #endif /* RT_USING_INTERRUPT_INFO */
  157. irq_handle_table[vector].handler = handler;
  158. irq_handle_table[vector].param = param;
  159. }
  160. if(vector <= 32)
  161. {
  162. mips_unmask_cpu_irq(2);
  163. }
  164. else
  165. {
  166. mips_unmask_cpu_irq(3);
  167. }
  168. return old_handler;
  169. }
  170. void rt_do_mips_cpu_irq(rt_uint32_t ip)
  171. {
  172. void *param;
  173. rt_isr_handler_t irq_func;
  174. if (ip == 7)
  175. {
  176. rt_hw_timer_handler();
  177. }
  178. else if (ip == 2)
  179. {
  180. liointc_isr(LIOINTC0_BASE, CORE0_INTISR0, LIOINTC0_IRQBASE);
  181. }
  182. else if (ip == 3)
  183. {
  184. liointc_isr(LIOINTC1_BASE, CORE0_INTISR1, LIOINTC1_IRQBASE);
  185. }
  186. }
  187. void rt_hw_interrupt_umask(int irq)
  188. {
  189. if(irq < LIOINTC0_IRQBASE + 32)
  190. {
  191. HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_ENABLE) = (1 << irq);
  192. }
  193. else if(irq < LIOINTC1_IRQBASE + 32)
  194. {
  195. HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_ENABLE) = (1 << (irq - 32));
  196. }
  197. }
  198. void rt_hw_interrupt_mask(int irq)
  199. {
  200. if(irq < LIOINTC0_IRQBASE + 32)
  201. {
  202. HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_DISABLE) = (1 << irq);
  203. }
  204. else if(irq < LIOINTC1_IRQBASE + 32)
  205. {
  206. HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_DISABLE) = (1 << (irq - 32));
  207. }
  208. }
  209. /*@}*/