Skip to content

Commit 35e78c4

Browse files
Jordan Yatescarlescufi
authored andcommitted
arch: arm: return arm specific fatal error reasons
Return specific fault reasons instead of the generic `K_ERR_CPU_EXCEPTION`, which provides minimal debugging aid. Fixes #53093. Signed-off-by: Jordan Yates <[email protected]>
1 parent 2684c7c commit 35e78c4

File tree

2 files changed

+55
-11
lines changed

2 files changed

+55
-11
lines changed

arch/arm/core/aarch32/cortex_a_r/fault.c

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,41 +48,51 @@ static void dump_debug_event(void)
4848
LOG_ERR("Debug Event (%s)", get_dbgdscr_moe_string(moe));
4949
}
5050

51-
static void dump_fault(uint32_t status, uint32_t addr)
51+
static uint32_t dump_fault(uint32_t status, uint32_t addr)
5252
{
53+
uint32_t reason = K_ERR_CPU_EXCEPTION;
5354
/*
5455
* Dump fault status and, if applicable, tatus-specific information.
5556
* Note that the fault address is only displayed for the synchronous
5657
* faults because it is unpredictable for asynchronous faults.
5758
*/
5859
switch (status) {
5960
case FSR_FS_ALIGNMENT_FAULT:
61+
reason = K_ERR_ARM_ALIGNMENT_FAULT;
6062
LOG_ERR("Alignment Fault @ 0x%08x", addr);
6163
break;
6264
case FSR_FS_BACKGROUND_FAULT:
65+
reason = K_ERR_ARM_BACKGROUND_FAULT;
6366
LOG_ERR("Background Fault @ 0x%08x", addr);
6467
break;
6568
case FSR_FS_PERMISSION_FAULT:
69+
reason = K_ERR_ARM_PERMISSION_FAULT;
6670
LOG_ERR("Permission Fault @ 0x%08x", addr);
6771
break;
6872
case FSR_FS_SYNC_EXTERNAL_ABORT:
73+
reason = K_ERR_ARM_SYNC_EXTERNAL_ABORT;
6974
LOG_ERR("Synchronous External Abort @ 0x%08x", addr);
7075
break;
7176
case FSR_FS_ASYNC_EXTERNAL_ABORT:
77+
reason = K_ERR_ARM_ASYNC_EXTERNAL_ABORT;
7278
LOG_ERR("Asynchronous External Abort");
7379
break;
7480
case FSR_FS_SYNC_PARITY_ERROR:
81+
reason = K_ERR_ARM_SYNC_PARITY_ERROR;
7582
LOG_ERR("Synchronous Parity/ECC Error @ 0x%08x", addr);
7683
break;
7784
case FSR_FS_ASYNC_PARITY_ERROR:
85+
reason = K_ERR_ARM_ASYNC_PARITY_ERROR;
7886
LOG_ERR("Asynchronous Parity/ECC Error");
7987
break;
8088
case FSR_FS_DEBUG_EVENT:
89+
reason = K_ERR_ARM_DEBUG_EVENT;
8190
dump_debug_event();
8291
break;
8392
default:
8493
LOG_ERR("Unknown (%u)", status);
8594
}
95+
return reason;
8696
}
8797
#endif
8898

@@ -185,7 +195,7 @@ bool z_arm_fault_undef_instruction(z_arch_esf_t *esf)
185195
LOG_ERR("***** UNDEFINED INSTRUCTION ABORT *****");
186196

187197
/* Invoke kernel fatal exception handler */
188-
z_arm_fatal_error(K_ERR_CPU_EXCEPTION, esf);
198+
z_arm_fatal_error(K_ERR_ARM_UNDEFINED_INSTRUCTION, esf);
189199

