diff --git a/arch/arm/src/armv7-m/arm_hardfault.c b/arch/arm/src/armv7-m/arm_hardfault.c index 2b886478cf2..8b89dfd2bb6 100644 --- a/arch/arm/src/armv7-m/arm_hardfault.c +++ b/arch/arm/src/armv7-m/arm_hardfault.c @@ -74,6 +74,11 @@ int arm_hardfault(int irq, FAR void *context, FAR void *arg) { + uint32_t hfsr = getreg32(NVIC_HFAULTS); + uint32_t cfsr = getreg32(NVIC_CFAULTS); + + UNUSED(cfsr); + /* Get the value of the program counter where the fault occurred */ #ifndef CONFIG_ARMV7M_USEBASEPRI @@ -118,20 +123,54 @@ int arm_hardfault(int irq, FAR void *context, FAR void *arg) } #endif + if (hfsr & NVIC_HFAULTS_FORCED) + { + hfalert("Hard Fault escalation:\n"); + +#ifdef CONFIG_DEBUG_MEMFAULT + if (cfsr & NVIC_CFAULTS_MEMFAULTSR_MASK) + { + return arm_memfault(irq, context, arg); + } +#endif /* CONFIG_DEBUG_MEMFAULT */ + +#ifdef CONFIG_DEBUG_BUSFAULT + if (cfsr & NVIC_CFAULTS_BUSFAULTSR_MASK) + { + return arm_busfault(irq, context, arg); + } +#endif /* CONFIG_DEBUG_BUSFAULT */ + +#ifdef CONFIG_DEBUG_USAGEFAULT + if (cfsr & NVIC_CFAULTS_USGFAULTSR_MASK) + { + return arm_usagefault(irq, context, arg); + } +#endif /* CONFIG_DEBUG_USAGEFAULT */ + } + /* Dump some hard fault info */ - hfalert("Hard Fault:\n"); - hfalert(" IRQ: %d regs: %p\n", irq, context); - hfalert(" BASEPRI: %08x PRIMASK: %08x IPSR: %08x CONTROL: %08x\n", + hfalert("PANIC!!! Hard Fault!:"); + hfalert("\tIRQ: %d regs: %p\n", irq, context); + hfalert("\tBASEPRI: %08x PRIMASK: %08x IPSR: %08x CONTROL: %08x\n", getbasepri(), getprimask(), getipsr(), getcontrol()); - hfalert(" CFAULTS: %08x HFAULTS: %08x DFAULTS: %08x BFAULTADDR: %08x " - "AFAULTS: %08x\n", - getreg32(NVIC_CFAULTS), getreg32(NVIC_HFAULTS), - getreg32(NVIC_DFAULTS), getreg32(NVIC_BFAULT_ADDR), - getreg32(NVIC_AFAULTS)); + hfalert("\tCFSR: %08x HFSR: %08x DFSR: %08x BFAR: %08x AFSR: %08x\n", + cfsr, hfsr, getreg32(NVIC_DFAULTS), + getreg32(NVIC_BFAULT_ADDR), getreg32(NVIC_AFAULTS)); + + hfalert("Hard Fault Reason:\n"); + + if (hfsr & NVIC_HFAULTS_VECTTBL) + { + hfalert("\tBusFault on a vector table read\n"); + } + else if (hfsr & NVIC_HFAULTS_DEBUGEVT) + { + hfalert("\tDebug event\n"); + } up_irq_save(); - _alert("PANIC!!! Hard fault: %08" PRIx32 "\n", getreg32(NVIC_HFAULTS)); PANIC(); return OK; } diff --git a/arch/arm/src/armv7-m/arm_memfault.c b/arch/arm/src/armv7-m/arm_memfault.c index db932a99f2c..0e4a7177d69 100644 --- a/arch/arm/src/armv7-m/arm_memfault.c +++ b/arch/arm/src/armv7-m/arm_memfault.c @@ -39,11 +39,9 @@ ****************************************************************************/ #ifdef CONFIG_DEBUG_MEMFAULT -# define mferr(format, ...) _alert(format, ##__VA_ARGS__) -# define mfinfo(format, ...) _alert(format, ##__VA_ARGS__) +# define mfalert(format, ...) _alert(format, ##__VA_ARGS__) #else -# define mferr(x...) -# define mfinfo(x...) +# define mfalert(x...) #endif /**************************************************************************** @@ -63,17 +61,44 @@ int arm_memfault(int irq, FAR void *context, FAR void *arg) { + uint32_t cfsr = getreg32(NVIC_CFAULTS); + /* Dump some memory management fault info */ - up_irq_save(); - _alert("PANIC!!! Memory Management Fault:\n"); - mfinfo(" IRQ: %d context: %p\n", irq, context); - _alert(" CFAULTS: %08" PRIx32 " MMFAR: %08" PRIx32 "\n", - getreg32(NVIC_CFAULTS), getreg32(NVIC_MEMMANAGE_ADDR)); - mfinfo(" BASEPRI: %08" PRIx32 " PRIMASK: %08" PRIx32 - " IPSR: %08" PRIx32 " CONTROL: %08" PRIx32 "\n", - getbasepri(), getprimask(), getipsr(), getcontrol()); + mfalert("PANIC!!! Memory Management Fault:\n"); + mfalert("\tIRQ: %d context: %p\n", irq, context); + mfalert("\tCFSR: %08x MMFAR: %08x\n", + getreg32(NVIC_CFAULTS), getreg32(NVIC_MEMMANAGE_ADDR)); + mfalert("\tBASEPRI: %08x PRIMASK: %08x IPSR: %08x CONTROL: %08x\n", + getbasepri(), getprimask(), getipsr(), getcontrol()); + mfalert("Memory Management Fault Reason:\n"); + if (cfsr & NVIC_CFAULTS_IACCVIOL) + { + mfalert("\tInstruction access violation\n"); + } + + if (cfsr & NVIC_CFAULTS_DACCVIOL) + { + mfalert("\tData access violation\n"); + } + + if (cfsr & NVIC_CFAULTS_MUNSTKERR) + { + mfalert("\tMemManage fault on unstacking\n"); + } + + if (cfsr & NVIC_CFAULTS_MSTKERR) + { + mfalert("\tMemManage fault on stacking\n"); + } + + if (cfsr & NVIC_CFAULTS_MLSPERR) + { + mfalert("\tFloating-point lazy state preservation error\n"); + } + + up_irq_save(); PANIC(); return OK; /* Won't get here */ } diff --git a/arch/arm/src/armv8-m/arm_hardfault.c b/arch/arm/src/armv8-m/arm_hardfault.c index 8ff247834ec..dd413c30e8c 100644 --- a/arch/arm/src/armv8-m/arm_hardfault.c +++ b/arch/arm/src/armv8-m/arm_hardfault.c @@ -73,6 +73,11 @@ int arm_hardfault(int irq, FAR void *context, FAR void *arg) { + uint32_t hfsr = getreg32(NVIC_HFAULTS); + uint32_t cfsr = getreg32(NVIC_CFAULTS); + + UNUSED(cfsr); + /* Get the value of the program counter where the fault occurred */ #ifndef CONFIG_ARMV8M_USEBASEPRI @@ -117,20 +122,54 @@ int arm_hardfault(int irq, FAR void *context, FAR void *arg) } #endif + if (hfsr & NVIC_HFAULTS_FORCED) + { + hfalert("Hard Fault escalation:\n"); + +#ifdef CONFIG_DEBUG_MEMFAULT + if (cfsr & NVIC_CFAULTS_MEMFAULTSR_MASK) + { + return arm_memfault(irq, context, arg); + } +#endif /* CONFIG_DEBUG_MEMFAULT */ + +#ifdef CONFIG_DEBUG_BUSFAULT + if (cfsr & NVIC_CFAULTS_BUSFAULTSR_MASK) + { + return arm_busfault(irq, context, arg); + } +#endif /* CONFIG_DEBUG_BUSFAULT */ + +#ifdef CONFIG_DEBUG_USAGEFAULT + if (cfsr & NVIC_CFAULTS_USGFAULTSR_MASK) + { + return arm_usagefault(irq, context, arg); + } +#endif /* CONFIG_DEBUG_USAGEFAULT */ + } + /* Dump some hard fault info */ - hfalert("Hard Fault:\n"); - hfalert(" IRQ: %d regs: %p\n", irq, context); - hfalert(" BASEPRI: %08x PRIMASK: %08x IPSR: %08x CONTROL: %08x\n", + hfalert("PANIC!!! Hard Fault!:"); + hfalert("\tIRQ: %d regs: %p\n", irq, context); + hfalert("\tBASEPRI: %08x PRIMASK: %08x IPSR: %08x CONTROL: %08x\n", getbasepri(), getprimask(), getipsr(), getcontrol()); - hfalert(" CFAULTS: %08x HFAULTS: %08x DFAULTS: %08x BFAULTADDR: %08x " - "AFAULTS: %08x\n", - getreg32(NVIC_CFAULTS), getreg32(NVIC_HFAULTS), - getreg32(NVIC_DFAULTS), getreg32(NVIC_BFAULT_ADDR), - getreg32(NVIC_AFAULTS)); + hfalert("\tCFSR: %08x HFSR: %08x DFSR: %08x BFAR: %08x AFSR: %08x\n", + cfsr, hfsr, getreg32(NVIC_DFAULTS), + getreg32(NVIC_BFAULT_ADDR), getreg32(NVIC_AFAULTS)); + + hfalert("Hard Fault Reason:\n"); + + if (hfsr & NVIC_HFAULTS_VECTTBL) + { + hfalert("\tBusFault on a vector table read\n"); + } + else if (hfsr & NVIC_HFAULTS_DEBUGEVT) + { + hfalert("\tDebug event\n"); + } up_irq_save(); - _alert("PANIC!!! Hard fault: %08x\n", getreg32(NVIC_HFAULTS)); PANIC(); return OK; } diff --git a/arch/arm/src/armv8-m/arm_memfault.c b/arch/arm/src/armv8-m/arm_memfault.c index b9f0b1fddd1..a1f4d5dfa0f 100644 --- a/arch/arm/src/armv8-m/arm_memfault.c +++ b/arch/arm/src/armv8-m/arm_memfault.c @@ -26,6 +26,7 @@ #include #include +#include #include @@ -38,11 +39,9 @@ ****************************************************************************/ #ifdef CONFIG_DEBUG_MEMFAULT -# define mferr(format, ...) _alert(format, ##__VA_ARGS__) -# define mfinfo(format, ...) _alert(format, ##__VA_ARGS__) +# define mfalert(format, ...) _alert(format, ##__VA_ARGS__) #else -# define mferr(x...) -# define mfinfo(x...) +# define mfalert(x...) #endif /**************************************************************************** @@ -62,16 +61,44 @@ int arm_memfault(int irq, FAR void *context, FAR void *arg) { + uint32_t cfsr = getreg32(NVIC_CFAULTS); + /* Dump some memory management fault info */ - up_irq_save(); - _alert("PANIC!!! Memory Management Fault:\n"); - mfinfo(" IRQ: %d context: %p\n", irq, context); - _alert(" CFAULTS: %08x MMFAR: %08x\n", - getreg32(NVIC_CFAULTS), getreg32(NVIC_MEMMANAGE_ADDR)); - mfinfo(" BASEPRI: %08x PRIMASK: %08x IPSR: %08x CONTROL: %08x\n", - getbasepri(), getprimask(), getipsr(), getcontrol()); + mfalert("PANIC!!! Memory Management Fault:\n"); + mfalert("\tIRQ: %d context: %p\n", irq, context); + mfalert("\tCFSR: %08x MMFAR: %08x\n", + getreg32(NVIC_CFAULTS), getreg32(NVIC_MEMMANAGE_ADDR)); + mfalert("\tBASEPRI: %08x PRIMASK: %08x IPSR: %08x CONTROL: %08x\n", + getbasepri(), getprimask(), getipsr(), getcontrol()); + mfalert("Memory Management Fault Reason:\n"); + if (cfsr & NVIC_CFAULTS_IACCVIOL) + { + mfalert("\tInstruction access violation\n"); + } + + if (cfsr & NVIC_CFAULTS_DACCVIOL) + { + mfalert("\tData access violation\n"); + } + + if (cfsr & NVIC_CFAULTS_MUNSTKERR) + { + mfalert("\tMemManage fault on unstacking\n"); + } + + if (cfsr & NVIC_CFAULTS_MSTKERR) + { + mfalert("\tMemManage fault on stacking\n"); + } + + if (cfsr & NVIC_CFAULTS_MLSPERR) + { + mfalert("\tFloating-point lazy state preservation error\n"); + } + + up_irq_save(); PANIC(); return OK; /* Won't get here */ }