exception.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. #include "rtthread.h"
  2. static void data_abort(unsigned long far, unsigned long iss)
  3. {
  4. rt_kprintf("fault addr = 0x%016lx\n", far);
  5. if (iss & 0x40)
  6. {
  7. rt_kprintf("abort caused by write instruction\n");
  8. }
  9. else
  10. {
  11. rt_kprintf("abort caused by read instruction\n");
  12. }
  13. switch (iss & 0x3f)
  14. {
  15. case 0b000000:
  16. rt_kprintf("Address size fault, zeroth level of translation or translation table base register\n");
  17. break;
  18. case 0b000001:
  19. rt_kprintf("Address size fault, first level\n");
  20. break;
  21. case 0b000010:
  22. rt_kprintf("Address size fault, second level\n");
  23. break;
  24. case 0b000011:
  25. rt_kprintf("Address size fault, third level\n");
  26. break;
  27. case 0b000100:
  28. rt_kprintf("Translation fault, zeroth level\n");
  29. break;
  30. case 0b000101:
  31. rt_kprintf("Translation fault, first level\n");
  32. break;
  33. case 0b000110:
  34. rt_kprintf("Translation fault, second level\n");
  35. break;
  36. case 0b000111:
  37. rt_kprintf("Translation fault, third level\n");
  38. break;
  39. case 0b001001:
  40. rt_kprintf("Access flag fault, first level\n");
  41. break;
  42. case 0b001010:
  43. rt_kprintf("Access flag fault, second level\n");
  44. break;
  45. case 0b001011:
  46. rt_kprintf("Access flag fault, third level\n");
  47. break;
  48. case 0b001101:
  49. rt_kprintf("Permission fault, first level\n");
  50. break;
  51. case 0b001110:
  52. rt_kprintf("Permission fault, second level\n");
  53. break;
  54. case 0b001111:
  55. rt_kprintf("Permission fault, third level\n");
  56. break;
  57. case 0b010000:
  58. rt_kprintf("Synchronous external abort, not on translation table walk\n");
  59. break;
  60. case 0b011000:
  61. rt_kprintf("Synchronous parity or ECC error on memory access, not on translation table walk\n");
  62. break;
  63. case 0b010100:
  64. rt_kprintf("Synchronous external abort on translation table walk, zeroth level\n");
  65. break;
  66. case 0b010101:
  67. rt_kprintf("Synchronous external abort on translation table walk, first level\n");
  68. break;
  69. case 0b010110:
  70. rt_kprintf("Synchronous external abort on translation table walk, second level\n");
  71. break;
  72. case 0b010111:
  73. rt_kprintf("Synchronous external abort on translation table walk, third level\n");
  74. break;
  75. case 0b011100:
  76. rt_kprintf("Synchronous parity or ECC error on memory access on translation table walk, zeroth level\n");
  77. break;
  78. case 0b011101:
  79. rt_kprintf("Synchronous parity or ECC error on memory access on translation table walk, first level\n");
  80. break;
  81. case 0b011110:
  82. rt_kprintf("Synchronous parity or ECC error on memory access on translation table walk, second level\n");
  83. break;
  84. case 0b011111:
  85. rt_kprintf("Synchronous parity or ECC error on memory access on translation table walk, third level\n");
  86. break;
  87. case 0b100001:
  88. rt_kprintf("Alignment fault\n");
  89. break;
  90. case 0b110000:
  91. rt_kprintf("TLB conflict abort\n");
  92. break;
  93. case 0b110100:
  94. rt_kprintf("IMPLEMENTATION DEFINED fault (Lockdown fault)\n");
  95. break;
  96. case 0b110101:
  97. rt_kprintf("IMPLEMENTATION DEFINED fault (Unsupported Exclusive access fault)\n");
  98. break;
  99. case 0b111101:
  100. rt_kprintf("Section Domain Fault, used only for faults reported in the PAR_EL1\n");
  101. break;
  102. case 0b111110:
  103. rt_kprintf("Page Domain Fault, used only for faults reported in the PAR_EL1\n");
  104. break;
  105. default:
  106. rt_kprintf("unknow abort\n");
  107. break;
  108. }
  109. }
  110. void process_exception(unsigned long esr, unsigned long epc)
  111. {
  112. rt_uint8_t ec;
  113. rt_uint32_t iss;
  114. unsigned long fault_addr;
  115. rt_kprintf("\nexception info:\n");
  116. ec = (unsigned char)((esr >> 26) & 0x3fU);
  117. iss = (unsigned int)(esr & 0x00ffffffU);
  118. rt_kprintf("esr.EC :0x%02x\n", ec);
  119. rt_kprintf("esr.IL :0x%02x\n", (unsigned char)((esr >> 25) & 0x01U));
  120. rt_kprintf("esr.ISS:0x%08x\n", iss);
  121. rt_kprintf("epc :0x%016p\n", (void *)epc);
  122. switch (ec)
  123. {
  124. case 0x00:
  125. rt_kprintf("Exceptions with an unknow reason\n");
  126. break;
  127. case 0x01:
  128. rt_kprintf("Exceptions from an WFI or WFE instruction\n");
  129. break;
  130. case 0x03:
  131. rt_kprintf("Exceptions from an MCR or MRC access to CP15 from AArch32\n");
  132. break;
  133. case 0x04:
  134. rt_kprintf("Exceptions from an MCRR or MRRC access to CP15 from AArch32\n");
  135. break;
  136. case 0x05:
  137. rt_kprintf("Exceptions from an MCR or MRC access to CP14 from AArch32\n");
  138. break;
  139. case 0x06:
  140. rt_kprintf("Exceptions from an LDC or STC access to CP14 from AArch32\n");
  141. break;
  142. case 0x07:
  143. rt_kprintf("Exceptions from Access to Advanced SIMD or floating-point registers\n");
  144. break;
  145. case 0x08:
  146. rt_kprintf("Exceptions from an MRC (or VMRS) access to CP10 from AArch32\n");
  147. break;
  148. case 0x0c:
  149. rt_kprintf("Exceptions from an MCRR or MRRC access to CP14 from AArch32\n");
  150. break;
  151. case 0x0e:
  152. rt_kprintf("Exceptions that occur because ther value of PSTATE.IL is 1\n");
  153. break;
  154. case 0x11:
  155. rt_kprintf("SVC call from AArch32 state\n");
  156. break;
  157. case 0x15:
  158. rt_kprintf("SVC call from AArch64 state\n");
  159. break;
  160. case 0x20:
  161. rt_kprintf("Instruction abort from lower exception level\n");
  162. break;
  163. case 0x21:
  164. rt_kprintf("Instruction abort from current exception level\n");
  165. break;
  166. case 0x22:
  167. rt_kprintf("PC alignment fault\n");
  168. break;
  169. case 0x24:
  170. rt_kprintf("Data abort from a lower Exception level\n");
  171. __asm__ volatile("mrs %0, far_el1":"=r"(fault_addr));
  172. data_abort(fault_addr, iss);
  173. break;
  174. case 0x25:
  175. rt_kprintf("Data abort\n");
  176. __asm__ volatile("mrs %0, far_el1":"=r"(fault_addr));
  177. data_abort(fault_addr, iss);
  178. break;
  179. default:
  180. rt_kprintf("Other error\n");
  181. break;
  182. }
  183. }