forked from Imagelibrary/rtems
score/arm: improve printed exception information for Cortex-Mx CPUs
Sponsored-By: Precidata
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user