You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2021/12/09 17:42:35 UTC

[incubator-nuttx] branch master updated (99fa58c -> 3d75c25)

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git.


    from 99fa58c  arm/cortex-m23: armv8-m baseline do not support mem-fault
     new 2f44924  cortex-m/hardfault: add bus-fault handler
     new 66e604b  cortex-m/hardfault: add usage-fault handler
     new 3d75c25  cortex-m/hardfault: enhance the dump information of mem/hard-fault

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 arch/arm/Kconfig                                   | 38 ++++++++++
 .../arm_memfault.c => armv7-m/arm_busfault.c}      | 72 +++++++++++++------
 arch/arm/src/armv7-m/arm_hardfault.c               | 57 ++++++++++++---
 arch/arm/src/armv7-m/arm_memfault.c                | 49 +++++++++----
 .../armv7-m/{arm_memfault.c => arm_usagefault.c}   | 82 ++++++++++++++++------
 .../src/armv8-m/{arm_memfault.c => arm_busfault.c} | 72 +++++++++++++------
 arch/arm/src/armv8-m/arm_hardfault.c               | 57 ++++++++++++---
 arch/arm/src/armv8-m/arm_memfault.c                | 49 ++++++++++---
 .../arm_memfault.c => armv8-m/arm_usagefault.c}    | 82 ++++++++++++++++------
 arch/arm/src/common/arm_internal.h                 |  2 +
 10 files changed, 431 insertions(+), 129 deletions(-)
 copy arch/arm/src/{armv8-m/arm_memfault.c => armv7-m/arm_busfault.c} (55%)
 copy arch/arm/src/armv7-m/{arm_memfault.c => arm_usagefault.c} (53%)
 copy arch/arm/src/armv8-m/{arm_memfault.c => arm_busfault.c} (55%)
 copy arch/arm/src/{armv7-m/arm_memfault.c => armv8-m/arm_usagefault.c} (53%)

[incubator-nuttx] 01/03: cortex-m/hardfault: add bus-fault handler

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 2f449245cc60217c1975db5344d19937ab829540
Author: chao.an <an...@xiaomi.com>
AuthorDate: Tue Nov 30 21:55:48 2021 +0800

    cortex-m/hardfault: add bus-fault handler
    
    Signed-off-by: chao.an <an...@xiaomi.com>
---
 arch/arm/Kconfig                    |  19 +++++++
 arch/arm/src/armv7-m/arm_busfault.c | 107 ++++++++++++++++++++++++++++++++++++
 arch/arm/src/armv8-m/arm_busfault.c | 107 ++++++++++++++++++++++++++++++++++++
 arch/arm/src/common/arm_internal.h  |   1 +
 4 files changed, 234 insertions(+)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 016fd2f..d897ddc 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 0000000..81b07fc
--- /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 <nuttx/config.h>
+
+#include <stdint.h>
+#include <string.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <arch/irq.h>
+
+#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 0000000..aae2bec
--- /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 <nuttx/config.h>
+
+#include <stdint.h>
+#include <string.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <arch/irq.h>
+
+#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 0dd2d94..5ee5707 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 */
 

[incubator-nuttx] 03/03: cortex-m/hardfault: enhance the dump information of mem/hard-fault

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 3d75c25737dceb0caaefe3204c3e221ddbf7336f
Author: chao.an <an...@xiaomi.com>
AuthorDate: Tue Nov 30 22:04:05 2021 +0800

    cortex-m/hardfault: enhance the dump information of mem/hard-fault
    
    Signed-off-by: chao.an <an...@xiaomi.com>
---
 arch/arm/src/armv7-m/arm_hardfault.c | 57 ++++++++++++++++++++++++++++++------
 arch/arm/src/armv7-m/arm_memfault.c  | 49 +++++++++++++++++++++++--------
 arch/arm/src/armv8-m/arm_hardfault.c | 57 ++++++++++++++++++++++++++++++------
 arch/arm/src/armv8-m/arm_memfault.c  | 49 ++++++++++++++++++++++++-------
 4 files changed, 171 insertions(+), 41 deletions(-)

