interrupt.S 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. #include "riscv_encoding.h"
  2. .section .text.entry
  3. .align 8
  4. /**
  5. * \brief Global interrupt disabled
  6. * \details
  7. * This function disable global interrupt.
  8. * \remarks
  9. * - All the interrupt requests will be ignored by CPU.
  10. */
  11. .macro DISABLE_MIE
  12. csrc CSR_MSTATUS, MSTATUS_MIE
  13. .endm
  14. /**
  15. * \brief Macro for context save
  16. * \details
  17. * This macro save ABI defined caller saved registers in the stack.
  18. * \remarks
  19. * - This Macro could use to save context when you enter to interrupt
  20. * or exception
  21. */
  22. /* Save caller registers */
  23. .macro SAVE_CONTEXT
  24. #if defined(ECLIC_HW_CTX_AUTO) && defined(CFG_HAS_ECLICV2)
  25. #else
  26. csrrw sp, CSR_MSCRATCHCSWL, sp
  27. /* Allocate stack space for context saving */
  28. #ifndef __riscv_32e
  29. addi sp, sp, -20*REGBYTES
  30. #else
  31. addi sp, sp, -14*REGBYTES
  32. #endif /* __riscv_32e */
  33. STORE x1, 0*REGBYTES(sp)
  34. STORE x4, 1*REGBYTES(sp)
  35. STORE x5, 2*REGBYTES(sp)
  36. STORE x6, 3*REGBYTES(sp)
  37. STORE x7, 4*REGBYTES(sp)
  38. STORE x10, 5*REGBYTES(sp)
  39. STORE x11, 6*REGBYTES(sp)
  40. STORE x12, 7*REGBYTES(sp)
  41. STORE x13, 8*REGBYTES(sp)
  42. STORE x14, 9*REGBYTES(sp)
  43. STORE x15, 10*REGBYTES(sp)
  44. #ifndef __riscv_32e
  45. STORE x16, 14*REGBYTES(sp)
  46. STORE x17, 15*REGBYTES(sp)
  47. STORE x28, 16*REGBYTES(sp)
  48. STORE x29, 17*REGBYTES(sp)
  49. STORE x30, 18*REGBYTES(sp)
  50. STORE x31, 19*REGBYTES(sp)
  51. #endif /* __riscv_32e */
  52. #endif
  53. .endm
  54. /**
  55. * \brief Macro for restore caller registers
  56. * \details
  57. * This macro restore ABI defined caller saved registers from stack.
  58. * \remarks
  59. * - You could use this macro to restore context before you want return
  60. * from interrupt or exeception
  61. */
  62. /* Restore caller registers */
  63. .macro RESTORE_CONTEXT
  64. #if defined(ECLIC_HW_CTX_AUTO) && defined(CFG_HAS_ECLICV2)
  65. #else
  66. LOAD x1, 0*REGBYTES(sp)
  67. LOAD x4, 1*REGBYTES(sp)
  68. LOAD x5, 2*REGBYTES(sp)
  69. LOAD x6, 3*REGBYTES(sp)
  70. LOAD x7, 4*REGBYTES(sp)
  71. LOAD x10, 5*REGBYTES(sp)
  72. LOAD x11, 6*REGBYTES(sp)
  73. LOAD x12, 7*REGBYTES(sp)
  74. LOAD x13, 8*REGBYTES(sp)
  75. LOAD x14, 9*REGBYTES(sp)
  76. LOAD x15, 10*REGBYTES(sp)
  77. #ifndef __riscv_32e
  78. LOAD x16, 14*REGBYTES(sp)
  79. LOAD x17, 15*REGBYTES(sp)
  80. LOAD x28, 16*REGBYTES(sp)
  81. LOAD x29, 17*REGBYTES(sp)
  82. LOAD x30, 18*REGBYTES(sp)
  83. LOAD x31, 19*REGBYTES(sp)
  84. /* De-allocate the stack space */
  85. addi sp, sp, 20*REGBYTES
  86. #else
  87. /* De-allocate the stack space */
  88. addi sp, sp, 14*REGBYTES
  89. #endif /* __riscv_32e */
  90. csrrw sp, CSR_MSCRATCHCSWL, sp
  91. #endif
  92. .endm
  93. /**
  94. * \brief Macro for save necessary CSRs to stack
  95. * \details
  96. * This macro store MCAUSE, MEPC, MSUBM to stack.
  97. */
  98. .macro SAVE_CSR_CONTEXT
  99. #if defined(ECLIC_HW_CTX_AUTO) && defined(CFG_HAS_ECLICV2)
  100. #else
  101. /* Store CSR mcause to stack using pushmcause */
  102. csrrwi x0, CSR_PUSHMCAUSE, 11
  103. /* Store CSR mepc to stack using pushmepc */
  104. csrrwi x0, CSR_PUSHMEPC, 12
  105. /* Store CSR msub to stack using pushmsub */
  106. csrrwi x0, CSR_PUSHMSUBM, 13
  107. #endif
  108. .endm
  109. /**
  110. * \brief Macro for restore necessary CSRs from stack
  111. * \details
  112. * This macro restore MSUBM, MEPC, MCAUSE from stack.
  113. */
  114. .macro RESTORE_CSR_CONTEXT
  115. #if defined(ECLIC_HW_CTX_AUTO) && defined(CFG_HAS_ECLICV2)
  116. #else
  117. LOAD x5, 13*REGBYTES(sp)
  118. csrw CSR_MSUBM, x5
  119. LOAD x5, 12*REGBYTES(sp)
  120. csrw CSR_MEPC, x5
  121. LOAD x5, 11*REGBYTES(sp)
  122. csrw CSR_MCAUSE, x5
  123. #endif
  124. .endm
  125. /**
  126. * \brief Exception/NMI Entry
  127. * \details
  128. * This function provide common entry functions for exception/nmi.
  129. * \remarks
  130. * This function provide a default exception/nmi entry.
  131. * ABI defined caller save register and some CSR registers
  132. * to be saved before enter interrupt handler and be restored before return.
  133. */
  134. .section .text.trap
  135. /* In CLIC mode, the exeception entry must be 64bytes aligned */
  136. .align 6
  137. .type exc_entry, @function
  138. .global exc_entry
  139. exc_entry:
  140. /* Save the caller saving registers (context) */
  141. SAVE_CONTEXT
  142. /* Save the necessary CSR registers */
  143. SAVE_CSR_CONTEXT
  144. /*
  145. * Set the exception handler function arguments
  146. * argument 1: mcause value
  147. * argument 2: current stack point(SP) value
  148. */
  149. csrr a0, mcause
  150. mv a1, sp
  151. /*
  152. * TODO: Call the exception handler function
  153. * By default, the function template is provided in
  154. * system_Device.c, you can adjust it as you want
  155. */
  156. call core_exception_handler
  157. /* Restore the necessary CSR registers */
  158. RESTORE_CSR_CONTEXT
  159. /* Restore the caller saving registers (context) */
  160. RESTORE_CONTEXT
  161. /* Return to regular code */
  162. #if defined(ECLIC_HW_CTX_AUTO) && defined(CFG_HAS_ECLICV2)
  163. csrrwi x0, CSR_POPXRET, 0
  164. #else
  165. mret
  166. #endif
  167. .size exc_entry, . - exc_entry
  168. /**
  169. * \brief Non-Vector Interrupt Entry
  170. * \details
  171. * This function provide common entry functions for handling
  172. * non-vector interrupts
  173. * \remarks
  174. * This function provide a default non-vector interrupt entry.
  175. * ABI defined caller save register and some CSR registers need
  176. * to be saved before enter interrupt handler and be restored before return.
  177. */
  178. .section .text.irq
  179. /* In CLIC mode, the interrupt entry must be 4bytes aligned */
  180. .align 2
  181. .global irq_entry
  182. .type irq_entry, @function
  183. /* This label will be set to MTVT2 register */
  184. irq_entry:
  185. /* Save the caller saving registers (context) */
  186. SAVE_CONTEXT
  187. /* Save the necessary CSR registers */
  188. SAVE_CSR_CONTEXT
  189. /* This special CSR read/write operation, which is actually
  190. * claim the CLIC to find its pending highest ID, if the ID
  191. * is not 0, then automatically enable the mstatus.MIE, and
  192. * jump to its vector-entry-label, and update the link register
  193. */
  194. csrrw ra, CSR_JALMNXTI, ra
  195. /* Critical section with interrupts disabled */
  196. DISABLE_MIE
  197. /* Restore the necessary CSR registers */
  198. RESTORE_CSR_CONTEXT
  199. /* Restore the caller saving registers (context) */
  200. RESTORE_CONTEXT
  201. /* Return to regular code */
  202. #if defined(ECLIC_HW_CTX_AUTO) && defined(CFG_HAS_ECLICV2)
  203. csrrwi x0, CSR_POPXRET, 0
  204. #else
  205. mret
  206. #endif
  207. .size irq_entry, . - irq_entry
  208. /* Default Handler for Exceptions / Interrupts */
  209. .global default_intexc_handler
  210. .type default_intexc_handler, @function
  211. Undef_Handler:
  212. default_intexc_handler:
  213. 1:
  214. j 1b
  215. .size default_intexc_handler, . - default_intexc_handler