[PATCH] score/arm: improve printed exception information for Cortex-Mx CPUs

Karel Gardas karel at functional.vision
Fri Jul 7 08:00:59 UTC 2023


Sponsored-By:	Precidata
---
 .../score/cpu/arm/arm-exception-frame-print.c | 145 +++++++++++++++++-
 .../cpu/arm/include/rtems/score/armv7m.h      |  11 ++
 2 files changed, 154 insertions(+), 2 deletions(-)

diff --git a/cpukit/score/cpu/arm/arm-exception-frame-print.c b/cpukit/score/cpu/arm/arm-exception-frame-print.c
index 7bc6795ea5..b089648184 100644
--- a/cpukit/score/cpu/arm/arm-exception-frame-print.c
+++ b/cpukit/score/cpu/arm/arm-exception-frame-print.c
@@ -41,11 +41,14 @@
 #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 )
 {
-#ifdef ARM_MULTILIB_VFP_D32
+#ifdef ARM_MULTILIB_VFP
   if ( vfp_context != NULL ) {
     const uint64_t *dx = &vfp_context->register_d0;
     int i;
@@ -56,7 +59,14 @@ static void _ARM_VFP_context_print( const ARM_VFP_context *vfp_context )
       vfp_context->register_fpscr
     );
 
-    for ( i = 0; i < 32; ++i ) {
+#if defined(ARM_MULTILIB_VFP_D32)
+    int regcount = 32;
+#elif defined(ARM_MULTILIB_VFP_D16)
+    int regcount = 16;
+#else
+    int regcount = 0;
+#endif
+    for ( i = 0; i < regcount; ++i ) {
       uint32_t low = (uint32_t) dx[i];
       uint32_t high = (uint32_t) (dx[i] >> 32);
 
@@ -66,6 +76,136 @@ 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(
@@ -109,4 +249,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 0f129f1d2e..7fa48b3aa5 100644
--- a/cpukit/score/cpu/arm/include/rtems/score/armv7m.h
+++ b/cpukit/score/cpu/arm/include/rtems/score/armv7m.h
@@ -159,8 +159,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