context_gcc.S 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. ;/*
  2. ; * File : context_gcc.S
  3. ; * This file is part of RT-Thread RTOS
  4. ; * COPYRIGHT (C) 2018, RT-Thread Development Team
  5. ; *
  6. ; * This program is free software; you can redistribute it and/or modify
  7. ; * it under the terms of the GNU General Public License as published by
  8. ; * the Free Software Foundation; either version 2 of the License, or
  9. ; * (at your option) any later version.
  10. ; *
  11. ; * This program is distributed in the hope that it will be useful,
  12. ; * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. ; * GNU General Public License for more details.
  15. ; *
  16. ; * You should have received a copy of the GNU General Public License along
  17. ; * with this program; if not, write to the Free Software Foundation, Inc.,
  18. ; * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  19. ; *
  20. ; * Change Logs:
  21. ; * Date Author Notes
  22. ; * 2017-07-16 zhangjun for hifive1
  23. ; * 2018-05-29 tanek optimize rt_hw_interrupt_*
  24. ; * 2018-05-29 tanek add mie register to context
  25. ; */
  26. /*
  27. * rt_base_t rt_hw_interrupt_disable(void);
  28. */
  29. .globl rt_hw_interrupt_disable
  30. rt_hw_interrupt_disable:
  31. csrrci a0, mstatus, 8
  32. ret
  33. /*
  34. * void rt_hw_interrupt_enable(rt_base_t level);
  35. */
  36. .globl rt_hw_interrupt_enable
  37. rt_hw_interrupt_enable:
  38. csrw mstatus, a0
  39. ret
  40. /*
  41. * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
  42. * a0 --> from
  43. * a1 --> to
  44. */
  45. .globl rt_hw_context_switch
  46. rt_hw_context_switch:
  47. /* saved from thread context
  48. * x1/ra -> sp(0)
  49. * x1/ra -> sp(1)
  50. * mstatus.mie -> sp(2)
  51. * x(i) -> sp(i-4)
  52. */
  53. addi sp, sp, -32 * 4
  54. sw sp, (a0)
  55. sw x1, 0 * 4(sp)
  56. sw x1, 1 * 4(sp)
  57. csrr a0, mstatus
  58. andi a0, a0, 8
  59. beqz a0, save_mpie
  60. li a0, 0x80
  61. save_mpie:
  62. sw a0, 2 * 4(sp)
  63. sw x4, 4 * 4(sp)
  64. sw x5, 5 * 4(sp)
  65. sw x6, 6 * 4(sp)
  66. sw x7, 7 * 4(sp)
  67. sw x8, 8 * 4(sp)
  68. sw x9, 9 * 4(sp)
  69. sw x10, 10 * 4(sp)
  70. sw x11, 11 * 4(sp)
  71. sw x12, 12 * 4(sp)
  72. sw x13, 13 * 4(sp)
  73. sw x14, 14 * 4(sp)
  74. sw x15, 15 * 4(sp)
  75. sw x16, 16 * 4(sp)
  76. sw x17, 17 * 4(sp)
  77. sw x18, 18 * 4(sp)
  78. sw x19, 19 * 4(sp)
  79. sw x20, 20 * 4(sp)
  80. sw x21, 21 * 4(sp)
  81. sw x22, 22 * 4(sp)
  82. sw x23, 23 * 4(sp)
  83. sw x24, 24 * 4(sp)
  84. sw x25, 25 * 4(sp)
  85. sw x26, 26 * 4(sp)
  86. sw x27, 27 * 4(sp)
  87. sw x28, 28 * 4(sp)
  88. sw x29, 29 * 4(sp)
  89. sw x30, 30 * 4(sp)
  90. sw x31, 31 * 4(sp)
  91. /* restore to thread context
  92. * sp(0) -> epc;
  93. * sp(1) -> ra;
  94. * sp(i) -> x(i+2)
  95. */
  96. lw sp, (a1)
  97. /* resw ra to mepc */
  98. lw a1, 0 * 4(sp)
  99. csrw mepc, a1
  100. lw x1, 1 * 4(sp)
  101. /* force to machin mode(MPP=11) */
  102. li a1, 0x00001800;
  103. csrs mstatus, a1
  104. lw a1, 2 * 4(sp)
  105. csrs mstatus, a1
  106. lw x4, 4 * 4(sp)
  107. lw x5, 5 * 4(sp)
  108. lw x6, 6 * 4(sp)
  109. lw x7, 7 * 4(sp)
  110. lw x8, 8 * 4(sp)
  111. lw x9, 9 * 4(sp)
  112. lw x10, 10 * 4(sp)
  113. lw x11, 11 * 4(sp)
  114. lw x12, 12 * 4(sp)
  115. lw x13, 13 * 4(sp)
  116. lw x14, 14 * 4(sp)
  117. lw x15, 15 * 4(sp)
  118. lw x16, 16 * 4(sp)
  119. lw x17, 17 * 4(sp)
  120. lw x18, 18 * 4(sp)
  121. lw x19, 19 * 4(sp)
  122. lw x20, 20 * 4(sp)
  123. lw x21, 21 * 4(sp)
  124. lw x22, 22 * 4(sp)
  125. lw x23, 23 * 4(sp)
  126. lw x24, 24 * 4(sp)
  127. lw x25, 25 * 4(sp)
  128. lw x26, 26 * 4(sp)
  129. lw x27, 27 * 4(sp)
  130. lw x28, 28 * 4(sp)
  131. lw x29, 29 * 4(sp)
  132. lw x30, 30 * 4(sp)
  133. lw x31, 31 * 4(sp)
  134. addi sp, sp, 32 * 4
  135. mret
  136. /*
  137. * void rt_hw_context_switch_to(rt_uint32 to);
  138. * a0 --> to
  139. */
  140. .globl rt_hw_context_switch_to
  141. rt_hw_context_switch_to:
  142. lw sp, (a0)
  143. /* load epc from stack */
  144. lw a0, 0 * 4(sp)
  145. csrw mepc, a0
  146. lw x1, 1 * 4(sp)
  147. /* load mstatus from stack */
  148. lw a0, 2 * 4(sp)
  149. csrw mstatus, a0
  150. lw x4, 4 * 4(sp)
  151. lw x5, 5 * 4(sp)
  152. lw x6, 6 * 4(sp)
  153. lw x7, 7 * 4(sp)
  154. lw x8, 8 * 4(sp)
  155. lw x9, 9 * 4(sp)
  156. lw x10, 10 * 4(sp)
  157. lw x11, 11 * 4(sp)
  158. lw x12, 12 * 4(sp)
  159. lw x13, 13 * 4(sp)
  160. lw x14, 14 * 4(sp)
  161. lw x15, 15 * 4(sp)
  162. lw x16, 16 * 4(sp)
  163. lw x17, 17 * 4(sp)
  164. lw x18, 18 * 4(sp)
  165. lw x19, 19 * 4(sp)
  166. lw x20, 20 * 4(sp)
  167. lw x21, 21 * 4(sp)
  168. lw x22, 22 * 4(sp)
  169. lw x23, 23 * 4(sp)
  170. lw x24, 24 * 4(sp)
  171. lw x25, 25 * 4(sp)
  172. lw x26, 26 * 4(sp)
  173. lw x27, 27 * 4(sp)
  174. lw x28, 28 * 4(sp)
  175. lw x29, 29 * 4(sp)
  176. lw x30, 30 * 4(sp)
  177. lw x31, 31 * 4(sp)
  178. addi sp, sp, 32 * 4
  179. mret
  180. /*
  181. * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
  182. */
  183. .globl rt_thread_switch_interrupt_flag
  184. .globl rt_interrupt_from_thread
  185. .globl rt_interrupt_to_thread
  186. .globl rt_hw_context_switch_interrupt
  187. rt_hw_context_switch_interrupt:
  188. addi sp, sp, -16
  189. sw s0, 12(sp)
  190. sw a0, 8(sp)
  191. sw a5, 4(sp)
  192. la a0, rt_thread_switch_interrupt_flag
  193. lw a5, (a0)
  194. bnez a5, _reswitch
  195. li a5, 1
  196. sw a5, (a0)
  197. la a5, rt_interrupt_from_thread
  198. lw a0, 8(sp)
  199. sw a0, (a5)
  200. _reswitch:
  201. la a5, rt_interrupt_to_thread
  202. sw a1, (a5)
  203. lw a5, 4(sp)
  204. lw a0, 8(sp)
  205. lw s0, 12(sp)
  206. addi sp, sp, 16
  207. ret