trap.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2021/1/30 lizirui first version
  9. * 2021/10/20 JasonHu move to trap.c
  10. */
  11. #include <rthw.h>
  12. #include <rtthread.h>
  13. #define DBG_LVL DBG_LOG
  14. #include <rtdbg.h>
  15. #include "board.h"
  16. #include "tick.h"
  17. #include "drv_uart.h"
  18. #include "encoding.h"
  19. #include "stack.h"
  20. #include "sbi.h"
  21. #include "riscv.h"
  22. #include "rt_interrupt.h"
  23. #include "plic.h"
  24. #ifdef RT_USING_USERSPACE
  25. #include "riscv_mmu.h"
  26. #include "mmu.h"
  27. #include "page.h"
  28. #include "lwp_arch.h"
  29. #endif
  30. void dump_regs(struct rt_hw_stack_frame *regs)
  31. {
  32. rt_kprintf("--------------Dump Registers-----------------\n");
  33. rt_kprintf("Function Registers:\n");
  34. rt_kprintf("\tra(x1) = 0x%p(",regs->ra);
  35. rt_kprintf(")\n");
  36. rt_kprintf("\tuser_sp(x2) = 0x%p(",regs->user_sp_exc_stack);
  37. rt_kprintf(")\n");
  38. rt_kprintf("\tgp(x3) = 0x%p(",regs->gp);
  39. rt_kprintf(")\n");
  40. rt_kprintf("\ttp(x4) = 0x%p(",regs->tp);
  41. rt_kprintf(")\n");
  42. rt_kprintf("Temporary Registers:\n");
  43. rt_kprintf("\tt0(x5) = 0x%p(",regs->t0);
  44. rt_kprintf(")\n");
  45. rt_kprintf("\tt1(x6) = 0x%p(",regs->t1);
  46. rt_kprintf(")\n");
  47. rt_kprintf("\tt2(x7) = 0x%p(",regs->t2);
  48. rt_kprintf(")\n");
  49. rt_kprintf("\tt3(x28) = 0x%p(",regs->t3);
  50. rt_kprintf(")\n");
  51. rt_kprintf("\tt4(x29) = 0x%p(",regs->t4);
  52. rt_kprintf(")\n");
  53. rt_kprintf("\tt5(x30) = 0x%p(",regs->t5);
  54. rt_kprintf(")\n");
  55. rt_kprintf("\tt6(x31) = 0x%p(",regs->t6);
  56. rt_kprintf(")\n");
  57. rt_kprintf("Saved Registers:\n");
  58. rt_kprintf("\ts0/fp(x8) = 0x%p(",regs->s0_fp);
  59. rt_kprintf(")\n");
  60. rt_kprintf("\ts1(x9) = 0x%p(",regs->s1);
  61. rt_kprintf(")\n");
  62. rt_kprintf("\ts2(x18) = 0x%p(",regs->s2);
  63. rt_kprintf(")\n");
  64. rt_kprintf("\ts3(x19) = 0x%p(",regs->s3);
  65. rt_kprintf(")\n");
  66. rt_kprintf("\ts4(x20) = 0x%p(",regs->s4);
  67. rt_kprintf(")\n");
  68. rt_kprintf("\ts5(x21) = 0x%p(",regs->s5);
  69. rt_kprintf(")\n");
  70. rt_kprintf("\ts6(x22) = 0x%p(",regs->s6);
  71. rt_kprintf(")\n");
  72. rt_kprintf("\ts7(x23) = 0x%p(",regs->s7);
  73. rt_kprintf(")\n");
  74. rt_kprintf("\ts8(x24) = 0x%p(",regs->s8);
  75. rt_kprintf(")\n");
  76. rt_kprintf("\ts9(x25) = 0x%p(",regs->s9);
  77. rt_kprintf(")\n");
  78. rt_kprintf("\ts10(x26) = 0x%p(",regs->s10);
  79. rt_kprintf(")\n");
  80. rt_kprintf("\ts11(x27) = 0x%p(",regs->s11);
  81. rt_kprintf(")\n");
  82. rt_kprintf("Function Arguments Registers:\n");
  83. rt_kprintf("\ta0(x10) = 0x%p(",regs->a0);
  84. rt_kprintf(")\n");
  85. rt_kprintf("\ta1(x11) = 0x%p(",regs->a1);
  86. rt_kprintf(")\n");
  87. rt_kprintf("\ta2(x12) = 0x%p(",regs->a2);
  88. rt_kprintf(")\n");
  89. rt_kprintf("\ta3(x13) = 0x%p(",regs->a3);
  90. rt_kprintf(")\n");
  91. rt_kprintf("\ta4(x14) = 0x%p(",regs->a4);
  92. rt_kprintf(")\n");
  93. rt_kprintf("\ta5(x15) = 0x%p(",regs->a5);
  94. rt_kprintf(")\n");
  95. rt_kprintf("\ta6(x16) = 0x%p(",regs->a6);
  96. rt_kprintf(")\n");
  97. rt_kprintf("\ta7(x17) = 0x%p(",regs->a7);
  98. rt_kprintf(")\n");
  99. rt_kprintf("sstatus = 0x%p\n",regs->sstatus);
  100. rt_kprintf("\t%s\n",(regs->sstatus & SSTATUS_SIE) ? "Supervisor Interrupt Enabled" : "Supervisor Interrupt Disabled");
  101. rt_kprintf("\t%s\n",(regs->sstatus & SSTATUS_SPIE) ? "Last Time Supervisor Interrupt Enabled" : "Last Time Supervisor Interrupt Disabled");
  102. rt_kprintf("\t%s\n",(regs->sstatus & SSTATUS_SPP) ? "Last Privilege is Supervisor Mode" : "Last Privilege is User Mode");
  103. rt_kprintf("\t%s\n",(regs->sstatus & SSTATUS_PUM) ? "Permit to Access User Page" : "Not Permit to Access User Page");
  104. rt_kprintf("\t%s\n",(regs->sstatus & (1 << 19)) ? "Permit to Read Executable-only Page" : "Not Permit to Read Executable-only Page");
  105. rt_size_t satp_v = read_csr(satp);
  106. rt_kprintf("satp = 0x%p\n",satp_v);
  107. #ifdef RT_USING_USERSPACE
  108. rt_kprintf("\tCurrent Page Table(Physical) = 0x%p\n",__MASKVALUE(satp_v,__MASK(44)) << PAGE_OFFSET_BIT);
  109. rt_kprintf("\tCurrent ASID = 0x%p\n",__MASKVALUE(satp_v >> 44,__MASK(16)) << PAGE_OFFSET_BIT);
  110. #endif
  111. const char *mode_str = "Unknown Address Translation/Protection Mode";
  112. switch(__MASKVALUE(satp_v >> 60,__MASK(4)))
  113. {
  114. case 0:
  115. mode_str = "No Address Translation/Protection Mode";
  116. break;
  117. case 8:
  118. mode_str = "Page-based 39-bit Virtual Addressing Mode";
  119. break;
  120. case 9:
  121. mode_str = "Page-based 48-bit Virtual Addressing Mode";
  122. break;
  123. }
  124. rt_kprintf("\tMode = %s\n",mode_str);
  125. rt_kprintf("-----------------Dump OK---------------------\n");
  126. }
  127. static const char *Exception_Name[] =
  128. {
  129. "Instruction Address Misaligned",
  130. "Instruction Access Fault",
  131. "Illegal Instruction",
  132. "Breakpoint",
  133. "Load Address Misaligned",
  134. "Load Access Fault",
  135. "Store/AMO Address Misaligned",
  136. "Store/AMO Access Fault",
  137. "Environment call from U-mode",
  138. "Environment call from S-mode",
  139. "Reserved-10",
  140. "Reserved-11",
  141. "Instruction Page Fault",
  142. "Load Page Fault",
  143. "Reserved-14",
  144. "Store/AMO Page Fault"
  145. };
  146. static const char *Interrupt_Name[] =
  147. {
  148. "User Software Interrupt",
  149. "Supervisor Software Interrupt",
  150. "Reversed-2",
  151. "Reversed-3",
  152. "User Timer Interrupt",
  153. "Supervisor Timer Interrupt",
  154. "Reversed-6",
  155. "Reversed-7",
  156. "User External Interrupt",
  157. "Supervisor External Interrupt",
  158. "Reserved-10",
  159. "Reserved-11",
  160. };
  161. extern struct rt_irq_desc isr_table[];
  162. void generic_handle_irq(int irq)
  163. {
  164. rt_isr_handler_t isr;
  165. void *param;
  166. if (irq < 0 || irq >= IRQ_MAX_NR)
  167. {
  168. LOG_E("bad irq number %d!\n", irq);
  169. return;
  170. }
  171. if (!irq) // irq = 0 => no irq
  172. {
  173. LOG_W("no irq!\n");
  174. return;
  175. }
  176. isr = isr_table[IRQ_OFFSET + irq].handler;
  177. param = isr_table[IRQ_OFFSET + irq].param;
  178. if (isr != RT_NULL)
  179. {
  180. isr(irq, param);
  181. }
  182. /* complete irq. */
  183. plic_complete(irq);
  184. }
  185. /* Trap entry */
  186. void handle_trap(rt_size_t scause,rt_size_t stval,rt_size_t sepc,struct rt_hw_stack_frame *sp)
  187. {
  188. rt_size_t id = __MASKVALUE(scause,__MASK(63UL));
  189. const char *msg;
  190. /* supervisor external interrupt */
  191. if ((SCAUSE_INTERRUPT & scause) && SCAUSE_S_EXTERNAL_INTR == (scause & 0xff))
  192. {
  193. rt_interrupt_enter();
  194. plic_handle_irq();
  195. rt_interrupt_leave();
  196. return;
  197. }
  198. else if ((SCAUSE_INTERRUPT | SCAUSE_S_TIMER_INTR) == scause)
  199. {
  200. /* supervisor timer */
  201. rt_interrupt_enter();
  202. tick_isr();
  203. rt_interrupt_leave();
  204. return;
  205. }
  206. else if (SCAUSE_INTERRUPT & scause)
  207. {
  208. if(id < sizeof(Interrupt_Name) / sizeof(const char *))
  209. {
  210. msg = Interrupt_Name[id];
  211. }
  212. else
  213. {
  214. msg = "Unknown Interrupt";
  215. }
  216. LOG_E("Unhandled Interrupt %ld:%s\n",id,msg);
  217. }
  218. else
  219. {
  220. #ifdef RT_USING_USERSPACE
  221. /* page fault */
  222. if (id == EP_LOAD_PAGE_FAULT ||
  223. id == EP_STORE_PAGE_FAULT)
  224. {
  225. arch_expand_user_stack((void *)stval);
  226. return;
  227. }
  228. #endif
  229. if(id < sizeof(Exception_Name) / sizeof(const char *))
  230. {
  231. msg = Exception_Name[id];
  232. }
  233. else
  234. {
  235. msg = "Unknown Exception";
  236. }
  237. rt_kprintf("Unhandled Exception %ld:%s\n",id,msg);
  238. }
  239. rt_kprintf("scause:0x%p,stval:0x%p,sepc:0x%p\n",scause,stval,sepc);
  240. dump_regs(sp);
  241. while(1);
  242. }