interrupt.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /*
  2. * File : interrupt.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006 - 2011, 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. * 2010-10-15 lgnq modified for LS1B
  14. */
  15. #include <rtthread.h>
  16. #include "ls1b.h"
  17. #define MAX_INTR 32
  18. extern rt_uint32_t rt_interrupt_nest;
  19. rt_uint32_t rt_interrupt_from_thread;
  20. rt_uint32_t rt_interrupt_to_thread;
  21. rt_uint32_t rt_thread_switch_interrupt_flag;
  22. static rt_isr_handler_t irq_handle_table[MAX_INTR];
  23. void rt_interrupt_dispatch(void *ptreg);
  24. void rt_hw_timer_handler();
  25. static struct ls1b_intc_regs volatile *ls1b_hw0_icregs
  26. = (struct ls1b_intc_regs volatile *)(LS1B_INTREG_BASE);
  27. /**
  28. * @addtogroup Loongson LS1B
  29. */
  30. /*@{*/
  31. void rt_hw_interrupt_handler(int vector)
  32. {
  33. rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
  34. }
  35. /**
  36. * This function will initialize hardware interrupt
  37. */
  38. void rt_hw_interrupt_init(void)
  39. {
  40. rt_int32_t index;
  41. /* pci active low */
  42. ls1b_hw0_icregs->int_pol = -1; //must be done here 20110802 lgnq
  43. /* make all interrupts level triggered */
  44. (ls1b_hw0_icregs+0)->int_edge = 0x0000e000;
  45. /* mask all interrupts */
  46. (ls1b_hw0_icregs+0)->int_clr = 0xffffffff;
  47. for (index = 0; index < MAX_INTR; index ++)
  48. {
  49. irq_handle_table[index] = (rt_isr_handler_t)rt_hw_interrupt_handler;
  50. }
  51. /* init interrupt nest, and context in thread sp */
  52. rt_interrupt_nest = 0;
  53. rt_interrupt_from_thread = 0;
  54. rt_interrupt_to_thread = 0;
  55. rt_thread_switch_interrupt_flag = 0;
  56. }
  57. /**
  58. * This function will mask a interrupt.
  59. * @param vector the interrupt number
  60. */
  61. void rt_hw_interrupt_mask(int vector)
  62. {
  63. /* mask interrupt */
  64. (ls1b_hw0_icregs+(vector>>5))->int_en &= ~(1 << (vector&0x1f));
  65. }
  66. /**
  67. * This function will un-mask a interrupt.
  68. * @param vector the interrupt number
  69. */
  70. void rt_hw_interrupt_umask(int vector)
  71. {
  72. (ls1b_hw0_icregs+(vector>>5))->int_en |= (1 << (vector&0x1f));
  73. }
  74. /**
  75. * This function will install a interrupt service routine to a interrupt.
  76. * @param vector the interrupt number
  77. * @param new_handler the interrupt service routine to be installed
  78. * @param old_handler the old interrupt service routine
  79. */
  80. void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler)
  81. {
  82. if (vector >= 0 && vector < MAX_INTR)
  83. {
  84. if (old_handler != RT_NULL)
  85. *old_handler = irq_handle_table[vector];
  86. if (new_handler != RT_NULL)
  87. irq_handle_table[vector] = (rt_isr_handler_t)new_handler;
  88. }
  89. }
  90. void rt_interrupt_dispatch(void *ptreg)
  91. {
  92. int i;
  93. rt_isr_handler_t irq_func;
  94. static rt_uint32_t status = 0;
  95. rt_uint32_t c0_status;
  96. rt_uint32_t c0_cause;
  97. volatile rt_uint32_t cause_im;
  98. volatile rt_uint32_t status_im;
  99. rt_uint32_t pending_im;
  100. /* check os timer */
  101. c0_status = read_c0_status();
  102. c0_cause = read_c0_cause();
  103. cause_im = c0_cause & ST0_IM;
  104. status_im = c0_status & ST0_IM;
  105. pending_im = cause_im & status_im;
  106. if (pending_im & CAUSEF_IP7)
  107. {
  108. rt_hw_timer_handler();
  109. }
  110. if (pending_im & CAUSEF_IP2)
  111. {
  112. /* the hardware interrupt */
  113. status = ls1b_hw0_icregs->int_isr;
  114. if (!status)
  115. return;
  116. for (i = MAX_INTR; i > 0; --i)
  117. {
  118. if ((status & (1<<i)))
  119. {
  120. status &= ~(1<<i);
  121. irq_func = irq_handle_table[i];
  122. /* do interrupt */
  123. (*irq_func)(i);
  124. /* ack interrupt */
  125. ls1b_hw0_icregs->int_clr |= (1 << i);
  126. }
  127. }
  128. }
  129. else if (pending_im & CAUSEF_IP3)
  130. {
  131. rt_kprintf("%s %d\r\n", __FUNCTION__, __LINE__);
  132. }
  133. else if (pending_im & CAUSEF_IP4)
  134. {
  135. rt_kprintf("%s %d\r\n", __FUNCTION__, __LINE__);
  136. }
  137. else if (pending_im & CAUSEF_IP5)
  138. {
  139. rt_kprintf("%s %d\r\n", __FUNCTION__, __LINE__);
  140. }
  141. else if (pending_im & CAUSEF_IP6)
  142. {
  143. rt_kprintf("%s %d\r\n", __FUNCTION__, __LINE__);
  144. }
  145. }
  146. /*@}*/