stackframe.h 8.4 KB

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