context_gcc.S 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. ;/*
  2. ; * Copyright (c) 2006-2021, RT-Thread Development Team
  3. ; *
  4. ; * SPDX-License-Identifier: Apache-2.0
  5. ; *
  6. ; * Change Logs:
  7. ; * Date Author Notes
  8. ; * 2017-07-16 zhangjun for hifive1
  9. ; * 2018-05-29 tanek optimize rt_hw_interrupt_*
  10. ; * 2018-05-29 tanek add mie register to context
  11. ; */
  12. /*
  13. * rt_base_t rt_hw_interrupt_disable(void);
  14. */
  15. .globl rt_hw_interrupt_disable
  16. rt_hw_interrupt_disable:
  17. csrrci a0, mstatus, 8
  18. ret
  19. /*
  20. * void rt_hw_interrupt_enable(rt_base_t level);
  21. */
  22. .globl rt_hw_interrupt_enable
  23. rt_hw_interrupt_enable:
  24. csrw mstatus, a0
  25. ret
  26. /*
  27. * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
  28. * a0 --> from
  29. * a1 --> to
  30. */
  31. .globl rt_hw_context_switch
  32. rt_hw_context_switch:
  33. /* saved from thread context
  34. * x1/ra -> sp(0)
  35. * x1/ra -> sp(1)
  36. * mstatus.mie -> sp(2)
  37. * x(i) -> sp(i-4)
  38. */
  39. addi sp, sp, -32 * 4
  40. sw sp, (a0)
  41. sw x1, 0 * 4(sp)
  42. sw x1, 1 * 4(sp)
  43. csrr a0, mstatus
  44. andi a0, a0, 8
  45. beqz a0, save_mpie
  46. li a0, 0x80
  47. save_mpie:
  48. sw a0, 2 * 4(sp)
  49. sw x4, 4 * 4(sp)
  50. sw x5, 5 * 4(sp)
  51. sw x6, 6 * 4(sp)
  52. sw x7, 7 * 4(sp)
  53. sw x8, 8 * 4(sp)
  54. sw x9, 9 * 4(sp)
  55. sw x10, 10 * 4(sp)
  56. sw x11, 11 * 4(sp)
  57. sw x12, 12 * 4(sp)
  58. sw x13, 13 * 4(sp)
  59. sw x14, 14 * 4(sp)
  60. sw x15, 15 * 4(sp)
  61. sw x16, 16 * 4(sp)
  62. sw x17, 17 * 4(sp)
  63. sw x18, 18 * 4(sp)
  64. sw x19, 19 * 4(sp)
  65. sw x20, 20 * 4(sp)
  66. sw x21, 21 * 4(sp)
  67. sw x22, 22 * 4(sp)
  68. sw x23, 23 * 4(sp)
  69. sw x24, 24 * 4(sp)
  70. sw x25, 25 * 4(sp)
  71. sw x26, 26 * 4(sp)
  72. sw x27, 27 * 4(sp)
  73. sw x28, 28 * 4(sp)
  74. sw x29, 29 * 4(sp)
  75. sw x30, 30 * 4(sp)
  76. sw x31, 31 * 4(sp)
  77. /* restore to thread context
  78. * sp(0) -> epc;
  79. * sp(1) -> ra;
  80. * sp(i) -> x(i+2)
  81. */
  82. lw sp, (a1)
  83. /* resw ra to mepc */
  84. lw a1, 0 * 4(sp)
  85. csrw mepc, a1
  86. lw x1, 1 * 4(sp)
  87. /* force to machin mode(MPP=11) */
  88. li a1, 0x00001800;
  89. csrs mstatus, a1
  90. lw a1, 2 * 4(sp)
  91. csrs mstatus, a1
  92. lw x4, 4 * 4(sp)
  93. lw x5, 5 * 4(sp)
  94. lw x6, 6 * 4(sp)
  95. lw x7, 7 * 4(sp)
  96. lw x8, 8 * 4(sp)
  97. lw x9, 9 * 4(sp)
  98. lw x10, 10 * 4(sp)
  99. lw x11, 11 * 4(sp)
  100. lw x12, 12 * 4(sp)
  101. lw x13, 13 * 4(sp)
  102. lw x14, 14 * 4(sp)
  103. lw x15, 15 * 4(sp)
  104. lw x16, 16 * 4(sp)
  105. lw x17, 17 * 4(sp)
  106. lw x18, 18 * 4(sp)
  107. lw x19, 19 * 4(sp)
  108. lw x20, 20 * 4(sp)
  109. lw x21, 21 * 4(sp)
  110. lw x22, 22 * 4(sp)
  111. lw x23, 23 * 4(sp)
  112. lw x24, 24 * 4(sp)
  113. lw x25, 25 * 4(sp)
  114. lw x26, 26 * 4(sp)
  115. lw x27, 27 * 4(sp)
  116. lw x28, 28 * 4(sp)
  117. lw x29, 29 * 4(sp)
  118. lw x30, 30 * 4(sp)
  119. lw x31, 31 * 4(sp)
  120. addi sp, sp, 32 * 4
  121. mret
  122. /*
  123. * void rt_hw_context_switch_to(rt_uint32 to);
  124. * a0 --> to
  125. */
  126. .globl rt_hw_context_switch_to
  127. rt_hw_context_switch_to:
  128. lw sp, (a0)
  129. /* load epc from stack */
  130. lw a0, 0 * 4(sp)
  131. csrw mepc, a0
  132. lw x1, 1 * 4(sp)
  133. /* load mstatus from stack */
  134. lw a0, 2 * 4(sp)
  135. csrw mstatus, a0
  136. lw x4, 4 * 4(sp)
  137. lw x5, 5 * 4(sp)
  138. lw x6, 6 * 4(sp)
  139. lw x7, 7 * 4(sp)
  140. lw x8, 8 * 4(sp)
  141. lw x9, 9 * 4(sp)
  142. lw x10, 10 * 4(sp)
  143. lw x11, 11 * 4(sp)
  144. lw x12, 12 * 4(sp)
  145. lw x13, 13 * 4(sp)
  146. lw x14, 14 * 4(sp)
  147. lw x15, 15 * 4(sp)
  148. lw x16, 16 * 4(sp)
  149. lw x17, 17 * 4(sp)
  150. lw x18, 18 * 4(sp)
  151. lw x19, 19 * 4(sp)
  152. lw x20, 20 * 4(sp)
  153. lw x21, 21 * 4(sp)
  154. lw x22, 22 * 4(sp)
  155. lw x23, 23 * 4(sp)
  156. lw x24, 24 * 4(sp)
  157. lw x25, 25 * 4(sp)
  158. lw x26, 26 * 4(sp)
  159. lw x27, 27 * 4(sp)
  160. lw x28, 28 * 4(sp)
  161. lw x29, 29 * 4(sp)
  162. lw x30, 30 * 4(sp)
  163. lw x31, 31 * 4(sp)
  164. addi sp, sp, 32 * 4
  165. mret
  166. /*
  167. * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
  168. */
  169. .globl rt_thread_switch_interrupt_flag
  170. .globl rt_interrupt_from_thread
  171. .globl rt_interrupt_to_thread
  172. .globl rt_hw_context_switch_interrupt
  173. rt_hw_context_switch_interrupt:
  174. addi sp, sp, -16
  175. sw s0, 12(sp)
  176. sw a0, 8(sp)
  177. sw a5, 4(sp)
  178. la a0, rt_thread_switch_interrupt_flag
  179. lw a5, (a0)
  180. bnez a5, _reswitch
  181. li a5, 1
  182. sw a5, (a0)
  183. la a5, rt_interrupt_from_thread
  184. lw a0, 8(sp)
  185. sw a0, (a5)
  186. _reswitch:
  187. la a5, rt_interrupt_to_thread
  188. sw a1, (a5)
  189. lw a5, 4(sp)
  190. lw a0, 8(sp)
  191. lw s0, 12(sp)
  192. addi sp, sp, 16
  193. ret