exception.c 6.1 KB

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