arm: cmsis: Convert _Scb*FaultIs* & _ScbIs*Fault to use CMSIS register access

Converted:
	_ScbHardFaultIsBusErrOnVectorRead
	_ScbIsMemFault
	_ScbMemFaultIsMmfarValid
	_ScbMemFaultIsStacking
	_ScbMemFaultIsUnstacking
	_ScbMemFaultIsDataAccessViolation
	_ScbMemFaultIsInstrAccessViolation
	_ScbIsBusFault
	_ScbBusFaultIsBfarValid
	_ScbBusFaultIsStacking
	_ScbBusFaultIsUnstacking
	_ScbBusFaultIsImprecise
	_ScbBusFaultIsPrecise
	_ScbBusFaultIsInstrBusErr
	_ScbIsUsageFault
	_ScbUsageFaultIsDivByZero
	_ScbUsageFaultIsUnaligned
	_ScbUsageFaultIsNoCp
	_ScbUsageFaultIsInvalidPcLoad
	_ScbUsageFaultIsInvalidState
	_ScbUsageFaultIsUndefinedInstr

To use direct CMSIS register access

Jira: ZEP-1568

Change-Id: I2a99a4101c5960f825a502c225e511e49fe93bba
Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
Signed-off-by: Maureen Helm <maureen.helm@nxp.com>
This commit is contained in:
Kumar Gala 2017-01-27 20:20:24 -06:00 committed by Maureen Helm
commit d2679c7bbb
3 changed files with 73 additions and 331 deletions

View file

