portContext.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. /*
  2. * FreeRTOS Kernel <DEVELOPMENT BRANCH>
  3. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
  4. *
  5. * SPDX-License-Identifier: MIT
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a copy of
  8. * this software and associated documentation files (the "Software"), to deal in
  9. * the Software without restriction, including without limitation the rights to
  10. * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  11. * the Software, and to permit persons to whom the Software is furnished to do so,
  12. * subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included in all
  15. * copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  19. * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  20. * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  21. * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  22. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23. *
  24. * https://www.FreeRTOS.org
  25. * https://github.com/FreeRTOS
  26. *
  27. */
  28. #ifndef PORTCONTEXT_H
  29. #define PORTCONTEXT_H
  30. #ifndef configENABLE_FPU
  31. #define configENABLE_FPU 0
  32. #endif
  33. #ifndef configENABLE_VPU
  34. #define configENABLE_VPU 0
  35. #endif
  36. #if __riscv_xlen == 64
  37. #define portWORD_SIZE 8
  38. #define store_x sd
  39. #define load_x ld
  40. #elif __riscv_xlen == 32
  41. #define store_x sw
  42. #define load_x lw
  43. #define portWORD_SIZE 4
  44. #else
  45. #error Assembler did not define __riscv_xlen
  46. #endif
  47. #include "freertos_risc_v_chip_specific_extensions.h"
  48. /* Only the standard core registers are stored by default. Any additional
  49. * registers must be saved by the portasmSAVE_ADDITIONAL_REGISTERS and
  50. * portasmRESTORE_ADDITIONAL_REGISTERS macros - which can be defined in a chip
  51. * specific version of freertos_risc_v_chip_specific_extensions.h. See the
  52. * notes at the top of portASM.S file. */
  53. #ifdef __riscv_32e
  54. #define portCONTEXT_SIZE ( 15 * portWORD_SIZE )
  55. #define portCRITICAL_NESTING_OFFSET 14
  56. #else
  57. #define portCONTEXT_SIZE ( 31 * portWORD_SIZE )
  58. #define portCRITICAL_NESTING_OFFSET 30
  59. #endif
  60. #if ( configENABLE_FPU == 1 )
  61. /* Bit [14:13] in the mstatus encode the status of FPU state which is one of
  62. * the following values:
  63. * 1. Value: 0, Meaning: Off.
  64. * 2. Value: 1, Meaning: Initial.
  65. * 3. Value: 2, Meaning: Clean.
  66. * 4. Value: 3, Meaning: Dirty.
  67. */
  68. #define MSTATUS_FS_MASK 0x6000
  69. #define MSTATUS_FS_INITIAL 0x2000
  70. #define MSTATUS_FS_CLEAN 0x4000
  71. #define MSTATUS_FS_DIRTY 0x6000
  72. #define MSTATUS_FS_OFFSET 13
  73. #ifdef __riscv_fdiv
  74. #if __riscv_flen == 32
  75. #define load_f flw
  76. #define store_f fsw
  77. #elif __riscv_flen == 64
  78. #define load_f fld
  79. #define store_f fsd
  80. #else
  81. #error Assembler did not define __riscv_flen
  82. #endif
  83. #define portFPU_REG_SIZE ( __riscv_flen / 8 )
  84. #define portFPU_REG_COUNT 33 /* 32 Floating point registers plus one CSR. */
  85. #define portFPU_REG_OFFSET( regIndex ) ( ( 2 * portWORD_SIZE ) + ( regIndex * portFPU_REG_SIZE ) )
  86. #define portFPU_CONTEXT_SIZE ( portFPU_REG_SIZE * portFPU_REG_COUNT )
  87. #else
  88. #error configENABLE_FPU must not be set to 1 if the hardware does not have FPU
  89. #endif
  90. #endif
  91. #if ( configENABLE_VPU == 1 )
  92. /* Bit [10:9] in the mstatus encode the status of VPU state which is one of
  93. * the following values:
  94. * 1. Value: 0, Meaning: Off.
  95. * 2. Value: 1, Meaning: Initial.
  96. * 3. Value: 2, Meaning: Clean.
  97. * 4. Value: 3, Meaning: Dirty.
  98. */
  99. #define MSTATUS_VS_MASK 0x600
  100. #define MSTATUS_VS_INITIAL 0x200
  101. #define MSTATUS_VS_CLEAN 0x400
  102. #define MSTATUS_VS_DIRTY 0x600
  103. #define MSTATUS_VS_OFFSET 9
  104. #ifndef __riscv_vector
  105. #error configENABLE_VPU must not be set to 1 if the hardware does not have VPU
  106. #endif
  107. #endif
  108. /*-----------------------------------------------------------*/
  109. .extern pxCurrentTCB
  110. .extern xISRStackTop
  111. .extern xCriticalNesting
  112. .extern pxCriticalNesting
  113. /*-----------------------------------------------------------*/
  114. .macro portcontexSAVE_FPU_CONTEXT
  115. addi sp, sp, -( portFPU_CONTEXT_SIZE )
  116. /* Store the FPU registers. */
  117. store_f f0, portFPU_REG_OFFSET( 0 )( sp )
  118. store_f f1, portFPU_REG_OFFSET( 1 )( sp )
  119. store_f f2, portFPU_REG_OFFSET( 2 )( sp )
  120. store_f f3, portFPU_REG_OFFSET( 3 )( sp )
  121. store_f f4, portFPU_REG_OFFSET( 4 )( sp )
  122. store_f f5, portFPU_REG_OFFSET( 5 )( sp )
  123. store_f f6, portFPU_REG_OFFSET( 6 )( sp )
  124. store_f f7, portFPU_REG_OFFSET( 7 )( sp )
  125. store_f f8, portFPU_REG_OFFSET( 8 )( sp )
  126. store_f f9, portFPU_REG_OFFSET( 9 )( sp )
  127. store_f f10, portFPU_REG_OFFSET( 10 )( sp )
  128. store_f f11, portFPU_REG_OFFSET( 11 )( sp )
  129. store_f f12, portFPU_REG_OFFSET( 12 )( sp )
  130. store_f f13, portFPU_REG_OFFSET( 13 )( sp )
  131. store_f f14, portFPU_REG_OFFSET( 14 )( sp )
  132. store_f f15, portFPU_REG_OFFSET( 15 )( sp )
  133. store_f f16, portFPU_REG_OFFSET( 16 )( sp )
  134. store_f f17, portFPU_REG_OFFSET( 17 )( sp )
  135. store_f f18, portFPU_REG_OFFSET( 18 )( sp )
  136. store_f f19, portFPU_REG_OFFSET( 19 )( sp )
  137. store_f f20, portFPU_REG_OFFSET( 20 )( sp )
  138. store_f f21, portFPU_REG_OFFSET( 21 )( sp )
  139. store_f f22, portFPU_REG_OFFSET( 22 )( sp )
  140. store_f f23, portFPU_REG_OFFSET( 23 )( sp )
  141. store_f f24, portFPU_REG_OFFSET( 24 )( sp )
  142. store_f f25, portFPU_REG_OFFSET( 25 )( sp )
  143. store_f f26, portFPU_REG_OFFSET( 26 )( sp )
  144. store_f f27, portFPU_REG_OFFSET( 27 )( sp )
  145. store_f f28, portFPU_REG_OFFSET( 28 )( sp )
  146. store_f f29, portFPU_REG_OFFSET( 29 )( sp )
  147. store_f f30, portFPU_REG_OFFSET( 30 )( sp )
  148. store_f f31, portFPU_REG_OFFSET( 31 )( sp )
  149. csrr t0, fcsr
  150. store_x t0, portFPU_REG_OFFSET( 32 )( sp )
  151. .endm
  152. /*-----------------------------------------------------------*/
  153. .macro portcontextRESTORE_FPU_CONTEXT
  154. /* Restore the FPU registers. */
  155. load_f f0, portFPU_REG_OFFSET( 0 )( sp )
  156. load_f f1, portFPU_REG_OFFSET( 1 )( sp )
  157. load_f f2, portFPU_REG_OFFSET( 2 )( sp )
  158. load_f f3, portFPU_REG_OFFSET( 3 )( sp )
  159. load_f f4, portFPU_REG_OFFSET( 4 )( sp )
  160. load_f f5, portFPU_REG_OFFSET( 5 )( sp )
  161. load_f f6, portFPU_REG_OFFSET( 6 )( sp )
  162. load_f f7, portFPU_REG_OFFSET( 7 )( sp )
  163. load_f f8, portFPU_REG_OFFSET( 8 )( sp )
  164. load_f f9, portFPU_REG_OFFSET( 9 )( sp )
  165. load_f f10, portFPU_REG_OFFSET( 10 )( sp )
  166. load_f f11, portFPU_REG_OFFSET( 11 )( sp )
  167. load_f f12, portFPU_REG_OFFSET( 12 )( sp )
  168. load_f f13, portFPU_REG_OFFSET( 13 )( sp )
  169. load_f f14, portFPU_REG_OFFSET( 14 )( sp )
  170. load_f f15, portFPU_REG_OFFSET( 15 )( sp )
  171. load_f f16, portFPU_REG_OFFSET( 16 )( sp )
  172. load_f f17, portFPU_REG_OFFSET( 17 )( sp )
  173. load_f f18, portFPU_REG_OFFSET( 18 )( sp )
  174. load_f f19, portFPU_REG_OFFSET( 19 )( sp )
  175. load_f f20, portFPU_REG_OFFSET( 20 )( sp )
  176. load_f f21, portFPU_REG_OFFSET( 21 )( sp )
  177. load_f f22, portFPU_REG_OFFSET( 22 )( sp )
  178. load_f f23, portFPU_REG_OFFSET( 23 )( sp )
  179. load_f f24, portFPU_REG_OFFSET( 24 )( sp )
  180. load_f f25, portFPU_REG_OFFSET( 25 )( sp )
  181. load_f f26, portFPU_REG_OFFSET( 26 )( sp )
  182. load_f f27, portFPU_REG_OFFSET( 27 )( sp )
  183. load_f f28, portFPU_REG_OFFSET( 28 )( sp )
  184. load_f f29, portFPU_REG_OFFSET( 29 )( sp )
  185. load_f f30, portFPU_REG_OFFSET( 30 )( sp )
  186. load_f f31, portFPU_REG_OFFSET( 31 )( sp )
  187. load_x t0, portFPU_REG_OFFSET( 32 )( sp )
  188. csrw fcsr, t0
  189. addi sp, sp, ( portFPU_CONTEXT_SIZE )
  190. .endm
  191. /*-----------------------------------------------------------*/
  192. .macro portcontexSAVE_VPU_CONTEXT
  193. /* Un-reserve the space reserved for mstatus and epc. */
  194. add sp, sp, ( 2 * portWORD_SIZE )
  195. csrr t0, vlenb /* t0 = vlenb. vlenb is the length of each vector register in bytes. */
  196. slli t0, t0, 3 /* t0 = vlenb * 8. t0 now contains the space required to store 8 vector registers. */
  197. neg t0, t0
  198. /* Store the vector registers in group of 8. */
  199. add sp, sp, t0
  200. vs8r.v v24, (sp) /* Store v24-v31. */
  201. add sp, sp, t0
  202. vs8r.v v16, (sp) /* Store v16-v23. */
  203. add sp, sp, t0
  204. vs8r.v v8, (sp) /* Store v8-v15. */
  205. add sp, sp, t0
  206. vs8r.v v0, (sp) /* Store v0-v7. */
  207. /* Store the VPU CSRs. */
  208. addi sp, sp, -( 4 * portWORD_SIZE )
  209. csrr t0, vstart
  210. store_x t0, 0 * portWORD_SIZE( sp )
  211. csrr t0, vcsr
  212. store_x t0, 1 * portWORD_SIZE( sp )
  213. csrr t0, vl
  214. store_x t0, 2 * portWORD_SIZE( sp )
  215. csrr t0, vtype
  216. store_x t0, 3 * portWORD_SIZE( sp )
  217. /* Re-reserve the space for mstatus and epc. */
  218. add sp, sp, -( 2 * portWORD_SIZE )
  219. .endm
  220. /*-----------------------------------------------------------*/
  221. .macro portcontextRESTORE_VPU_CONTEXT
  222. /* Un-reserve the space reserved for mstatus and epc. */
  223. add sp, sp, ( 2 * portWORD_SIZE )
  224. /* Restore the VPU CSRs. */
  225. load_x t0, 0 * portWORD_SIZE( sp )
  226. csrw vstart, t0
  227. load_x t0, 1 * portWORD_SIZE( sp )
  228. csrw vcsr, t0
  229. load_x t0, 2 * portWORD_SIZE( sp )
  230. load_x t1, 3 * portWORD_SIZE( sp )
  231. vsetvl x0, t0, t1 /* vlen and vtype can only be updated by using vset*vl* instructions. */
  232. addi sp, sp, ( 4 * portWORD_SIZE )
  233. csrr t0, vlenb /* t0 = vlenb. vlenb is the length of each vector register in bytes. */
  234. slli t0, t0, 3 /* t0 = vlenb * 8. t0 now contains the space required to store 8 vector registers. */
  235. /* Restore the vector registers. */
  236. vl8r.v v0, (sp) /* Restore v0-v7. */
  237. add sp, sp, t0
  238. vl8r.v v8, (sp) /* Restore v8-v15. */
  239. add sp, sp, t0
  240. vl8r.v v16, (sp) /* Restore v16-v23. */
  241. add sp, sp, t0
  242. vl8r.v v24, (sp) /* Restore v23-v31. */
  243. add sp, sp, t0
  244. /* Re-reserve the space for mstatus and epc. */
  245. add sp, sp, -( 2 * portWORD_SIZE )
  246. .endm
  247. /*-----------------------------------------------------------*/
  248. .macro portcontextSAVE_CONTEXT_INTERNAL
  249. addi sp, sp, -portCONTEXT_SIZE
  250. store_x x1, 2 * portWORD_SIZE( sp )
  251. store_x x5, 3 * portWORD_SIZE( sp )
  252. store_x x6, 4 * portWORD_SIZE( sp )
  253. store_x x7, 5 * portWORD_SIZE( sp )
  254. store_x x8, 6 * portWORD_SIZE( sp )
  255. store_x x9, 7 * portWORD_SIZE( sp )
  256. store_x x10, 8 * portWORD_SIZE( sp )
  257. store_x x11, 9 * portWORD_SIZE( sp )
  258. store_x x12, 10 * portWORD_SIZE( sp )
  259. store_x x13, 11 * portWORD_SIZE( sp )
  260. store_x x14, 12 * portWORD_SIZE( sp )
  261. store_x x15, 13 * portWORD_SIZE( sp )
  262. #ifndef __riscv_32e
  263. store_x x16, 14 * portWORD_SIZE( sp )
  264. store_x x17, 15 * portWORD_SIZE( sp )
  265. store_x x18, 16 * portWORD_SIZE( sp )
  266. store_x x19, 17 * portWORD_SIZE( sp )
  267. store_x x20, 18 * portWORD_SIZE( sp )
  268. store_x x21, 19 * portWORD_SIZE( sp )
  269. store_x x22, 20 * portWORD_SIZE( sp )
  270. store_x x23, 21 * portWORD_SIZE( sp )
  271. store_x x24, 22 * portWORD_SIZE( sp )
  272. store_x x25, 23 * portWORD_SIZE( sp )
  273. store_x x26, 24 * portWORD_SIZE( sp )
  274. store_x x27, 25 * portWORD_SIZE( sp )
  275. store_x x28, 26 * portWORD_SIZE( sp )
  276. store_x x29, 27 * portWORD_SIZE( sp )
  277. store_x x30, 28 * portWORD_SIZE( sp )
  278. store_x x31, 29 * portWORD_SIZE( sp )
  279. #endif /* ifndef __riscv_32e */
  280. load_x t0, xCriticalNesting /* Load the value of xCriticalNesting into t0. */
  281. store_x t0, portCRITICAL_NESTING_OFFSET * portWORD_SIZE( sp ) /* Store the critical nesting value to the stack. */
  282. #if( configENABLE_FPU == 1 )
  283. csrr t0, mstatus
  284. srl t1, t0, MSTATUS_FS_OFFSET
  285. andi t1, t1, 3
  286. addi t2, x0, 3
  287. bne t1, t2, 1f /* If FPU status is not dirty, do not save FPU registers. */
  288. portcontexSAVE_FPU_CONTEXT
  289. 1:
  290. #endif
  291. #if( configENABLE_VPU == 1 )
  292. csrr t0, mstatus
  293. srl t1, t0, MSTATUS_VS_OFFSET
  294. andi t1, t1, 3
  295. addi t2, x0, 3
  296. bne t1, t2, 2f /* If VPU status is not dirty, do not save VPU registers. */
  297. portcontexSAVE_VPU_CONTEXT
  298. 2:
  299. #endif
  300. csrr t0, mstatus
  301. store_x t0, 1 * portWORD_SIZE( sp )
  302. portasmSAVE_ADDITIONAL_REGISTERS /* Defined in freertos_risc_v_chip_specific_extensions.h to save any registers unique to the RISC-V implementation. */
  303. #if( configENABLE_FPU == 1 )
  304. /* Mark the FPU as clean, if it was dirty and we saved FPU registers. */
  305. srl t1, t0, MSTATUS_FS_OFFSET
  306. andi t1, t1, 3
  307. addi t2, x0, 3
  308. bne t1, t2, 3f
  309. li t1, ~MSTATUS_FS_MASK
  310. and t0, t0, t1
  311. li t1, MSTATUS_FS_CLEAN
  312. or t0, t0, t1
  313. csrw mstatus, t0
  314. 3:
  315. #endif
  316. #if( configENABLE_VPU == 1 )
  317. /* Mark the VPU as clean, if it was dirty and we saved VPU registers. */
  318. srl t1, t0, MSTATUS_VS_OFFSET
  319. andi t1, t1, 3
  320. addi t2, x0, 3
  321. bne t1, t2, 4f
  322. li t1, ~MSTATUS_VS_MASK
  323. and t0, t0, t1
  324. li t1, MSTATUS_VS_CLEAN
  325. or t0, t0, t1
  326. csrw mstatus, t0
  327. 4:
  328. #endif
  329. load_x t0, pxCurrentTCB /* Load pxCurrentTCB. */
  330. store_x sp, 0 ( t0 ) /* Write sp to first TCB member. */
  331. .endm
  332. /*-----------------------------------------------------------*/
  333. .macro portcontextSAVE_EXCEPTION_CONTEXT
  334. portcontextSAVE_CONTEXT_INTERNAL
  335. csrr a0, mcause
  336. csrr a1, mepc
  337. addi a1, a1, 4 /* Synchronous so update exception return address to the instruction after the instruction that generated the exception. */
  338. store_x a1, 0 ( sp ) /* Save updated exception return address. */
  339. load_x sp, xISRStackTop /* Switch to ISR stack. */
  340. .endm
  341. /*-----------------------------------------------------------*/
  342. .macro portcontextSAVE_INTERRUPT_CONTEXT
  343. portcontextSAVE_CONTEXT_INTERNAL
  344. csrr a0, mcause
  345. csrr a1, mepc
  346. store_x a1, 0 ( sp ) /* Asynchronous interrupt so save unmodified exception return address. */
  347. load_x sp, xISRStackTop /* Switch to ISR stack. */
  348. .endm
  349. /*-----------------------------------------------------------*/
  350. .macro portcontextRESTORE_CONTEXT
  351. load_x t1, pxCurrentTCB /* Load pxCurrentTCB. */
  352. load_x sp, 0 ( t1 ) /* Read sp from first TCB member. */
  353. /* Load mepc with the address of the instruction in the task to run next. */
  354. load_x t0, 0 ( sp )
  355. csrw mepc, t0
  356. /* Defined in freertos_risc_v_chip_specific_extensions.h to restore any registers unique to the RISC-V implementation. */
  357. portasmRESTORE_ADDITIONAL_REGISTERS
  358. /* Restore mstatus register. It is important to use t3 (and not t0) here as t3
  359. * is not clobbered by portcontextRESTORE_VPU_CONTEXT and
  360. * portcontextRESTORE_FPU_CONTEXT. */
  361. load_x t3, 1 * portWORD_SIZE( sp )
  362. csrw mstatus, t3
  363. #if( configENABLE_VPU == 1 )
  364. srl t1, t3, MSTATUS_VS_OFFSET
  365. andi t1, t1, 3
  366. addi t2, x0, 3
  367. bne t1, t2, 5f /* If VPU status is not dirty, do not restore VPU registers. */
  368. portcontextRESTORE_VPU_CONTEXT
  369. 5:
  370. #endif /* ifdef portasmSTORE_VPU_CONTEXT */
  371. #if( configENABLE_FPU == 1 )
  372. srl t1, t3, MSTATUS_FS_OFFSET
  373. andi t1, t1, 3
  374. addi t2, x0, 3
  375. bne t1, t2, 6f /* If FPU status is not dirty, do not restore FPU registers. */
  376. portcontextRESTORE_FPU_CONTEXT
  377. 6:
  378. #endif /* ifdef portasmSTORE_FPU_CONTEXT */
  379. load_x t0, portCRITICAL_NESTING_OFFSET * portWORD_SIZE( sp ) /* Obtain xCriticalNesting value for this task from task's stack. */
  380. load_x t1, pxCriticalNesting /* Load the address of xCriticalNesting into t1. */
  381. store_x t0, 0 ( t1 ) /* Restore the critical nesting value for this task. */
  382. load_x x1, 2 * portWORD_SIZE( sp )
  383. load_x x5, 3 * portWORD_SIZE( sp )
  384. load_x x6, 4 * portWORD_SIZE( sp )
  385. load_x x7, 5 * portWORD_SIZE( sp )
  386. load_x x8, 6 * portWORD_SIZE( sp )
  387. load_x x9, 7 * portWORD_SIZE( sp )
  388. load_x x10, 8 * portWORD_SIZE( sp )
  389. load_x x11, 9 * portWORD_SIZE( sp )
  390. load_x x12, 10 * portWORD_SIZE( sp )
  391. load_x x13, 11 * portWORD_SIZE( sp )
  392. load_x x14, 12 * portWORD_SIZE( sp )
  393. load_x x15, 13 * portWORD_SIZE( sp )
  394. #ifndef __riscv_32e
  395. load_x x16, 14 * portWORD_SIZE( sp )
  396. load_x x17, 15 * portWORD_SIZE( sp )
  397. load_x x18, 16 * portWORD_SIZE( sp )
  398. load_x x19, 17 * portWORD_SIZE( sp )
  399. load_x x20, 18 * portWORD_SIZE( sp )
  400. load_x x21, 19 * portWORD_SIZE( sp )
  401. load_x x22, 20 * portWORD_SIZE( sp )
  402. load_x x23, 21 * portWORD_SIZE( sp )
  403. load_x x24, 22 * portWORD_SIZE( sp )
  404. load_x x25, 23 * portWORD_SIZE( sp )
  405. load_x x26, 24 * portWORD_SIZE( sp )
  406. load_x x27, 25 * portWORD_SIZE( sp )
  407. load_x x28, 26 * portWORD_SIZE( sp )
  408. load_x x29, 27 * portWORD_SIZE( sp )
  409. load_x x30, 28 * portWORD_SIZE( sp )
  410. load_x x31, 29 * portWORD_SIZE( sp )
  411. #endif /* ifndef __riscv_32e */
  412. addi sp, sp, portCONTEXT_SIZE
  413. mret
  414. .endm
  415. /*-----------------------------------------------------------*/
  416. #endif /* PORTCONTEXT_H */