context_gcc.S 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. /*
  2. * Copyright (c) 2006-2018, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2018/10/28 Bernard The unify RISC-V porting implementation
  9. * 2018/12/27 Jesven Add SMP support
  10. */
  11. #include "cpuport.h"
  12. #ifdef RT_USING_SMP
  13. #define rt_hw_interrupt_disable rt_hw_local_irq_disable
  14. #define rt_hw_interrupt_enable rt_hw_local_irq_enable
  15. #endif
  16. /*
  17. * rt_base_t rt_hw_interrupt_disable(void);
  18. */
  19. .globl rt_hw_interrupt_disable
  20. rt_hw_interrupt_disable:
  21. csrrci a0, mstatus, 8
  22. ret
  23. /*
  24. * void rt_hw_interrupt_enable(rt_base_t level);
  25. */
  26. .globl rt_hw_interrupt_enable
  27. rt_hw_interrupt_enable:
  28. csrw mstatus, a0
  29. ret
  30. /*
  31. * #ifdef RT_USING_SMP
  32. * void rt_hw_context_switch_to(rt_ubase_t to, stuct rt_thread *to_thread);
  33. * #else
  34. * void rt_hw_context_switch_to(rt_ubase_t to);
  35. * #endif
  36. * a0 --> to
  37. * a1 --> to_thread
  38. */
  39. .globl rt_hw_context_switch_to
  40. rt_hw_context_switch_to:
  41. LOAD sp, (a0)
  42. #ifdef RT_USING_SMP
  43. mv a0, a1
  44. jal rt_cpus_lock_status_restore
  45. #endif
  46. /* load epc from stack */
  47. LOAD a0, 0 * REGBYTES(sp)
  48. csrw mepc, a0
  49. LOAD x1, 1 * REGBYTES(sp)
  50. /* load mstatus from stack */
  51. LOAD a0, 2 * REGBYTES(sp)
  52. csrw mstatus, a0
  53. LOAD x4, 4 * REGBYTES(sp)
  54. LOAD x5, 5 * REGBYTES(sp)
  55. LOAD x6, 6 * REGBYTES(sp)
  56. LOAD x7, 7 * REGBYTES(sp)
  57. LOAD x8, 8 * REGBYTES(sp)
  58. LOAD x9, 9 * REGBYTES(sp)
  59. LOAD x10, 10 * REGBYTES(sp)
  60. LOAD x11, 11 * REGBYTES(sp)
  61. LOAD x12, 12 * REGBYTES(sp)
  62. LOAD x13, 13 * REGBYTES(sp)
  63. LOAD x14, 14 * REGBYTES(sp)
  64. LOAD x15, 15 * REGBYTES(sp)
  65. LOAD x16, 16 * REGBYTES(sp)
  66. LOAD x17, 17 * REGBYTES(sp)
  67. LOAD x18, 18 * REGBYTES(sp)
  68. LOAD x19, 19 * REGBYTES(sp)
  69. LOAD x20, 20 * REGBYTES(sp)
  70. LOAD x21, 21 * REGBYTES(sp)
  71. LOAD x22, 22 * REGBYTES(sp)
  72. LOAD x23, 23 * REGBYTES(sp)
  73. LOAD x24, 24 * REGBYTES(sp)
  74. LOAD x25, 25 * REGBYTES(sp)
  75. LOAD x26, 26 * REGBYTES(sp)
  76. LOAD x27, 27 * REGBYTES(sp)
  77. LOAD x28, 28 * REGBYTES(sp)
  78. LOAD x29, 29 * REGBYTES(sp)
  79. LOAD x30, 30 * REGBYTES(sp)
  80. LOAD x31, 31 * REGBYTES(sp)
  81. addi sp, sp, 32 * REGBYTES
  82. mret
  83. /*
  84. * #ifdef RT_USING_SMP
  85. * void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to, struct rt_thread *to_thread);
  86. * #else
  87. * void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to);
  88. * #endif
  89. *
  90. * a0 --> from
  91. * a1 --> to
  92. * a2 --> to_thread
  93. */
  94. .globl rt_hw_context_switch
  95. rt_hw_context_switch:
  96. /* saved from thread context
  97. * x1/ra -> sp(0)
  98. * x1/ra -> sp(1)
  99. * mstatus.mie -> sp(2)
  100. * x(i) -> sp(i-4)
  101. */
  102. addi sp, sp, -32 * REGBYTES
  103. STORE sp, (a0)
  104. STORE x1, 0 * REGBYTES(sp)
  105. STORE x1, 1 * REGBYTES(sp)
  106. csrr a0, mstatus
  107. andi a0, a0, 8
  108. beqz a0, save_mpie
  109. li a0, 0x80
  110. save_mpie:
  111. STORE a0, 2 * REGBYTES(sp)
  112. STORE x4, 4 * REGBYTES(sp)
  113. STORE x5, 5 * REGBYTES(sp)
  114. STORE x6, 6 * REGBYTES(sp)
  115. STORE x7, 7 * REGBYTES(sp)
  116. STORE x8, 8 * REGBYTES(sp)
  117. STORE x9, 9 * REGBYTES(sp)
  118. STORE x10, 10 * REGBYTES(sp)
  119. STORE x11, 11 * REGBYTES(sp)
  120. STORE x12, 12 * REGBYTES(sp)
  121. STORE x13, 13 * REGBYTES(sp)
  122. STORE x14, 14 * REGBYTES(sp)
  123. STORE x15, 15 * REGBYTES(sp)
  124. STORE x16, 16 * REGBYTES(sp)
  125. STORE x17, 17 * REGBYTES(sp)
  126. STORE x18, 18 * REGBYTES(sp)
  127. STORE x19, 19 * REGBYTES(sp)
  128. STORE x20, 20 * REGBYTES(sp)
  129. STORE x21, 21 * REGBYTES(sp)
  130. STORE x22, 22 * REGBYTES(sp)
  131. STORE x23, 23 * REGBYTES(sp)
  132. STORE x24, 24 * REGBYTES(sp)
  133. STORE x25, 25 * REGBYTES(sp)
  134. STORE x26, 26 * REGBYTES(sp)
  135. STORE x27, 27 * REGBYTES(sp)
  136. STORE x28, 28 * REGBYTES(sp)
  137. STORE x29, 29 * REGBYTES(sp)
  138. STORE x30, 30 * REGBYTES(sp)
  139. STORE x31, 31 * REGBYTES(sp)
  140. /* restore to thread context
  141. * sp(0) -> epc;
  142. * sp(1) -> ra;
  143. * sp(i) -> x(i+2)
  144. */
  145. LOAD sp, (a1)
  146. #ifdef RT_USING_SMP
  147. mv a0, a2
  148. jal rt_cpus_lock_status_restore
  149. #endif /*RT_USING_SMP*/
  150. /* resw ra to mepc */
  151. LOAD a1, 0 * REGBYTES(sp)
  152. csrw mepc, a1
  153. LOAD x1, 1 * REGBYTES(sp)
  154. /* force to machin mode(MPP=11) */
  155. li a1, 0x00001800;
  156. csrs mstatus, a1
  157. LOAD a1, 2 * REGBYTES(sp)
  158. csrs mstatus, a1
  159. LOAD x4, 4 * REGBYTES(sp)
  160. LOAD x5, 5 * REGBYTES(sp)
  161. LOAD x6, 6 * REGBYTES(sp)
  162. LOAD x7, 7 * REGBYTES(sp)
  163. LOAD x8, 8 * REGBYTES(sp)
  164. LOAD x9, 9 * REGBYTES(sp)
  165. LOAD x10, 10 * REGBYTES(sp)
  166. LOAD x11, 11 * REGBYTES(sp)
  167. LOAD x12, 12 * REGBYTES(sp)
  168. LOAD x13, 13 * REGBYTES(sp)
  169. LOAD x14, 14 * REGBYTES(sp)
  170. LOAD x15, 15 * REGBYTES(sp)
  171. LOAD x16, 16 * REGBYTES(sp)
  172. LOAD x17, 17 * REGBYTES(sp)
  173. LOAD x18, 18 * REGBYTES(sp)
  174. LOAD x19, 19 * REGBYTES(sp)
  175. LOAD x20, 20 * REGBYTES(sp)
  176. LOAD x21, 21 * REGBYTES(sp)
  177. LOAD x22, 22 * REGBYTES(sp)
  178. LOAD x23, 23 * REGBYTES(sp)
  179. LOAD x24, 24 * REGBYTES(sp)
  180. LOAD x25, 25 * REGBYTES(sp)
  181. LOAD x26, 26 * REGBYTES(sp)
  182. LOAD x27, 27 * REGBYTES(sp)
  183. LOAD x28, 28 * REGBYTES(sp)
  184. LOAD x29, 29 * REGBYTES(sp)
  185. LOAD x30, 30 * REGBYTES(sp)
  186. LOAD x31, 31 * REGBYTES(sp)
  187. addi sp, sp, 32 * REGBYTES
  188. mret
  189. #ifdef RT_USING_SMP
  190. /*
  191. * void rt_hw_context_switch_interrupt(void *context, rt_ubase_t from, rt_ubase_t to, struct rt_thread *to_thread);
  192. *
  193. * a0 --> context
  194. * a1 --> from
  195. * a2 --> to
  196. * a3 --> to_thread
  197. */
  198. .globl rt_hw_context_switch_interrupt
  199. rt_hw_context_switch_interrupt:
  200. STORE a0, 0(a1)
  201. csrr a1, mepc
  202. STORE a1, 0 * REGBYTES(a0)
  203. csrr a1, mstatus
  204. STORE a1, 2 * REGBYTES(a0)
  205. LOAD sp, 0(a2)
  206. move a0, a3
  207. call rt_cpus_lock_status_restore
  208. /* resw ra to mepc */
  209. LOAD a1, 0 * REGBYTES(sp)
  210. csrw mepc, a1
  211. LOAD x1, 1 * REGBYTES(sp)
  212. /* force to machin mode(MPP=11) */
  213. li a1, 0x00001800;
  214. csrs mstatus, a1
  215. LOAD a1, 2 * REGBYTES(sp)
  216. csrs mstatus, a1
  217. LOAD x4, 4 * REGBYTES(sp)
  218. LOAD x5, 5 * REGBYTES(sp)
  219. LOAD x6, 6 * REGBYTES(sp)
  220. LOAD x7, 7 * REGBYTES(sp)
  221. LOAD x8, 8 * REGBYTES(sp)
  222. LOAD x9, 9 * REGBYTES(sp)
  223. LOAD x10, 10 * REGBYTES(sp)
  224. LOAD x11, 11 * REGBYTES(sp)
  225. LOAD x12, 12 * REGBYTES(sp)
  226. LOAD x13, 13 * REGBYTES(sp)
  227. LOAD x14, 14 * REGBYTES(sp)
  228. LOAD x15, 15 * REGBYTES(sp)
  229. LOAD x16, 16 * REGBYTES(sp)
  230. LOAD x17, 17 * REGBYTES(sp)
  231. LOAD x18, 18 * REGBYTES(sp)
  232. LOAD x19, 19 * REGBYTES(sp)
  233. LOAD x20, 20 * REGBYTES(sp)
  234. LOAD x21, 21 * REGBYTES(sp)
  235. LOAD x22, 22 * REGBYTES(sp)
  236. LOAD x23, 23 * REGBYTES(sp)
  237. LOAD x24, 24 * REGBYTES(sp)
  238. LOAD x25, 25 * REGBYTES(sp)
  239. LOAD x26, 26 * REGBYTES(sp)
  240. LOAD x27, 27 * REGBYTES(sp)
  241. LOAD x28, 28 * REGBYTES(sp)
  242. LOAD x29, 29 * REGBYTES(sp)
  243. LOAD x30, 30 * REGBYTES(sp)
  244. LOAD x31, 31 * REGBYTES(sp)
  245. addi sp, sp, 32 * REGBYTES
  246. mret
  247. #endif