arch: arm: correct fault address logging
In ARMv7-M (and ARMv8-M) architecture it is implementation defined whether separate MMFAR and BFAR are implemented. This commit ensures that we always get the true faulting address displayed in case of MemManage- or BusFault. Signed-off-by: Ioannis Glaropoulos <Ioannis.Glaropoulos@nordicsemi.no>
This commit is contained in:
parent
83fa6c9554
commit
571069e986
@ -21,8 +21,10 @@
|
||||
#ifdef CONFIG_PRINTK
|
||||
#include <misc/printk.h>
|
||||
#define PR_EXC(...) printk(__VA_ARGS__)
|
||||
#define STORE_xFAR(reg_var, reg) u32_t reg_var = (u32_t)reg
|
||||
#else
|
||||
#define PR_EXC(...)
|
||||
#define STORE_xFAR(reg_var, reg)
|
||||
#endif /* CONFIG_PRINTK */
|
||||
|
||||
#if (CONFIG_FAULT_DUMP > 0)
|
||||
@ -73,15 +75,26 @@ void _FaultDump(const NANO_ESF *esf, int fault)
|
||||
PR_EXC("MMFSR: 0x%x, BFSR: 0x%x, UFSR: 0x%x\n",
|
||||
SCB_MMFSR, SCB_BFSR, SCB_MMFSR);
|
||||
|
||||
/* In a fault handler, to determine the true faulting address:
|
||||
* 1. Read and save the MMFAR or BFAR value.
|
||||
* 2. Read the MMARVALID bit in the MMFSR, or the BFARVALID bit in the
|
||||
* BFSR. The MMFAR or BFAR address is valid only if this bit is 1.
|
||||
*
|
||||
* Software must follow this sequence because another higher priority
|
||||
* exception might change the MMFAR or BFAR value.
|
||||
*/
|
||||
STORE_xFAR(mmfar, SCB->MMFAR);
|
||||
STORE_xFAR(bfar, SCB->BFAR);
|
||||
|
||||
if (SCB->CFSR & CFSR_MMARVALID_Msk) {
|
||||
PR_EXC("MMFAR: 0x%x\n", SCB->MMFAR);
|
||||
PR_EXC("MMFAR: 0x%x\n", mmfar);
|
||||
if (escalation) {
|
||||
/* clear MMAR[VALID] to reset */
|
||||
SCB->CFSR &= ~CFSR_MMARVALID_Msk;
|
||||
}
|
||||
}
|
||||
if (SCB->CFSR & CFSR_BFARVALID_Msk) {
|
||||
PR_EXC("BFAR: 0x%x\n", SCB->BFAR);
|
||||
PR_EXC("BFAR: 0x%x\n", bfar);
|
||||
if (escalation) {
|
||||
/* clear CFSR_BFAR[VALID] to reset */
|
||||
SCB->CFSR &= ~CFSR_BFARVALID_Msk;
|
||||
@ -136,8 +149,18 @@ static void _MpuFault(const NANO_ESF *esf, int fromHardFault)
|
||||
PR_EXC(" Unstacking error\n");
|
||||
} else if (SCB->CFSR & CFSR_DACCVIOL_Msk) {
|
||||
PR_EXC(" Data Access Violation\n");
|
||||
/* In a fault handler, to determine the true faulting address:
|
||||
* 1. Read and save the MMFAR value.
|
||||
* 2. Read the MMARVALID bit in the MMFSR.
|
||||
* The MMFAR address is valid only if this bit is 1.
|
||||
*
|
||||
* Software must follow this sequence because another higher
|
||||
* priority exception might change the MMFAR value.
|
||||
*/
|
||||
STORE_xFAR(mmfar, SCB->MMFAR);
|
||||
|
||||
if (SCB->CFSR & CFSR_MMARVALID_Msk) {
|
||||
PR_EXC(" Address: 0x%x\n", (u32_t)SCB->MMFAR);
|
||||
PR_EXC(" Address: 0x%x\n", mmfar);
|
||||
if (fromHardFault) {
|
||||
/* clear MMAR[VALID] to reset */
|
||||
SCB->CFSR &= ~CFSR_MMARVALID_Msk;
|
||||
@ -168,8 +191,18 @@ static void _BusFault(const NANO_ESF *esf, int fromHardFault)
|
||||
PR_EXC(" Unstacking error\n");
|
||||
} else if (SCB->CFSR & CFSR_PRECISERR_Msk) {
|
||||
PR_EXC(" Precise data bus error\n");
|
||||
/* In a fault handler, to determine the true faulting address:
|
||||
* 1. Read and save the BFAR value.
|
||||
* 2. Read the BFARVALID bit in the BFSR.
|
||||
* The BFAR address is valid only if this bit is 1.
|
||||
*
|
||||
* Software must follow this sequence because another
|
||||
* higher priority exception might change the BFAR value.
|
||||
*/
|
||||
STORE_xFAR(bfar, SCB->BFAR);
|
||||
|
||||
if (SCB->CFSR & CFSR_BFARVALID_Msk) {
|
||||
PR_EXC(" Address: 0x%x\n", (u32_t)SCB->BFAR);
|
||||
PR_EXC(" Address: 0x%x\n", bfar);
|
||||
if (fromHardFault) {
|
||||
/* clear CFSR_BFAR[VALID] to reset */
|
||||
SCB->CFSR &= ~CFSR_BFARVALID_Msk;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user