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

2023-07-07 Thread Karel Gardas
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 
 
 #include 
+#if defined(ARM_MULTILIB_ARCH_V7M)
+#include 
+#endif
 #include 
 
 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 = _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 " 

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

2023-03-15 Thread Karel Gardas
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 
 
 #include 
+#if defined(ARM_MULTILIB_ARCH_V7M)
+#include 
+#endif
 #include 
 
 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 @@