@ -76,13 +76,13 @@ void _FaultDump(const NANO_ESF *esf, int fault)
__scs.scb.cfsr.byte.bfsr.val, __scs.scb.cfsr.byte.bfsr.val,
__scs.scb.cfsr.byte.ufsr.val); __scs.scb.cfsr.byte.ufsr.val);
if (_ScbMemFaultIsMmfarValid()) { if (SCB->CFSR & CFSR_MMARVALID_Msk) {
PR_EXC("MMFAR: 0x%" PRIx32 "\n", _ScbMemFaultAddrGet()); PR_EXC("MMFAR: 0x%" PRIx32 "\n", _ScbMemFaultAddrGet());
if (escalation) { if (escalation) {
_ScbMemFaultMmfarReset(); _ScbMemFaultMmfarReset();
} }
} }
if (_ScbBusFaultIsBfarValid()) { if (SCB->CFSR & CFSR_BFARVALID_Msk) {
PR_EXC("BFAR: 0x%" PRIx32 "\n", _ScbBusFaultAddrGet()); PR_EXC("BFAR: 0x%" PRIx32 "\n", _ScbBusFaultAddrGet());
if (escalation) { if (escalation) {
_ScbBusFaultBfarReset(); _ScbBusFaultBfarReset();
@ -130,20 +130,20 @@ static void _MpuFault(const NANO_ESF *esf, int fromHardFault)
_FaultThreadShow(esf); _FaultThreadShow(esf);
if (_ScbMemFaultIsStacking()) { if (SCB->CFSR & CFSR_MSTKERR_Msk) {
PR_EXC(" Stacking error\n"); PR_EXC(" Stacking error\n");
} else if (_ScbMemFaultIsUnstacking()) { } else if (SCB->CFSR & CFSR_MUNSTKERR_Msk) {
PR_EXC(" Unstacking error\n"); PR_EXC(" Unstacking error\n");
} else if (_ScbMemFaultIsDataAccessViolation()) { } else if (SCB->CFSR & CFSR_DACCVIOL_Msk) {
PR_EXC(" Data Access Violation\n"); PR_EXC(" Data Access Violation\n");
if (_ScbMemFaultIsMmfarValid()) { if (SCB->CFSR & CFSR_MMARVALID_Msk) {
PR_EXC(" Address: 0x%" PRIx32 "\n", PR_EXC(" Address: 0x%" PRIx32 "\n",
_ScbMemFaultAddrGet()); _ScbMemFaultAddrGet());
if (fromHardFault) { if (fromHardFault) {
_ScbMemFaultMmfarReset(); _ScbMemFaultMmfarReset();
} }
} }
} else if (_ScbMemFaultIsInstrAccessViolation()) { } else if (SCB->CFSR & CFSR_IACCVIOL_Msk) {
PR_EXC(" Instruction Access Violation\n"); PR_EXC(" Instruction Access Violation\n");
} }
} }
@ -162,13 +162,13 @@ static void _BusFault(const NANO_ESF *esf, int fromHardFault)
_FaultThreadShow(esf); _FaultThreadShow(esf);
if (_ScbBusFaultIsStacking()) { if (SCB->CFSR & CFSR_STKERR_Msk) {
PR_EXC(" Stacking error\n"); PR_EXC(" Stacking error\n");
} else if (_ScbBusFaultIsUnstacking()) { } else if (SCB->CFSR & CFSR_UNSTKERR_Msk) {
PR_EXC(" Unstacking error\n"); PR_EXC(" Unstacking error\n");
} else if (_ScbBusFaultIsPrecise()) { } else if (SCB->CFSR & CFSR_PRECISERR_Msk) {
PR_EXC(" Precise data bus error\n"); PR_EXC(" Precise data bus error\n");
if (_ScbBusFaultIsBfarValid()) { if (SCB->CFSR & CFSR_BFARVALID_Msk) {
PR_EXC(" Address: 0x%" PRIx32 "\n", PR_EXC(" Address: 0x%" PRIx32 "\n",
_ScbBusFaultAddrGet()); _ScbBusFaultAddrGet());
if (fromHardFault) { if (fromHardFault) {
@ -176,12 +176,12 @@ static void _BusFault(const NANO_ESF *esf, int fromHardFault)
} }
} }
/* it's possible to have both a precise and imprecise fault */ /* it's possible to have both a precise and imprecise fault */
if (_ScbBusFaultIsImprecise()) { if (SCB->CFSR & CFSR_IMPRECISERR_Msk) {
PR_EXC(" Imprecise data bus error\n"); PR_EXC(" Imprecise data bus error\n");
} }
} else if (_ScbBusFaultIsImprecise()) { } else if (SCB->CFSR & CFSR_IMPRECISERR_Msk) {
PR_EXC(" Imprecise data bus error\n"); PR_EXC(" Imprecise data bus error\n");
} else if (_ScbBusFaultIsInstrBusErr()) { } else if (SCB->CFSR & CFSR_IBUSERR_Msk) {
PR_EXC(" Instruction bus error\n"); PR_EXC(" Instruction bus error\n");
} }
} }
@ -201,22 +201,22 @@ static void _UsageFault(const NANO_ESF *esf)
_FaultThreadShow(esf); _FaultThreadShow(esf);
/* bits are sticky: they stack and must be reset */ /* bits are sticky: they stack and must be reset */
if (_ScbUsageFaultIsDivByZero()) { if (SCB->CFSR & CFSR_DIVBYZERO_Msk) {
PR_EXC(" Division by zero\n"); PR_EXC(" Division by zero\n");
} }
if (_ScbUsageFaultIsUnaligned()) { if (SCB->CFSR & CFSR_UNALIGNED_Msk) {
PR_EXC(" Unaligned memory access\n"); PR_EXC(" Unaligned memory access\n");
} }
if (_ScbUsageFaultIsNoCp()) { if (SCB->CFSR & CFSR_NOCP_Msk) {
PR_EXC(" No coprocessor instructions\n"); PR_EXC(" No coprocessor instructions\n");
} }
if (_ScbUsageFaultIsInvalidPcLoad()) { if (SCB->CFSR & CFSR_INVPC_Msk) {
PR_EXC(" Illegal load of EXC_RETURN into PC\n"); PR_EXC(" Illegal load of EXC_RETURN into PC\n");
} }
if (_ScbUsageFaultIsInvalidState()) { if (SCB->CFSR & CFSR_INVSTATE_Msk) {
PR_EXC(" Illegal use of the EPSR\n"); PR_EXC(" Illegal use of the EPSR\n");
} }
if (_ScbUsageFaultIsUndefinedInstr()) { if (SCB->CFSR & CFSR_UNDEFINSTR_Msk) {
PR_EXC(" Attempt to execute undefined instruction\n"); PR_EXC(" Attempt to execute undefined instruction\n");
} }
@ -257,15 +257,15 @@ static void _HardFault(const NANO_ESF *esf)
#if defined(CONFIG_ARMV6_M) #if defined(CONFIG_ARMV6_M)
_FaultThreadShow(esf); _FaultThreadShow(esf);
#elif defined(CONFIG_ARMV7_M) #elif defined(CONFIG_ARMV7_M)
if (_ScbHardFaultIsBusErrOnVectorRead()) { if (SCB->HFSR & SCB_HFSR_VECTTBL_Msk) {
PR_EXC(" Bus fault on vector table read\n"); PR_EXC(" Bus fault on vector table read\n");
} else if (SCB->HFSR & SCB_HFSR_FORCED_Msk) { } else if (SCB->HFSR & SCB_HFSR_FORCED_Msk) {
PR_EXC(" Fault escalation (see below)\n"); PR_EXC(" Fault escalation (see below)\n");
if (_ScbIsMemFault()) { if (SCB_MMFSR) {
_MpuFault(esf, 1); _MpuFault(esf, 1);
} else if (_ScbIsBusFault()) { } else if (SCB_BFSR) {
_BusFault(esf, 1); _BusFault(esf, 1);
} else if (_ScbIsUsageFault()) { } else if (SCB_UFSR) {
_UsageFault(esf); _UsageFault(esf);
} }
} }

