interrupt.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /*
  2. * File : cpu_intc.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2008 - 2012, RT-Thread Development Team
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along
  17. * with this program; if not, write to the Free Software Foundation, Inc.,
  18. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  19. *
  20. * Change Logs:
  21. * Date Author Notes
  22. * 2016/09/07 Urey the first version
  23. */
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <rtthread.h>
  27. #include <rthw.h>
  28. #include <board.h>
  29. #include "../common/mips.h"
  30. #define INTERRUPTS_MAX 64
  31. extern rt_uint32_t rt_interrupt_nest;
  32. rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
  33. rt_uint32_t rt_thread_switch_interrupt_flag;
  34. static struct rt_irq_desc isr_table[INTERRUPTS_MAX];
  35. static void rt_hw_interrupt_handler(int vector, void *param)
  36. {
  37. rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
  38. }
  39. void rt_hw_interrupt_init(void)
  40. {
  41. rt_int32_t idx;
  42. clear_c0_status(0xff04); /* clear ERL */
  43. set_c0_status(0x0400); /* set IP2 */
  44. rt_memset(isr_table, 0x00, sizeof(isr_table));
  45. for (idx = 0; idx < INTERRUPTS_MAX; idx ++)
  46. {
  47. isr_table[idx].handler = rt_hw_interrupt_handler;
  48. }
  49. /* init interrupt nest, and context in thread sp */
  50. rt_interrupt_nest = 0;
  51. rt_interrupt_from_thread = 0;
  52. rt_interrupt_to_thread = 0;
  53. rt_thread_switch_interrupt_flag = 0;
  54. /* enable cpu interrupt mask */
  55. set_c0_status(IE_IRQ0 | IE_IRQ1);
  56. }
  57. void rt_hw_interrupt_mask(int vector)
  58. {
  59. /* mask interrupt */
  60. __intc_mask_irq(vector);
  61. }
  62. void rt_hw_interrupt_umask(int vector)
  63. {
  64. __intc_unmask_irq(vector);
  65. }
  66. rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
  67. void *param, char *name)
  68. {
  69. rt_isr_handler_t old_handler = RT_NULL;
  70. if(vector < INTERRUPTS_MAX)
  71. {
  72. old_handler = isr_table[vector].handler;
  73. #ifdef RT_USING_INTERRUPT_INFO
  74. rt_strncpy(isr_table[vector].name, name, RT_NAME_MAX);
  75. #endif /* RT_USING_INTERRUPT_INFO */
  76. isr_table[vector].handler = handler;
  77. isr_table[vector].param = param;
  78. }
  79. return old_handler;
  80. }
  81. rt_inline int fls(int x)
  82. {
  83. __asm__("clz %0, %1" : "=r" (x) : "r" (x));
  84. return 32 - x;
  85. }
  86. void rt_interrupt_dispatch(void *ptreg)
  87. {
  88. void *param;
  89. rt_isr_handler_t irq_func;
  90. int irq = 0, group;
  91. rt_uint32_t intc_ipr0 = 0, intc_ipr1 = 0, vpu_pending = 0;
  92. rt_uint32_t c0_status, c0_cause;
  93. rt_uint32_t pending_im;
  94. /* check os timer */
  95. c0_status = read_c0_status();
  96. c0_cause = read_c0_cause();
  97. pending_im = (c0_cause & ST0_IM) & (c0_status & ST0_IM);
  98. if (pending_im & CAUSEF_IP3)
  99. {
  100. extern void rt_hw_ost_handler(void);
  101. rt_hw_ost_handler();
  102. return;
  103. }
  104. if (pending_im & CAUSEF_IP2)
  105. {
  106. intc_ipr0 = REG_INTC_IPR(0);
  107. intc_ipr1 = REG_INTC_IPR(1);
  108. if (intc_ipr0)
  109. {
  110. irq = fls(intc_ipr0) - 1;
  111. intc_ipr0 &= ~(1<<irq);
  112. }
  113. else if(intc_ipr1)
  114. {
  115. irq = fls(intc_ipr1) - 1;
  116. intc_ipr1 &= ~(1<<irq);
  117. irq += 32;
  118. }
  119. else
  120. {
  121. //VPU
  122. }
  123. if (irq >= INTERRUPTS_MAX)
  124. rt_kprintf("max interrupt, irq=%d\n", irq);
  125. /* do interrupt */
  126. irq_func = isr_table[irq].handler;
  127. param = isr_table[irq].param;
  128. (*irq_func)(irq, param);
  129. #ifdef RT_USING_INTERRUPT_INFO
  130. isr_table[irq].counter++;
  131. #endif /* RT_USING_INTERRUPT_INFO */
  132. /* ack interrupt */
  133. __intc_ack_irq(irq);
  134. }
  135. if (pending_im & CAUSEF_IP0)
  136. rt_kprintf("CAUSEF_IP0\n");
  137. if (pending_im & CAUSEF_IP1)
  138. rt_kprintf("CAUSEF_IP1\n");
  139. if (pending_im & CAUSEF_IP4)
  140. rt_kprintf("CAUSEF_IP4\n");
  141. if (pending_im & CAUSEF_IP5)
  142. rt_kprintf("CAUSEF_IP5\n");
  143. if (pending_im & CAUSEF_IP6)
  144. rt_kprintf("CAUSEF_IP6\n");
  145. if (pending_im & CAUSEF_IP7)
  146. rt_kprintf("CAUSEF_IP7\n");
  147. }
  148. #ifdef RT_USING_INTERRUPT_INFO
  149. #include <finsh.h>
  150. int list_irqs(void)
  151. {
  152. int index;
  153. rt_kprintf("interrupt list:\n");
  154. rt_kprintf("----------------\n");
  155. rt_kprintf("name counter\n");
  156. for (index = 0; index < INTERRUPTS_MAX; index ++)
  157. {
  158. if (isr_table[index].handler != rt_hw_interrupt_handler)
  159. {
  160. rt_kprintf("%-*.*s %d\n", RT_NAME_MAX, RT_NAME_MAX, isr_table[index].name, isr_table[index].counter);
  161. }
  162. }
  163. return 0;
  164. }
  165. MSH_CMD_EXPORT(list_irqs, list interrupt counter);
  166. #endif
  167. unsigned int spin_lock_irqsave(void)
  168. {
  169. register unsigned int t;
  170. t = read_c0_status();
  171. write_c0_status((t & (~1)));
  172. return (t);
  173. }
  174. void spin_unlock_irqrestore(unsigned int val)
  175. {
  176. write_c0_status(val);
  177. }