diff --git a/arch/arm/src/armv7-m/arm_hardfault.c b/arch/arm/src/armv7-m/arm_hardfault.c
index 2b88647..8b89dfd 100644
--- a/arch/arm/src/armv7-m/arm_hardfault.c
+++ b/arch/arm/src/armv7-m/arm_hardfault.c
@@ -74,6 +74,11 @@
 
 int arm_hardfault(int irq, FAR void *context, FAR void *arg)
 {
+  uint32_t hfsr = getreg32(NVIC_HFAULTS);
+  uint32_t cfsr = getreg32(NVIC_CFAULTS);
+
+  UNUSED(cfsr);
+
   /* Get the value of the program counter where the fault occurred */
 
 #ifndef CONFIG_ARMV7M_USEBASEPRI
@@ -118,20 +123,54 @@ int arm_hardfault(int irq, FAR void *context, FAR void *arg)
     }
 #endif
 
+  if (hfsr & NVIC_HFAULTS_FORCED)
+    {
+      hfalert("Hard Fault escalation:\n");
+
+#ifdef CONFIG_DEBUG_MEMFAULT
+      if (cfsr & NVIC_CFAULTS_MEMFAULTSR_MASK)
+        {
+          return arm_memfault(irq, context, arg);
+        }
+#endif /* CONFIG_DEBUG_MEMFAULT */
+
+#ifdef CONFIG_DEBUG_BUSFAULT
+      if (cfsr & NVIC_CFAULTS_BUSFAULTSR_MASK)
+        {
+          return arm_busfault(irq, context, arg);
+        }
+#endif /* CONFIG_DEBUG_BUSFAULT */
+
+#ifdef CONFIG_DEBUG_USAGEFAULT
+      if (cfsr & NVIC_CFAULTS_USGFAULTSR_MASK)
+        {
+          return arm_usagefault(irq, context, arg);
+        }
+#endif /* CONFIG_DEBUG_USAGEFAULT */
+    }
+
   /* Dump some hard fault info */
 
-  hfalert("Hard Fault:\n");
-  hfalert("  IRQ: %d regs: %p\n", irq, context);
-  hfalert("  BASEPRI: %08x PRIMASK: %08x IPSR: %08x CONTROL: %08x\n",
+  hfalert("PANIC!!! Hard Fault!:");
+  hfalert("\tIRQ: %d regs: %p\n", irq, context);
+  hfalert("\tBASEPRI: %08x PRIMASK: %08x IPSR: %08x CONTROL: %08x\n",
           getbasepri(), getprimask(), getipsr(), getcontrol());
-  hfalert("  CFAULTS: %08x HFAULTS: %08x DFAULTS: %08x BFAULTADDR: %08x "
-          "AFAULTS: %08x\n",
-          getreg32(NVIC_CFAULTS), getreg32(NVIC_HFAULTS),
-          getreg32(NVIC_DFAULTS), getreg32(NVIC_BFAULT_ADDR),
-          getreg32(NVIC_AFAULTS));
+  hfalert("\tCFSR: %08x HFSR: %08x DFSR: %08x BFAR: %08x AFSR: %08x\n",
+          cfsr, hfsr, getreg32(NVIC_DFAULTS),
+          getreg32(NVIC_BFAULT_ADDR), getreg32(NVIC_AFAULTS));
+
+  hfalert("Hard Fault Reason:\n");
+
+  if (hfsr & NVIC_HFAULTS_VECTTBL)
+    {
+      hfalert("\tBusFault on a vector table read\n");
+    }
+  else if (hfsr & NVIC_HFAULTS_DEBUGEVT)
+    {
+      hfalert("\tDebug event\n");
+    }
 
   up_irq_save();
-  _alert("PANIC!!! Hard fault: %08" PRIx32 "\n", getreg32(NVIC_HFAULTS));
   PANIC();
   return OK;
 }
