[PATCH] score/arm: improve printed exception information for Cortex-Mx CPUs
Karel Gardas
karel at functional.vision
Wed Mar 15 18:16:38 UTC 2023
Sponsored-By: Precidata
---
.../score/cpu/arm/arm-exception-frame-print.c | 101 ++++++++++++++++++
.../cpu/arm/include/rtems/score/armv7m.h | 11 ++
2 files changed, 112 insertions(+)
diff --git a/cpukit/score/cpu/arm/arm-exception-frame-print.c b/cpukit/score/cpu/arm/arm-exception-frame-print.c
index 4bb1efedec..6a773d9e2d 100644
--- a/cpukit/score/cpu/arm/arm-exception-frame-print.c
+++ b/cpukit/score/cpu/arm/arm-exception-frame-print.c
@@ -32,6 +32,9 @@
#include <inttypes.h>
#include <rtems/score/cpu.h>
+#if defined(ARM_MULTILIB_ARCH_V7M)
+#include <rtems/score/armv7m.h>
+#endif
#include <rtems/bspIo.h>
static void _ARM_VFP_context_print( const ARM_VFP_context *vfp_context )
@@ -57,6 +60,103 @@ static void _ARM_VFP_context_print( const ARM_VFP_context *vfp_context )
#endif
}
+static void _ARM_Cortex_M_fault_info_print(void)
+{
+#if defined(ARM_MULTILIB_ARCH_V7M)
+ /* prints content of additional debugging registers
+ * available on Cortex-Mx where x > 0 cores.
+ */
+ uint32_t cfsr = _ARMV7M_SCB->cfsr;
+ uint8_t mmfsr = ARMV7M_SCB_CFSR_MMFSR_GET(cfsr);
+ uint8_t bfsr = (ARMV7M_SCB_CFSR_BFSR_GET(cfsr) >> 8);
+ uint16_t ufsr = (ARMV7M_SCB_CFSR_UFSR_GET(cfsr) >> 16);
+ uint32_t hfsr = _ARMV7M_SCB->hfsr;
+ if (mmfsr > 0) {
+ printk("MMFSR= 0x%08" PRIx32 " (memory fault)\n", mmfsr);
+ if ((mmfsr & 0x1) != 0) {
+ printk(" IACCVIOL : 1 (instruction access violation)\n");
+ }
+ if ((mmfsr & 0x2) != 0) {
+ printk(" DACCVIOL : 1 (data access violation)\n");
+ }
+ if ((mmfsr & 0x8) != 0) {
+ printk(" MUNSTKERR : 1 (fault on unstacking on exception return)\n");
+ }
+ if ((mmfsr & 0x10) != 0) {
+ printk(" MSTKERR : 1 (fault on stacking on exception entry)\n");
+ }
+ if ((mmfsr & 0x20) != 0) {
+ printk(" MLSPERR : 1 (fault during lazy FP stack preservation)\n");
+ }
+ if ((mmfsr & 0x80) != 0) {
+ printk(" MMFARVALID : 1 -> 0x%08" PRIx32 " (error address)\n", _ARMV7M_SCB->mmfar);
+ }
+ else {
+ printk(" MMFARVALID : 0 (undetermined error address)\n");
+ }
+ }
+ if (bfsr > 0) {
+ printk("BFSR = 0x%08" PRIx32 " (bus fault)\n", bfsr);
+ if ((bfsr & 0x1) != 0) {
+ printk(" IBUSERR : 1 (instruction fetch error)\n");
+ }
+ if ((bfsr & 0x2) != 0) {
+ printk(" PRECISERR : 1 (data bus error with known exact location)\n");
+ }
+ if ((bfsr & 0x4) != 0) {
+ printk(" IMPRECISERR: 1 (data bus error without known exact location)\n");
+ }
+ if ((bfsr & 0x8) != 0) {
+ printk(" UNSTKERR : 1 (fault on unstacking on exception return)\n");
+ }
+ if ((bfsr & 0x10) != 0) {
+ printk(" STKERR : 1 (fault on stacking on exception entry)\n");
+ }
+ if ((bfsr & 0x20) != 0) {
+ printk(" LSPERR : 1 (fault during lazy FP stack preservation)\n");
+ }
+ if ((bfsr & 0x80) != 0) {
+ printk(" BFARVALID : 1 -> 0x%08" PRIx32 " (error address)\n", _ARMV7M_SCB->bfar);
+ }
+ else {
+ printk(" BFARVALID : 0 (undetermined error address)\n");
+ }
+ }
+ if (ufsr > 0) {
+ printk("UFSR = 0x%08" PRIx32 " (usage fault)\n", ufsr);
+ if ((ufsr & 0x1) != 0) {
+ printk(" UNDEFINSTR : 1 (undefined instruction issued)\n");
+ }
+ if ((ufsr & 0x2) != 0) {
+ printk(" INVSTATE : 1 (invalid instruction state (Thumb not set in EPSR or invalid IT state in EPSR))\n");
+ }
+ if ((ufsr & 0x4) != 0) {
+ printk(" INVPC : 1 (integrity check failure on EXC_RETURN)\n");
+ }
+ if ((ufsr & 0x8) != 0) {
+ printk(" NOCP : 1 (coprocessor instruction issued but coprocessor disabled or non existent)\n");
+ }
+ if ((ufsr & 0x100) != 0) {
+ printk(" UNALIGNED : 1 (unaligned access operation occurred)\n");
+ }
+ if ((ufsr & 0x200) != 0) {
+ printk(" DIVBYZERO : 1 (division by zero)");
+ }
+ }
+ if ((hfsr & (ARMV7M_SCB_HFSR_VECTTBL_MASK | ARMV7M_SCB_HFSR_DEBUGEVT_MASK | ARMV7M_SCB_HFSR_FORCED_MASK)) != 0) {
+ printk("HFSR = 0x%08" PRIx32 " (hard fault)\n", hfsr);
+ if ((hfsr & ARMV7M_SCB_HFSR_VECTTBL_MASK) != 0) {
+ printk(" VECTTBL : 1 (error in address located in vector table)\n");
+ }
+ if ((hfsr & ARMV7M_SCB_HFSR_FORCED_MASK) != 0) {
+ printk(" FORCED : 1 (configurable fault escalated to hard fault)\n");
+ }
+ if ((hfsr & ARMV7M_SCB_HFSR_DEBUGEVT_MASK) != 0) {
+ printk(" DEBUGEVT : 1 (debug event occurred with debug system disabled)\n");
+ }
+ }
+#endif
+}
void _CPU_Exception_frame_print( const CPU_Exception_frame *frame )
{
printk(
@@ -100,4 +200,5 @@ void _CPU_Exception_frame_print( const CPU_Exception_frame *frame )
);
_ARM_VFP_context_print( frame->vfp_context );
+ _ARM_Cortex_M_fault_info_print();
}
diff --git a/cpukit/score/cpu/arm/include/rtems/score/armv7m.h b/cpukit/score/cpu/arm/include/rtems/score/armv7m.h
index 10b3955671..744dca26d3 100644
--- a/cpukit/score/cpu/arm/include/rtems/score/armv7m.h
+++ b/cpukit/score/cpu/arm/include/rtems/score/armv7m.h
@@ -156,8 +156,19 @@ typedef struct {
#define ARMV7M_SCB_SHCSR_MEMFAULTENA (1U << 16)
uint32_t shcsr;
+#define ARMV7M_SCB_CFSR_MMFSR_MASK 0xff
+#define ARMV7M_SCB_CFSR_MMFSR_GET(n) (n & ARMV7M_SCB_CFSR_MMFSR_MASK)
+#define ARMV7M_SCB_CFSR_BFSR_MASK 0xff00
+#define ARMV7M_SCB_CFSR_BFSR_GET(n) (n & ARMV7M_SCB_CFSR_BFSR_MASK)
+#define ARMV7M_SCB_CFSR_UFSR_MASK 0xffff0000
+#define ARMV7M_SCB_CFSR_UFSR_GET(n) (n & ARMV7M_SCB_CFSR_UFSR_MASK)
uint32_t cfsr;
+
+#define ARMV7M_SCB_HFSR_VECTTBL_MASK 0x2
+#define ARMV7M_SCB_HFSR_FORCED_MASK (1U << 30)
+#define ARMV7M_SCB_HFSR_DEBUGEVT_MASK (1U << 31)
uint32_t hfsr;
+
uint32_t dfsr;
uint32_t mmfar;
uint32_t bfar;
--
2.25.1
More information about the devel
mailing list