entry.S 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. // See LICENSE for license details
  2. #ifndef ENTRY_S
  3. #define ENTRY_S
  4. #include "riscv_encoding.h"
  5. #include "riscv_bits.h"
  6. #include "n200_eclic.h"
  7. #include "n200_timer.h"
  8. ###############################################
  9. ###############################################
  10. # Disable Interrupt
  11. #
  12. .macro DISABLE_MIE
  13. csrc CSR_MSTATUS, MSTATUS_MIE
  14. .endm
  15. ###############################################
  16. ###############################################
  17. #Save caller registers
  18. .macro SAVE_CONTEXT
  19. #ifdef __riscv_flen
  20. #if (__riscv_flen==64 )
  21. addi sp, sp, -20*REGBYTES - 20*FPREGBYTES
  22. #else
  23. addi sp, sp, -20*REGBYTES
  24. #endif
  25. #else
  26. addi sp, sp, -20*REGBYTES
  27. #endif
  28. STORE x1, 0*REGBYTES(sp)
  29. STORE x4, 1*REGBYTES(sp)
  30. STORE x5, 2*REGBYTES(sp)
  31. STORE x6, 3*REGBYTES(sp)
  32. STORE x7, 4*REGBYTES(sp)
  33. STORE x10, 5*REGBYTES(sp)
  34. STORE x11, 6*REGBYTES(sp)
  35. STORE x12, 7*REGBYTES(sp)
  36. STORE x13, 8*REGBYTES(sp)
  37. STORE x14, 9*REGBYTES(sp)
  38. STORE x15, 10*REGBYTES(sp)
  39. #ifndef __riscv_32e
  40. STORE x16, 11*REGBYTES(sp)
  41. STORE x17, 12*REGBYTES(sp)
  42. STORE x28, 13*REGBYTES(sp)
  43. STORE x29, 14*REGBYTES(sp)
  44. STORE x30, 15*REGBYTES(sp)
  45. STORE x31, 16*REGBYTES(sp)
  46. #endif
  47. #ifdef __riscv_flen
  48. #if (__riscv_flen == 64)
  49. FPSTORE f0, (20*REGBYTES + 0*FPREGBYTES)(sp)
  50. FPSTORE f1, (20*REGBYTES + 1*FPREGBYTES)(sp)
  51. FPSTORE f2, (20*REGBYTES + 2*FPREGBYTES)(sp)
  52. FPSTORE f3, (20*REGBYTES + 3*FPREGBYTES)(sp)
  53. FPSTORE f4, (20*REGBYTES + 4*FPREGBYTES)(sp)
  54. FPSTORE f5, (20*REGBYTES + 5*FPREGBYTES)(sp)
  55. FPSTORE f6, (20*REGBYTES + 6*FPREGBYTES)(sp)
  56. FPSTORE f7, (20*REGBYTES + 7*FPREGBYTES)(sp)
  57. FPSTORE f10, (20*REGBYTES + 8*FPREGBYTES)(sp)
  58. FPSTORE f11, (20*REGBYTES + 9*FPREGBYTES)(sp)
  59. FPSTORE f12, (20*REGBYTES + 10*FPREGBYTES)(sp)
  60. FPSTORE f13, (20*REGBYTES + 11*FPREGBYTES)(sp)
  61. FPSTORE f14, (20*REGBYTES + 12*FPREGBYTES)(sp)
  62. FPSTORE f15, (20*REGBYTES + 13*FPREGBYTES)(sp)
  63. FPSTORE f16, (20*REGBYTES + 14*FPREGBYTES)(sp)
  64. FPSTORE f17, (20*REGBYTES + 15*FPREGBYTES)(sp)
  65. FPSTORE f28, (20*REGBYTES + 16*FPREGBYTES)(sp)
  66. FPSTORE f29, (20*REGBYTES + 17*FPREGBYTES)(sp)
  67. FPSTORE f30, (20*REGBYTES + 18*FPREGBYTES)(sp)
  68. FPSTORE f31, (20*REGBYTES + 19*FPREGBYTES)(sp)
  69. #endif
  70. #endif
  71. .endm
  72. ###############################################
  73. ###############################################
  74. #restore caller registers
  75. .macro RESTORE_CONTEXT
  76. LOAD x1, 0*REGBYTES(sp)
  77. LOAD x4, 1*REGBYTES(sp)
  78. LOAD x5, 2*REGBYTES(sp)
  79. LOAD x6, 3*REGBYTES(sp)
  80. LOAD x7, 4*REGBYTES(sp)
  81. LOAD x10, 5*REGBYTES(sp)
  82. LOAD x11, 6*REGBYTES(sp)
  83. LOAD x12, 7*REGBYTES(sp)
  84. LOAD x13, 8*REGBYTES(sp)
  85. LOAD x14, 9*REGBYTES(sp)
  86. LOAD x15, 10*REGBYTES(sp)
  87. #ifndef __riscv_32e
  88. LOAD x16, 11*REGBYTES(sp)
  89. LOAD x17, 12*REGBYTES(sp)
  90. LOAD x28, 13*REGBYTES(sp)
  91. LOAD x29, 14*REGBYTES(sp)
  92. LOAD x30, 15*REGBYTES(sp)
  93. LOAD x31, 16*REGBYTES(sp)
  94. #endif
  95. #ifdef __riscv_flen
  96. #if (__riscv_flen==64)
  97. /* Restore fp caller registers */
  98. FPLOAD f0, (20*REGBYTES + 0*FPREGBYTES)(sp)
  99. FPLOAD f1, (20*REGBYTES + 1*FPREGBYTES)(sp)
  100. FPLOAD f2, (20*REGBYTES + 2*FPREGBYTES)(sp)
  101. FPLOAD f3, (20*REGBYTES + 3*FPREGBYTES)(sp)
  102. FPLOAD f4, (20*REGBYTES + 4*FPREGBYTES)(sp)
  103. FPLOAD f5, (20*REGBYTES + 5*FPREGBYTES)(sp)
  104. FPLOAD f6, (20*REGBYTES + 6*FPREGBYTES)(sp)
  105. FPLOAD f7, (20*REGBYTES + 7*FPREGBYTES)(sp)
  106. FPLOAD f10, (20*REGBYTES + 8*FPREGBYTES)(sp)
  107. FPLOAD f11, (20*REGBYTES + 9*FPREGBYTES)(sp)
  108. FPLOAD f12, (20*REGBYTES + 10*FPREGBYTES)(sp)
  109. FPLOAD f13, (20*REGBYTES + 11*FPREGBYTES)(sp)
  110. FPLOAD f14, (20*REGBYTES + 12*FPREGBYTES)(sp)
  111. FPLOAD f15, (20*REGBYTES + 13*FPREGBYTES)(sp)
  112. FPLOAD f16, (20*REGBYTES + 14*FPREGBYTES)(sp)
  113. FPLOAD f17, (20*REGBYTES + 15*FPREGBYTES)(sp)
  114. FPLOAD f28, (20*REGBYTES + 16*FPREGBYTES)(sp)
  115. FPLOAD f29, (20*REGBYTES + 17*FPREGBYTES)(sp)
  116. FPLOAD f30, (20*REGBYTES + 18*FPREGBYTES)(sp)
  117. FPLOAD f31, (20*REGBYTES + 19*FPREGBYTES)(sp)
  118. #endif
  119. #endif
  120. #ifdef __riscv_flen
  121. #if(__riscv_flen == 64 )
  122. addi sp, sp, 20*REGBYTES + 20*FPREGBYTES
  123. #else
  124. addi sp, sp, 20*REGBYTES
  125. #endif
  126. #else
  127. // De-allocate the stack space
  128. addi sp, sp, 20*REGBYTES
  129. #endif
  130. .endm
  131. ###############################################
  132. ###############################################
  133. #restore caller registers
  134. .macro RESTORE_CONTEXT_EXCPT_X5
  135. LOAD x1, 0*REGBYTES(sp)
  136. LOAD x6, 2*REGBYTES(sp)
  137. LOAD x7, 3*REGBYTES(sp)
  138. LOAD x10, 4*REGBYTES(sp)
  139. LOAD x11, 5*REGBYTES(sp)
  140. LOAD x12, 6*REGBYTES(sp)
  141. LOAD x13, 7*REGBYTES(sp)
  142. LOAD x14, 8*REGBYTES(sp)
  143. LOAD x15, 9*REGBYTES(sp)
  144. #ifndef __riscv_32e
  145. LOAD x16, 10*REGBYTES(sp)
  146. LOAD x17, 11*REGBYTES(sp)
  147. LOAD x28, 12*REGBYTES(sp)
  148. LOAD x29, 13*REGBYTES(sp)
  149. LOAD x30, 14*REGBYTES(sp)
  150. LOAD x31, 15*REGBYTES(sp)
  151. #endif
  152. .endm
  153. ###############################################
  154. ###############################################
  155. #restore caller registers
  156. .macro RESTORE_CONTEXT_ONLY_X5
  157. LOAD x5, 1*REGBYTES(sp)
  158. .endm
  159. ###############################################
  160. ###############################################
  161. # Save the mepc and mstatus
  162. #
  163. .macro SAVE_EPC_STATUS
  164. csrr x5, CSR_MEPC
  165. STORE x5, 16*REGBYTES(sp)
  166. csrr x5, CSR_MSTATUS
  167. STORE x5, 17*REGBYTES(sp)
  168. csrr x5, CSR_MSUBM
  169. STORE x5, 18*REGBYTES(sp)
  170. .endm
  171. ###############################################
  172. ###############################################
  173. # Restore the mepc and mstatus
  174. #
  175. .macro RESTORE_EPC_STATUS
  176. LOAD x5, 16*REGBYTES(sp)
  177. csrw CSR_MEPC, x5
  178. LOAD x5, 17*REGBYTES(sp)
  179. csrw CSR_MSTATUS, x5
  180. LOAD x5, 18*REGBYTES(sp)
  181. csrw CSR_MSUBM, x5
  182. .endm
  183. ###############################################
  184. ###############################################
  185. // Trap entry point
  186. //
  187. .section .text.trap
  188. .align 6// In CLIC mode, the trap entry must be 64bytes aligned
  189. .global trap_entry
  190. .weak trap_entry
  191. trap_entry:
  192. // Allocate the stack space
  193. // addi sp, sp, -19*REGBYTES
  194. // Save the caller saving registers (context)
  195. SAVE_CONTEXT
  196. // Save the MEPC/Mstatus/Msubm reg
  197. SAVE_EPC_STATUS
  198. // Set the function argument
  199. csrr a0, mcause
  200. mv a1, sp
  201. // Call the function
  202. call handle_trap
  203. // Restore the MEPC/Mstatus/Msubm reg
  204. RESTORE_EPC_STATUS
  205. // Restore the caller saving registers (context)
  206. RESTORE_CONTEXT
  207. // De-allocate the stack space
  208. // addi sp, sp, 19*REGBYTES
  209. // Return to regular code
  210. mret
  211. ###############################################
  212. ###############################################
  213. // IRQ entry point
  214. //
  215. .section .text.irq
  216. .align 2
  217. .global irq_entry
  218. .weak irq_entry
  219. irq_entry: // -------------> This label will be set to MTVT2 register
  220. // Allocate the stack space
  221. SAVE_CONTEXT// Save 16 regs
  222. //------This special CSR read operation, which is actually use mcause as operand to directly store it to memory
  223. csrrwi x0, CSR_PUSHMCAUSE, 17
  224. //------This special CSR read operation, which is actually use mepc as operand to directly store it to memory
  225. csrrwi x0, CSR_PUSHMEPC, 18
  226. //------This special CSR read operation, which is actually use Msubm as operand to directly store it to memory
  227. csrrwi x0, CSR_PUSHMSUBM, 19
  228. service_loop:
  229. //------This special CSR read/write operation, which is actually Claim the CLIC to find its pending highest
  230. // ID, if the ID is not 0, then automatically enable the mstatus.MIE, and jump to its vector-entry-label, and
  231. // update the link register
  232. csrrw ra, CSR_JALMNXTI, ra
  233. //RESTORE_CONTEXT_EXCPT_X5
  234. #---- Critical section with interrupts disabled -----------------------
  235. DISABLE_MIE # Disable interrupts
  236. LOAD x5, 19*REGBYTES(sp)
  237. csrw CSR_MSUBM, x5
  238. LOAD x5, 18*REGBYTES(sp)
  239. csrw CSR_MEPC, x5
  240. LOAD x5, 17*REGBYTES(sp)
  241. csrw CSR_MCAUSE, x5
  242. RESTORE_CONTEXT
  243. // Return to regular code
  244. mret
  245. #endif