1
0

stackframe.h 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  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. * 2021-02-02 lizhirui first version
  9. * 2021-02-11 lizhirui fixed gp save/store bug
  10. * 2021-11-18 JasonHu add fpu registers save/restore
  11. * 2022/10/22 WangXiaoyao Support kernel mode RVV;
  12. */
  13. #ifndef __STACKFRAME_H__
  14. #define __STACKFRAME_H__
  15. #include "cpuport.h"
  16. #include "encoding.h"
  17. #include "ext_context.h"
  18. #define BYTES(idx) ((idx) * REGBYTES)
  19. #define FRAME_OFF_SSTATUS BYTES(2)
  20. #define FRAME_OFF_SP BYTES(32)
  21. #define FRAME_OFF_GP BYTES(3)
  22. #ifdef __ASSEMBLY__
  23. .macro SAVE_ALL
  24. #ifdef ENABLE_FPU
  25. /* reserve float registers */
  26. addi sp, sp, -CTX_FPU_REG_NR * REGBYTES
  27. #endif /* ENABLE_FPU */
  28. #ifdef ENABLE_VECTOR
  29. /* reserve float registers */
  30. addi sp, sp, -CTX_VECTOR_REG_NR * REGBYTES
  31. #endif /* ENABLE_VECTOR */
  32. /* save general registers */
  33. addi sp, sp, -CTX_GENERAL_REG_NR * REGBYTES
  34. STORE x1, 1 * REGBYTES(sp)
  35. csrr x1, sstatus
  36. STORE x1, FRAME_OFF_SSTATUS(sp)
  37. csrr x1, sepc
  38. STORE x1, 0 * REGBYTES(sp)
  39. STORE x3, 3 * REGBYTES(sp)
  40. STORE x4, 4 * REGBYTES(sp) /* save tp */
  41. STORE x5, 5 * REGBYTES(sp)
  42. STORE x6, 6 * REGBYTES(sp)
  43. STORE x7, 7 * REGBYTES(sp)
  44. STORE x8, 8 * REGBYTES(sp)
  45. STORE x9, 9 * REGBYTES(sp)
  46. STORE x10, 10 * REGBYTES(sp)
  47. STORE x11, 11 * REGBYTES(sp)
  48. STORE x12, 12 * REGBYTES(sp)
  49. STORE x13, 13 * REGBYTES(sp)
  50. STORE x14, 14 * REGBYTES(sp)
  51. STORE x15, 15 * REGBYTES(sp)
  52. STORE x16, 16 * REGBYTES(sp)
  53. STORE x17, 17 * REGBYTES(sp)
  54. STORE x18, 18 * REGBYTES(sp)
  55. STORE x19, 19 * REGBYTES(sp)
  56. STORE x20, 20 * REGBYTES(sp)
  57. STORE x21, 21 * REGBYTES(sp)
  58. STORE x22, 22 * REGBYTES(sp)
  59. STORE x23, 23 * REGBYTES(sp)
  60. STORE x24, 24 * REGBYTES(sp)
  61. STORE x25, 25 * REGBYTES(sp)
  62. STORE x26, 26 * REGBYTES(sp)
  63. STORE x27, 27 * REGBYTES(sp)
  64. STORE x28, 28 * REGBYTES(sp)
  65. STORE x29, 29 * REGBYTES(sp)
  66. STORE x30, 30 * REGBYTES(sp)
  67. STORE x31, 31 * REGBYTES(sp)
  68. csrr t0, sscratch
  69. STORE t0, 32 * REGBYTES(sp)
  70. #ifdef ENABLE_FPU
  71. /* backup sp and adjust sp to save float registers */
  72. mv t1, sp
  73. addi t1, t1, CTX_GENERAL_REG_NR * REGBYTES
  74. li t0, SSTATUS_FS
  75. csrs sstatus, t0
  76. fsd f0, FPU_CTX_F0_OFF(t1)
  77. fsd f1, FPU_CTX_F1_OFF(t1)
  78. fsd f2, FPU_CTX_F2_OFF(t1)
  79. fsd f3, FPU_CTX_F3_OFF(t1)
  80. fsd f4, FPU_CTX_F4_OFF(t1)
  81. fsd f5, FPU_CTX_F5_OFF(t1)
  82. fsd f6, FPU_CTX_F6_OFF(t1)
  83. fsd f7, FPU_CTX_F7_OFF(t1)
  84. fsd f8, FPU_CTX_F8_OFF(t1)
  85. fsd f9, FPU_CTX_F9_OFF(t1)
  86. fsd f10, FPU_CTX_F10_OFF(t1)
  87. fsd f11, FPU_CTX_F11_OFF(t1)
  88. fsd f12, FPU_CTX_F12_OFF(t1)
  89. fsd f13, FPU_CTX_F13_OFF(t1)
  90. fsd f14, FPU_CTX_F14_OFF(t1)
  91. fsd f15, FPU_CTX_F15_OFF(t1)
  92. fsd f16, FPU_CTX_F16_OFF(t1)
  93. fsd f17, FPU_CTX_F17_OFF(t1)
  94. fsd f18, FPU_CTX_F18_OFF(t1)
  95. fsd f19, FPU_CTX_F19_OFF(t1)
  96. fsd f20, FPU_CTX_F20_OFF(t1)
  97. fsd f21, FPU_CTX_F21_OFF(t1)
  98. fsd f22, FPU_CTX_F22_OFF(t1)
  99. fsd f23, FPU_CTX_F23_OFF(t1)
  100. fsd f24, FPU_CTX_F24_OFF(t1)
  101. fsd f25, FPU_CTX_F25_OFF(t1)
  102. fsd f26, FPU_CTX_F26_OFF(t1)
  103. fsd f27, FPU_CTX_F27_OFF(t1)
  104. fsd f28, FPU_CTX_F28_OFF(t1)
  105. fsd f29, FPU_CTX_F29_OFF(t1)
  106. fsd f30, FPU_CTX_F30_OFF(t1)
  107. fsd f31, FPU_CTX_F31_OFF(t1)
  108. /* clr FS domain */
  109. csrc sstatus, t0
  110. /* clean status would clr sr_sd; */
  111. li t0, SSTATUS_FS_CLEAN
  112. csrs sstatus, t0
  113. #endif /* ENABLE_FPU */
  114. #ifdef ENABLE_VECTOR
  115. csrr t0, sstatus
  116. andi t0, t0, SSTATUS_VS
  117. beqz t0, 0f
  118. /* push vector frame */
  119. addi t1, sp, (CTX_GENERAL_REG_NR + CTX_FPU_REG_NR) * REGBYTES
  120. SAVE_VECTOR t1
  121. 0:
  122. #endif /* ENABLE_VECTOR */
  123. .endm
  124. /**
  125. * @brief Restore All General Registers, for interrupt handling
  126. *
  127. */
  128. .macro RESTORE_ALL
  129. #ifdef ENABLE_VECTOR
  130. // skip on close
  131. ld t0, 2 * REGBYTES(sp)
  132. // cannot use vector on initial
  133. andi t0, t0, SSTATUS_VS_CLEAN
  134. beqz t0, 0f
  135. /* push vector frame */
  136. addi t1, sp, (CTX_GENERAL_REG_NR + CTX_FPU_REG_NR) * REGBYTES
  137. RESTORE_VECTOR t1
  138. 0:
  139. #endif /* ENABLE_VECTOR */
  140. #ifdef ENABLE_FPU
  141. /* restore float register */
  142. addi t2, sp, CTX_GENERAL_REG_NR * REGBYTES
  143. li t0, SSTATUS_FS
  144. csrs sstatus, t0
  145. fld f0, FPU_CTX_F0_OFF(t2)
  146. fld f1, FPU_CTX_F1_OFF(t2)
  147. fld f2, FPU_CTX_F2_OFF(t2)
  148. fld f3, FPU_CTX_F3_OFF(t2)
  149. fld f4, FPU_CTX_F4_OFF(t2)
  150. fld f5, FPU_CTX_F5_OFF(t2)
  151. fld f6, FPU_CTX_F6_OFF(t2)
  152. fld f7, FPU_CTX_F7_OFF(t2)
  153. fld f8, FPU_CTX_F8_OFF(t2)
  154. fld f9, FPU_CTX_F9_OFF(t2)
  155. fld f10, FPU_CTX_F10_OFF(t2)
  156. fld f11, FPU_CTX_F11_OFF(t2)
  157. fld f12, FPU_CTX_F12_OFF(t2)
  158. fld f13, FPU_CTX_F13_OFF(t2)
  159. fld f14, FPU_CTX_F14_OFF(t2)
  160. fld f15, FPU_CTX_F15_OFF(t2)
  161. fld f16, FPU_CTX_F16_OFF(t2)
  162. fld f17, FPU_CTX_F17_OFF(t2)
  163. fld f18, FPU_CTX_F18_OFF(t2)
  164. fld f19, FPU_CTX_F19_OFF(t2)
  165. fld f20, FPU_CTX_F20_OFF(t2)
  166. fld f21, FPU_CTX_F21_OFF(t2)
  167. fld f22, FPU_CTX_F22_OFF(t2)
  168. fld f23, FPU_CTX_F23_OFF(t2)
  169. fld f24, FPU_CTX_F24_OFF(t2)
  170. fld f25, FPU_CTX_F25_OFF(t2)
  171. fld f26, FPU_CTX_F26_OFF(t2)
  172. fld f27, FPU_CTX_F27_OFF(t2)
  173. fld f28, FPU_CTX_F28_OFF(t2)
  174. fld f29, FPU_CTX_F29_OFF(t2)
  175. fld f30, FPU_CTX_F30_OFF(t2)
  176. fld f31, FPU_CTX_F31_OFF(t2)
  177. /* clr FS domain */
  178. csrc sstatus, t0
  179. /* clean status would clr sr_sd; */
  180. li t0, SSTATUS_FS_CLEAN
  181. csrs sstatus, t0
  182. #endif /* ENABLE_FPU */
  183. /* restore general register */
  184. addi t0, sp, CTX_REG_NR * REGBYTES
  185. csrw sscratch, t0
  186. /* resw ra to sepc */
  187. LOAD x1, 0 * REGBYTES(sp)
  188. csrw sepc, x1
  189. LOAD x1, 2 * REGBYTES(sp)
  190. csrw sstatus, x1
  191. LOAD x1, 1 * REGBYTES(sp)
  192. LOAD x3, 3 * REGBYTES(sp)
  193. LOAD x4, 4 * REGBYTES(sp) /* restore tp */
  194. LOAD x5, 5 * REGBYTES(sp)
  195. LOAD x6, 6 * REGBYTES(sp)
  196. LOAD x7, 7 * REGBYTES(sp)
  197. LOAD x8, 8 * REGBYTES(sp)
  198. LOAD x9, 9 * REGBYTES(sp)
  199. LOAD x10, 10 * REGBYTES(sp)
  200. LOAD x11, 11 * REGBYTES(sp)
  201. LOAD x12, 12 * REGBYTES(sp)
  202. LOAD x13, 13 * REGBYTES(sp)
  203. LOAD x14, 14 * REGBYTES(sp)
  204. LOAD x15, 15 * REGBYTES(sp)
  205. LOAD x16, 16 * REGBYTES(sp)
  206. LOAD x17, 17 * REGBYTES(sp)
  207. LOAD x18, 18 * REGBYTES(sp)
  208. LOAD x19, 19 * REGBYTES(sp)
  209. LOAD x20, 20 * REGBYTES(sp)
  210. LOAD x21, 21 * REGBYTES(sp)
  211. LOAD x22, 22 * REGBYTES(sp)
  212. LOAD x23, 23 * REGBYTES(sp)
  213. LOAD x24, 24 * REGBYTES(sp)
  214. LOAD x25, 25 * REGBYTES(sp)
  215. LOAD x26, 26 * REGBYTES(sp)
  216. LOAD x27, 27 * REGBYTES(sp)
  217. LOAD x28, 28 * REGBYTES(sp)
  218. LOAD x29, 29 * REGBYTES(sp)
  219. LOAD x30, 30 * REGBYTES(sp)
  220. LOAD x31, 31 * REGBYTES(sp)
  221. /* restore user sp */
  222. LOAD sp, 32 * REGBYTES(sp)
  223. .endm
  224. .macro RESTORE_SYS_GP
  225. .option push
  226. .option norelax
  227. la gp, __global_pointer$
  228. .option pop
  229. .endm
  230. .macro OPEN_INTERRUPT
  231. csrsi sstatus, 2
  232. .endm
  233. .macro CLOSE_INTERRUPT
  234. csrci sstatus, 2
  235. .endm
  236. #endif /* __ASSEMBLY__ */
  237. #endif /* __STACKFRAME_H__ */