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
11 #include "trap.h"
12 #include "c66xx.h"
13
14 #include <rthw.h>
15 #include <rtdef.h>
16 #include <rtthread.h>
17
18 #define RT_SYS_STACK_SIZE 4096
19
20 rt_uint8_t rt_system_stack[RT_SYS_STACK_SIZE];
21 rt_uint8_t *rt_system_stack_top;
22
rt_trap_init(void)23 void rt_trap_init(void)
24 {
25 rt_system_stack_top = &rt_system_stack[RT_SYS_STACK_SIZE-1];
26 rt_system_stack_top = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)rt_system_stack_top, 8);
27
28 ack_exception(EXCEPT_TYPE_NXF);
29 ack_exception(EXCEPT_TYPE_EXC);
30 ack_exception(EXCEPT_TYPE_IXF);
31 ack_exception(EXCEPT_TYPE_SXF);
32 rt_hw_enable_exception();
33 }
34
show_regs(struct rt_hw_exp_stack_register * regs)35 void show_regs(struct rt_hw_exp_stack_register *regs)
36 {
37 rt_kprintf("\n");
38 rt_kprintf("PC: %08lx SP: %08lx\n",
39 regs->pc, regs->hw_register.sp);
40 rt_kprintf("Status: %08lx ORIG_A4: %08lx\n",
41 regs->csr, regs->orig_a4);
42 rt_kprintf("A0: %08lx B0: %08lx\n",
43 regs->hw_register.a0, regs->hw_register.b0);
44 rt_kprintf("A1: %08lx B1: %08lx\n",
45 regs->hw_register.a1, regs->hw_register.b1);
46 rt_kprintf("A2: %08lx B2: %08lx\n",
47 regs->hw_register.a2, regs->hw_register.b2);
48 rt_kprintf("A3: %08lx B3: %08lx\n",
49 regs->hw_register.a3, regs->hw_register.b3);
50 rt_kprintf("A4: %08lx B4: %08lx\n",
51 regs->hw_register.a4, regs->hw_register.b4);
52 rt_kprintf("A5: %08lx B5: %08lx\n",
53 regs->hw_register.a5, regs->hw_register.b5);
54 rt_kprintf("A6: %08lx B6: %08lx\n",
55 regs->hw_register.a6, regs->hw_register.b6);
56 rt_kprintf("A7: %08lx B7: %08lx\n",
57 regs->hw_register.a7, regs->hw_register.b7);
58 rt_kprintf("A8: %08lx B8: %08lx\n",
59 regs->hw_register.a8, regs->hw_register.b8);
60 rt_kprintf("A9: %08lx B9: %08lx\n",
61 regs->hw_register.a9, regs->hw_register.b9);
62 rt_kprintf("A10: %08lx B10: %08lx\n",
63 regs->hw_register.a10, regs->hw_register.b10);
64 rt_kprintf("A11: %08lx B11: %08lx\n",
65 regs->hw_register.a11, regs->hw_register.b11);
66 rt_kprintf("A12: %08lx B12: %08lx\n",
67 regs->hw_register.a12, regs->hw_register.b12);
68 rt_kprintf("A13: %08lx B13: %08lx\n",
69 regs->hw_register.a13, regs->hw_register.b13);
70 rt_kprintf("A14: %08lx B14: %08lx\n",
71 regs->hw_register.a14, regs->hw_register.dp);
72 rt_kprintf("A15: %08lx B15: %08lx\n",
73 regs->hw_register.a15, regs->hw_register.sp);
74 rt_kprintf("A16: %08lx B16: %08lx\n",
75 regs->hw_register.a16, regs->hw_register.b16);
76 rt_kprintf("A17: %08lx B17: %08lx\n",
77 regs->hw_register.a17, regs->hw_register.b17);
78 rt_kprintf("A18: %08lx B18: %08lx\n",
79 regs->hw_register.a18, regs->hw_register.b18);
80 rt_kprintf("A19: %08lx B19: %08lx\n",
81 regs->hw_register.a19, regs->hw_register.b19);
82 rt_kprintf("A20: %08lx B20: %08lx\n",
83 regs->hw_register.a20, regs->hw_register.b20);
84 rt_kprintf("A21: %08lx B21: %08lx\n",
85 regs->hw_register.a21, regs->hw_register.b21);
86 rt_kprintf("A22: %08lx B22: %08lx\n",
87 regs->hw_register.a22, regs->hw_register.b22);
88 rt_kprintf("A23: %08lx B23: %08lx\n",
89 regs->hw_register.a23, regs->hw_register.b23);
90 rt_kprintf("A24: %08lx B24: %08lx\n",
91 regs->hw_register.a24, regs->hw_register.b24);
92 rt_kprintf("A25: %08lx B25: %08lx\n",
93 regs->hw_register.a25, regs->hw_register.b25);
94 rt_kprintf("A26: %08lx B26: %08lx\n",
95 regs->hw_register.a26, regs->hw_register.b26);
96 rt_kprintf("A27: %08lx B27: %08lx\n",
97 regs->hw_register.a27, regs->hw_register.b27);
98 rt_kprintf("A28: %08lx B28: %08lx\n",
99 regs->hw_register.a28, regs->hw_register.b28);
100 rt_kprintf("A29: %08lx B29: %08lx\n",
101 regs->hw_register.a29, regs->hw_register.b29);
102 rt_kprintf("A30: %08lx B30: %08lx\n",
103 regs->hw_register.a30, regs->hw_register.b30);
104 rt_kprintf("A31: %08lx B31: %08lx\n",
105 regs->hw_register.a31, regs->hw_register.b31);
106 }
107
do_trap(struct rt_exception_info * except_info,struct rt_hw_exp_stack_register * regs)108 void do_trap(struct rt_exception_info *except_info, struct rt_hw_exp_stack_register *regs)
109 {
110 rt_kprintf("Enter exception: %s\n", except_info->kernel_str);
111
112 show_regs(regs);
113
114 for(;;){}
115 }
116
117 static struct rt_exception_info iexcept_table[10] = {
118 { " - instruction fetch", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
119 { " - fetch packet", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
120 { " - execute packet", ABORT_TYPE_UNDDEF, ABORT_OPCODE_ILL },
121 { " - undefined instruction", ABORT_TYPE_UNDDEF, ABORT_OPCODE_ILL },
122 { " - resource conflict", ABORT_TYPE_UNDDEF, ABORT_OPCODE_ILL },
123 { " - resource access", ABORT_TYPE_UNDDEF, ABORT_PRVREG_ILL },
124 { " - privilege", ABORT_TYPE_UNDDEF, ABORT_PRVOPC_ILL },
125 { " - loops buffer", ABORT_TYPE_UNDDEF, ABORT_PRVOPC_ILL },
126 { " - software exception", ABORT_TYPE_UNDDEF, ABORT_ILLTRP_ILL },
127 { " - unknown exception", ABORT_TYPE_UNDDEF, ABORT_PRVOPC_ILL }
128 };
129
130 /*
131 * Process an internal exception (non maskable)
132 */
process_iexcept(struct rt_hw_exp_stack_register * regs)133 static int process_iexcept(struct rt_hw_exp_stack_register *regs)
134 {
135 unsigned int iexcept_report = get_iexcept();
136 unsigned int iexcept_num = 0;
137
138 ack_exception(EXCEPT_TYPE_IXF);
139
140 while(iexcept_report)
141 {
142 iexcept_num = ffs(iexcept_report);
143 iexcept_report &= ~(1 << iexcept_num);
144 set_iexcept(iexcept_report);
145
146 if (*(unsigned int *)regs->pc == BKPT_OPCODE)
147 {
148 /* This is a breakpoint */
149 struct rt_exception_info bkpt_exception = \
150 { " - undefined instruction",\
151 ABORT_TYPE_UNDDEF, ABORT_BRKPT_ILL };
152 do_trap(&bkpt_exception, regs);
153 iexcept_report &= ~(0xFF);
154 set_iexcept(iexcept_report);
155 continue;
156 }
157 do_trap(&iexcept_table[iexcept_num], regs);
158 }
159 return 0;
160 }
161
162 static struct rt_exception_info eexcept_table[128] = {
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
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
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
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 { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
267 { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
268 { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
269 { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
270 { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
271 { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
272 { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
273 { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
274 { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
275 { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
276 { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
277 { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
278 { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
279 { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
280 { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
281 { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
282 { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
283 { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
284 { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR },
285
286 { " - CPU memory protection fault", ABORT_TYPE_MAP, ABORT_BUS_ACCERR },
287 { " - CPU memory protection fault in L1P", ABORT_TYPE_MAP, ABORT_BUS_ACCERR },
288 { " - DMA memory protection fault in L1P", ABORT_TYPE_MAP, ABORT_BUS_ACCERR },
289 { " - CPU memory protection fault in L1D", ABORT_TYPE_MAP, ABORT_BUS_ACCERR },
290 { " - DMA memory protection fault in L1D", ABORT_TYPE_MAP, ABORT_BUS_ACCERR },
291 { " - CPU memory protection fault in L2", ABORT_TYPE_MAP, ABORT_BUS_ACCERR },
292 { " - DMA memory protection fault in L2", ABORT_TYPE_MAP, ABORT_BUS_ACCERR },
293 { " - EMC CPU memory protection fault", ABORT_TYPE_MAP, ABORT_BUS_ACCERR },
294 { " - EMC bus error", ABORT_TYPE_MAP, ABORT_BUS_ADDRERR }
295 };
296
297 /*
298 * Process an external exception (maskable)
299 */
process_eexcept(struct rt_hw_exp_stack_register * regs)300 static void process_eexcept(struct rt_hw_exp_stack_register *regs)
301 {
302 int except_num = 0;
303 int bank = 0;
304 int i = 0;
305
306 for (i = 0; i <= 3; i++)
307 {
308 while (INTC_MEXPMASK[i])
309 {
310 __dint();
311 except_num = ffs(INTC_MEXPMASK[i]);
312 INTC_MEXPMASK[i] &= ~(1 << except_num); /* ack the external exception */
313 __rint();
314 do_trap(&eexcept_table[except_num + (bank << 5)], regs);
315 }
316 bank++;
317 }
318
319 ack_exception(EXCEPT_TYPE_EXC);
320 }
321
322 extern void hw_nmi_handler(struct rt_hw_exp_stack_register *regs);
323 /*
324 * Main exception processing
325 */
rt_hw_process_exception(struct rt_hw_exp_stack_register * regs)326 int rt_hw_process_exception(struct rt_hw_exp_stack_register *regs)
327 {
328 int type = 0;
329 int type_num = 0;
330 int ie_num = 9; /* default is unknown exception */
331
332 while ((type = get_except_type()) != 0) {
333 type_num = fls(type) - 1;
334
335 switch(type_num) {
336 case EXCEPT_TYPE_NXF: /* NMI exception */
337 ack_exception(EXCEPT_TYPE_NXF); /* clear exception */
338 if (hw_nmi_handler != RT_NULL)
339 {
340 hw_nmi_handler(regs);
341 }
342 break;
343
344 case EXCEPT_TYPE_IXF: /* internal exception */
345 if (process_iexcept(regs))
346 {
347 return 1;
348 }
349 break;
350
351 case EXCEPT_TYPE_EXC: /* external exception */
352 process_eexcept(regs);
353 break;
354
355 case EXCEPT_TYPE_SXF: /* software exception */
356 ie_num = 8;
357 ack_exception(type_num);
358 break;
359 default: /* clear exception */
360 ack_exception(type_num);
361 do_trap(&iexcept_table[ie_num], regs);
362 break;
363 }
364 }
365 return 0;
366 }
367
368