diff --git a/arch/arm/src/armv7-m/arm_memfault.c b/arch/arm/src/armv7-m/arm_memfault.c
index db932a9..0e4a717 100644
--- a/arch/arm/src/armv7-m/arm_memfault.c
+++ b/arch/arm/src/armv7-m/arm_memfault.c
@@ -39,11 +39,9 @@
  ****************************************************************************/
 
 #ifdef CONFIG_DEBUG_MEMFAULT
-# define mferr(format, ...)  _alert(format, ##__VA_ARGS__)
-# define mfinfo(format, ...) _alert(format, ##__VA_ARGS__)
+# define mfalert(format, ...)  _alert(format, ##__VA_ARGS__)
 #else
-# define mferr(x...)
-# define mfinfo(x...)
+# define mfalert(x...)
 #endif
 
 /****************************************************************************
@@ -63,17 +61,44 @@
 
 int arm_memfault(int irq, FAR void *context, FAR void *arg)
 {
+  uint32_t cfsr = getreg32(NVIC_CFAULTS);
+
   /* Dump some memory management fault info */
 
-  up_irq_save();
-  _alert("PANIC!!! Memory Management Fault:\n");
-  mfinfo("  IRQ: %d context: %p\n", irq, context);
-  _alert("  CFAULTS: %08" PRIx32 " MMFAR: %08" PRIx32 "\n",
-        getreg32(NVIC_CFAULTS), getreg32(NVIC_MEMMANAGE_ADDR));
-  mfinfo("  BASEPRI: %08" PRIx32 " PRIMASK: %08" PRIx32
-         " IPSR: %08" PRIx32 " CONTROL: %08" PRIx32 "\n",
-         getbasepri(), getprimask(), getipsr(), getcontrol());
+  mfalert("PANIC!!! Memory Management Fault:\n");
+  mfalert("\tIRQ: %d context: %p\n", irq, context);
+  mfalert("\tCFSR: %08x MMFAR: %08x\n",
+          getreg32(NVIC_CFAULTS), getreg32(NVIC_MEMMANAGE_ADDR));
+  mfalert("\tBASEPRI: %08x PRIMASK: %08x IPSR: %08x CONTROL: %08x\n",
+          getbasepri(), getprimask(), getipsr(), getcontrol());
+
+  mfalert("Memory Management Fault Reason:\n");
+  if (cfsr & NVIC_CFAULTS_IACCVIOL)
+    {
+      mfalert("\tInstruction access violation\n");
+    }
+
+  if (cfsr & NVIC_CFAULTS_DACCVIOL)
+    {
+      mfalert("\tData access violation\n");
+    }
 
+  if (cfsr & NVIC_CFAULTS_MUNSTKERR)
+    {
+      mfalert("\tMemManage fault on unstacking\n");
+    }
+
+  if (cfsr & NVIC_CFAULTS_MSTKERR)
+    {
+      mfalert("\tMemManage fault on stacking\n");
+    }
+
+  if (cfsr & NVIC_CFAULTS_MLSPERR)
+    {
+      mfalert("\tFloating-point lazy state preservation error\n");
+    }
+
+  up_irq_save();
   PANIC();
   return OK; /* Won't get here */
 }
diff --git a/arch/arm/src/armv8-m/arm_hardfault.c b/arch/arm/src/armv8-m/arm_hardfault.c
index 8ff2478..dd413c3 100644
--- a/arch/arm/src/armv8-m/arm_hardfault.c
+++ b/arch/arm/src/armv8-m/arm_hardfault.c
@@ -73,6 +73,11 @@
 
 int arm_hardfault(int irq, FAR void *context, FAR void *arg)
 {
+  uint32_t hfsr = getreg32(NVIC_HFAULTS);
+  uint32_t cfsr = getreg32(NVIC_CFAULTS);
+
+  UNUSED(cfsr);
+
   /* Get the value of the program counter where the fault occurred */
 
 #ifndef CONFIG_ARMV8M_USEBASEPRI
@@ -117,20 +122,54 @@ int arm_hardfault(int irq, FAR void *context, FAR void *arg)
     }
 #endif
 
