From d2679c7bbbdde59d8dca362355feaac63d02ba99 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Fri, 27 Jan 2017 20:20:24 -0600 Subject: [PATCH] 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 Signed-off-by: Maureen Helm --- arch/arm/core/fault.c | 48 ++--- include/arch/arm/cortex_m/cmsis.h | 49 +++++ include/arch/arm/cortex_m/scb.h | 307 ------------------------------ 3 files changed, 73 insertions(+), 331 deletions(-) diff --git a/arch/arm/core/fault.c b/arch/arm/core/fault.c index 347b9b48446..1c92ba60d4d 100644 --- a/arch/arm/core/fault.c +++ b/arch/arm/core/fault.c @@ -76,13 +76,13 @@ void _FaultDump(const NANO_ESF *esf, int fault) __scs.scb.cfsr.byte.bfsr.val, __scs.scb.cfsr.byte.ufsr.val); - if (_ScbMemFaultIsMmfarValid()) { + if (SCB->CFSR & CFSR_MMARVALID_Msk) { PR_EXC("MMFAR: 0x%" PRIx32 "\n", _ScbMemFaultAddrGet()); if (escalation) { _ScbMemFaultMmfarReset(); } } - if (_ScbBusFaultIsBfarValid()) { + if (SCB->CFSR & CFSR_BFARVALID_Msk) { PR_EXC("BFAR: 0x%" PRIx32 "\n", _ScbBusFaultAddrGet()); if (escalation) { _ScbBusFaultBfarReset(); @@ -130,20 +130,20 @@ static void _MpuFault(const NANO_ESF *esf, int fromHardFault) _FaultThreadShow(esf); - if (_ScbMemFaultIsStacking()) { + if (SCB->CFSR & CFSR_MSTKERR_Msk) { PR_EXC(" Stacking error\n"); - } else if (_ScbMemFaultIsUnstacking()) { + } else if (SCB->CFSR & CFSR_MUNSTKERR_Msk) { PR_EXC(" Unstacking error\n"); - } else if (_ScbMemFaultIsDataAccessViolation()) { + } else if (SCB->CFSR & CFSR_DACCVIOL_Msk) { PR_EXC(" Data Access Violation\n"); - if (_ScbMemFaultIsMmfarValid()) { + if (SCB->CFSR & CFSR_MMARVALID_Msk) { PR_EXC(" Address: 0x%" PRIx32 "\n", _ScbMemFaultAddrGet()); if (fromHardFault) { _ScbMemFaultMmfarReset(); } } - } else if (_ScbMemFaultIsInstrAccessViolation()) { + } else if (SCB->CFSR & CFSR_IACCVIOL_Msk) { PR_EXC(" Instruction Access Violation\n"); } } @@ -162,13 +162,13 @@ static void _BusFault(const NANO_ESF *esf, int fromHardFault) _FaultThreadShow(esf); - if (_ScbBusFaultIsStacking()) { + if (SCB->CFSR & CFSR_STKERR_Msk) { PR_EXC(" Stacking error\n"); - } else if (_ScbBusFaultIsUnstacking()) { + } else if (SCB->CFSR & CFSR_UNSTKERR_Msk) { PR_EXC(" Unstacking error\n"); - } else if (_ScbBusFaultIsPrecise()) { + } else if (SCB->CFSR & CFSR_PRECISERR_Msk) { PR_EXC(" Precise data bus error\n"); - if (_ScbBusFaultIsBfarValid()) { + if (SCB->CFSR & CFSR_BFARVALID_Msk) { PR_EXC(" Address: 0x%" PRIx32 "\n", _ScbBusFaultAddrGet()); 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 */ - if (_ScbBusFaultIsImprecise()) { + if (SCB->CFSR & CFSR_IMPRECISERR_Msk) { PR_EXC(" Imprecise data bus error\n"); } - } else if (_ScbBusFaultIsImprecise()) { + } else if (SCB->CFSR & CFSR_IMPRECISERR_Msk) { PR_EXC(" Imprecise data bus error\n"); - } else if (_ScbBusFaultIsInstrBusErr()) { + } else if (SCB->CFSR & CFSR_IBUSERR_Msk) { PR_EXC(" Instruction bus error\n"); } } @@ -201,22 +201,22 @@ static void _UsageFault(const NANO_ESF *esf) _FaultThreadShow(esf); /* bits are sticky: they stack and must be reset */ - if (_ScbUsageFaultIsDivByZero()) { + if (SCB->CFSR & CFSR_DIVBYZERO_Msk) { PR_EXC(" Division by zero\n"); } - if (_ScbUsageFaultIsUnaligned()) { + if (SCB->CFSR & CFSR_UNALIGNED_Msk) { PR_EXC(" Unaligned memory access\n"); } - if (_ScbUsageFaultIsNoCp()) { + if (SCB->CFSR & CFSR_NOCP_Msk) { PR_EXC(" No coprocessor instructions\n"); } - if (_ScbUsageFaultIsInvalidPcLoad()) { + if (SCB->CFSR & CFSR_INVPC_Msk) { 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"); } - if (_ScbUsageFaultIsUndefinedInstr()) { + if (SCB->CFSR & CFSR_UNDEFINSTR_Msk) { PR_EXC(" Attempt to execute undefined instruction\n"); } @@ -257,15 +257,15 @@ static void _HardFault(const NANO_ESF *esf) #if defined(CONFIG_ARMV6_M) _FaultThreadShow(esf); #elif defined(CONFIG_ARMV7_M) - if (_ScbHardFaultIsBusErrOnVectorRead()) { + if (SCB->HFSR & SCB_HFSR_VECTTBL_Msk) { PR_EXC(" Bus fault on vector table read\n"); } else if (SCB->HFSR & SCB_HFSR_FORCED_Msk) { PR_EXC(" Fault escalation (see below)\n"); - if (_ScbIsMemFault()) { + if (SCB_MMFSR) { _MpuFault(esf, 1); - } else if (_ScbIsBusFault()) { + } else if (SCB_BFSR) { _BusFault(esf, 1); - } else if (_ScbIsUsageFault()) { + } else if (SCB_UFSR) { _UsageFault(esf); } } diff --git a/include/arch/arm/cortex_m/cmsis.h b/include/arch/arm/cortex_m/cmsis.h index 097fe011e27..714bb6791ed 100644 --- a/include/arch/arm/cortex_m/cmsis.h +++ b/include/arch/arm/cortex_m/cmsis.h @@ -36,6 +36,55 @@ extern "C" { #define CPACR_CP11_RESERVED (2UL << _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. * Use __NVIC_PRIO_BITS as it is required and simple to check, but * ultimately all SoCs will define their own CMSIS types and constants. diff --git a/include/arch/arm/cortex_m/scb.h b/include/arch/arm/cortex_m/scb.h index 7394897c57e..de7f1f36bf8 100644 --- a/include/arch/arm/cortex_m/scb.h +++ b/include/arch/arm/cortex_m/scb.h @@ -46,21 +46,6 @@ extern "C" { #if defined(CONFIG_ARMV6_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) @@ -75,34 +60,6 @@ static inline int _ScbHardFaultAllFaultsReset(void) 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 @@ -132,66 +89,6 @@ static inline void _ScbMemFaultAllFaultsReset(void) __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 @@ -204,34 +101,6 @@ static inline uint32_t _ScbMemFaultAddrGet(void) 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 @@ -261,80 +130,6 @@ static inline void _ScbBusFaultAllFaultsReset(void) __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 @@ -349,108 +144,6 @@ static inline uint32_t _ScbBusFaultAddrGet(void) 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)