View file

@ -36,6 +36,55 @@ extern "C" {
#define CPACR_CP11_RESERVED (2UL << _SCS_CPACR_CP11_Pos) #define CPACR_CP11_RESERVED (2UL << _SCS_CPACR_CP11_Pos)
#define CPACR_CP11_FULL_ACCESS (3UL << _SCS_CPACR_CP11_Pos) #define CPACR_CP11_FULL_ACCESS (3UL << _SCS_CPACR_CP11_Pos)
#define SCB_UFSR (*((__IOM uint16_t *) &SCB->CFSR + 2))
#define SCB_BFSR (*((__IOM uint8_t *) &SCB->CFSR + 1))
#define SCB_MMFSR (*((__IOM uint8_t *) &SCB->CFSR))
/* CFSR[UFSR] */
#define CFSR_DIVBYZERO_Pos (25U)
#define CFSR_DIVBYZERO_Msk (0x1U << CFSR_DIVBYZERO_Pos)
#define CFSR_UNALIGNED_Pos (24U)
#define CFSR_UNALIGNED_Msk (0x1U << CFSR_UNALIGNED_Pos)
#define CFSR_NOCP_Pos (19U)
#define CFSR_NOCP_Msk (0x1U << CFSR_NOCP_Pos)
#define CFSR_INVPC_Pos (18U)
#define CFSR_INVPC_Msk (0x1U << CFSR_INVPC_Pos)
#define CFSR_INVSTATE_Pos (17U)
#define CFSR_INVSTATE_Msk (0x1U << CFSR_INVSTATE_Pos)
#define CFSR_UNDEFINSTR_Pos (16U)
#define CFSR_UNDEFINSTR_Msk (0x1U << CFSR_UNDEFINSTR_Pos)
/* CFSR[BFSR] */
#define CFSR_BFARVALID_Pos (15U)
#define CFSR_BFARVALID_Msk (0x1U << CFSR_BFARVALID_Pos)
#define CFSR_LSPERR_Pos (13U)
#define CFSR_LSPERR_Msk (0x1U << CFSR_LSPERR_Pos)
#define CFSR_STKERR_Pos (12U)
#define CFSR_STKERR_Msk (0x1U << CFSR_STKERR_Pos)
#define CFSR_UNSTKERR_Pos (11U)
#define CFSR_UNSTKERR_Msk (0x1U << CFSR_UNSTKERR_Pos)
#define CFSR_IMPRECISERR_Pos (10U)
#define CFSR_IMPRECISERR_Msk (0x1U << CFSR_IMPRECISERR_Pos)
#define CFSR_PRECISERR_Pos (9U)
#define CFSR_PRECISERR_Msk (0x1U << CFSR_PRECISERR_Pos)
#define CFSR_IBUSERR_Pos (8U)
#define CFSR_IBUSERR_Msk (0x1U << CFSR_IBUSERR_Pos)
/* CFSR[MMFSR] */
#define CFSR_MMARVALID_Pos (7U)
#define CFSR_MMARVALID_Msk (0x1U << CFSR_MMARVALID_Pos)
#define CFSR_MLSPERR_Pos (5U)
#define CFSR_MLSPERR_Msk (0x1U << CFSR_MLSPERR_Pos)
#define CFSR_MSTKERR_Pos (4U)
#define CFSR_MSTKERR_Msk (0x1U << CFSR_MSTKERR_Pos)
#define CFSR_MUNSTKERR_Pos (3U)
#define CFSR_MUNSTKERR_Msk (0x1U << CFSR_MUNSTKERR_Pos)
#define CFSR_DACCVIOL_Pos (1U)
#define CFSR_DACCVIOL_Msk (0x1U << CFSR_DACCVIOL_Pos)
#define CFSR_IACCVIOL_Pos (0U)
#define CFSR_IACCVIOL_Msk (0x1U << CFSR_IACCVIOL_Pos)
/* Fill in CMSIS required values for non-CMSIS compliant SoCs. /* Fill in CMSIS required values for non-CMSIS compliant SoCs.
* Use __NVIC_PRIO_BITS as it is required and simple to check, but * Use __NVIC_PRIO_BITS as it is required and simple to check, but
* ultimately all SoCs will define their own CMSIS types and constants. * ultimately all SoCs will define their own CMSIS types and constants.

View file

@ -46,21 +46,6 @@ extern "C" {
#if defined(CONFIG_ARMV6_M) #if defined(CONFIG_ARMV6_M)
#elif defined(CONFIG_ARMV7_M) #elif defined(CONFIG_ARMV7_M)
/**
*
* @brief Find out if a hard fault is caused by a bus error on vector read
*
* This routine determines if a hard fault is caused by a bus error during
* a vector table read operation.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbHardFaultIsBusErrOnVectorRead(void)
{
return __scs.scb.hfsr.bit.vecttbl;
}
/** /**
* *
* @brief Clear all hard faults (HFSR register) * @brief Clear all hard faults (HFSR register)
@ -75,34 +60,6 @@ static inline int _ScbHardFaultAllFaultsReset(void)
return __scs.scb.hfsr.val = 0xffff; return __scs.scb.hfsr.val = 0xffff;
} }
/**
*
* @brief Find out if a hard fault is an MPU fault
*
* This routine determines if a hard fault is an MPU fault.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbIsMemFault(void)
{
return !!__scs.scb.cfsr.byte.mmfsr.val;
}
/**
*
* @brief Find out if the MMFAR register contains a valid value
*
* The MMFAR register contains the faulting address on an MPU fault.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbMemFaultIsMmfarValid(void)
{
return !!__scs.scb.cfsr.byte.mmfsr.bit.mmarvalid;
}
/** /**
* *
* @brief Invalid the value in MMFAR * @brief Invalid the value in MMFAR
@ -132,66 +89,6 @@ static inline void _ScbMemFaultAllFaultsReset(void)
__scs.scb.cfsr.byte.mmfsr.val = 0xfe; __scs.scb.cfsr.byte.mmfsr.val = 0xfe;
} }
/**
*
* @brief Find out if an MPU fault is a stacking fault
*
* This routine determines if an MPU fault is a stacking fault.
* This may occur upon exception entry.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbMemFaultIsStacking(void)
{
return !!__scs.scb.cfsr.byte.mmfsr.bit.mstkerr;
}
/**
*
* @brief Find out if an MPU fault is an unstacking fault
*
* This routine determines if an MPU fault is an unstacking fault.
* This may occur upon exception exit.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbMemFaultIsUnstacking(void)
{
return !!__scs.scb.cfsr.byte.mmfsr.bit.munstkerr;
}
/**
*
* @brief Find out if an MPU fault is a data access violation
*
* If this routine returns 1, read the MMFAR register via _ScbMemFaultAddrGet()
* to get the faulting address.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbMemFaultIsDataAccessViolation(void)
{
return !!__scs.scb.cfsr.byte.mmfsr.bit.daccviol;
}
/**
*
* @brief Find out if an MPU fault is an instruction access violation
*
* This routine determines if an MPU fault is due to an instruction access
* violation.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbMemFaultIsInstrAccessViolation(void)
{
return !!__scs.scb.cfsr.byte.mmfsr.bit.iaccviol;
}
/** /**
* *
* @brief Find out the faulting address on an MPU fault * @brief Find out the faulting address on an MPU fault
@ -204,34 +101,6 @@ static inline uint32_t _ScbMemFaultAddrGet(void)
return __scs.scb.mmfar; return __scs.scb.mmfar;
} }
/**
*
* @brief Find out if a hard fault is a bus fault
*
* This routine determines if a hard fault is a bus fault.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbIsBusFault(void)
{
return !!__scs.scb.cfsr.byte.bfsr.val;
}
/**
*
* @brief Find out if the BFAR register contains a valid value
*
* The BFAR register contains the faulting address on bus fault.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbBusFaultIsBfarValid(void)
{
return !!__scs.scb.cfsr.byte.bfsr.bit.bfarvalid;
}
/** /**
* *
* @brief Invalid the value in BFAR * @brief Invalid the value in BFAR
@ -261,80 +130,6 @@ static inline void _ScbBusFaultAllFaultsReset(void)
__scs.scb.cfsr.byte.bfsr.val = 0xfe; __scs.scb.cfsr.byte.bfsr.val = 0xfe;
} }
/**
*
* @brief Find out if a bus fault is a stacking fault
*
* This routine determines if a bus fault is a stacking fault.
* This may occurs upon exception entry.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbBusFaultIsStacking(void)
{
return !!__scs.scb.cfsr.byte.bfsr.bit.stkerr;
}
/**
*
* @brief Find out if a bus fault is an unstacking fault
*
* This routine determines if a bus fault is an unstacking fault.
* This may occur upon exception exit.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbBusFaultIsUnstacking(void)
{
return !!__scs.scb.cfsr.byte.bfsr.bit.unstkerr;
}
/**
*
* @brief Find out if a bus fault is an imprecise error
*
* This routine determines if a bus fault is an imprecise error.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbBusFaultIsImprecise(void)
{
return !!__scs.scb.cfsr.byte.bfsr.bit.impreciserr;
}
/**
*
* @brief Find out if a bus fault is an precise error
*
* Read the BFAR register via _ScbBusFaultAddrGet() if this routine returns 1,
* as it will contain the faulting address.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbBusFaultIsPrecise(void)
{
return !!__scs.scb.cfsr.byte.bfsr.bit.preciserr;
}
/**
*
* @brief Find out if a bus fault is an instruction bus error
*
* This routine determines if a bus fault is an instruction bus error.
* It is signalled only if the instruction is issued.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbBusFaultIsInstrBusErr(void)
{
return !!__scs.scb.cfsr.byte.bfsr.bit.ibuserr;
}
/** /**
* *
* @brief Get the faulting address on a precise bus fault * @brief Get the faulting address on a precise bus fault
@ -349,108 +144,6 @@ static inline uint32_t _ScbBusFaultAddrGet(void)
return __scs.scb.bfar; return __scs.scb.bfar;
} }
/**
*
* @brief Find out if a hard fault is a usage fault
*
* This routine determines if a hard fault is a usage fault.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbIsUsageFault(void)
{
return !!__scs.scb.cfsr.byte.ufsr.val;
}
/**
*
* @brief Find out if a usage fault is a 'divide by zero' fault
*
* This routine determines if a usage fault is a 'divide by zero' fault.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbUsageFaultIsDivByZero(void)
{
return !!__scs.scb.cfsr.byte.ufsr.bit.divbyzero;
}
/**
*
* @brief Find out if a usage fault is a unaligned access error
*
* This routine determines if a usage fault is an unaligned access error.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbUsageFaultIsUnaligned(void)
{
return !!__scs.scb.cfsr.byte.ufsr.bit.unaligned;
}
/**
*
* @brief Find out if a usage fault is a co-processor access error
*
* This routine determines if a usage fault is caused by a co-processor access.
* This happens if the co-processor is either absent or disabled.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbUsageFaultIsNoCp(void)
{
return !!__scs.scb.cfsr.byte.ufsr.bit.nocp;
}
/**
*
* @brief Find out if a usage fault is a invalid PC load error
*
* Happens if the the instruction address on an exception return is not
* halfword-aligned.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbUsageFaultIsInvalidPcLoad(void)
{
return !!__scs.scb.cfsr.byte.ufsr.bit.invpc;
}
/**
*
* @brief Find out if a usage fault is a invalid state error
*
* Happens if the the instruction address loaded in the PC via a branch, LDR or
* POP, or if the instruction address installed in a exception vector, does not
* have bit 0 set; i.e, is not halfword-aligned.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbUsageFaultIsInvalidState(void)
{
return !!__scs.scb.cfsr.byte.ufsr.bit.invstate;
}
/**
*
* @brief Find out if a usage fault is a undefined instruction error
*
* The processor tried to execute an invalid opcode.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbUsageFaultIsUndefinedInstr(void)
{
return !!__scs.scb.cfsr.byte.ufsr.bit.undefinstr;
}
/** /**
* *
* @brief Clear all usage faults (UFSR register) * @brief Clear all usage faults (UFSR register)