diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 016fd2f044f..d897ddc226a 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -593,6 +593,7 @@ config ARCH_CORTEXM3 select ARCH_HAVE_TESTSET select ARCH_HAVE_HARDFAULT_DEBUG select ARCH_HAVE_MEMFAULT_DEBUG + select ARCH_HAVE_BUSFAULT_DEBUG config ARCH_CORTEXM4 bool @@ -607,6 +608,7 @@ config ARCH_CORTEXM4 select ARCH_HAVE_TESTSET select ARCH_HAVE_HARDFAULT_DEBUG select ARCH_HAVE_MEMFAULT_DEBUG + select ARCH_HAVE_BUSFAULT_DEBUG config ARCH_CORTEXM7 bool @@ -622,6 +624,7 @@ config ARCH_CORTEXM7 select ARCH_HAVE_TESTSET select ARCH_HAVE_HARDFAULT_DEBUG select ARCH_HAVE_MEMFAULT_DEBUG + select ARCH_HAVE_BUSFAULT_DEBUG config ARCH_ARMV7A bool @@ -730,6 +733,7 @@ config ARCH_CORTEXM33 select ARCH_HAVE_TESTSET select ARCH_HAVE_HARDFAULT_DEBUG select ARCH_HAVE_MEMFAULT_DEBUG + select ARCH_HAVE_BUSFAULT_DEBUG config ARCH_CORTEXM35P bool @@ -744,6 +748,7 @@ config ARCH_CORTEXM35P select ARCH_HAVE_TESTSET select ARCH_HAVE_HARDFAULT_DEBUG select ARCH_HAVE_MEMFAULT_DEBUG + select ARCH_HAVE_BUSFAULT_DEBUG config ARCH_CORTEXM55 bool @@ -758,6 +763,7 @@ config ARCH_CORTEXM55 select ARCH_HAVE_TESTSET select ARCH_HAVE_HARDFAULT_DEBUG select ARCH_HAVE_MEMFAULT_DEBUG + select ARCH_HAVE_BUSFAULT_DEBUG config ARCH_FAMILY string @@ -967,6 +973,19 @@ config DEBUG_MEMFAULT output is sometimes helpful when debugging difficult mem fault problems, but may be more than you typically want to see. +config ARCH_HAVE_BUSFAULT_DEBUG + bool + default n + +config DEBUG_BUSFAULT + bool "Verbose Bus-Fault Debug" + default n + depends on ARCH_HAVE_BUSFAULT_DEBUG && DEBUG_ALERT + ---help--- + Enables verbose debug output when a bus fault is occurs. This verbose + output is sometimes helpful when debugging difficult bus fault problems, + but may be more than you typically want to see. + config ARM_SEMIHOSTING_SYSLOG bool "Semihosting SYSLOG support" select ARCH_SYSLOG diff --git a/arch/arm/src/armv7-m/arm_busfault.c b/arch/arm/src/armv7-m/arm_busfault.c new file mode 100644 index 00000000000..81b07fce8c9 --- /dev/null +++ b/arch/arm/src/armv7-m/arm_busfault.c @@ -0,0 +1,107 @@ +/**************************************************************************** + * arch/arm/src/armv7-m/arm_busfault.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +#include "arm_arch.h" +#include "nvic.h" +#include "arm_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_BUSFAULT +# define bfalert(format, ...) _alert(format, ##__VA_ARGS__) +#else +# define bfalert(x...) +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_busfault + * + * Description: + * This is Bus Fault exception handler. It also catches SVC call + * exceptions that are performed in bad contexts. + * + ****************************************************************************/ + +int arm_busfault(int irq, FAR void *context, FAR void *arg) +{ + uint32_t cfsr = getreg32(NVIC_CFAULTS); + + bfalert("PANIC!!! Bus Fault:\n"); + bfalert("\tIRQ: %d regs: %p\n", irq, context); + bfalert("\tBASEPRI: %08x PRIMASK: %08x IPSR: %08x CONTROL: %08x\n", + getbasepri(), getprimask(), getipsr(), getcontrol()); + bfalert("\tCFSR: %08x HFSR: %08x DFSR: %08x BFAR: %08x AFSR: %08x\n", + cfsr, getreg32(NVIC_HFAULTS), getreg32(NVIC_DFAULTS), + getreg32(NVIC_BFAULT_ADDR), getreg32(NVIC_AFAULTS)); + + bfalert("Bus Fault Reason:\n"); + if (cfsr & NVIC_CFAULTS_IBUSERR) + { + bfalert("\tInstruction bus error\n"); + } + + if (cfsr & NVIC_CFAULTS_PRECISERR) + { + bfalert("\tPrecise data bus error\n"); + } + + if (cfsr & NVIC_CFAULTS_IMPRECISERR) + { + bfalert("\tImprecise data bus error\n"); + } + + if (cfsr & NVIC_CFAULTS_UNSTKERR) + { + bfalert("\tBusFault on unstacking for a return from exception\n"); + } + + if (cfsr & NVIC_CFAULTS_STKERR) + { + bfalert("\tBusFault on stacking for exception entry\n"); + } + + if (cfsr & NVIC_CFAULTS_LSPERR) + { + bfalert("\tFloating-point lazy state preservation error\n"); + } + + up_irq_save(); + PANIC(); + return OK; +} diff --git a/arch/arm/src/armv8-m/arm_busfault.c b/arch/arm/src/armv8-m/arm_busfault.c new file mode 100644 index 00000000000..aae2bec914a --- /dev/null +++ b/arch/arm/src/armv8-m/arm_busfault.c @@ -0,0 +1,107 @@ +/**************************************************************************** + * arch/arm/src/armv8-m/arm_busfault.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +#include "arm_arch.h" +#include "nvic.h" +#include "arm_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_BUSFAULT +# define bfalert(format, ...) _alert(format, ##__VA_ARGS__) +#else +# define bfalert(x...) +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_busfault + * + * Description: + * This is Bus Fault exception handler. It also catches SVC call + * exceptions that are performed in bad contexts. + * + ****************************************************************************/ + +int arm_busfault(int irq, FAR void *context, FAR void *arg) +{ + uint32_t cfsr = getreg32(NVIC_CFAULTS); + + bfalert("PANIC!!! Bus Fault:\n"); + bfalert("\tIRQ: %d regs: %p\n", irq, context); + bfalert("\tBASEPRI: %08x PRIMASK: %08x IPSR: %08x CONTROL: %08x\n", + getbasepri(), getprimask(), getipsr(), getcontrol()); + bfalert("\tCFSR: %08x HFSR: %08x DFSR: %08x BFAR: %08x AFSR: %08x\n", + cfsr, getreg32(NVIC_HFAULTS), getreg32(NVIC_DFAULTS), + getreg32(NVIC_BFAULT_ADDR), getreg32(NVIC_AFAULTS)); + + bfalert("Bus Fault Reason:\n"); + if (cfsr & NVIC_CFAULTS_IBUSERR) + { + bfalert("\tInstruction bus error\n"); + } + + if (cfsr & NVIC_CFAULTS_PRECISERR) + { + bfalert("\tPrecise data bus error\n"); + } + + if (cfsr & NVIC_CFAULTS_IMPRECISERR) + { + bfalert("\tImprecise data bus error\n"); + } + + if (cfsr & NVIC_CFAULTS_UNSTKERR) + { + bfalert("\tBusFault on unstacking for a return from exception\n"); + } + + if (cfsr & NVIC_CFAULTS_STKERR) + { + bfalert("\tBusFault on stacking for exception entry\n"); + } + + if (cfsr & NVIC_CFAULTS_LSPERR) + { + bfalert("\tFloating-point lazy state preservation error\n"); + } + + up_irq_save(); + PANIC(); + return OK; +} diff --git a/arch/arm/src/common/arm_internal.h b/arch/arm/src/common/arm_internal.h index 0dd2d947d2e..5ee5707417b 100644 --- a/arch/arm/src/common/arm_internal.h +++ b/arch/arm/src/common/arm_internal.h @@ -343,6 +343,7 @@ int arm_hardfault(int irq, FAR void *context, FAR void *arg); # if defined(CONFIG_ARCH_ARMV7M) || defined(CONFIG_ARCH_ARMV8M) int arm_memfault(int irq, FAR void *context, FAR void *arg); +int arm_busfault(int irq, FAR void *context, FAR void *arg); # endif /* CONFIG_ARCH_CORTEXM3,4,7 */