190200
/* All undefined instructions are treated as fatal for now */
191201
return true;
@@ -198,6 +208,8 @@ bool z_arm_fault_undef_instruction(z_arch_esf_t *esf)
198208
*/
199209
bool z_arm_fault_prefetch(z_arch_esf_t *esf)
200210
{
211+
uint32_t reason = K_ERR_CPU_EXCEPTION;
212+
201213
/* Read and parse Instruction Fault Status Register (IFSR) */
202214
uint32_t ifsr = __get_IFSR();
203215
uint32_t fs = ((ifsr & IFSR_FS1_Msk) >> 6) | (ifsr & IFSR_FS0_Msk);
@@ -208,11 +220,11 @@ bool z_arm_fault_prefetch(z_arch_esf_t *esf)
208220
/* Print fault information*/
209221
LOG_ERR("***** PREFETCH ABORT *****");
210222
if (FAULT_DUMP_VERBOSE) {
211-
dump_fault(fs, ifar);
223+
reason = dump_fault(fs, ifar);
212224
}
213225

214226
/* Invoke kernel fatal exception handler */
215-
z_arm_fatal_error(K_ERR_CPU_EXCEPTION, esf);
227+
z_arm_fatal_error(reason, esf);
216228

217229
/* All prefetch aborts are treated as fatal for now */
218230
return true;
@@ -254,6 +266,8 @@ static bool memory_fault_recoverable(z_arch_esf_t *esf)
254266
*/
255267
bool z_arm_fault_data(z_arch_esf_t *esf)
256268
{
269+
uint32_t reason = K_ERR_CPU_EXCEPTION;
270+
257271
/* Read and parse Data Fault Status Register (DFSR) */
258272
uint32_t dfsr = __get_DFSR();
259273
uint32_t fs = ((dfsr & DFSR_FS1_Msk) >> 6) | (dfsr & DFSR_FS0_Msk);
@@ -273,11 +287,11 @@ bool z_arm_fault_data(z_arch_esf_t *esf)
273287
/* Print fault information*/
274288
LOG_ERR("***** DATA ABORT *****");
275289
if (FAULT_DUMP_VERBOSE) {
276-
dump_fault(fs, dfar);
290+
reason = dump_fault(fs, dfar);
277291
}
278292

279293
/* Invoke kernel fatal exception handler */
280-
z_arm_fatal_error(K_ERR_CPU_EXCEPTION, esf);
294+
z_arm_fatal_error(reason, esf);
281295

282296
/* All data aborts are treated as fatal for now */
283297
return true;

arch/arm/core/aarch32/cortex_m/fault.c

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -229,19 +229,22 @@ uint32_t z_check_thread_stack_fail(const uint32_t fault_addr,
229229
static uint32_t mem_manage_fault(z_arch_esf_t *esf, int from_hard_fault,
230230
bool *recoverable)
231231
{
232-
uint32_t reason = K_ERR_CPU_EXCEPTION;
232+
uint32_t reason = K_ERR_ARM_MEM_GENERIC;
233233
uint32_t mmfar = -EINVAL;
234234

235235
PR_FAULT_INFO("***** MPU FAULT *****");
236236

237237
if ((SCB->CFSR & SCB_CFSR_MSTKERR_Msk) != 0) {
238+
reason = K_ERR_ARM_MEM_STACKING;
238239
PR_FAULT_INFO(" Stacking error (context area might be"
239240
" not valid)");
240241
}
241242
if ((SCB->CFSR & SCB_CFSR_MUNSTKERR_Msk) != 0) {
243+
reason = K_ERR_ARM_MEM_UNSTACKING;
242244
PR_FAULT_INFO(" Unstacking error");
243245
}
244246
if ((SCB->CFSR & SCB_CFSR_DACCVIOL_Msk) != 0) {
247+
reason = K_ERR_ARM_MEM_DATA_ACCESS;
245248
PR_FAULT_INFO(" Data Access Violation");
246249
/* In a fault handler, to determine the true faulting address:
247250
* 1. Read and save the MMFAR value.
@@ -263,10 +266,12 @@ static uint32_t mem_manage_fault(z_arch_esf_t *esf, int from_hard_fault,
263266
}
264267
}
265268
if ((SCB->CFSR & SCB_CFSR_IACCVIOL_Msk) != 0) {
269+
reason = K_ERR_ARM_MEM_INSTRUCTION_ACCESS;
266270
PR_FAULT_INFO(" Instruction Access Violation");
267271
}
268272
#if defined(CONFIG_ARMV7_M_ARMV8_M_FP)
269273
if ((SCB->CFSR & SCB_CFSR_MLSPERR_Msk) != 0) {
274+
reason = K_ERR_ARM_MEM_FP_LAZY_STATE_PRESERVATION;
270275
PR_FAULT_INFO(
271276
" Floating-point lazy state preservation error");
272277
}
@@ -382,17 +387,20 @@ static uint32_t mem_manage_fault(z_arch_esf_t *esf, int from_hard_fault,
382387
*/
383388
static int bus_fault(z_arch_esf_t *esf, int from_hard_fault, bool *recoverable)
384389
{
385-
uint32_t reason = K_ERR_CPU_EXCEPTION;
390+
uint32_t reason = K_ERR_ARM_BUS_GENERIC;
386391

387392
PR_FAULT_INFO("***** BUS FAULT *****");
388393

389394
if (SCB->CFSR & SCB_CFSR_STKERR_Msk) {
395+
reason = K_ERR_ARM_BUS_STACKING;
390396
PR_FAULT_INFO(" Stacking error");
391397
}
392398
if (SCB->CFSR & SCB_CFSR_UNSTKERR_Msk) {
399+
reason = K_ERR_ARM_BUS_UNSTACKING;
393400
PR_FAULT_INFO(" Unstacking error");
394401
}
395402
if (SCB->CFSR & SCB_CFSR_PRECISERR_Msk) {
403+
reason = K_ERR_ARM_BUS_PRECISE_DATA_BUS;
396404
PR_FAULT_INFO(" Precise data bus error");
397405
/* In a fault handler, to determine the true faulting address:
398406
* 1. Read and save the BFAR value.
@@ -413,14 +421,17 @@ static int bus_fault(z_arch_esf_t *esf, int from_hard_fault, bool *recoverable)
413421
}
414422
}
415423
if (SCB->CFSR & SCB_CFSR_IMPRECISERR_Msk) {
424+
reason = K_ERR_ARM_BUS_IMPRECISE_DATA_BUS;
416425
PR_FAULT_INFO(" Imprecise data bus error");
417426
}
418427
if ((SCB->CFSR & SCB_CFSR_IBUSERR_Msk) != 0) {
428+
reason = K_ERR_ARM_BUS_INSTRUCTION_BUS;
419429
PR_FAULT_INFO(" Instruction bus error");
420430
#if !defined(CONFIG_ARMV7_M_ARMV8_M_FP)
421431
}
422432
#else
423433
} else if (SCB->CFSR & SCB_CFSR_LSPERR_Msk) {
434+
reason = K_ERR_ARM_BUS_FP_LAZY_STATE_PRESERVATION;
424435
PR_FAULT_INFO(" Floating-point lazy state preservation error");
425436
} else {
426437
;
@@ -538,19 +549,22 @@ static int bus_fault(z_arch_esf_t *esf, int from_hard_fault, bool *recoverable)
538549
*/
539550
static uint32_t usage_fault(const z_arch_esf_t *esf)
540551
{
541-
uint32_t reason = K_ERR_CPU_EXCEPTION;
552+
uint32_t reason = K_ERR_ARM_USAGE_GENERIC;
542553

543554
PR_FAULT_INFO("***** USAGE FAULT *****");
544555

545556
/* bits are sticky: they stack and must be reset */
546557
if ((SCB->CFSR & SCB_CFSR_DIVBYZERO_Msk) != 0) {
558+
reason = K_ERR_ARM_USAGE_DIV_0;
547559
PR_FAULT_INFO(" Division by zero");
548560
}
549561
if ((SCB->CFSR & SCB_CFSR_UNALIGNED_Msk) != 0) {
562+
reason = K_ERR_ARM_USAGE_UNALIGNED_ACCESS;
550563
PR_FAULT_INFO(" Unaligned memory access");
551564
}
552565
#if defined(CONFIG_ARMV8_M_MAINLINE)
553566
if ((SCB->CFSR & SCB_CFSR_STKOF_Msk) != 0) {
567+
reason = K_ERR_ARM_USAGE_STACK_OVERFLOW;
554568
PR_FAULT_INFO(" Stack overflow (context area not valid)");
555569
#if defined(CONFIG_BUILTIN_STACK_GUARD)
556570
/* Stack Overflows are always reported as stack corruption
@@ -565,15 +579,19 @@ static uint32_t usage_fault(const z_arch_esf_t *esf)
565579
}
566580
#endif /* CONFIG_ARMV8_M_MAINLINE */
567581
if ((SCB->CFSR & SCB_CFSR_NOCP_Msk) != 0) {
582+
reason = K_ERR_ARM_USAGE_NO_COPROCESSOR;
568583
PR_FAULT_INFO(" No coprocessor instructions");
569584
}
570585
if ((SCB->CFSR & SCB_CFSR_INVPC_Msk) != 0) {
586+
reason = K_ERR_ARM_USAGE_ILLEGAL_EXC_RETURN;
571587
PR_FAULT_INFO(" Illegal load of EXC_RETURN into PC");
572588
}
573589
if ((SCB->CFSR & SCB_CFSR_INVSTATE_Msk) != 0) {
590+
reason = K_ERR_ARM_USAGE_ILLEGAL_EPSR;
574591
PR_FAULT_INFO(" Illegal use of the EPSR");
575592
}
576593
if ((SCB->CFSR & SCB_CFSR_UNDEFINSTR_Msk) != 0) {
594+
reason = K_ERR_ARM_USAGE_UNDEFINED_INSTRUCTION;
577595
PR_FAULT_INFO(" Attempt to execute undefined instruction");
578596
}
579597

@@ -590,9 +608,12 @@ static uint32_t usage_fault(const z_arch_esf_t *esf)
590608
*
591609
* See z_arm_fault_dump() for example.
592610
*
611+
* @return error code to identify the fatal error reason
593612
*/
594-
static void secure_fault(const z_arch_esf_t *esf)
613+
static uint32_t secure_fault(const z_arch_esf_t *esf)
595614
{
615+
uint32_t reason = K_ERR_ARM_SECURE_GENERIC;
616+
596617
PR_FAULT_INFO("***** SECURE FAULT *****");
597618

598619
STORE_xFAR(sfar, SAU->SFAR);
@@ -602,23 +623,32 @@ static void secure_fault(const z_arch_esf_t *esf)
602623

603624
/* bits are sticky: they stack and must be reset */
604625
if ((SAU->SFSR & SAU_SFSR_INVEP_Msk) != 0) {
626+
reason = K_ERR_ARM_SECURE_ENTRY_POINT;
605627
PR_FAULT_INFO(" Invalid entry point");
606628
} else if ((SAU->SFSR & SAU_SFSR_INVIS_Msk) != 0) {
629+
reason = K_ERR_ARM_SECURE_INTEGRITY_SIGNATURE;
607630
PR_FAULT_INFO(" Invalid integrity signature");
608631
} else if ((SAU->SFSR & SAU_SFSR_INVER_Msk) != 0) {
632+
reason = K_ERR_ARM_SECURE_EXCEPTION_RETURN;
609633
PR_FAULT_INFO(" Invalid exception return");
610634
} else if ((SAU->SFSR & SAU_SFSR_AUVIOL_Msk) != 0) {
635+
reason = K_ERR_ARM_SECURE_ATTRIBUTION_UNIT;
611636
PR_FAULT_INFO(" Attribution unit violation");
612637
} else if ((SAU->SFSR & SAU_SFSR_INVTRAN_Msk) != 0) {
638+
reason = K_ERR_ARM_SECURE_TRANSITION;
613639
PR_FAULT_INFO(" Invalid transition");
614640
} else if ((SAU->SFSR & SAU_SFSR_LSPERR_Msk) != 0) {
641+
reason = K_ERR_ARM_SECURE_LAZY_STATE_PRESERVATION;
615642
PR_FAULT_INFO(" Lazy state preservation");
616643
} else if ((SAU->SFSR & SAU_SFSR_LSERR_Msk) != 0) {
644+
reason = K_ERR_ARM_SECURE_LAZY_STATE_ERROR;
617645
PR_FAULT_INFO(" Lazy state error");
618646
}
619647

620648
/* clear SFSR sticky bits */
621649
SAU->SFSR |= 0xFF;
650+
651+
return reason;
622652
}
623653
#endif /* defined(CONFIG_ARM_SECURE_FIRMWARE) */
624654

@@ -748,7 +778,7 @@ static uint32_t hard_fault(z_arch_esf_t *esf, bool *recoverable)
748778
reason = usage_fault(esf);
749779
#if defined(CONFIG_ARM_SECURE_FIRMWARE)
750780
} else if (SAU->SFSR != 0) {
751-
secure_fault(esf);
781+
reason = secure_fault(esf);
752782
#endif /* CONFIG_ARM_SECURE_FIRMWARE */
753783
} else {
754784
__ASSERT(0,

0 commit comments

Comments
 (0)