+  if (hfsr & NVIC_HFAULTS_FORCED)
+    {
+      hfalert("Hard Fault escalation:\n");
+
+#ifdef CONFIG_DEBUG_MEMFAULT
+      if (cfsr & NVIC_CFAULTS_MEMFAULTSR_MASK)
+        {
+          return arm_memfault(irq, context, arg);
+        }
+#endif /* CONFIG_DEBUG_MEMFAULT */
+
+#ifdef CONFIG_DEBUG_BUSFAULT
+      if (cfsr & NVIC_CFAULTS_BUSFAULTSR_MASK)
+        {
+          return arm_busfault(irq, context, arg);
+        }
+#endif /* CONFIG_DEBUG_BUSFAULT */
+
+#ifdef CONFIG_DEBUG_USAGEFAULT
+      if (cfsr & NVIC_CFAULTS_USGFAULTSR_MASK)
+        {
+          return arm_usagefault(irq, context, arg);
+        }
+#endif /* CONFIG_DEBUG_USAGEFAULT */
+    }
+
   /* Dump some hard fault info */
 
-  hfalert("Hard Fault:\n");
-  hfalert("  IRQ: %d regs: %p\n", irq, context);
-  hfalert("  BASEPRI: %08x PRIMASK: %08x IPSR: %08x CONTROL: %08x\n",
+  hfalert("PANIC!!! Hard Fault!:");
+  hfalert("\tIRQ: %d regs: %p\n", irq, context);
+  hfalert("\tBASEPRI: %08x PRIMASK: %08x IPSR: %08x CONTROL: %08x\n",
           getbasepri(), getprimask(), getipsr(), getcontrol());
-  hfalert("  CFAULTS: %08x HFAULTS: %08x DFAULTS: %08x BFAULTADDR: %08x "
-          "AFAULTS: %08x\n",
-          getreg32(NVIC_CFAULTS), getreg32(NVIC_HFAULTS),
-          getreg32(NVIC_DFAULTS), getreg32(NVIC_BFAULT_ADDR),
-          getreg32(NVIC_AFAULTS));
+  hfalert("\tCFSR: %08x HFSR: %08x DFSR: %08x BFAR: %08x AFSR: %08x\n",
+          cfsr, hfsr, getreg32(NVIC_DFAULTS),
+          getreg32(NVIC_BFAULT_ADDR), getreg32(NVIC_AFAULTS));
+
+  hfalert("Hard Fault Reason:\n");
+
+  if (hfsr & NVIC_HFAULTS_VECTTBL)
+    {
+      hfalert("\tBusFault on a vector table read\n");
+    }
+  else if (hfsr & NVIC_HFAULTS_DEBUGEVT)
+    {
+      hfalert("\tDebug event\n");
+    }
 
   up_irq_save();
-  _alert("PANIC!!! Hard fault: %08x\n", getreg32(NVIC_HFAULTS));
   PANIC();
   return OK;
 }
diff --git a/arch/arm/src/armv8-m/arm_memfault.c b/arch/arm/src/armv8-m/arm_memfault.c
index b9f0b1f..a1f4d5d 100644
--- a/arch/arm/src/armv8-m/arm_memfault.c
+++ b/arch/arm/src/armv8-m/arm_memfault.c
@@ -26,6 +26,7 @@
 
 #include <assert.h>
 #include <debug.h>
+#include <inttypes.h>
 
 #include <arch/irq.h>
 
@@ -38,11 +39,9 @@
  ****************************************************************************/
 
 #ifdef CONFIG_DEBUG_MEMFAULT
-# define mferr(format, ...)  _alert(format, ##__VA_ARGS__)
-# define mfinfo(format, ...) _alert(format, ##__VA_ARGS__)
+# define mfalert(format, ...)  _alert(format, ##__VA_ARGS__)
 #else
-# define mferr(x...)
-# define mfinfo(x...)
+# define mfalert(x...)
 #endif
 
 /****************************************************************************
@@ -62,16 +61,44 @@
 
 int arm_memfault(int irq, FAR void *context, FAR void *arg)
 {
+  uint32_t cfsr = getreg32(NVIC_CFAULTS);
+
   /* Dump some memory management fault info */
 
