context_gcc.S 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  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. .section .text
  127. .align 2
  128. .ent _interrupt_handler
  129. .type _interrupt_handler, @function
  130. _interrupt_handler:
  131. PUSH_ALL
  132. MFS r3, RMSR
  133. ORI r3, r3, IE_BIT
  134. SWI r3, r1, STACK_RMSR /* push MSR */
  135. BRLID r15, rt_interrupt_enter
  136. AND r0, r0, r0
  137. BRLID r15, rt_hw_trap_irq
  138. AND r0, r0, r0
  139. BRLID r15, rt_interrupt_leave
  140. AND r0, r0, r0
  141. /*
  142. * if rt_thread_switch_interrupt_flag set, jump to
  143. * rt_hw_context_switch_interrupt_do and don't return
  144. */
  145. LA r3, r0, rt_thread_switch_interrupt_flag
  146. LWI r4, r3, 0
  147. ANDI r4, r4, 1
  148. BNEI r4, rt_hw_context_switch_interrupt_do
  149. LWI r3, r1, STACK_RMSR
  150. ANDNI r3, r3, IE_BIT
  151. MTS RMSR,r3
  152. POP_ALL
  153. ADDIK r1, r1, STACK_SIZE
  154. RTID r14, 0
  155. AND r0, r0, r0
  156. /*
  157. * void rt_hw_context_switch_interrupt_do(rt_base_t flag)
  158. */
  159. rt_hw_context_switch_interrupt_do:
  160. SWI r0, r3, 0 /* clear rt_thread_switch_interrupt_flag */
  161. LA r3, r0, rt_interrupt_from_thread
  162. LW r4, r0, r3
  163. SWI r1, r4, 0 /* store sp in preempted tasks's TCB */
  164. LA r3, r0, rt_interrupt_to_thread
  165. LW r4, r0, r3
  166. LWI r1, r4, 0 /* get new task's stack pointer */
  167. LWI r3, r1, STACK_RMSR
  168. ANDI r3, r3, IE_BIT
  169. BNEI r3, return_with_ie /*if IE bit set,should be use RTID (return from interrupt). */
  170. LWI r3, r1, STACK_RMSR
  171. MTS RMSR,r3
  172. POP_ALL
  173. ADDIK r1, r1, STACK_SIZE
  174. RTSD r15, 8
  175. AND r0, r0, r0
  176. return_with_ie:
  177. LWI r3, r1, STACK_RMSR
  178. ANDNI r3, r3, IE_BIT /* clear IE bit, prevent interrupt occur immediately*/
  179. MTS RMSR,r3
  180. LWI r3, r1, STACK_R03
  181. POP_ALL
  182. ADDIK r1, r1, STACK_SIZE
  183. RTID r14, 0 /* IE bit will be set automatically */
  184. AND r0, r0, r0
  185. .end _interrupt_handler