interrupt.c 4.0 KB

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