interrupt.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /*
  2. * File : interrupt.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006 - 2010, RT-Thread Development Team
  5. *
  6. * The license and distribution terms for this file may be
  7. * found in the file LICENSE in this distribution or at
  8. * http://www.rt-thread.org/license/LICENSE
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. * 2010-10-15 Bernard first version
  13. * 2013-03-29 aozima Modify the interrupt interface implementations.
  14. */
  15. #include <rtthread.h>
  16. #include <rthw.h>
  17. #include "soc3210.h"
  18. #define MAX_INTR 32
  19. extern rt_uint32_t rt_interrupt_nest;
  20. rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
  21. rt_uint32_t rt_thread_switch_interrupt_flag;
  22. static struct rt_irq_desc irq_handle_table[MAX_INTR];
  23. void rt_interrupt_dispatch(void *ptreg);
  24. void rt_hw_timer_handler();
  25. /**
  26. * @addtogroup Loongson SoC3210
  27. */
  28. /*@{*/
  29. static void rt_hw_interrupt_handler(int vector, void *param)
  30. {
  31. rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
  32. }
  33. /**
  34. * This function will initialize hardware interrupt
  35. */
  36. void rt_hw_interrupt_init(void)
  37. {
  38. rt_int32_t idx;
  39. rt_memset(irq_handle_table, 0x00, sizeof(irq_handle_table));
  40. for (idx = 0; idx < MAX_INTR; idx ++)
  41. {
  42. irq_handle_table[idx].handler = rt_hw_interrupt_handler;
  43. }
  44. /* init interrupt nest, and context in thread sp */
  45. rt_interrupt_nest = 0;
  46. rt_interrupt_from_thread = 0;
  47. rt_interrupt_to_thread = 0;
  48. rt_thread_switch_interrupt_flag = 0;
  49. }
  50. /**
  51. * This function will mask a interrupt.
  52. * @param vector the interrupt number
  53. */
  54. void rt_hw_interrupt_mask(int vector)
  55. {
  56. /* mask interrupt */
  57. INT_EN &= ~(1 << vector);
  58. }
  59. /**
  60. * This function will un-mask a interrupt.
  61. * @param vector the interrupt number
  62. */
  63. void rt_hw_interrupt_umask(int vector)
  64. {
  65. INT_EN |= (1 << vector);
  66. }
  67. /**
  68. * This function will install a interrupt service routine to a interrupt.
  69. * @param vector the interrupt number
  70. * @param new_handler the interrupt service routine to be installed
  71. * @param old_handler the old interrupt service routine
  72. */
  73. rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
  74. void *param, char *name)
  75. {
  76. rt_isr_handler_t old_handler = RT_NULL;
  77. if(vector < MAX_INTR)
  78. {
  79. old_handler = irq_handle_table[vector].handler;
  80. if (handler != RT_NULL)
  81. {
  82. #ifdef RT_USING_INTERRUPT_INFO
  83. rt_strncpy(irq_handle_table[vector].name, name, RT_NAME_MAX);
  84. #endif /* RT_USING_INTERRUPT_INFO */
  85. irq_handle_table[vector].handler = handler;
  86. irq_handle_table[vector].param = param;
  87. }
  88. }
  89. return old_handler;
  90. }
  91. void rt_interrupt_dispatch(void *ptreg)
  92. {
  93. int irq;
  94. void *param;
  95. rt_isr_handler_t irq_func;
  96. static rt_uint32_t status = 0;
  97. rt_uint32_t c0_status;
  98. /* check os timer */
  99. c0_status = read_c0_status();
  100. if (c0_status & 0x8000)
  101. {
  102. rt_hw_timer_handler();
  103. }
  104. if (c0_status & 0x0400)
  105. {
  106. /* the hardware interrupt */
  107. status |= INT_ISR;
  108. if (!status) return;
  109. for (irq = MAX_INTR; irq > 0; --irq)
  110. {
  111. if ((status & (1 << irq)))
  112. {
  113. status &= ~(1 << irq);
  114. irq_func = irq_handle_table[irq].handler;
  115. param = irq_handle_table[irq].param;
  116. /* do interrupt */
  117. (*irq_func)(irq, param);
  118. #ifdef RT_USING_INTERRUPT_INFO
  119. irq_handle_table[irq].counter++;
  120. #endif /* RT_USING_INTERRUPT_INFO */
  121. /* ack interrupt */
  122. INT_CLR = (1 << irq);
  123. }
  124. }
  125. }
  126. }
  127. /*@}*/