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