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 <jordan.yates@data61.csiro.au>
This commit is contained in:
parent
2684c7ca78
commit
35e78c4502
2 changed files with 55 additions and 11 deletions
|
@ -48,8 +48,9 @@ static void dump_debug_event(void)
|
||||||
LOG_ERR("Debug Event (%s)", get_dbgdscr_moe_string(moe));
|
LOG_ERR("Debug Event (%s)", get_dbgdscr_moe_string(moe));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dump_fault(uint32_t status, uint32_t addr)
|
static uint32_t dump_fault(uint32_t status, uint32_t addr)
|
||||||
{
|
{
|
||||||
|
uint32_t reason = K_ERR_CPU_EXCEPTION;
|
||||||
/*
|
/*
|
||||||
* Dump fault status and, if applicable, tatus-specific information.
|
* Dump fault status and, if applicable, tatus-specific information.
|
||||||
* Note that the fault address is only displayed for the synchronous
|
* Note that the fault address is only displayed for the synchronous
|
||||||
|
@ -57,32 +58,41 @@ static void dump_fault(uint32_t status, uint32_t addr)
|
||||||
*/
|
*/
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case FSR_FS_ALIGNMENT_FAULT:
|
case FSR_FS_ALIGNMENT_FAULT:
|
||||||
|
reason = K_ERR_ARM_ALIGNMENT_FAULT;
|
||||||
LOG_ERR("Alignment Fault @ 0x%08x", addr);
|
LOG_ERR("Alignment Fault @ 0x%08x", addr);
|
||||||
break;
|
break;
|
||||||
case FSR_FS_BACKGROUND_FAULT:
|
case FSR_FS_BACKGROUND_FAULT:
|
||||||
|
reason = K_ERR_ARM_BACKGROUND_FAULT;
|
||||||
LOG_ERR("Background Fault @ 0x%08x", addr);
|
LOG_ERR("Background Fault @ 0x%08x", addr);
|
||||||
break;
|
break;
|
||||||
case FSR_FS_PERMISSION_FAULT:
|
case FSR_FS_PERMISSION_FAULT:
|
||||||
|
reason = K_ERR_ARM_PERMISSION_FAULT;
|
||||||
LOG_ERR("Permission Fault @ 0x%08x", addr);
|
LOG_ERR("Permission Fault @ 0x%08x", addr);
|
||||||
break;
|
break;
|
||||||
case FSR_FS_SYNC_EXTERNAL_ABORT:
|
case FSR_FS_SYNC_EXTERNAL_ABORT:
|
||||||
|
reason = K_ERR_ARM_SYNC_EXTERNAL_ABORT;
|
||||||
LOG_ERR("Synchronous External Abort @ 0x%08x", addr);
|
LOG_ERR("Synchronous External Abort @ 0x%08x", addr);
|
||||||
break;
|
break;
|
||||||
case FSR_FS_ASYNC_EXTERNAL_ABORT:
|
case FSR_FS_ASYNC_EXTERNAL_ABORT:
|
||||||
|
reason = K_ERR_ARM_ASYNC_EXTERNAL_ABORT;
|
||||||
LOG_ERR("Asynchronous External Abort");
|
LOG_ERR("Asynchronous External Abort");
|
||||||
break;
|
break;
|
||||||
case FSR_FS_SYNC_PARITY_ERROR:
|
case FSR_FS_SYNC_PARITY_ERROR:
|
||||||
|
reason = K_ERR_ARM_SYNC_PARITY_ERROR;
|
||||||
LOG_ERR("Synchronous Parity/ECC Error @ 0x%08x", addr);
|
LOG_ERR("Synchronous Parity/ECC Error @ 0x%08x", addr);
|
||||||
break;
|
break;
|
||||||
case FSR_FS_ASYNC_PARITY_ERROR:
|
case FSR_FS_ASYNC_PARITY_ERROR:
|
||||||
|
reason = K_ERR_ARM_ASYNC_PARITY_ERROR;
|
||||||
LOG_ERR("Asynchronous Parity/ECC Error");
|
LOG_ERR("Asynchronous Parity/ECC Error");
|
||||||
break;
|
break;
|
||||||
case FSR_FS_DEBUG_EVENT:
|
case FSR_FS_DEBUG_EVENT:
|
||||||
|
reason = K_ERR_ARM_DEBUG_EVENT;
|
||||||
dump_debug_event();
|
dump_debug_event();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG_ERR("Unknown (%u)", status);
|
LOG_ERR("Unknown (%u)", status);
|
||||||
}
|
}
|
||||||
|
return reason;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -185,7 +195,7 @@ bool z_arm_fault_undef_instruction(z_arch_esf_t *esf)
|
||||||
LOG_ERR("***** UNDEFINED INSTRUCTION ABORT *****");
|
LOG_ERR("***** UNDEFINED INSTRUCTION ABORT *****");
|
||||||
|
|
||||||
/* Invoke kernel fatal exception handler */
|
/* Invoke kernel fatal exception handler */
|
||||||
z_arm_fatal_error(K_ERR_CPU_EXCEPTION, esf);
|
z_arm_fatal_error(K_ERR_ARM_UNDEFINED_INSTRUCTION, esf);
|
||||||
|
|
||||||
/* All undefined instructions are treated as fatal for now */
|
/* All undefined instructions are treated as fatal for now */
|
||||||
return true;
|
return true;
|
||||||
|
@ -198,6 +208,8 @@ bool z_arm_fault_undef_instruction(z_arch_esf_t *esf)
|
||||||
*/
|
*/
|
||||||
bool z_arm_fault_prefetch(z_arch_esf_t *esf)
|
bool z_arm_fault_prefetch(z_arch_esf_t *esf)
|
||||||
{
|
{
|
||||||
|
uint32_t reason = K_ERR_CPU_EXCEPTION;
|
||||||
|
|
||||||
/* Read and parse Instruction Fault Status Register (IFSR) */
|
/* Read and parse Instruction Fault Status Register (IFSR) */
|
||||||
uint32_t ifsr = __get_IFSR();
|
uint32_t ifsr = __get_IFSR();
|
||||||
uint32_t fs = ((ifsr & IFSR_FS1_Msk) >> 6) | (ifsr & IFSR_FS0_Msk);
|
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)
|
||||||
/* Print fault information*/
|
/* Print fault information*/
|
||||||
LOG_ERR("***** PREFETCH ABORT *****");
|
LOG_ERR("***** PREFETCH ABORT *****");
|
||||||
if (FAULT_DUMP_VERBOSE) {
|
if (FAULT_DUMP_VERBOSE) {
|
||||||
dump_fault(fs, ifar);
|
reason = dump_fault(fs, ifar);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Invoke kernel fatal exception handler */
|
/* Invoke kernel fatal exception handler */
|
||||||
z_arm_fatal_error(K_ERR_CPU_EXCEPTION, esf);
|
z_arm_fatal_error(reason, esf);
|
||||||
|
|
||||||
/* All prefetch aborts are treated as fatal for now */
|
/* All prefetch aborts are treated as fatal for now */
|
||||||
return true;
|
return true;
|
||||||
|
@ -254,6 +266,8 @@ static bool memory_fault_recoverable(z_arch_esf_t *esf)
|
||||||
*/
|
*/
|
||||||
bool z_arm_fault_data(z_arch_esf_t *esf)
|
bool z_arm_fault_data(z_arch_esf_t *esf)
|
||||||
{
|
{
|
||||||
|
uint32_t reason = K_ERR_CPU_EXCEPTION;
|
||||||
|
|
||||||
/* Read and parse Data Fault Status Register (DFSR) */
|
/* Read and parse Data Fault Status Register (DFSR) */
|
||||||
uint32_t dfsr = __get_DFSR();
|
uint32_t dfsr = __get_DFSR();
|
||||||
uint32_t fs = ((dfsr & DFSR_FS1_Msk) >> 6) | (dfsr & DFSR_FS0_Msk);
|
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)
|
||||||
/* Print fault information*/
|
/* Print fault information*/
|
||||||
LOG_ERR("***** DATA ABORT *****");
|
LOG_ERR("***** DATA ABORT *****");
|
||||||
if (FAULT_DUMP_VERBOSE) {
|
if (FAULT_DUMP_VERBOSE) {
|
||||||
dump_fault(fs, dfar);
|
reason = dump_fault(fs, dfar);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Invoke kernel fatal exception handler */
|
/* Invoke kernel fatal exception handler */
|
||||||
z_arm_fatal_error(K_ERR_CPU_EXCEPTION, esf);
|
z_arm_fatal_error(reason, esf);
|
||||||
|
|
||||||
/* All data aborts are treated as fatal for now */
|
/* All data aborts are treated as fatal for now */
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -229,19 +229,22 @@ uint32_t z_check_thread_stack_fail(const uint32_t fault_addr,
|
||||||
static uint32_t mem_manage_fault(z_arch_esf_t *esf, int from_hard_fault,
|
static uint32_t mem_manage_fault(z_arch_esf_t *esf, int from_hard_fault,
|
||||||
bool *recoverable)
|
bool *recoverable)
|
||||||
{
|
{
|
||||||
uint32_t reason = K_ERR_CPU_EXCEPTION;
|
uint32_t reason = K_ERR_ARM_MEM_GENERIC;
|
||||||
uint32_t mmfar = -EINVAL;
|
uint32_t mmfar = -EINVAL;
|
||||||
|
|
||||||
PR_FAULT_INFO("***** MPU FAULT *****");
|
PR_FAULT_INFO("***** MPU FAULT *****");
|
||||||
|
|
||||||
if ((SCB->CFSR & SCB_CFSR_MSTKERR_Msk) != 0) {
|
if ((SCB->CFSR & SCB_CFSR_MSTKERR_Msk) != 0) {
|
||||||
|
reason = K_ERR_ARM_MEM_STACKING;
|
||||||
PR_FAULT_INFO(" Stacking error (context area might be"
|
PR_FAULT_INFO(" Stacking error (context area might be"
|
||||||
" not valid)");
|
" not valid)");
|
||||||
}
|
}
|
||||||
if ((SCB->CFSR & SCB_CFSR_MUNSTKERR_Msk) != 0) {
|
if ((SCB->CFSR & SCB_CFSR_MUNSTKERR_Msk) != 0) {
|
||||||
|
reason = K_ERR_ARM_MEM_UNSTACKING;
|
||||||
PR_FAULT_INFO(" Unstacking error");
|
PR_FAULT_INFO(" Unstacking error");
|
||||||
}
|
}
|
||||||
if ((SCB->CFSR & SCB_CFSR_DACCVIOL_Msk) != 0) {
|
if ((SCB->CFSR & SCB_CFSR_DACCVIOL_Msk) != 0) {
|
||||||
|
reason = K_ERR_ARM_MEM_DATA_ACCESS;
|
||||||
PR_FAULT_INFO(" Data Access Violation");
|
PR_FAULT_INFO(" Data Access Violation");
|
||||||
/* In a fault handler, to determine the true faulting address:
|
/* In a fault handler, to determine the true faulting address:
|
||||||
* 1. Read and save the MMFAR value.
|
* 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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((SCB->CFSR & SCB_CFSR_IACCVIOL_Msk) != 0) {
|
if ((SCB->CFSR & SCB_CFSR_IACCVIOL_Msk) != 0) {
|
||||||
|
reason = K_ERR_ARM_MEM_INSTRUCTION_ACCESS;
|
||||||
PR_FAULT_INFO(" Instruction Access Violation");
|
PR_FAULT_INFO(" Instruction Access Violation");
|
||||||
}
|
}
|
||||||
#if defined(CONFIG_ARMV7_M_ARMV8_M_FP)
|
#if defined(CONFIG_ARMV7_M_ARMV8_M_FP)
|
||||||
if ((SCB->CFSR & SCB_CFSR_MLSPERR_Msk) != 0) {
|
if ((SCB->CFSR & SCB_CFSR_MLSPERR_Msk) != 0) {
|
||||||
|
reason = K_ERR_ARM_MEM_FP_LAZY_STATE_PRESERVATION;
|
||||||
PR_FAULT_INFO(
|
PR_FAULT_INFO(
|
||||||
" Floating-point lazy state preservation error");
|
" Floating-point lazy state preservation error");
|
||||||
}
|
}
|
||||||
|
@ -382,17 +387,20 @@ static uint32_t mem_manage_fault(z_arch_esf_t *esf, int from_hard_fault,
|
||||||
*/
|
*/
|
||||||
static int bus_fault(z_arch_esf_t *esf, int from_hard_fault, bool *recoverable)
|
static int bus_fault(z_arch_esf_t *esf, int from_hard_fault, bool *recoverable)
|
||||||
{
|
{
|
||||||
uint32_t reason = K_ERR_CPU_EXCEPTION;
|
uint32_t reason = K_ERR_ARM_BUS_GENERIC;
|
||||||
|
|
||||||
PR_FAULT_INFO("***** BUS FAULT *****");
|
PR_FAULT_INFO("***** BUS FAULT *****");
|
||||||
|
|
||||||
if (SCB->CFSR & SCB_CFSR_STKERR_Msk) {
|
if (SCB->CFSR & SCB_CFSR_STKERR_Msk) {
|
||||||
|
reason = K_ERR_ARM_BUS_STACKING;
|
||||||
PR_FAULT_INFO(" Stacking error");
|
PR_FAULT_INFO(" Stacking error");
|
||||||
}
|
}
|
||||||
if (SCB->CFSR & SCB_CFSR_UNSTKERR_Msk) {
|
if (SCB->CFSR & SCB_CFSR_UNSTKERR_Msk) {
|
||||||
|
reason = K_ERR_ARM_BUS_UNSTACKING;
|
||||||
PR_FAULT_INFO(" Unstacking error");
|
PR_FAULT_INFO(" Unstacking error");
|
||||||
}
|
}
|
||||||
if (SCB->CFSR & SCB_CFSR_PRECISERR_Msk) {
|
if (SCB->CFSR & SCB_CFSR_PRECISERR_Msk) {
|
||||||
|
reason = K_ERR_ARM_BUS_PRECISE_DATA_BUS;
|
||||||
PR_FAULT_INFO(" Precise data bus error");
|
PR_FAULT_INFO(" Precise data bus error");
|
||||||
/* In a fault handler, to determine the true faulting address:
|
/* In a fault handler, to determine the true faulting address:
|
||||||
* 1. Read and save the BFAR value.
|
* 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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (SCB->CFSR & SCB_CFSR_IMPRECISERR_Msk) {
|
if (SCB->CFSR & SCB_CFSR_IMPRECISERR_Msk) {
|
||||||
|
reason = K_ERR_ARM_BUS_IMPRECISE_DATA_BUS;
|
||||||
PR_FAULT_INFO(" Imprecise data bus error");
|
PR_FAULT_INFO(" Imprecise data bus error");
|
||||||
}
|
}
|
||||||
if ((SCB->CFSR & SCB_CFSR_IBUSERR_Msk) != 0) {
|
if ((SCB->CFSR & SCB_CFSR_IBUSERR_Msk) != 0) {
|
||||||
|
reason = K_ERR_ARM_BUS_INSTRUCTION_BUS;
|
||||||
PR_FAULT_INFO(" Instruction bus error");
|
PR_FAULT_INFO(" Instruction bus error");
|
||||||
#if !defined(CONFIG_ARMV7_M_ARMV8_M_FP)
|
#if !defined(CONFIG_ARMV7_M_ARMV8_M_FP)
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
} else if (SCB->CFSR & SCB_CFSR_LSPERR_Msk) {
|
} else if (SCB->CFSR & SCB_CFSR_LSPERR_Msk) {
|
||||||
|
reason = K_ERR_ARM_BUS_FP_LAZY_STATE_PRESERVATION;
|
||||||
PR_FAULT_INFO(" Floating-point lazy state preservation error");
|
PR_FAULT_INFO(" Floating-point lazy state preservation error");
|
||||||
} else {
|
} else {
|
||||||
;
|
;
|
||||||
|
@ -538,19 +549,22 @@ static int bus_fault(z_arch_esf_t *esf, int from_hard_fault, bool *recoverable)
|
||||||
*/
|
*/
|
||||||
static uint32_t usage_fault(const z_arch_esf_t *esf)
|
static uint32_t usage_fault(const z_arch_esf_t *esf)
|
||||||
{
|
{
|
||||||
uint32_t reason = K_ERR_CPU_EXCEPTION;
|
uint32_t reason = K_ERR_ARM_USAGE_GENERIC;
|
||||||
|
|
||||||
PR_FAULT_INFO("***** USAGE FAULT *****");
|
PR_FAULT_INFO("***** USAGE FAULT *****");
|
||||||
|
|
||||||
/* bits are sticky: they stack and must be reset */
|
/* bits are sticky: they stack and must be reset */
|
||||||
if ((SCB->CFSR & SCB_CFSR_DIVBYZERO_Msk) != 0) {
|
if ((SCB->CFSR & SCB_CFSR_DIVBYZERO_Msk) != 0) {
|
||||||
|
reason = K_ERR_ARM_USAGE_DIV_0;
|
||||||
PR_FAULT_INFO(" Division by zero");
|
PR_FAULT_INFO(" Division by zero");
|
||||||
}
|
}
|
||||||
if ((SCB->CFSR & SCB_CFSR_UNALIGNED_Msk) != 0) {
|
if ((SCB->CFSR & SCB_CFSR_UNALIGNED_Msk) != 0) {
|
||||||
|
reason = K_ERR_ARM_USAGE_UNALIGNED_ACCESS;
|
||||||
PR_FAULT_INFO(" Unaligned memory access");
|
PR_FAULT_INFO(" Unaligned memory access");
|
||||||
}
|
}
|
||||||
#if defined(CONFIG_ARMV8_M_MAINLINE)
|
#if defined(CONFIG_ARMV8_M_MAINLINE)
|
||||||
if ((SCB->CFSR & SCB_CFSR_STKOF_Msk) != 0) {
|
if ((SCB->CFSR & SCB_CFSR_STKOF_Msk) != 0) {
|
||||||
|
reason = K_ERR_ARM_USAGE_STACK_OVERFLOW;
|
||||||
PR_FAULT_INFO(" Stack overflow (context area not valid)");
|
PR_FAULT_INFO(" Stack overflow (context area not valid)");
|
||||||
#if defined(CONFIG_BUILTIN_STACK_GUARD)
|
#if defined(CONFIG_BUILTIN_STACK_GUARD)
|
||||||
/* Stack Overflows are always reported as stack corruption
|
/* Stack Overflows are always reported as stack corruption
|
||||||
|
@ -565,15 +579,19 @@ static uint32_t usage_fault(const z_arch_esf_t *esf)
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_ARMV8_M_MAINLINE */
|
#endif /* CONFIG_ARMV8_M_MAINLINE */
|
||||||
if ((SCB->CFSR & SCB_CFSR_NOCP_Msk) != 0) {
|
if ((SCB->CFSR & SCB_CFSR_NOCP_Msk) != 0) {
|
||||||
|
reason = K_ERR_ARM_USAGE_NO_COPROCESSOR;
|
||||||
PR_FAULT_INFO(" No coprocessor instructions");
|
PR_FAULT_INFO(" No coprocessor instructions");
|
||||||
}
|
}
|
||||||
if ((SCB->CFSR & SCB_CFSR_INVPC_Msk) != 0) {
|
if ((SCB->CFSR & SCB_CFSR_INVPC_Msk) != 0) {
|
||||||
|
reason = K_ERR_ARM_USAGE_ILLEGAL_EXC_RETURN;
|
||||||
PR_FAULT_INFO(" Illegal load of EXC_RETURN into PC");
|
PR_FAULT_INFO(" Illegal load of EXC_RETURN into PC");
|
||||||
}
|
}
|
||||||
if ((SCB->CFSR & SCB_CFSR_INVSTATE_Msk) != 0) {
|
if ((SCB->CFSR & SCB_CFSR_INVSTATE_Msk) != 0) {
|
||||||
|
reason = K_ERR_ARM_USAGE_ILLEGAL_EPSR;
|
||||||
PR_FAULT_INFO(" Illegal use of the EPSR");
|
PR_FAULT_INFO(" Illegal use of the EPSR");
|
||||||
}
|
}
|
||||||
if ((SCB->CFSR & SCB_CFSR_UNDEFINSTR_Msk) != 0) {
|
if ((SCB->CFSR & SCB_CFSR_UNDEFINSTR_Msk) != 0) {
|
||||||
|
reason = K_ERR_ARM_USAGE_UNDEFINED_INSTRUCTION;
|
||||||
PR_FAULT_INFO(" Attempt to execute undefined instruction");
|
PR_FAULT_INFO(" Attempt to execute undefined instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -590,9 +608,12 @@ static uint32_t usage_fault(const z_arch_esf_t *esf)
|
||||||
*
|
*
|
||||||
* See z_arm_fault_dump() for example.
|
* See z_arm_fault_dump() for example.
|
||||||
*
|
*
|
||||||
|
* @return error code to identify the fatal error reason
|
||||||
*/
|
*/
|
||||||
static void secure_fault(const z_arch_esf_t *esf)
|
static uint32_t secure_fault(const z_arch_esf_t *esf)
|
||||||
{
|
{
|
||||||
|
uint32_t reason = K_ERR_ARM_SECURE_GENERIC;
|
||||||
|
|
||||||
PR_FAULT_INFO("***** SECURE FAULT *****");
|
PR_FAULT_INFO("***** SECURE FAULT *****");
|
||||||
|
|
||||||
STORE_xFAR(sfar, SAU->SFAR);
|
STORE_xFAR(sfar, SAU->SFAR);
|
||||||
|
@ -602,23 +623,32 @@ static void secure_fault(const z_arch_esf_t *esf)
|
||||||
|
|
||||||
/* bits are sticky: they stack and must be reset */
|
/* bits are sticky: they stack and must be reset */
|
||||||
if ((SAU->SFSR & SAU_SFSR_INVEP_Msk) != 0) {
|
if ((SAU->SFSR & SAU_SFSR_INVEP_Msk) != 0) {
|
||||||
|
reason = K_ERR_ARM_SECURE_ENTRY_POINT;
|
||||||
PR_FAULT_INFO(" Invalid entry point");
|
PR_FAULT_INFO(" Invalid entry point");
|
||||||
} else if ((SAU->SFSR & SAU_SFSR_INVIS_Msk) != 0) {
|
} else if ((SAU->SFSR & SAU_SFSR_INVIS_Msk) != 0) {
|
||||||
|
reason = K_ERR_ARM_SECURE_INTEGRITY_SIGNATURE;
|
||||||
PR_FAULT_INFO(" Invalid integrity signature");
|
PR_FAULT_INFO(" Invalid integrity signature");
|
||||||
} else if ((SAU->SFSR & SAU_SFSR_INVER_Msk) != 0) {
|
} else if ((SAU->SFSR & SAU_SFSR_INVER_Msk) != 0) {
|
||||||
|
reason = K_ERR_ARM_SECURE_EXCEPTION_RETURN;
|
||||||
PR_FAULT_INFO(" Invalid exception return");
|
PR_FAULT_INFO(" Invalid exception return");
|
||||||
} else if ((SAU->SFSR & SAU_SFSR_AUVIOL_Msk) != 0) {
|
} else if ((SAU->SFSR & SAU_SFSR_AUVIOL_Msk) != 0) {
|
||||||
|
reason = K_ERR_ARM_SECURE_ATTRIBUTION_UNIT;
|
||||||
PR_FAULT_INFO(" Attribution unit violation");
|
PR_FAULT_INFO(" Attribution unit violation");
|
||||||
} else if ((SAU->SFSR & SAU_SFSR_INVTRAN_Msk) != 0) {
|
} else if ((SAU->SFSR & SAU_SFSR_INVTRAN_Msk) != 0) {
|
||||||
|
reason = K_ERR_ARM_SECURE_TRANSITION;
|
||||||
PR_FAULT_INFO(" Invalid transition");
|
PR_FAULT_INFO(" Invalid transition");
|
||||||
} else if ((SAU->SFSR & SAU_SFSR_LSPERR_Msk) != 0) {
|
} else if ((SAU->SFSR & SAU_SFSR_LSPERR_Msk) != 0) {
|
||||||
|
reason = K_ERR_ARM_SECURE_LAZY_STATE_PRESERVATION;
|
||||||
PR_FAULT_INFO(" Lazy state preservation");
|
PR_FAULT_INFO(" Lazy state preservation");
|
||||||
} else if ((SAU->SFSR & SAU_SFSR_LSERR_Msk) != 0) {
|
} else if ((SAU->SFSR & SAU_SFSR_LSERR_Msk) != 0) {
|
||||||
|
reason = K_ERR_ARM_SECURE_LAZY_STATE_ERROR;
|
||||||
PR_FAULT_INFO(" Lazy state error");
|
PR_FAULT_INFO(" Lazy state error");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clear SFSR sticky bits */
|
/* clear SFSR sticky bits */
|
||||||
SAU->SFSR |= 0xFF;
|
SAU->SFSR |= 0xFF;
|
||||||
|
|
||||||
|
return reason;
|
||||||
}
|
}
|
||||||
#endif /* defined(CONFIG_ARM_SECURE_FIRMWARE) */
|
#endif /* defined(CONFIG_ARM_SECURE_FIRMWARE) */
|
||||||
|
|
||||||
|
@ -748,7 +778,7 @@ static uint32_t hard_fault(z_arch_esf_t *esf, bool *recoverable)
|
||||||
reason = usage_fault(esf);
|
reason = usage_fault(esf);
|
||||||
#if defined(CONFIG_ARM_SECURE_FIRMWARE)
|
#if defined(CONFIG_ARM_SECURE_FIRMWARE)
|
||||||
} else if (SAU->SFSR != 0) {
|
} else if (SAU->SFSR != 0) {
|
||||||
secure_fault(esf);
|
reason = secure_fault(esf);
|
||||||
#endif /* CONFIG_ARM_SECURE_FIRMWARE */
|
#endif /* CONFIG_ARM_SECURE_FIRMWARE */
|
||||||
} else {
|
} else {
|
||||||
__ASSERT(0,
|
__ASSERT(0,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue