|
20 | 20 | LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL);
|
21 | 21 |
|
22 | 22 | extern char xtensa_arch_except_epc[];
|
| 23 | +extern char xtensa_arch_kernel_oops_epc[]; |
23 | 24 |
|
24 | 25 | #ifdef CONFIG_USERSPACE
|
25 | 26 | Z_EXC_DECLARE(z_xtensa_user_string_nlen);
|
@@ -202,11 +203,12 @@ static inline unsigned int get_bits(int offset, int num_bits, unsigned int val)
|
202 | 203 | return val & mask;
|
203 | 204 | }
|
204 | 205 |
|
205 |
| -static void print_fatal_exception(_xtensa_irq_bsa_t *bsa, int cause, |
| 206 | +static void print_fatal_exception(void *print_stack, int cause, |
206 | 207 | bool is_dblexc, uint32_t depc)
|
207 | 208 | {
|
208 | 209 | void *pc;
|
209 | 210 | uint32_t ps, vaddr;
|
| 211 | + _xtensa_irq_bsa_t *bsa = (void *)*(int **)print_stack; |
210 | 212 |
|
211 | 213 | ps = bsa->ps;
|
212 | 214 | pc = (void *)bsa->pc;
|
@@ -334,7 +336,7 @@ void *xtensa_excint1_c(int *interrupted_stack)
|
334 | 336 | bool is_fatal_error = false;
|
335 | 337 | bool is_dblexc = false;
|
336 | 338 | uint32_t ps;
|
337 |
| - void *pc; |
| 339 | + void *pc, *print_stack = (void *)interrupted_stack; |
338 | 340 | uint32_t depc = 0;
|
339 | 341 |
|
340 | 342 | __asm__ volatile("rsr.exccause %0" : "=r"(cause));
|
@@ -399,22 +401,40 @@ void *xtensa_excint1_c(int *interrupted_stack)
|
399 | 401 | * We assign EXCCAUSE the unused, reserved code 63; this may be
|
400 | 402 | * problematic if the app or new boards also decide to repurpose
|
401 | 403 | * this code.
|
| 404 | + * |
| 405 | + * Another intentionally ill is from xtensa_arch_kernel_oops. |
| 406 | + * Kernel OOPS has to be explicity raised so we can simply |
| 407 | + * set the reason and continue. |
402 | 408 | */
|
403 |
| - if ((pc == (void *) &xtensa_arch_except_epc) && (cause == 0)) { |
404 |
| - cause = 63; |
405 |
| - __asm__ volatile("wsr.exccause %0" : : "r"(cause)); |
406 |
| - reason = bsa->a2; |
| 409 | + if (cause == EXCCAUSE_ILLEGAL) { |
| 410 | + if (pc == (void *)&xtensa_arch_except_epc) { |
| 411 | + cause = 63; |
| 412 | + __asm__ volatile("wsr.exccause %0" : : "r"(cause)); |
| 413 | + reason = bsa->a2; |
| 414 | + } else if (pc == (void *)&xtensa_arch_kernel_oops_epc) { |
| 415 | + cause = 64; /* kernel oops */ |
| 416 | + reason = K_ERR_KERNEL_OOPS; |
| 417 | + |
| 418 | + /* A3 contains the second argument to |
| 419 | + * xtensa_arch_kernel_oops(reason, ssf) |
| 420 | + * where ssf is the stack frame causing |
| 421 | + * the kernel oops. |
| 422 | + */ |
| 423 | + print_stack = (void *)bsa->a3; |
| 424 | + } |
407 | 425 | }
|
408 | 426 |
|
409 |
| - print_fatal_exception(bsa, cause, is_dblexc, depc); |
| 427 | + if (reason != K_ERR_KERNEL_OOPS) { |
| 428 | + print_fatal_exception(print_stack, cause, is_dblexc, depc); |
| 429 | + } |
410 | 430 |
|
411 | 431 | /* FIXME: legacy xtensa port reported "HW" exception
|
412 | 432 | * for all unhandled exceptions, which seems incorrect
|
413 | 433 | * as these are software errors. Should clean this
|
414 | 434 | * up.
|
415 | 435 | */
|
416 | 436 | z_xtensa_fatal_error(reason,
|
417 |
| - (void *)interrupted_stack); |
| 437 | + (void *)print_stack); |
418 | 438 | break;
|
419 | 439 | }
|
420 | 440 |
|
|
0 commit comments