portasm.S 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726
  1. /*
  2. * FreeRTOS Kernel Port For Nuclei RISC-V Processor
  3. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a copy of
  6. * this software and associated documentation files (the "Software"), to deal in
  7. * the Software without restriction, including without limitation the rights to
  8. * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  9. * the Software, and to permit persons to whom the Software is furnished to do so,
  10. * subject to the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be included in all
  13. * copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  17. * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  18. * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  19. * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  20. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  21. *
  22. * http://www.FreeRTOS.org
  23. * http://aws.amazon.com/freertos
  24. *
  25. * 1 tab == 4 spaces!
  26. */
  27. #include "riscv_encoding.h"
  28. #ifndef __riscv_32e
  29. #define portRegNum 32
  30. #else
  31. #define portRegNum 14
  32. #endif
  33. #define portCONTEXT_SIZE ( portRegNum * REGBYTES )
  34. .section .text.entry
  35. .align 8
  36. // If you want to use SMP freertos
  37. // configNUMBER_OF_CORES must be defined to the number of cores in your system.
  38. // If you define configNUMBER_OF_CORES using -D option, you must make sure that
  39. // asm option must contains this macro defined
  40. #ifndef configNUMBER_OF_CORES
  41. #define configNUMBER_OF_CORES 1
  42. #endif
  43. .extern xPortTaskSwitch
  44. #if ( configNUMBER_OF_CORES == 1 )
  45. .extern pxCurrentTCB
  46. #else
  47. .extern pxCurrentTCBs
  48. #endif
  49. .global prvPortStartFirstTask
  50. /**
  51. * \brief Global interrupt disabled
  52. * \details
  53. * This function disable global interrupt.
  54. * \remarks
  55. * - All the interrupt requests will be ignored by CPU.
  56. */
  57. .macro DISABLE_MIE
  58. csrc CSR_MSTATUS, MSTATUS_MIE
  59. .endm
  60. /**
  61. * \brief Macro for context save
  62. * \details
  63. * This macro save ABI defined caller saved registers in the stack.
  64. * \remarks
  65. * - This Macro could use to save context when you enter to interrupt
  66. * or exception
  67. */
  68. /* Save caller registers */
  69. .macro SAVE_CONTEXT
  70. #if defined(ECLIC_HW_CTX_AUTO) && defined(CFG_HAS_ECLICV2)
  71. #else
  72. csrrw sp, CSR_MSCRATCHCSWL, sp
  73. /* Allocate stack space for context saving */
  74. #ifndef __riscv_32e
  75. addi sp, sp, -20*REGBYTES
  76. #else
  77. addi sp, sp, -14*REGBYTES
  78. #endif /* __riscv_32e */
  79. STORE x1, 0*REGBYTES(sp)
  80. STORE x4, 1*REGBYTES(sp)
  81. STORE x5, 2*REGBYTES(sp)
  82. STORE x6, 3*REGBYTES(sp)
  83. STORE x7, 4*REGBYTES(sp)
  84. STORE x10, 5*REGBYTES(sp)
  85. STORE x11, 6*REGBYTES(sp)
  86. STORE x12, 7*REGBYTES(sp)
  87. STORE x13, 8*REGBYTES(sp)
  88. STORE x14, 9*REGBYTES(sp)
  89. STORE x15, 10*REGBYTES(sp)
  90. #ifndef __riscv_32e
  91. STORE x16, 14*REGBYTES(sp)
  92. STORE x17, 15*REGBYTES(sp)
  93. STORE x28, 16*REGBYTES(sp)
  94. STORE x29, 17*REGBYTES(sp)
  95. STORE x30, 18*REGBYTES(sp)
  96. STORE x31, 19*REGBYTES(sp)
  97. #endif /* __riscv_32e */
  98. #endif
  99. .endm
  100. /**
  101. * \brief Macro for restore caller registers
  102. * \details
  103. * This macro restore ABI defined caller saved registers from stack.
  104. * \remarks
  105. * - You could use this macro to restore context before you want return
  106. * from interrupt or exeception
  107. */
  108. /* Restore caller registers */
  109. .macro RESTORE_CONTEXT
  110. #if defined(ECLIC_HW_CTX_AUTO) && defined(CFG_HAS_ECLICV2)
  111. #else
  112. LOAD x1, 0*REGBYTES(sp)
  113. LOAD x4, 1*REGBYTES(sp)
  114. LOAD x5, 2*REGBYTES(sp)
  115. LOAD x6, 3*REGBYTES(sp)
  116. LOAD x7, 4*REGBYTES(sp)
  117. LOAD x10, 5*REGBYTES(sp)
  118. LOAD x11, 6*REGBYTES(sp)
  119. LOAD x12, 7*REGBYTES(sp)
  120. LOAD x13, 8*REGBYTES(sp)
  121. LOAD x14, 9*REGBYTES(sp)
  122. LOAD x15, 10*REGBYTES(sp)
  123. #ifndef __riscv_32e
  124. LOAD x16, 14*REGBYTES(sp)
  125. LOAD x17, 15*REGBYTES(sp)
  126. LOAD x28, 16*REGBYTES(sp)
  127. LOAD x29, 17*REGBYTES(sp)
  128. LOAD x30, 18*REGBYTES(sp)
  129. LOAD x31, 19*REGBYTES(sp)
  130. /* De-allocate the stack space */
  131. addi sp, sp, 20*REGBYTES
  132. #else
  133. /* De-allocate the stack space */
  134. addi sp, sp, 14*REGBYTES
  135. #endif /* __riscv_32e */
  136. csrrw sp, CSR_MSCRATCHCSWL, sp
  137. #endif
  138. .endm
  139. /**
  140. * \brief Macro for save necessary CSRs to stack
  141. * \details
  142. * This macro store MCAUSE, MEPC, MSUBM to stack.
  143. */
  144. .macro SAVE_CSR_CONTEXT
  145. #if defined(ECLIC_HW_CTX_AUTO) && defined(CFG_HAS_ECLICV2)
  146. #else
  147. /* Store CSR mcause to stack using pushmcause */
  148. csrrwi x0, CSR_PUSHMCAUSE, 11
  149. /* Store CSR mepc to stack using pushmepc */
  150. csrrwi x0, CSR_PUSHMEPC, 12
  151. /* Store CSR msub to stack using pushmsub */
  152. csrrwi x0, CSR_PUSHMSUBM, 13
  153. #endif
  154. .endm
  155. /**
  156. * \brief Macro for restore necessary CSRs from stack
  157. * \details
  158. * This macro restore MSUBM, MEPC, MCAUSE from stack.
  159. */
  160. .macro RESTORE_CSR_CONTEXT
  161. #if defined(ECLIC_HW_CTX_AUTO) && defined(CFG_HAS_ECLICV2)
  162. #else
  163. LOAD x5, 13*REGBYTES(sp)
  164. csrw CSR_MSUBM, x5
  165. LOAD x5, 12*REGBYTES(sp)
  166. csrw CSR_MEPC, x5
  167. LOAD x5, 11*REGBYTES(sp)
  168. csrw CSR_MCAUSE, x5
  169. #endif
  170. .endm
  171. /**
  172. * \brief Exception/NMI Entry
  173. * \details
  174. * This function provide common entry functions for exception/nmi.
  175. * \remarks
  176. * This function provide a default exception/nmi entry.
  177. * ABI defined caller save register and some CSR registers
  178. * to be saved before enter interrupt handler and be restored before return.
  179. */
  180. .section .text.trap
  181. /* In CLIC mode, the exeception entry must be 64bytes aligned */
  182. .align 6
  183. .global exc_entry
  184. .type exc_entry, @function
  185. exc_entry:
  186. /* Save the caller saving registers (context) */
  187. SAVE_CONTEXT
  188. /* Save the necessary CSR registers */
  189. SAVE_CSR_CONTEXT
  190. /*
  191. * Set the exception handler function arguments
  192. * argument 1: mcause value
  193. * argument 2: current stack point(SP) value
  194. */
  195. csrr a0, mcause
  196. mv a1, sp
  197. /*
  198. * TODO: Call the exception handler function
  199. * By default, the function template is provided in
  200. * system_Device.c, you can adjust it as you want
  201. */
  202. call core_exception_handler
  203. /* Restore the necessary CSR registers */
  204. RESTORE_CSR_CONTEXT
  205. /* Restore the caller saving registers (context) */
  206. RESTORE_CONTEXT
  207. /* Return to regular code */
  208. #if defined(ECLIC_HW_CTX_AUTO) && defined(CFG_HAS_ECLICV2)
  209. csrrwi x0, CSR_POPXRET, 0
  210. #else
  211. mret
  212. #endif
  213. .size exc_entry, . - exc_entry
  214. /**
  215. * \brief Non-Vector Interrupt Entry
  216. * \details
  217. * This function provide common entry functions for handling
  218. * non-vector interrupts
  219. * \remarks
  220. * This function provide a default non-vector interrupt entry.
  221. * ABI defined caller save register and some CSR registers need
  222. * to be saved before enter interrupt handler and be restored before return.
  223. */
  224. .section .text.irq
  225. /* In CLIC mode, the interrupt entry must be 4bytes aligned */
  226. .align 2
  227. .global irq_entry
  228. .type irq_entry, @function
  229. /* This label will be set to MTVT2 register */
  230. irq_entry:
  231. /* Save the caller saving registers (context) */
  232. SAVE_CONTEXT
  233. /* Save the necessary CSR registers */
  234. SAVE_CSR_CONTEXT
  235. /* This special CSR read/write operation, which is actually
  236. * claim the CLIC to find its pending highest ID, if the ID
  237. * is not 0, then automatically enable the mstatus.MIE, and
  238. * jump to its vector-entry-label, and update the link register
  239. */
  240. csrrw ra, CSR_JALMNXTI, ra
  241. /* Critical section with interrupts disabled */
  242. DISABLE_MIE
  243. /* Restore the necessary CSR registers */
  244. RESTORE_CSR_CONTEXT
  245. /* Restore the caller saving registers (context) */
  246. RESTORE_CONTEXT
  247. /* Return to regular code */
  248. #if defined(ECLIC_HW_CTX_AUTO) && defined(CFG_HAS_ECLICV2)
  249. csrrwi x0, CSR_POPXRET, 0
  250. #else
  251. mret
  252. #endif
  253. .size irq_entry, . - irq_entry
  254. /* Default Handler for Exceptions / Interrupts */
  255. .global default_intexc_handler
  256. .type default_intexc_handler, @function
  257. Undef_Handler:
  258. default_intexc_handler:
  259. 1:
  260. j 1b
  261. .size default_intexc_handler, . - default_intexc_handler
  262. /* Start the first task. This also clears the bit that indicates the FPU is
  263. in use in case the FPU was used before the scheduler was started - which
  264. would otherwise result in the unnecessary leaving of space in the stack
  265. for lazy saving of FPU registers. */
  266. .type prvPortStartFirstTask, @function
  267. .align 3
  268. prvPortStartFirstTask:
  269. /* Setup Interrupt Stack using
  270. The stack that was used by main()
  271. before the scheduler is started is
  272. no longer required after the scheduler is started.
  273. Interrupt stack pointer is stored in CSR_MSCRATCH */
  274. #if defined(SMP_CPU_CNT) && (SMP_CPU_CNT > 1)
  275. /* get correct sp for each cpu
  276. * each stack size is __STACK_SIZE
  277. * defined in linker script */
  278. lui t1, %hi(__STACK_SIZE)
  279. addi t1, t1, %lo(__STACK_SIZE)
  280. la t0, _sp
  281. csrr a0, CSR_MHARTID
  282. andi a0, a0, 0xFF
  283. li a1, 0
  284. 1:
  285. beq a0, a1, 2f
  286. sub t0, t0, t1
  287. addi a1, a1, 1
  288. j 1b
  289. 2:
  290. #else
  291. la t0, _sp // TODO need to consider SMP case
  292. #endif
  293. csrw CSR_MSCRATCH, t0
  294. #if ( configNUMBER_OF_CORES == 1 )
  295. LOAD t0, pxCurrentTCB /* Load pxCurrentTCB. */
  296. #else
  297. la t0, pxCurrentTCBs /* Load pxCurrentTCBs[core] */
  298. csrr t1, CSR_MHARTID
  299. slli t1, t1, LOG_REGBYTES
  300. add t0, t0, t1
  301. LOAD t0, 0(t0)
  302. #endif
  303. LOAD sp, 0x0(t0) /* Read sp from first TCB member */
  304. /* Pop PC from stack and set MEPC */
  305. LOAD t0, 0 * REGBYTES(sp)
  306. csrw CSR_MEPC, t0
  307. /* Pop mstatus from stack and set it */
  308. LOAD t0, (portRegNum - 1) * REGBYTES(sp)
  309. csrw CSR_MSTATUS, t0
  310. /* Interrupt still disable here */
  311. /* Restore Registers from Stack */
  312. LOAD x1, 1 * REGBYTES(sp) /* RA */
  313. LOAD x5, 2 * REGBYTES(sp)
  314. LOAD x6, 3 * REGBYTES(sp)
  315. LOAD x7, 4 * REGBYTES(sp)
  316. LOAD x8, 5 * REGBYTES(sp)
  317. LOAD x9, 6 * REGBYTES(sp)
  318. LOAD x10, 7 * REGBYTES(sp)
  319. LOAD x11, 8 * REGBYTES(sp)
  320. LOAD x12, 9 * REGBYTES(sp)
  321. LOAD x13, 10 * REGBYTES(sp)
  322. LOAD x14, 11 * REGBYTES(sp)
  323. LOAD x15, 12 * REGBYTES(sp)
  324. #ifndef __riscv_32e
  325. LOAD x16, 13 * REGBYTES(sp)
  326. LOAD x17, 14 * REGBYTES(sp)
  327. LOAD x18, 15 * REGBYTES(sp)
  328. LOAD x19, 16 * REGBYTES(sp)
  329. LOAD x20, 17 * REGBYTES(sp)
  330. LOAD x21, 18 * REGBYTES(sp)
  331. LOAD x22, 19 * REGBYTES(sp)
  332. LOAD x23, 20 * REGBYTES(sp)
  333. LOAD x24, 21 * REGBYTES(sp)
  334. LOAD x25, 22 * REGBYTES(sp)
  335. LOAD x26, 23 * REGBYTES(sp)
  336. LOAD x27, 24 * REGBYTES(sp)
  337. LOAD x28, 25 * REGBYTES(sp)
  338. LOAD x29, 26 * REGBYTES(sp)
  339. LOAD x30, 27 * REGBYTES(sp)
  340. LOAD x31, 28 * REGBYTES(sp)
  341. #endif
  342. addi sp, sp, portCONTEXT_SIZE
  343. mret
  344. .size prvPortStartFirstTask, . - prvPortStartFirstTask
  345. .align 2
  346. .global eclic_msip_handler
  347. .type eclic_msip_handler, @function
  348. eclic_msip_handler:
  349. #if defined(__riscv_flen)
  350. addi sp, sp, -(2 * REGBYTES)
  351. STORE t0, 0 * REGBYTES(sp)
  352. STORE t1, 1 * REGBYTES(sp)
  353. _save_fp_stack:
  354. csrr t0, CSR_MSTATUS
  355. li t1, MSTATUS_FS_DIRTY
  356. and t0,t0,t1
  357. #if defined(__riscv_vector)
  358. bne t0, t1, _save_vector_stack
  359. #else
  360. bne t0, t1, _save_integer_stack
  361. #endif
  362. LOAD t0, 0 * REGBYTES(sp)
  363. LOAD t1, 1 * REGBYTES(sp)
  364. addi sp, sp, (2 * REGBYTES)
  365. /* Save fp registers and fcsr and 3 reserved reg space, make sure 16 bytes aligned */
  366. addi sp, sp, -(5 * REGBYTES)
  367. STORE t0, 0 * REGBYTES(sp)
  368. csrr t0, CSR_FCSR
  369. STORE t0, 1 * REGBYTES(sp)
  370. LOAD t0, 0 * REGBYTES(sp)
  371. addi sp, sp, (1 * REGBYTES)
  372. addi sp, sp, -(32 * FPREGBYTES)
  373. FPSTORE f0 , 0 * FPREGBYTES(sp)
  374. FPSTORE f1 , 1 * FPREGBYTES(sp)
  375. FPSTORE f2 , 2 * FPREGBYTES(sp)
  376. FPSTORE f3 , 3 * FPREGBYTES(sp)
  377. FPSTORE f4 , 4 * FPREGBYTES(sp)
  378. FPSTORE f5 , 5 * FPREGBYTES(sp)
  379. FPSTORE f6 , 6 * FPREGBYTES(sp)
  380. FPSTORE f7 , 7 * FPREGBYTES(sp)
  381. FPSTORE f8 , 8 * FPREGBYTES(sp)
  382. FPSTORE f9 , 9 * FPREGBYTES(sp)
  383. FPSTORE f10, 10 * FPREGBYTES(sp)
  384. FPSTORE f11, 11 * FPREGBYTES(sp)
  385. FPSTORE f12, 12 * FPREGBYTES(sp)
  386. FPSTORE f13, 13 * FPREGBYTES(sp)
  387. FPSTORE f14, 14 * FPREGBYTES(sp)
  388. FPSTORE f15, 15 * FPREGBYTES(sp)
  389. FPSTORE f16, 16 * FPREGBYTES(sp)
  390. FPSTORE f17, 17 * FPREGBYTES(sp)
  391. FPSTORE f18, 18 * FPREGBYTES(sp)
  392. FPSTORE f19, 19 * FPREGBYTES(sp)
  393. FPSTORE f20, 20 * FPREGBYTES(sp)
  394. FPSTORE f21, 21 * FPREGBYTES(sp)
  395. FPSTORE f22, 22 * FPREGBYTES(sp)
  396. FPSTORE f23, 23 * FPREGBYTES(sp)
  397. FPSTORE f24, 24 * FPREGBYTES(sp)
  398. FPSTORE f25, 25 * FPREGBYTES(sp)
  399. FPSTORE f26, 26 * FPREGBYTES(sp)
  400. FPSTORE f27, 27 * FPREGBYTES(sp)
  401. FPSTORE f28, 28 * FPREGBYTES(sp)
  402. FPSTORE f29, 29 * FPREGBYTES(sp)
  403. FPSTORE f30, 30 * FPREGBYTES(sp)
  404. FPSTORE f31, 31 * FPREGBYTES(sp)
  405. #endif
  406. #if defined(__riscv_vector)
  407. addi sp, sp, -(2 * REGBYTES)
  408. STORE t0, 0 * REGBYTES(sp)
  409. STORE t1, 1 * REGBYTES(sp)
  410. _save_vector_stack:
  411. csrr t0, CSR_MSTATUS
  412. li t1, MSTATUS_VS_DIRTY
  413. and t0,t0,t1
  414. bne t0, t1, _save_integer_stack
  415. LOAD t0, 0 * REGBYTES(sp)
  416. LOAD t1, 1 * REGBYTES(sp)
  417. addi sp, sp, (2 * REGBYTES)
  418. /* Save vector registers and vtype/vl/vstart/vcsr */
  419. addi sp, sp, -(6 * REGBYTES)
  420. STORE t0, 0 * REGBYTES(sp)
  421. STORE t1, 1 * REGBYTES(sp)
  422. csrr t0, CSR_VSTART
  423. STORE t0, 2 * REGBYTES(sp)
  424. csrr t0, CSR_VTYPE
  425. STORE t0, 3 * REGBYTES(sp)
  426. csrr t0, CSR_VL
  427. STORE t0, 4 * REGBYTES(sp)
  428. csrr t0, CSR_VCSR
  429. STORE t0, 5 * REGBYTES(sp)
  430. mv t1, sp
  431. csrr t0, CSR_VLENB
  432. slli t0, t0, 5
  433. /* t1 is the new temp stack where t0, t1 saved */
  434. sub t1, t1, t0
  435. LOAD t0, 0 * REGBYTES(sp)
  436. STORE t0, 0 * REGBYTES(t1)
  437. LOAD t0, 1 * REGBYTES(sp)
  438. STORE t0, 1 * REGBYTES(t1)
  439. mv sp, t1
  440. /* new sp -> t1 to save vector registers */
  441. addi t1, t1, (2 * REGBYTES)
  442. vsetvli t0, x0, e8, m8, ta, ma
  443. vse8.v v0, (t1)
  444. add t1, t1, t0
  445. vse8.v v8, (t1)
  446. add t1, t1, t0
  447. vse8.v v16, (t1)
  448. add t1, t1, t0
  449. vse8.v v24, (t1)
  450. LOAD t0, 0 * REGBYTES(sp)
  451. LOAD t1, 1 * REGBYTES(sp)
  452. addi sp, sp, (2 * REGBYTES)
  453. #endif
  454. #if defined(__riscv_flen) || defined(__riscv_vector)
  455. addi sp, sp, -(2 * REGBYTES)
  456. STORE t0, 0 * REGBYTES(sp)
  457. STORE t1, 1 * REGBYTES(sp)
  458. _save_integer_stack:
  459. LOAD t0, 0 * REGBYTES(sp)
  460. LOAD t1, 1 * REGBYTES(sp)
  461. addi sp, sp, (2 * REGBYTES)
  462. #endif
  463. addi sp, sp, -portCONTEXT_SIZE
  464. STORE x1, 1 * REGBYTES(sp) /* RA */
  465. STORE x5, 2 * REGBYTES(sp)
  466. STORE x6, 3 * REGBYTES(sp)
  467. STORE x7, 4 * REGBYTES(sp)
  468. STORE x8, 5 * REGBYTES(sp)
  469. STORE x9, 6 * REGBYTES(sp)
  470. STORE x10, 7 * REGBYTES(sp)
  471. STORE x11, 8 * REGBYTES(sp)
  472. STORE x12, 9 * REGBYTES(sp)
  473. STORE x13, 10 * REGBYTES(sp)
  474. STORE x14, 11 * REGBYTES(sp)
  475. STORE x15, 12 * REGBYTES(sp)
  476. #ifndef __riscv_32e
  477. STORE x16, 13 * REGBYTES(sp)
  478. STORE x17, 14 * REGBYTES(sp)
  479. STORE x18, 15 * REGBYTES(sp)
  480. STORE x19, 16 * REGBYTES(sp)
  481. STORE x20, 17 * REGBYTES(sp)
  482. STORE x21, 18 * REGBYTES(sp)
  483. STORE x22, 19 * REGBYTES(sp)
  484. STORE x23, 20 * REGBYTES(sp)
  485. STORE x24, 21 * REGBYTES(sp)
  486. STORE x25, 22 * REGBYTES(sp)
  487. STORE x26, 23 * REGBYTES(sp)
  488. STORE x27, 24 * REGBYTES(sp)
  489. STORE x28, 25 * REGBYTES(sp)
  490. STORE x29, 26 * REGBYTES(sp)
  491. STORE x30, 27 * REGBYTES(sp)
  492. STORE x31, 28 * REGBYTES(sp)
  493. #endif
  494. /* Push mstatus to stack */
  495. csrr t0, CSR_MSTATUS
  496. STORE t0, (portRegNum - 1) * REGBYTES(sp)
  497. /* Push additional registers */
  498. /* Store sp to task stack */
  499. #if ( configNUMBER_OF_CORES == 1 )
  500. LOAD t0, pxCurrentTCB /* Load pxCurrentTCB. */
  501. #else
  502. la t0, pxCurrentTCBs /* Load pxCurrentTCBs[core] */
  503. csrr t1, CSR_MHARTID
  504. slli t1, t1, LOG_REGBYTES
  505. add t0, t0, t1
  506. LOAD t0, 0(t0)
  507. #endif
  508. STORE sp, 0(t0)
  509. csrr t0, CSR_MEPC
  510. STORE t0, 0(sp)
  511. jal xPortTaskSwitch
  512. /* Switch task context */
  513. #if ( configNUMBER_OF_CORES == 1 )
  514. LOAD t0, pxCurrentTCB /* Load pxCurrentTCB. */
  515. #else
  516. la t0, pxCurrentTCBs /* Load pxCurrentTCBs[core] */
  517. csrr t1, CSR_MHARTID
  518. slli t1, t1, LOG_REGBYTES
  519. add t0, t0, t1
  520. LOAD t0, 0(t0)
  521. #endif
  522. LOAD sp, 0x0(t0) /* Read sp from first TCB member */
  523. /* Pop PC from stack and set MEPC */
  524. LOAD t0, 0 * REGBYTES(sp)
  525. csrw CSR_MEPC, t0
  526. /* Pop additional registers */
  527. /* Pop mstatus from stack and set it */
  528. LOAD t0, (portRegNum - 1) * REGBYTES(sp)
  529. csrw CSR_MSTATUS, t0
  530. /* Interrupt still disable here */
  531. /* Restore Registers from Stack */
  532. LOAD x1, 1 * REGBYTES(sp) /* RA */
  533. LOAD x5, 2 * REGBYTES(sp)
  534. LOAD x6, 3 * REGBYTES(sp)
  535. LOAD x7, 4 * REGBYTES(sp)
  536. LOAD x8, 5 * REGBYTES(sp)
  537. LOAD x9, 6 * REGBYTES(sp)
  538. LOAD x10, 7 * REGBYTES(sp)
  539. LOAD x11, 8 * REGBYTES(sp)
  540. LOAD x12, 9 * REGBYTES(sp)
  541. LOAD x13, 10 * REGBYTES(sp)
  542. LOAD x14, 11 * REGBYTES(sp)
  543. LOAD x15, 12 * REGBYTES(sp)
  544. #ifndef __riscv_32e
  545. LOAD x16, 13 * REGBYTES(sp)
  546. LOAD x17, 14 * REGBYTES(sp)
  547. LOAD x18, 15 * REGBYTES(sp)
  548. LOAD x19, 16 * REGBYTES(sp)
  549. LOAD x20, 17 * REGBYTES(sp)
  550. LOAD x21, 18 * REGBYTES(sp)
  551. LOAD x22, 19 * REGBYTES(sp)
  552. LOAD x23, 20 * REGBYTES(sp)
  553. LOAD x24, 21 * REGBYTES(sp)
  554. LOAD x25, 22 * REGBYTES(sp)
  555. LOAD x26, 23 * REGBYTES(sp)
  556. LOAD x27, 24 * REGBYTES(sp)
  557. LOAD x28, 25 * REGBYTES(sp)
  558. LOAD x29, 26 * REGBYTES(sp)
  559. LOAD x30, 27 * REGBYTES(sp)
  560. LOAD x31, 28 * REGBYTES(sp)
  561. #endif
  562. addi sp, sp, portCONTEXT_SIZE
  563. #if defined(__riscv_vector)
  564. /* Pop vector stack if needed */
  565. addi sp, sp, -(2 * REGBYTES)
  566. STORE t0, 0 * REGBYTES(sp)
  567. STORE t1, 1 * REGBYTES(sp)
  568. _restore_vector_stack:
  569. csrr t0, CSR_MSTATUS
  570. li t1, MSTATUS_VS_DIRTY
  571. and t0,t0,t1
  572. #if defined(__riscv_flen)
  573. bne t0, t1, _restore_fp_stack
  574. #else
  575. bne t0, t1, _restore_done
  576. #endif
  577. LOAD t0, 0 * REGBYTES(sp)
  578. LOAD t1, 1 * REGBYTES(sp)
  579. addi sp, sp, (2 * REGBYTES)
  580. /* pop vector registers and vtype/vl/vstart/vcsr */
  581. addi sp, sp, -(3 * REGBYTES)
  582. STORE t0, 0 * REGBYTES(sp)
  583. STORE t1, 1 * REGBYTES(sp)
  584. STORE t2, 2 * REGBYTES(sp)
  585. mv t2, sp
  586. /* temp regs are stored in t2 stack top */
  587. addi sp, sp, (3 * REGBYTES)
  588. vsetvli t0, x0, e8, m8, ta, ma
  589. vle8.v v0, (sp)
  590. add sp, sp, t0
  591. vle8.v v8, (sp)
  592. add sp, sp, t0
  593. vle8.v v16, (sp)
  594. add sp, sp, t0
  595. vle8.v v24, (sp)
  596. add sp, sp, t0
  597. LOAD t0, 2 * REGBYTES(sp)
  598. LOAD t1, 1 * REGBYTES(sp)
  599. vsetvl x0, t0, t1
  600. LOAD t0, 0 * REGBYTES(sp)
  601. csrw CSR_VSTART, t0
  602. LOAD t0, 3 * REGBYTES(sp)
  603. csrw CSR_VCSR, t0
  604. addi sp, sp, (4 * REGBYTES)
  605. LOAD t0, 0 * REGBYTES(t2)
  606. LOAD t1, 1 * REGBYTES(t2)
  607. LOAD t2, 2 * REGBYTES(t2)
  608. #endif
  609. #if defined(__riscv_flen)
  610. addi sp, sp, -(2 * REGBYTES)
  611. STORE t0, 0 * REGBYTES(sp)
  612. STORE t1, 1 * REGBYTES(sp)
  613. _restore_fp_stack:
  614. csrr t0, CSR_MSTATUS
  615. li t1, MSTATUS_FS_DIRTY
  616. and t0,t0,t1
  617. bne t0, t1, _restore_done
  618. LOAD t0, 0 * REGBYTES(sp)
  619. LOAD t1, 1 * REGBYTES(sp)
  620. addi sp, sp, (2 * REGBYTES)
  621. /* Restore fp registers and fcsr and 3 reserved reg space */
  622. FPLOAD f0 , 0 * FPREGBYTES(sp)
  623. FPLOAD f1 , 1 * FPREGBYTES(sp)
  624. FPLOAD f2 , 2 * FPREGBYTES(sp)
  625. FPLOAD f3 , 3 * FPREGBYTES(sp)
  626. FPLOAD f4 , 4 * FPREGBYTES(sp)
  627. FPLOAD f5 , 5 * FPREGBYTES(sp)
  628. FPLOAD f6 , 6 * FPREGBYTES(sp)
  629. FPLOAD f7 , 7 * FPREGBYTES(sp)
  630. FPLOAD f8 , 8 * FPREGBYTES(sp)
  631. FPLOAD f9 , 9 * FPREGBYTES(sp)
  632. FPLOAD f10, 10 * FPREGBYTES(sp)
  633. FPLOAD f11, 11 * FPREGBYTES(sp)
  634. FPLOAD f12, 12 * FPREGBYTES(sp)
  635. FPLOAD f13, 13 * FPREGBYTES(sp)
  636. FPLOAD f14, 14 * FPREGBYTES(sp)
  637. FPLOAD f15, 15 * FPREGBYTES(sp)
  638. FPLOAD f16, 16 * FPREGBYTES(sp)
  639. FPLOAD f17, 17 * FPREGBYTES(sp)
  640. FPLOAD f18, 18 * FPREGBYTES(sp)
  641. FPLOAD f19, 19 * FPREGBYTES(sp)
  642. FPLOAD f20, 20 * FPREGBYTES(sp)
  643. FPLOAD f21, 21 * FPREGBYTES(sp)
  644. FPLOAD f22, 22 * FPREGBYTES(sp)
  645. FPLOAD f23, 23 * FPREGBYTES(sp)
  646. FPLOAD f24, 24 * FPREGBYTES(sp)
  647. FPLOAD f25, 25 * FPREGBYTES(sp)
  648. FPLOAD f26, 26 * FPREGBYTES(sp)
  649. FPLOAD f27, 27 * FPREGBYTES(sp)
  650. FPLOAD f28, 28 * FPREGBYTES(sp)
  651. FPLOAD f29, 29 * FPREGBYTES(sp)
  652. FPLOAD f30, 30 * FPREGBYTES(sp)
  653. FPLOAD f31, 31 * FPREGBYTES(sp)
  654. addi sp, sp, (32 * FPREGBYTES)
  655. addi sp, sp, -(1 * REGBYTES)
  656. STORE t0, 0 * REGBYTES(sp)
  657. LOAD t0, 1 * REGBYTES(sp)
  658. csrw CSR_FCSR, t0
  659. LOAD t0, 0 * REGBYTES(sp)
  660. addi sp, sp, (5 * REGBYTES)
  661. #endif
  662. #if defined(__riscv_flen) || defined(__riscv_vector)
  663. addi sp, sp, -(2 * REGBYTES)
  664. STORE t0, 0 * REGBYTES(sp)
  665. STORE t1, 1 * REGBYTES(sp)
  666. _restore_done:
  667. LOAD t0, 0 * REGBYTES(sp)
  668. LOAD t1, 1 * REGBYTES(sp)
  669. addi sp, sp, (2 * REGBYTES)
  670. #endif
  671. mret
  672. .size eclic_msip_handler, . - eclic_msip_handler