context_gcc.S 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /*
  2. * File : context_gcc.S
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006, 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. * 2011-12-17 nl1031 first implementation for MicroBlaze.
  13. *
  14. */
  15. #include "microblaze.inc"
  16. .text
  17. .globl rt_interrupt_enter
  18. .globl rt_interrupt_leave
  19. /*
  20. * rt_base_t rt_hw_interrupt_disable()
  21. * copy from ucos-ii
  22. */
  23. .globl rt_hw_interrupt_disable
  24. .ent rt_hw_interrupt_disable
  25. .align 2
  26. rt_hw_interrupt_disable:
  27. ADDIK r1, r1, -4
  28. SW r4, r1, r0
  29. MFS r3, RMSR
  30. ANDNI r4, r3, IE_BIT
  31. MTS RMSR, r4
  32. LW r4, r1, r0
  33. ADDIK r1, r1, 4
  34. AND r0, r0, r0 /* NO-OP - pipeline flush */
  35. AND r0, r0, r0 /* NO-OP - pipeline flush */
  36. AND r0, r0, r0 /* NO-OP - pipeline flush */
  37. RTSD r15, 8
  38. AND r0, r0, r0
  39. .end rt_hw_interrupt_disable
  40. /*
  41. * void rt_hw_interrupt_enable(rt_base_t level)
  42. * copy from ucos-ii
  43. */
  44. .globl rt_hw_interrupt_enable
  45. .ent rt_hw_interrupt_enable
  46. .align 2
  47. rt_hw_interrupt_enable:
  48. RTSD r15, 8
  49. MTS rMSR, r5 /* Move the saved status from r5 into rMSR */
  50. .end rt_hw_interrupt_enable
  51. /*
  52. * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to)
  53. * r5 --> from
  54. * r6 --> to
  55. */
  56. .globl rt_interrupt_from_thread
  57. .globl rt_interrupt_to_thread
  58. .globl rt_hw_context_switch
  59. .ent rt_hw_context_switch
  60. .align 2
  61. rt_hw_context_switch:
  62. PUSH_ALL
  63. MFS r3, RMSR /* save the MSR */
  64. SWI r3, r1, STACK_RMSR
  65. SWI r1, r5, 0 /* store sp in preempted tasks TCB */
  66. LWI r1, r6, 0 /* get new task stack pointer */
  67. LWI r3, r1, STACK_RMSR
  68. ANDI r3, r3, IE_BIT
  69. BNEI r3, rt_hw_context_switch_ie /*if IE bit set,should be use RTID (return from interrupt). */
  70. LWI r3, r1, STACK_RMSR
  71. MTS RMSR, r3
  72. POP_ALL
  73. ADDIK r1, r1, STACK_SIZE
  74. RTSD r15, 8
  75. AND r0, r0, r0
  76. rt_hw_context_switch_ie:
  77. LWI r3, r1, STACK_RMSR
  78. ANDNI r3, r3, IE_BIT /* clear IE bit, prevent interrupt occur immediately*/
  79. MTS RMSR, r3
  80. LWI r3, r1, STACK_R03
  81. POP_ALL
  82. ADDIK r1, r1, STACK_SIZE
  83. RTID r14, 0 /* IE bit will be set automatically */
  84. AND r0, r0, r0
  85. .end rt_hw_context_switch
  86. /*
  87. * void rt_hw_context_switch_to(rt_uint32 to)
  88. * r5 --> to
  89. */
  90. .globl rt_hw_context_switch_to
  91. .ent rt_hw_context_switch_to
  92. .align 2
  93. rt_hw_context_switch_to:
  94. LWI r1, r5, 0 /* get new task stack pointer */
  95. LWI r3, r1, STACK_RMSR
  96. ANDNI r3, r3, IE_BIT /* clear IE bit, prevent interrupt occur immediately*/
  97. MTS RMSR, r3
  98. POP_ALL
  99. ADDIK r1, r1, STACK_SIZE
  100. RTID r14, 0 /* IE bit will be set automatically */
  101. AND r0, r0, r0
  102. .end rt_hw_context_switch_to
  103. /*
  104. * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to)
  105. */
  106. .globl rt_thread_switch_interrupt_flag
  107. .globl rt_hw_context_switch_interrupt
  108. .ent rt_hw_context_switch_interrupt
  109. .align 2
  110. rt_hw_context_switch_interrupt:
  111. LA r3, r0, rt_thread_switch_interrupt_flag
  112. LWI r4, r3, 0 /* load rt_thread_switch_interrupt_flag into r4 */
  113. ANDI r4, r4, 1
  114. BNEI r4, _reswitch /* if rt_thread_switch_interrupt_flag = 1 */
  115. ADDIK r4, r0, 1 /* set rt_thread_switch_interrupt_flag to 1 */
  116. SWI r4, r3, 0
  117. LA r3, r0, rt_interrupt_from_thread /* set rt_interrupt_from_thread */
  118. SWI r5, r3, 0 /* rt_interrupt_from_thread = from */
  119. _reswitch:
  120. LA r3, r0, rt_interrupt_to_thread/* set rt_interrupt_to_thread */
  121. SWI r6, r3, 0 /* rt_interrupt_to_thread = to */
  122. RTSD r15, 8
  123. AND r0, r0, r0
  124. .end rt_hw_context_switch_interrupt
  125. .globl _interrupt_handler
  126. .align 2
  127. .ent _interrupt_handler
  128. .type _interrupt_handler, @function
  129. _interrupt_handler:
  130. PUSH_ALL
  131. MFS r3, RMSR
  132. ORI r3, r3, IE_BIT
  133. SWI r3, r1, STACK_RMSR /* push MSR */
  134. BRLID r15, rt_interrupt_enter
  135. AND r0, r0, r0
  136. BRLID r15, rt_hw_trap_irq
  137. AND r0, r0, r0
  138. BRLID r15, rt_interrupt_leave
  139. AND r0, r0, r0
  140. /*
  141. * if rt_thread_switch_interrupt_flag set, jump to
  142. * rt_hw_context_switch_interrupt_do and don't return
  143. */
  144. LA r3, r0, rt_thread_switch_interrupt_flag
  145. LWI r4, r3, 0
  146. ANDI r4, r4, 1
  147. BNEI r4, rt_hw_context_switch_interrupt_do
  148. LWI r3, r1, STACK_RMSR
  149. ANDNI r3, r3, IE_BIT
  150. MTS RMSR, r3
  151. POP_ALL
  152. ADDIK r1, r1, STACK_SIZE
  153. RTID r14, 0
  154. AND r0, r0, r0
  155. /*
  156. * void rt_hw_context_switch_interrupt_do(rt_base_t flag)
  157. */
  158. rt_hw_context_switch_interrupt_do:
  159. SWI r0, r3, 0 /* clear rt_thread_switch_interrupt_flag */
  160. LA r3, r0, rt_interrupt_from_thread
  161. LW r4, r0, r3
  162. SWI r1, r4, 0 /* store sp in preempted tasks's TCB */
  163. LA r3, r0, rt_interrupt_to_thread
  164. LW r4, r0, r3
  165. LWI r1, r4, 0 /* get new task's stack pointer */
  166. LWI r3, r1, STACK_RMSR
  167. ANDI r3, r3, IE_BIT
  168. BNEI r3, return_with_ie /*if IE bit set,should be use RTID (return from interrupt). */
  169. LWI r3, r1, STACK_RMSR
  170. MTS RMSR, r3
  171. POP_ALL
  172. ADDIK r1, r1, STACK_SIZE
  173. RTSD r15, 8
  174. AND r0, r0, r0
  175. return_with_ie:
  176. LWI r3, r1, STACK_RMSR
  177. ANDNI r3, r3, IE_BIT /* clear IE bit, prevent interrupt occur immediately*/
  178. MTS RMSR, r3
  179. LWI r3, r1, STACK_R03
  180. POP_ALL
  181. ADDIK r1, r1, STACK_SIZE
  182. RTID r14, 0 /* IE bit will be set automatically */
  183. AND r0, r0, r0
  184. .end _interrupt_handler