-  up_irq_save();
-  _alert("PANIC!!! Memory Management Fault:\n");
-  mfinfo("  IRQ: %d context: %p\n", irq, context);
-  _alert("  CFAULTS: %08x MMFAR: %08x\n",
-        getreg32(NVIC_CFAULTS), getreg32(NVIC_MEMMANAGE_ADDR));
-  mfinfo("  BASEPRI: %08x PRIMASK: %08x IPSR: %08x CONTROL: %08x\n",
-         getbasepri(), getprimask(), getipsr(), getcontrol());
+  mfalert("PANIC!!! Memory Management Fault:\n");
+  mfalert("\tIRQ: %d context: %p\n", irq, context);
+  mfalert("\tCFSR: %08x MMFAR: %08x\n",
+          getreg32(NVIC_CFAULTS), getreg32(NVIC_MEMMANAGE_ADDR));
+  mfalert("\tBASEPRI: %08x PRIMASK: %08x IPSR: %08x CONTROL: %08x\n",
+          getbasepri(), getprimask(), getipsr(), getcontrol());
+
+  mfalert("Memory Management Fault Reason:\n");
+  if (cfsr & NVIC_CFAULTS_IACCVIOL)
+    {
+      mfalert("\tInstruction access violation\n");
+    }
+
+  if (cfsr & NVIC_CFAULTS_DACCVIOL)
+    {
+      mfalert("\tData access violation\n");
+    }
 
+  if (cfsr & NVIC_CFAULTS_MUNSTKERR)
+    {
+      mfalert("\tMemManage fault on unstacking\n");
+    }
+
+  if (cfsr & NVIC_CFAULTS_MSTKERR)
+    {
+      mfalert("\tMemManage fault on stacking\n");
+    }
+
+  if (cfsr & NVIC_CFAULTS_MLSPERR)
+    {
+      mfalert("\tFloating-point lazy state preservation error\n");
+    }
+
+  up_irq_save();
   PANIC();
   return OK; /* Won't get here */
 }

[incubator-nuttx] 02/03: cortex-m/hardfault: add usage-fault handler

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 66e604b40e16e1a7b42c19617d598296f410bb5c
Author: chao.an <an...@xiaomi.com>
AuthorDate: Thu Dec 9 17:40:50 2021 +0800

    cortex-m/hardfault: add usage-fault handler
    
    Signed-off-by: chao.an <an...@xiaomi.com>
---
 arch/arm/Kconfig                      |  19 ++++++
 arch/arm/src/armv7-m/arm_usagefault.c | 115 ++++++++++++++++++++++++++++++++++
 arch/arm/src/armv8-m/arm_usagefault.c | 115 ++++++++++++++++++++++++++++++++++
 arch/arm/src/common/arm_internal.h    |   1 +
 4 files changed, 250 insertions(+)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index d897ddc..bae9401 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -594,6 +594,7 @@ config ARCH_CORTEXM3
 	select ARCH_HAVE_HARDFAULT_DEBUG
 	select ARCH_HAVE_MEMFAULT_DEBUG
 	select ARCH_HAVE_BUSFAULT_DEBUG
+	select ARCH_HAVE_USAGEFAULT_DEBUG
 
 config ARCH_CORTEXM4
 	bool
@@ -609,6 +610,7 @@ config ARCH_CORTEXM4
 	select ARCH_HAVE_HARDFAULT_DEBUG
 	select ARCH_HAVE_MEMFAULT_DEBUG
 	select ARCH_HAVE_BUSFAULT_DEBUG
+	select ARCH_HAVE_USAGEFAULT_DEBUG
 
 config ARCH_CORTEXM7
 	bool
@@ -625,6 +627,7 @@ config ARCH_CORTEXM7
 	select ARCH_HAVE_HARDFAULT_DEBUG
 	select ARCH_HAVE_MEMFAULT_DEBUG
 	select ARCH_HAVE_BUSFAULT_DEBUG
