context.S 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. #include "riscv_encoding.h"
  2. #ifndef __riscv_32e
  3. #define portRegNum 32
  4. #else
  5. #define portRegNum 14
  6. #endif
  7. #define portCONTEXT_SIZE ( portRegNum * REGBYTES )
  8. EXTERN _tx_thread_current_ptr
  9. EXTERN _tx_thread_execute_ptr
  10. EXTERN CSTACK$$Limit
  11. EXTERN PortThreadSwitch
  12. PUBLIC _tx_thread_schedule, eclic_msip_handler
  13. SECTION `.text`:CODE:NOROOT(2)
  14. CODE
  15. /*
  16. * VOID _tx_thread_schedule(VOID);
  17. */
  18. /* Start the first task. This also clears the bit that indicates the FPU is
  19. in use in case the FPU was used before the scheduler was started - which
  20. would otherwise result in the unnecessary leaving of space in the stack
  21. for lazy saving of FPU registers. */
  22. ALIGN 3
  23. _tx_thread_schedule:
  24. /* Setup Interrupt Stack using
  25. The stack that was used by main()
  26. before the scheduler is started is
  27. no longer required after the scheduler is started.
  28. Interrupt stack pointer is stored in CSR_MSCRATCH */
  29. #if defined(SMP_CPU_CNT) && (SMP_CPU_CNT > 1)
  30. /* get correct sp for each cpu
  31. * each stack size is __STACK_SIZE
  32. * defined in linker script */
  33. EXTERN __STACK_SIZE
  34. lui t1, %hi(__STACK_SIZE)
  35. addi t1, t1, %lo(__STACK_SIZE)
  36. la t0, CSTACK$$Limit
  37. csrr a0, CSR_MHARTID
  38. andi a0, a0, 0xFF
  39. li a1, 0
  40. _per_cpu_init_sp_cont:
  41. beq a0, a1, _per_cpu_init_sp_fin
  42. sub t0, t0, t1
  43. addi a1, a1, 1
  44. j _per_cpu_init_sp_cont
  45. _per_cpu_init_sp_fin:
  46. #else
  47. la t0, CSTACK$$Limit
  48. #endif
  49. csrw CSR_MSCRATCH, t0
  50. /* Enable interrupt to wait _tx_thread_execute_ptr is not null */
  51. csrsi CSR_MSTATUS, MSTATUS_MIE
  52. _tx_thread_schedule_loop:
  53. #if defined(SMP_CPU_CNT) && (SMP_CPU_CNT > 1)
  54. la a0, _tx_thread_execute_ptr /* Pick current thread to a0 */
  55. csrr t1, CSR_MHARTID
  56. slli t1, t1, LOG_REGBYTES
  57. add a0, a0, t1
  58. #else
  59. la a0, _tx_thread_execute_ptr /* Pick current thread to a0 */
  60. #endif
  61. LOAD a0, 0(a0)
  62. beqz a0, _tx_thread_schedule_loop
  63. _tx_thread_schedule_ready:
  64. /* Disable interrupt to load first thread */
  65. csrci CSR_MSTATUS, MSTATUS_MIE
  66. #if defined(SMP_CPU_CNT) && (SMP_CPU_CNT > 1)
  67. la a1, _tx_thread_current_ptr /* _tx_thread_current_ptr[coreid] = _tx_thread_execute_ptr[coreid] */
  68. csrr t1, CSR_MHARTID
  69. slli t1, t1, LOG_REGBYTES
  70. add a1, a1, t1
  71. #else
  72. la a1, _tx_thread_current_ptr /* _tx_thread_current_ptr = _tx_thread_execute_ptr */
  73. #endif
  74. STORE a0, 0(a1)
  75. /* Increment the run count for this thread. */
  76. /* _tx_thread_current_ptr[coreid] -> tx_thread_run_count++; */
  77. LOAD t0, 1 * REGBYTES(a0)
  78. addi t0, t0, 1
  79. STORE t0, 1 * REGBYTES(a0)
  80. LOAD sp, 2 * REGBYTES(a0) /* Read sp from _tx_thread_execute_ptr[coreid] -> tx_thread_stack_ptr */
  81. /* Pop PC from stack and set MEPC */
  82. LOAD t0, 0 * REGBYTES(sp)
  83. csrw CSR_MEPC, t0
  84. /* Pop mstatus from stack and set it */
  85. LOAD t0, (portRegNum - 1) * REGBYTES(sp)
  86. csrw CSR_MSTATUS, t0
  87. /* Interrupt still disable here */
  88. /* Restore Registers from Stack */
  89. LOAD x1, 1 * REGBYTES(sp) /* RA */
  90. LOAD x5, 2 * REGBYTES(sp)
  91. LOAD x6, 3 * REGBYTES(sp)
  92. LOAD x7, 4 * REGBYTES(sp)
  93. LOAD x8, 5 * REGBYTES(sp)
  94. LOAD x9, 6 * REGBYTES(sp)
  95. LOAD x10, 7 * REGBYTES(sp)
  96. LOAD x11, 8 * REGBYTES(sp)
  97. LOAD x12, 9 * REGBYTES(sp)
  98. LOAD x13, 10 * REGBYTES(sp)
  99. LOAD x14, 11 * REGBYTES(sp)
  100. LOAD x15, 12 * REGBYTES(sp)
  101. #ifndef __riscv_32e
  102. LOAD x16, 13 * REGBYTES(sp)
  103. LOAD x17, 14 * REGBYTES(sp)
  104. LOAD x18, 15 * REGBYTES(sp)
  105. LOAD x19, 16 * REGBYTES(sp)
  106. LOAD x20, 17 * REGBYTES(sp)
  107. LOAD x21, 18 * REGBYTES(sp)
  108. LOAD x22, 19 * REGBYTES(sp)
  109. LOAD x23, 20 * REGBYTES(sp)
  110. LOAD x24, 21 * REGBYTES(sp)
  111. LOAD x25, 22 * REGBYTES(sp)
  112. LOAD x26, 23 * REGBYTES(sp)
  113. LOAD x27, 24 * REGBYTES(sp)
  114. LOAD x28, 25 * REGBYTES(sp)
  115. LOAD x29, 26 * REGBYTES(sp)
  116. LOAD x30, 27 * REGBYTES(sp)
  117. LOAD x31, 28 * REGBYTES(sp)
  118. #endif
  119. addi sp, sp, portCONTEXT_SIZE
  120. mret
  121. ALIGN 2
  122. eclic_msip_handler:
  123. addi sp, sp, -portCONTEXT_SIZE
  124. STORE x1, 1 * REGBYTES(sp) /* RA */
  125. STORE x5, 2 * REGBYTES(sp)
  126. STORE x6, 3 * REGBYTES(sp)
  127. STORE x7, 4 * REGBYTES(sp)
  128. STORE x8, 5 * REGBYTES(sp)
  129. STORE x9, 6 * REGBYTES(sp)
  130. STORE x10, 7 * REGBYTES(sp)
  131. STORE x11, 8 * REGBYTES(sp)
  132. STORE x12, 9 * REGBYTES(sp)
  133. STORE x13, 10 * REGBYTES(sp)
  134. STORE x14, 11 * REGBYTES(sp)
  135. STORE x15, 12 * REGBYTES(sp)
  136. #ifndef __riscv_32e
  137. STORE x16, 13 * REGBYTES(sp)
  138. STORE x17, 14 * REGBYTES(sp)
  139. STORE x18, 15 * REGBYTES(sp)
  140. STORE x19, 16 * REGBYTES(sp)
  141. STORE x20, 17 * REGBYTES(sp)
  142. STORE x21, 18 * REGBYTES(sp)
  143. STORE x22, 19 * REGBYTES(sp)
  144. STORE x23, 20 * REGBYTES(sp)
  145. STORE x24, 21 * REGBYTES(sp)
  146. STORE x25, 22 * REGBYTES(sp)
  147. STORE x26, 23 * REGBYTES(sp)
  148. STORE x27, 24 * REGBYTES(sp)
  149. STORE x28, 25 * REGBYTES(sp)
  150. STORE x29, 26 * REGBYTES(sp)
  151. STORE x30, 27 * REGBYTES(sp)
  152. STORE x31, 28 * REGBYTES(sp)
  153. #endif
  154. /* Push mstatus to stack */
  155. csrr t0, CSR_MSTATUS
  156. STORE t0, (portRegNum - 1) * REGBYTES(sp)
  157. /* Push additional registers */
  158. /* If _tx_thread_current_ptr[coreid] is null, no sp need to be saved */
  159. #if defined(SMP_CPU_CNT) && (SMP_CPU_CNT > 1)
  160. la t0, _tx_thread_current_ptr
  161. csrr t1, CSR_MHARTID
  162. slli t1, t1, LOG_REGBYTES
  163. add t0, t0, t1
  164. #else
  165. la t0, _tx_thread_current_ptr
  166. #endif
  167. LOAD t0, 0(t0)
  168. beqz t0, _tx_thread_switch
  169. /* Store sp to task stack to _tx_thread_current_ptr -> tx_thread_stack_ptr */
  170. STORE sp, 2 * REGBYTES(t0)
  171. /* Store last pc to thread stack */
  172. csrr t0, CSR_MEPC
  173. STORE t0, 0(sp)
  174. _tx_thread_switch:
  175. jal PortThreadSwitch
  176. /* Switch task context to _tx_thread_execute_ptr[coreid] */
  177. #if defined(SMP_CPU_CNT) && (SMP_CPU_CNT > 1)
  178. la t0, _tx_thread_execute_ptr
  179. csrr t1, CSR_MHARTID
  180. slli t1, t1, LOG_REGBYTES
  181. add t0, t0, t1
  182. #else
  183. la t0, _tx_thread_execute_ptr
  184. #endif
  185. LOAD t0, 0(t0)
  186. LOAD sp, 2 * REGBYTES(t0)
  187. /* Pop PC from stack and set MEPC */
  188. LOAD t0, 0 * REGBYTES(sp)
  189. csrw CSR_MEPC, t0
  190. /* Pop additional registers */
  191. /* Pop mstatus from stack and set it */
  192. LOAD t0, (portRegNum - 1) * REGBYTES(sp)
  193. csrw CSR_MSTATUS, t0
  194. /* Interrupt still disable here */
  195. /* Restore Registers from Stack */
  196. LOAD x1, 1 * REGBYTES(sp) /* RA */
  197. LOAD x5, 2 * REGBYTES(sp)
  198. LOAD x6, 3 * REGBYTES(sp)
  199. LOAD x7, 4 * REGBYTES(sp)
  200. LOAD x8, 5 * REGBYTES(sp)
  201. LOAD x9, 6 * REGBYTES(sp)
  202. LOAD x10, 7 * REGBYTES(sp)
  203. LOAD x11, 8 * REGBYTES(sp)
  204. LOAD x12, 9 * REGBYTES(sp)
  205. LOAD x13, 10 * REGBYTES(sp)
  206. LOAD x14, 11 * REGBYTES(sp)
  207. LOAD x15, 12 * REGBYTES(sp)
  208. #ifndef __riscv_32e
  209. LOAD x16, 13 * REGBYTES(sp)
  210. LOAD x17, 14 * REGBYTES(sp)
  211. LOAD x18, 15 * REGBYTES(sp)
  212. LOAD x19, 16 * REGBYTES(sp)
  213. LOAD x20, 17 * REGBYTES(sp)
  214. LOAD x21, 18 * REGBYTES(sp)
  215. LOAD x22, 19 * REGBYTES(sp)
  216. LOAD x23, 20 * REGBYTES(sp)
  217. LOAD x24, 21 * REGBYTES(sp)
  218. LOAD x25, 22 * REGBYTES(sp)
  219. LOAD x26, 23 * REGBYTES(sp)
  220. LOAD x27, 24 * REGBYTES(sp)
  221. LOAD x28, 25 * REGBYTES(sp)
  222. LOAD x29, 26 * REGBYTES(sp)
  223. LOAD x30, 27 * REGBYTES(sp)
  224. LOAD x31, 28 * REGBYTES(sp)
  225. #endif
  226. addi sp, sp, portCONTEXT_SIZE
  227. mret
  228. END