trap.c 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. /*
  2. * Copyright (c) 2021-2023 HPMicro
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. *
  6. */
  7. #include "hpm_common.h"
  8. #include "hpm_soc.h"
  9. #include <rtthread.h>
  10. #include "rt_hw_stack_frame.h"
  11. #define MCAUSE_INSTR_ADDR_MISALIGNED (0U) //!< Instruction Address misaligned
  12. #define MCAUSE_INSTR_ACCESS_FAULT (1U) //!< Instruction access fault
  13. #define MCAUSE_ILLEGAL_INSTR (2U) //!< Illegal instruction
  14. #define MCAUSE_BREAKPOINT (3U) //!< Breakpoint
  15. #define MCAUSE_LOAD_ADDR_MISALIGNED (4U) //!< Load address misaligned
  16. #define MCAUSE_LOAD_ACCESS_FAULT (5U) //!< Load access fault
  17. #define MCAUSE_STORE_AMO_ADDR_MISALIGNED (6U) //!< Store/AMO address misaligned
  18. #define MCAUSE_STORE_AMO_ACCESS_FAULT (7U) //!< Store/AMO access fault
  19. #define MCAUSE_ECALL_FROM_USER_MODE (8U) //!< Environment call from User mode
  20. #define MCAUSE_ECALL_FROM_SUPERVISOR_MODE (9U) //!< Environment call from Supervisor mode
  21. #define MCAUSE_ECALL_FROM_MACHINE_MODE (11U) //!< Environment call from machine mode
  22. #define MCAUSE_INSTR_PAGE_FAULT (12U) //!< Instruction page fault
  23. #define MCAUSE_LOAD_PAGE_FAULT (13) //!< Load page fault
  24. #define MCAUSE_STORE_AMO_PAGE_FAULT (15U) //!< Store/AMO page fault
  25. #define IRQ_S_SOFT 1
  26. #define IRQ_H_SOFT 2
  27. #define IRQ_M_SOFT 3
  28. #define IRQ_S_TIMER 5
  29. #define IRQ_H_TIMER 6
  30. #define IRQ_M_TIMER 7
  31. #define IRQ_S_EXT 9
  32. #define IRQ_H_EXT 10
  33. #define IRQ_M_EXT 11
  34. #define IRQ_COP 12
  35. #define IRQ_HOST 13
  36. #ifdef DEBUG
  37. #define RT_EXCEPTION_TRACE rt_kprintf
  38. #else
  39. #define RT_EXCEPTION_TRACE(...)
  40. #endif
  41. typedef void (*isr_func_t)(void);
  42. static volatile rt_hw_stack_frame_t *s_stack_frame;
  43. __attribute((weak)) void mchtmr_isr(void)
  44. {
  45. }
  46. __attribute__((weak)) void mswi_isr(void)
  47. {
  48. }
  49. __attribute__((weak)) void syscall_handler(uint32_t n, uint32_t a0, uint32_t a1, uint32_t a2, uint32_t a3)
  50. {
  51. }
  52. void rt_show_stack_frame(void)
  53. {
  54. RT_EXCEPTION_TRACE("Stack frame:\r\n----------------------------------------\r\n");
  55. RT_EXCEPTION_TRACE("ra : 0x%08x\r\n", s_stack_frame->ra);
  56. RT_EXCEPTION_TRACE("mstatus : 0x%08x\r\n", read_csr(0x300));//mstatus
  57. RT_EXCEPTION_TRACE("t0 : 0x%08x\r\n", s_stack_frame->t0);
  58. RT_EXCEPTION_TRACE("t1 : 0x%08x\r\n", s_stack_frame->t1);
  59. RT_EXCEPTION_TRACE("t2 : 0x%08x\r\n", s_stack_frame->t2);
  60. RT_EXCEPTION_TRACE("a0 : 0x%08x\r\n", s_stack_frame->a0);
  61. RT_EXCEPTION_TRACE("a1 : 0x%08x\r\n", s_stack_frame->a1);
  62. RT_EXCEPTION_TRACE("a2 : 0x%08x\r\n", s_stack_frame->a2);
  63. RT_EXCEPTION_TRACE("a3 : 0x%08x\r\n", s_stack_frame->a3);
  64. RT_EXCEPTION_TRACE("a4 : 0x%08x\r\n", s_stack_frame->a4);
  65. RT_EXCEPTION_TRACE("a5 : 0x%08x\r\n", s_stack_frame->a5);
  66. #ifndef __riscv_32e
  67. RT_EXCEPTION_TRACE("a6 : 0x%08x\r\n", s_stack_frame->a6);
  68. RT_EXCEPTION_TRACE("a7 : 0x%08x\r\n", s_stack_frame->a7);
  69. RT_EXCEPTION_TRACE("t3 : 0x%08x\r\n", s_stack_frame->t3);
  70. RT_EXCEPTION_TRACE("t4 : 0x%08x\r\n", s_stack_frame->t4);
  71. RT_EXCEPTION_TRACE("t5 : 0x%08x\r\n", s_stack_frame->t5);
  72. RT_EXCEPTION_TRACE("t6 : 0x%08x\r\n", s_stack_frame->t6);
  73. #endif
  74. }
  75. uint32_t exception_handler(uint32_t cause, uint32_t epc)
  76. {
  77. /* Unhandled Trap */
  78. uint32_t mdcause = read_csr(CSR_MDCAUSE);
  79. uint32_t mtval = read_csr(CSR_MTVAL);
  80. rt_uint32_t mscratch = read_csr(0x340);
  81. s_stack_frame = (rt_hw_stack_frame_t *)mscratch;
  82. rt_show_stack_frame();
  83. switch (cause)
  84. {
  85. case MCAUSE_INSTR_ADDR_MISALIGNED:
  86. RT_EXCEPTION_TRACE("exception: instruction address was mis-aligned, mtval=0x%08x\n", mtval);
  87. break;
  88. case MCAUSE_INSTR_ACCESS_FAULT:
  89. RT_EXCEPTION_TRACE("exception: instruction access fault happened, mtval=0x%08x, epc=0x%08x\n", mtval, epc);
  90. switch (mdcause & 0x07)
  91. {
  92. case 1:
  93. RT_EXCEPTION_TRACE("mdcause: ECC/Parity error\r\n");
  94. break;
  95. case 2:
  96. RT_EXCEPTION_TRACE("mdcause: PMP instruction access violation \r\n");
  97. break;
  98. case 3:
  99. RT_EXCEPTION_TRACE("mdcause: BUS error\r\n");
  100. break;
  101. case 4:
  102. RT_EXCEPTION_TRACE("mdcause: PMP empty hole access \r\n");
  103. break;
  104. default:
  105. RT_EXCEPTION_TRACE("mdcause: reserved \r\n");
  106. break;
  107. }
  108. break;
  109. case MCAUSE_ILLEGAL_INSTR:
  110. RT_EXCEPTION_TRACE("exception: illegal instruction was met, mtval=0x%08x\n", mtval);
  111. switch (mdcause & 0x07)
  112. {
  113. case 0:
  114. RT_EXCEPTION_TRACE("mdcause: the actual faulting instruction is stored in the mtval CSR\r\n");
  115. break;
  116. case 1:
  117. RT_EXCEPTION_TRACE("mdcause: FP disabled exception \r\n");
  118. break;
  119. case 2:
  120. RT_EXCEPTION_TRACE("mdcause: ACE disabled exception \r\n");
  121. break;
  122. default:
  123. RT_EXCEPTION_TRACE("mdcause: reserved \r\n");
  124. break;
  125. }
  126. break;
  127. case MCAUSE_BREAKPOINT:
  128. RT_EXCEPTION_TRACE("exception: breakpoint was hit, mtval=0x%08x\n", mtval);
  129. break;
  130. case MCAUSE_LOAD_ADDR_MISALIGNED:
  131. RT_EXCEPTION_TRACE("exception: load address was mis-aligned, mtval=0x%08x\n", mtval);
  132. break;
  133. case MCAUSE_LOAD_ACCESS_FAULT:
  134. RT_EXCEPTION_TRACE("exception: load access fault happened, epc=%08x, mdcause=0x%x\n", epc, mdcause);
  135. switch (mdcause & 0x07)
  136. {
  137. case 1:
  138. RT_EXCEPTION_TRACE("mdcause: ECC/Parity error\r\n");
  139. break;
  140. case 2:
  141. RT_EXCEPTION_TRACE("mdcause: PMP instruction access violation \r\n");
  142. break;
  143. case 3:
  144. RT_EXCEPTION_TRACE("mdcause: BUS error\r\n");
  145. break;
  146. case 4:
  147. RT_EXCEPTION_TRACE("mdcause: Misaligned access \r\n");
  148. break;
  149. case 5:
  150. RT_EXCEPTION_TRACE("mdcause: PMP empty hole access \r\n");
  151. break;
  152. case 6:
  153. RT_EXCEPTION_TRACE("mdcause: PMA attribute inconsistency\r\n");
  154. break;
  155. default:
  156. RT_EXCEPTION_TRACE("mdcause: reserved \r\n");
  157. break;
  158. }
  159. break;
  160. case MCAUSE_STORE_AMO_ADDR_MISALIGNED:
  161. RT_EXCEPTION_TRACE("exception: store amo address was misaligned, epc=%08x\n", epc);
  162. break;
  163. case MCAUSE_STORE_AMO_ACCESS_FAULT:
  164. RT_EXCEPTION_TRACE("exception: store amo access fault happened, epc=%08x\n", epc);
  165. switch (mdcause & 0x07)
  166. {
  167. case 1:
  168. RT_EXCEPTION_TRACE("mdcause: ECC/Parity error\r\n");
  169. break;
  170. case 2:
  171. RT_EXCEPTION_TRACE("mdcause: PMP instruction access violation \r\n");
  172. break;
  173. case 3:
  174. RT_EXCEPTION_TRACE("mdcause: BUS error\r\n");
  175. break;
  176. case 4:
  177. RT_EXCEPTION_TRACE("mdcause: Misaligned access \r\n");
  178. break;
  179. case 5:
  180. RT_EXCEPTION_TRACE("mdcause: PMP empty hole access \r\n");
  181. break;
  182. case 6:
  183. RT_EXCEPTION_TRACE("mdcause: PMA attribute inconsistency\r\n");
  184. break;
  185. case 7:
  186. RT_EXCEPTION_TRACE("mdcause: PMA NAMO exception \r\n");
  187. default:
  188. RT_EXCEPTION_TRACE("mdcause: reserved \r\n");
  189. break;
  190. }
  191. break;
  192. default:
  193. RT_EXCEPTION_TRACE("Unknown exception happened, cause=%d\n", cause);
  194. break;
  195. }
  196. rt_kprintf("cause=0x%08x, epc=0x%08x, ra=0x%08x\n", cause, epc, s_stack_frame->ra);
  197. while(1) {
  198. }
  199. }
  200. void trap_entry(void);
  201. void trap_entry(void)
  202. {
  203. uint32_t mcause = read_csr(CSR_MCAUSE);
  204. uint32_t mepc = read_csr(CSR_MEPC);
  205. uint32_t mstatus = read_csr(CSR_MSTATUS);
  206. #if SUPPORT_PFT_ARCH
  207. uint32_t mxstatus = read_csr(CSR_MXSTATUS);
  208. #endif
  209. #ifdef __riscv_dsp
  210. int ucode = read_csr(CSR_UCODE);
  211. #endif
  212. #ifdef __riscv_flen
  213. int fcsr = read_fcsr();
  214. #endif
  215. /* clobbers list for ecall */
  216. #ifdef __riscv_32e
  217. __asm volatile("" : : :"t0", "a0", "a1", "a2", "a3");
  218. #else
  219. __asm volatile("" : : :"a7", "a0", "a1", "a2", "a3");
  220. #endif
  221. /* Do your trap handling */
  222. uint32_t cause_type = mcause & CSR_MCAUSE_EXCEPTION_CODE_MASK;
  223. uint32_t irq_index;
  224. if (mcause & CSR_MCAUSE_INTERRUPT_MASK)
  225. {
  226. switch (cause_type)
  227. {
  228. /* Machine timer interrupt */
  229. case IRQ_M_TIMER:
  230. mchtmr_isr();
  231. break;
  232. /* Machine EXT interrupt */
  233. case IRQ_M_EXT:
  234. /* Claim interrupt */
  235. irq_index = __plic_claim_irq(HPM_PLIC_BASE, HPM_PLIC_TARGET_M_MODE);
  236. /* Execute EXT interrupt handler */
  237. if (irq_index > 0)
  238. {
  239. ((isr_func_t) __vector_table[irq_index])();
  240. /* Complete interrupt */
  241. __plic_complete_irq(HPM_PLIC_BASE, HPM_PLIC_TARGET_M_MODE, irq_index);
  242. }
  243. break;
  244. /* Machine SWI interrupt */
  245. case IRQ_M_SOFT:
  246. mswi_isr();
  247. intc_m_complete_swi();
  248. break;
  249. }
  250. }
  251. else if (cause_type == MCAUSE_ECALL_FROM_MACHINE_MODE)
  252. {
  253. /* Machine Syscal call */
  254. __asm volatile(
  255. "mv a4, a3\n"
  256. "mv a3, a2\n"
  257. "mv a2, a1\n"
  258. "mv a1, a0\n"
  259. #ifdef __riscv_32e
  260. "mv a0, t0\n"
  261. #else
  262. "mv a0, a7\n"
  263. #endif
  264. "call syscall_handler\n"
  265. : : : "a4"
  266. );
  267. mepc += 4;
  268. }
  269. else
  270. {
  271. mepc = exception_handler(mcause, mepc);
  272. }
  273. /* Restore CSR */
  274. write_csr(CSR_MSTATUS, mstatus);
  275. write_csr(CSR_MEPC, mepc);
  276. #if SUPPORT_PFT_ARCH
  277. write_csr(CSR_MXSTATUS, mxstatus);
  278. #endif
  279. #ifdef __riscv_dsp
  280. write_csr(CSR_UCODE, ucode);
  281. #endif
  282. #ifdef __riscv_flen
  283. write_fcsr(fcsr);
  284. #endif
  285. }
  286. /**
  287. * Trap Handler
  288. */
  289. rt_weak void handle_trap(rt_uint32_t mcause, rt_uint32_t mepc, rt_uint32_t sp)
  290. {
  291. }