+	select ARCH_HAVE_USAGEFAULT_DEBUG
 
 config ARCH_ARMV7A
 	bool
@@ -734,6 +737,7 @@ config ARCH_CORTEXM33
 	select ARCH_HAVE_HARDFAULT_DEBUG
 	select ARCH_HAVE_MEMFAULT_DEBUG
 	select ARCH_HAVE_BUSFAULT_DEBUG
+	select ARCH_HAVE_USAGEFAULT_DEBUG
 
 config ARCH_CORTEXM35P
 	bool
@@ -749,6 +753,7 @@ config ARCH_CORTEXM35P
 	select ARCH_HAVE_HARDFAULT_DEBUG
 	select ARCH_HAVE_MEMFAULT_DEBUG
 	select ARCH_HAVE_BUSFAULT_DEBUG
+	select ARCH_HAVE_USAGEFAULT_DEBUG
 
 config ARCH_CORTEXM55
 	bool
@@ -764,6 +769,7 @@ config ARCH_CORTEXM55
 	select ARCH_HAVE_HARDFAULT_DEBUG
 	select ARCH_HAVE_MEMFAULT_DEBUG
 	select ARCH_HAVE_BUSFAULT_DEBUG
+	select ARCH_HAVE_USAGEFAULT_DEBUG
 
 config ARCH_FAMILY
 	string
@@ -986,6 +992,19 @@ config DEBUG_BUSFAULT
 		output is sometimes helpful when debugging difficult bus fault problems,
 		but may be more than you typically want to see.
 
