trap.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. /*
  2. * Copyright (c) 2021, Shenzhen Academy of Aerospace Technology
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2021-11-16 Dystopia the first version
  9. */
  10. #include "trap.h"
  11. #include "c66xx.h"
  12. #include <rthw.h>
  13. #include <rtdef.h>
  14. #include <rtthread.h>
  15. #define RT_SYS_STACK_SIZE 4096
  16. rt_uint8_t rt_system_stack[RT_SYS_STACK_SIZE];
  17. rt_uint8_t *rt_system_stack_top;
  18. void rt_trap_init(void)
  19. {
  20. rt_system_stack_top = &rt_system_stack[RT_SYS_STACK_SIZE-1];
  21. rt_system_stack_top = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)rt_system_stack_top, 8);
  22. ack_exception(EXCEPT_TYPE_NXF);
  23. ack_exception(EXCEPT_TYPE_EXC);
  24. ack_exception(EXCEPT_TYPE_IXF);
  25. ack_exception(EXCEPT_TYPE_SXF);
  26. rt_hw_enable_exception();
  27. }
  28. void show_regs(struct rt_hw_exp_stack_register *regs)
  29. {
  30. rt_kprintf("\n");
  31. rt_kprintf("PC: %08lx SP: %08lx\n",
  32. regs->pc, regs->hw_register.sp);
  33. rt_kprintf("Status: %08lx ORIG_A4: %08lx\n",
  34. regs->csr, regs->orig_a4);
  35. rt_kprintf("A0: %08lx B0: %08lx\n",
  36. regs->hw_register.a0, regs->hw_register.b0);
  37. rt_kprintf("A1: %08lx B1: %08lx\n",
  38. regs->hw_register.a1, regs->hw_register.b1);
  39. rt_kprintf("A2: %08lx B2: %08lx\n",
  40. regs->hw_register.a2, regs->hw_register.b2);
  41. rt_kprintf("A3: %08lx B3: %08lx\n",
  42. regs->hw_register.a3, regs->hw_register.b3);
  43. rt_kprintf("A4: %08lx B4: %08lx\n",
  44. regs->hw_register.a4, regs->hw_register.b4);
  45. rt_kprintf("A5: %08lx B5: %08lx\n",
  46. regs->hw_register.a5, regs->hw_register.b5);
  47. rt_kprintf("A6: %08lx B6: %08lx\n",
  48. regs->hw_register.a6, regs->hw_register.b6);
  49. rt_kprintf("A7: %08lx B7: %08lx\n",
  50. regs->hw_register.a7, regs->hw_register.b7);
  51. rt_kprintf("A8: %08lx B8: %08lx\n",
  52. regs->hw_register.a8, regs->hw_register.b8);
  53. rt_kprintf("A9: %08lx B9: %08lx\n",
  54. regs->hw_register.a9, regs->hw_register.b9);
  55. rt_kprintf("A10: %08lx B10: %08lx\n",
  56. regs->hw_register.a10, regs->hw_register.b10);
  57. rt_kprintf("A11: %08lx B11: %08lx\n",
  58. regs->hw_register.a11, regs->hw_register.b11);
  59. rt_kprintf("A12: %08lx B12: %08lx\n",
  60. regs->hw_register.a12, regs->hw_register.b12);
  61. rt_kprintf("A13: %08lx B13: %08lx\n",
  62. regs->hw_register.a13, regs->hw_register.b13);
  63. rt_kprintf("A14: %08lx B14: %08lx\n",
  64. regs->hw_register.a14, regs->hw_register.dp);
  65. rt_kprintf("A15: %08lx B15: %08lx\n",
  66. regs->hw_register.a15, regs->hw_register.sp);
  67. rt_kprintf("A16: %08lx B16: %08lx\n",
  68. regs->hw_register.a16, regs->hw_register.b16);
  69. rt_kprintf("A17: %08lx B17: %08lx\n",
  70. regs->hw_register.a17, regs->hw_register.b17);
  71. rt_kprintf("A18: %08lx B18: %08lx\n",
  72. regs->hw_register.a18, regs->hw_register.b18);
  73. rt_kprintf("A19: %08lx B19: %08lx\n",
  74. regs->hw_register.a19, regs->hw_register.b19);
  75. rt_kprintf("A20: %08lx B20: %08lx\n",
  76. regs->hw_register.a20, regs->hw_register.b20);
  77. rt_kprintf("A21: %08lx B21: %08lx\n",
  78. regs->hw_register.a21, regs->hw_register.b21);
  79. rt_kprintf("A22: %08lx B22: %08lx\n",
  80. regs->hw_register.a22, regs->hw_register.b22);
  81. rt_kprintf("A23: %08lx B23: %08lx\n",
  82. regs->hw_register.a23, regs->hw_register.b23);
  83. rt_kprintf("A24: %08lx B24: %08lx\n",
  84. regs->hw_register.a24, regs->hw_register.b24);
  85. rt_kprintf("A25: %08lx B25: %08lx\n",
  86. regs->hw_register.a25, regs->hw_register.b25);
  87. rt_kprintf("A26: %08lx B26: %08lx\n",
  88. regs->hw_register.a26, regs->hw_register.b26);
  89. rt_kprintf("A27: %08lx B27: %08lx\n",
  90. regs->hw_register.a27, regs->hw_register.b27);
  91. rt_kprintf("A28: %08lx B28: %08lx\n",
  92. regs->hw_register.a28, regs->hw_register.b28);
  93. rt_kprintf("A29: %08lx B29: %08lx\n",
  94. regs->hw_register.a29, regs->hw_register.b29);
  95. rt_kprintf("A30: %08lx B30: %08lx\n",
  96. regs->hw_register.a30, regs->hw_register.b30);
  97. rt_kprintf("A31: %08lx B31: %08lx\n",
  98. regs->hw_register.a31, regs->hw_register.b31);
  99. }
  100. void do_trap(struct rt_exception_info *except_info, struct rt_hw_exp_stack_register *regs)
  101. {
  102. rt_kprintf("Enter exception: %s\n", except_info->kernel_str);
  103. show_regs(regs);
  104. for(;;){}
  105. }
  106. static struct rt_exception_info iexcept_table[10] = {
  107. { " - instruction fetch", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  108. { " - fetch packet", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  109. { " - execute packet", ABORT_TYPE_UNDDEF, ABORT_OPCODE_ILL },
  110. { " - undefined instruction", ABORT_TYPE_UNDDEF, ABORT_OPCODE_ILL },
  111. { " - resource conflict", ABORT_TYPE_UNDDEF, ABORT_OPCODE_ILL },
  112. { " - resource access", ABORT_TYPE_UNDDEF, ABORT_PRVREG_ILL },
  113. { " - privilege", ABORT_TYPE_UNDDEF, ABORT_PRVOPC_ILL },
  114. { " - loops buffer", ABORT_TYPE_UNDDEF, ABORT_PRVOPC_ILL },
  115. { " - software exception", ABORT_TYPE_UNDDEF, ABORT_ILLTRP_ILL },
  116. { " - unknown exception", ABORT_TYPE_UNDDEF, ABORT_PRVOPC_ILL }
  117. };
  118. /*
  119. * Process an internal exception (non maskable)
  120. */
  121. static int process_iexcept(struct rt_hw_exp_stack_register *regs)
  122. {
  123. unsigned int iexcept_report = get_iexcept();
  124. unsigned int iexcept_num = 0;
  125. ack_exception(EXCEPT_TYPE_IXF);
  126. while(iexcept_report)
  127. {
  128. iexcept_num = ffs(iexcept_report);
  129. iexcept_report &= ~(1 << iexcept_num);
  130. set_iexcept(iexcept_report);
  131. if (*(unsigned int *)regs->pc == BKPT_OPCODE)
  132. {
  133. /* This is a breakpoint */
  134. struct rt_exception_info bkpt_exception = \
  135. { " - undefined instruction",\
  136. ABORT_TYPE_UNDDEF, ABORT_BRKPT_ILL };
  137. do_trap(&bkpt_exception, regs);
  138. iexcept_report &= ~(0xFF);
  139. set_iexcept(iexcept_report);
  140. continue;
  141. }
  142. do_trap(&iexcept_table[iexcept_num], regs);
  143. }
  144. return 0;
  145. }
  146. static struct rt_exception_info eexcept_table[128] = {
  147. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  148. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  149. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  150. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  151. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  152. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  153. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  154. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  155. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  156. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  157. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  158. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  159. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  160. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  161. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  162. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  163. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  164. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  165. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  166. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  167. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  168. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  169. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  170. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  171. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  172. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  173. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  174. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  175. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  176. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  177. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  178. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  179. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  180. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  181. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  182. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  183. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  184. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  185. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  186. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  187. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  188. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  189. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  190. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  191. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  192. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  193. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  194. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  195. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  196. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  197. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  198. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  199. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  200. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  201. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  202. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  203. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  204. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  205. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  206. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  207. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  208. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  209. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  210. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  211. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  212. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  213. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  214. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  215. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  216. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  217. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  218. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  219. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  220. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  221. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  222. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  223. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  224. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  225. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  226. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  227. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  228. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  229. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  230. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  231. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  232. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  233. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  234. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  235. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  236. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  237. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  238. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  239. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  240. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  241. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  242. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  243. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  244. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  245. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  246. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  247. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  248. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  249. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  250. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  251. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  252. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  253. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  254. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  255. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  256. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  257. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  258. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  259. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  260. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  261. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  262. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  263. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  264. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  265. { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
  266. { " - CPU memory protection fault", ABORT_TYPE_MAP, ABORT_BUS_ACCERR },
  267. { " - CPU memory protection fault in L1P", ABORT_TYPE_MAP, ABORT_BUS_ACCERR },
  268. { " - DMA memory protection fault in L1P", ABORT_TYPE_MAP, ABORT_BUS_ACCERR },
  269. { " - CPU memory protection fault in L1D", ABORT_TYPE_MAP, ABORT_BUS_ACCERR },
  270. { " - DMA memory protection fault in L1D", ABORT_TYPE_MAP, ABORT_BUS_ACCERR },
  271. { " - CPU memory protection fault in L2", ABORT_TYPE_MAP, ABORT_BUS_ACCERR },
  272. { " - DMA memory protection fault in L2", ABORT_TYPE_MAP, ABORT_BUS_ACCERR },
  273. { " - EMC CPU memory protection fault", ABORT_TYPE_MAP, ABORT_BUS_ACCERR },
  274. { " - EMC bus error", ABORT_TYPE_MAP, ABORT_BUS_ADDRERR }
  275. };
  276. /*
  277. * Process an external exception (maskable)
  278. */
  279. static void process_eexcept(struct rt_hw_exp_stack_register *regs)
  280. {
  281. int except_num = 0;
  282. int bank = 0;
  283. int i = 0;
  284. for (i = 0; i <= 3; i++)
  285. {
  286. while (INTC_MEXPMASK[i])
  287. {
  288. __dint();
  289. except_num = ffs(INTC_MEXPMASK[i]);
  290. INTC_MEXPMASK[i] &= ~(1 << except_num); /* ack the external exception */
  291. __rint();
  292. do_trap(&eexcept_table[except_num + (bank << 5)], regs);
  293. }
  294. bank++;
  295. }
  296. ack_exception(EXCEPT_TYPE_EXC);
  297. }
  298. extern void hw_nmi_handler(struct rt_hw_exp_stack_register *regs);
  299. /*
  300. * Main exception processing
  301. */
  302. int rt_hw_process_exception(struct rt_hw_exp_stack_register *regs)
  303. {
  304. int type = 0;
  305. int type_num = 0;
  306. int ie_num = 9; /* default is unknown exception */
  307. while ((type = get_except_type()) != 0) {
  308. type_num = fls(type) - 1;
  309. switch(type_num) {
  310. case EXCEPT_TYPE_NXF: /* NMI exception */
  311. ack_exception(EXCEPT_TYPE_NXF); /* clear exception */
  312. if (hw_nmi_handler != RT_NULL)
  313. {
  314. hw_nmi_handler(regs);
  315. }
  316. break;
  317. case EXCEPT_TYPE_IXF: /* internal exception */
  318. if (process_iexcept(regs))
  319. {
  320. return 1;
  321. }
  322. break;
  323. case EXCEPT_TYPE_EXC: /* external exception */
  324. process_eexcept(regs);
  325. break;
  326. case EXCEPT_TYPE_SXF: /* software exception */
  327. ie_num = 8;
  328. ack_exception(type_num);
  329. break;
  330. default: /* clear exception */
  331. ack_exception(type_num);
  332. do_trap(&iexcept_table[ie_num], regs);
  333. break;
  334. }
  335. }
  336. return 0;
  337. }