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