+config ARCH_HAVE_USAGEFAULT_DEBUG
+	bool
+	default n
+
+config DEBUG_USAGEFAULT
+	bool "Verbose Usage-Fault Debug"
+	default n
+	depends on ARCH_HAVE_USAGEFAULT_DEBUG && DEBUG_ALERT
+	---help---
+		Enables verbose debug output when a usage fault is occurs.  This verbose
+		output is sometimes helpful when debugging difficult usage 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_usagefault.c b/arch/arm/src/armv7-m/arm_usagefault.c
new file mode 100644
index 0000000..9a759cc
--- /dev/null
+++ b/arch/arm/src/armv7-m/arm_usagefault.c
@@ -0,0 +1,115 @@
+/****************************************************************************
+ * arch/arm/src/armv7-m/arm_usagefault.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 <nuttx/config.h>
+
+#include <stdint.h>
+#include <string.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <arch/irq.h>
+
+#include "arm_arch.h"
+#include "nvic.h"
+#include "arm_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_USAGEFAULT
+# define ufalert(format, ...)  _alert(format, ##__VA_ARGS__)
+#else
+# define ufalert(x...)
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: arm_usagefault
+ *
+ * Description:
+ *   This is Usage Fault exception handler.  It also catches SVC call
+ *   exceptions that are performed in bad contexts.
+ *
+ ****************************************************************************/
+
+int arm_usagefault(int irq, FAR void *context, FAR void *arg)
+{
+  uint32_t cfsr = getreg32(NVIC_CFAULTS);
+
+  /* Dump some usage fault info */
+
+  ufalert("PANIC!!! Usage Fault:\n");
+  ufalert("\tIRQ: %d regs: %p\n", irq, context);
+  ufalert("\tBASEPRI: %08x PRIMASK: %08x IPSR: %08x CONTROL: %08x\n",
+          getbasepri(), getprimask(), getipsr(), getcontrol());
+  ufalert("\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));
+
+  ufalert("Usage Fault Reason:\n");
+  if (cfsr & NVIC_CFAULTS_UNDEFINSTR)
+    {
+      ufalert("\tUndefined instruction\n");
+    }
+
+  if (cfsr & NVIC_CFAULTS_INVSTATE)
+    {
+      ufalert("\tInvalid state\n");
+    }
+
+  if (cfsr & NVIC_CFAULTS_INVPC)
+    {
+      ufalert("\tInvalid PC load, "
+              "caused by an invalid PC load by EXC_RETURN\n");
+    }
+
+  if (cfsr & NVIC_CFAULTS_NOCP)
+    {
+      ufalert("\tNo Coprocessor\n");
+    }
+
+  if (cfsr & NVIC_CFAULTS_STKOF)
+    {
+      ufalert("\tStack Overflow\n");
+    }
+
+  if (cfsr & NVIC_CFAULTS_UNALIGNED)
+    {
+      ufalert("\tUnaligned access\n");
+    }
+
+  if (cfsr & NVIC_CFAULTS_DIVBYZERO)
+    {
+      ufalert("\tDivide by zero\n");
+    }
+
+  up_irq_save();
+  PANIC();
+  return OK;
+}
diff --git a/arch/arm/src/armv8-m/arm_usagefault.c b/arch/arm/src/armv8-m/arm_usagefault.c
new file mode 100644
index 0000000..8f82112
--- /dev/null
+++ b/arch/arm/src/armv8-m/arm_usagefault.c
@@ -0,0 +1,115 @@
+/****************************************************************************
+ * arch/arm/src/armv8-m/arm_usagefault.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 <nuttx/config.h>
+
+#include <stdint.h>
+#include <string.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <arch/irq.h>
+
+#include "arm_arch.h"
+#include "nvic.h"
+#include "arm_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_USAGEFAULT
+# define ufalert(format, ...)  _alert(format, ##__VA_ARGS__)
+#else
+# define ufalert(x...)
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: arm_usagefault
+ *
+ * Description:
+ *   This is Usage Fault exception handler.  It also catches SVC call
+ *   exceptions that are performed in bad contexts.
+ *
+ ****************************************************************************/
+
+int arm_usagefault(int irq, FAR void *context, FAR void *arg)
+{
+  uint32_t cfsr = getreg32(NVIC_CFAULTS);
+
+  /* Dump some usage fault info */
+
+  ufalert("PANIC!!! Usage Fault:\n");
+  ufalert("\tIRQ: %d regs: %p\n", irq, context);
+  ufalert("\tBASEPRI: %08x PRIMASK: %08x IPSR: %08x CONTROL: %08x\n",
+          getbasepri(), getprimask(), getipsr(), getcontrol());
+  ufalert("\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));
+
+  ufalert("Usage Fault Reason:\n");
+  if (cfsr & NVIC_CFAULTS_UNDEFINSTR)
+    {
+      ufalert("\tUndefined instruction\n");
+    }
+
+  if (cfsr & NVIC_CFAULTS_INVSTATE)
+    {
+      ufalert("\tInvalid state\n");
+    }
+
+  if (cfsr & NVIC_CFAULTS_INVPC)
+    {
+      ufalert("\tInvalid PC load, "
+              "caused by an invalid PC load by EXC_RETURN\n");
+    }
+
+  if (cfsr & NVIC_CFAULTS_NOCP)
+    {
+      ufalert("\tNo Coprocessor\n");
+    }
+
+  if (cfsr & NVIC_CFAULTS_STKOF)
+    {
+      ufalert("\tStack Overflow\n");
+    }
+
+  if (cfsr & NVIC_CFAULTS_UNALIGNED)
+    {
+      ufalert("\tUnaligned access\n");
+    }
+
+  if (cfsr & NVIC_CFAULTS_DIVBYZERO)
+    {
+      ufalert("\tDivide by zero\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 5ee5707..457a146 100644
--- a/arch/arm/src/common/arm_internal.h
+++ b/arch/arm/src/common/arm_internal.h
@@ -344,6 +344,7 @@ int  arm_hardfault(int irq, FAR void *context, FAR void *arg);
 
 int  arm_memfault(int irq, FAR void *context, FAR void *arg);
 int  arm_busfault(int irq, FAR void *context, FAR void *arg);
+int  arm_usagefault(int irq, FAR void *context, FAR void *arg);
 
 #  endif /* CONFIG_ARCH_CORTEXM3,4,7 */