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/nuttx.git

commit dfdb3aa2f4e3c0897d0115db0d55e14863de364c
Author: ligd <[email protected]>
AuthorDate: Thu May 18 23:42:03 2023 +0800

    armv8m: support busfault forward to TEE
    
    For TEE & REE, securefault & busfault are not banked, so the faults can
    only forword to TEE/REE.
    But how to crash dump the other core which not handled faults ?
    
    Here we provide a way to resolve this problem:
    1. Set the securefault & busfault to TEE
    2. busfault happend from TEE, then directly dump TEE
    3. busfault happend from REE, then generate nonsecurefault
    4. Back to REE, and dump
    
    Signed-off-by: ligd <[email protected]>
---
 arch/arm/src/armv8-m/CMakeLists.txt        |   4 +
 arch/arm/src/armv8-m/Make.defs             |   4 +
 arch/arm/src/armv8-m/arm_busfault.c        |   7 ++
 arch/arm/src/armv8-m/arm_gen_nonsecfault.c | 136 +++++++++++++++++++++++++++++
 arch/arm/src/armv8-m/arm_securefault.c     |  48 +---------
 arch/arm/src/common/arm_internal.h         |   6 ++
 6 files changed, 158 insertions(+), 47 deletions(-)

diff --git a/arch/arm/src/armv8-m/CMakeLists.txt 
b/arch/arm/src/armv8-m/CMakeLists.txt
index 251a02a9e7..78f85cc122 100644
--- a/arch/arm/src/armv8-m/CMakeLists.txt
+++ b/arch/arm/src/armv8-m/CMakeLists.txt
@@ -66,4 +66,8 @@ if(CONFIG_ARM_MPU OR CONFIG_ARM_MPU_EARLY_RESET)
   list(APPEND SRCS arm_mpu.c)
 endif()
 
+if(CONFIG_ARCH_TRUSTZONE_SECURE)
+  list(APPEND SRCS arm_gen_nonsecfault.c)
+endif()
+
 target_sources(arch PRIVATE ${SRCS})
diff --git a/arch/arm/src/armv8-m/Make.defs b/arch/arm/src/armv8-m/Make.defs
index c3e05ffc11..d74ab316be 100644
--- a/arch/arm/src/armv8-m/Make.defs
+++ b/arch/arm/src/armv8-m/Make.defs
@@ -56,3 +56,7 @@ endif
 ifneq ($(filter y,$(CONFIG_ARM_MPU) $(CONFIG_ARM_MPU_EARLY_RESET)),)
   CMN_CSRCS += arm_mpu.c
 endif
+
+ifeq ($(CONFIG_ARCH_TRUSTZONE_SECURE),y)
+  CMN_CSRCS += arm_gen_nonsecfault.c
+endif
diff --git a/arch/arm/src/armv8-m/arm_busfault.c 
b/arch/arm/src/armv8-m/arm_busfault.c
index 2060cae591..c324555600 100644
--- a/arch/arm/src/armv8-m/arm_busfault.c
+++ b/arch/arm/src/armv8-m/arm_busfault.c
@@ -102,6 +102,13 @@ int arm_busfault(int irq, void *context, void *arg)
       bfalert("\tFloating-point lazy state preservation error\n");
     }
 
+#ifdef CONFIG_DEBUG_BUSFAULT
+  if (arm_gen_nonsecurefault(irq, context))
+    {
+      return OK;
+    }
+#endif
+
   up_irq_save();
   PANIC_WITH_REGS("panic", context);
   return OK;
diff --git a/arch/arm/src/armv8-m/arm_gen_nonsecfault.c 
b/arch/arm/src/armv8-m/arm_gen_nonsecfault.c
new file mode 100644
index 0000000000..f54fc92ad0
--- /dev/null
+++ b/arch/arm/src/armv8-m/arm_gen_nonsecfault.c
@@ -0,0 +1,136 @@
+/****************************************************************************
+ * arch/arm/src/armv8-m/arm_gen_nonsecfault.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 <nuttx/syslog/syslog.h>
+
+#include <stdint.h>
+#include <arch/irq.h>
+
+#include "nvic.h"
+#include "sau.h"
+#include "arm_internal.h"
+#include "exc_return.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define OFFSET_R0              (0 * 4) /* R0 */
+#define OFFSET_R1              (1 * 4) /* R1 */
+#define OFFSET_R2              (2 * 4) /* R2 */
+#define OFFSET_R3              (3 * 4) /* R3 */
+#define OFFSET_R12             (4 * 4) /* R12 */
+#define OFFSET_R14             (5 * 4) /* R14 = LR */
+#define OFFSET_R15             (6 * 4) /* R15 = PC */
+#define OFFSET_XPSR            (7 * 4) /* xPSR */
+
+/****************************************************************************
+ * Name: arm_should_gen_nonsecurefault
+ *
+ * Description:
+ *   Check whether should generate non-secure IRQ from securefault
+ *
+ ****************************************************************************/
+
+bool weak_function arm_should_gen_nonsecurefault(void)
+{
+  return true;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: arm_gen_nonsecurefault
+ *
+ * Description:
+ *   For TEE & REE, securefault & busfault are not banked, so the faults can
+ *   only forword to TEE/REE.
+ *   But how to crash dump the other core which not handled faults ?
+ *
+ *   Here we provide a way to resolve this problem:
+ *   1. Set the securefault & busfault to TEE
+ *   2. busfault happend from TEE, then directly dump TEE
+ *   3. busfault happend from REE, then generate nonsecurefault
+ *   4. Back to REE, and dump
+ *
+ * Return values:
+ *   1 means generated done
+ *   0 means don't need generated
+ *
+ ****************************************************************************/
+
+int arm_gen_nonsecurefault(int irq, uint32_t *regs)
+{
+  uint32_t nsp;
+
+  if (!arm_should_gen_nonsecurefault())
+    {
+      return 0;
+    }
+
+  /* Check whether come from REE */
+
+  if (regs[REG_EXC_RETURN] & EXC_RETURN_SECURE_STACK)
+    {
+      return 0;
+    }
+
+  /* busfault are forward to REE ? */
+
+  if (getreg32(NVIC_AIRCR) & NVIC_AIRCR_BFHFNMINS)
+    {
+      return 0;
+    }
+
+  /* Redict busfault to REE */
+
+  up_secure_irq(NVIC_IRQ_BUSFAULT, false);
+
+  /* Get non-secure SP */
+
+  __asm__ __volatile__ ("mrs %0, msp_ns" : "=r" (nsp));
+
+  _alert("Dump REE registers:\n");
+  _alert("R0: %08" PRIx32 " R1: %08" PRIx32
+         " R2: %08" PRIx32 "  R3: %08" PRIx32 "\n",
+         getreg32(nsp + OFFSET_R0), getreg32(nsp + OFFSET_R1),
+         getreg32(nsp + OFFSET_R2), getreg32(nsp + OFFSET_R3));
+  _alert("IP: %08" PRIx32 " SP: %08" PRIx32
+          " LR: %08" PRIx32 "  PC: %08" PRIx32 "\n",
+         getreg32(nsp + OFFSET_R12), nsp,
+         getreg32(nsp + OFFSET_R14), getreg32(nsp + OFFSET_R15));
+  syslog_flush();
+
+  /* Force set return ReturnAddress to 0, then non-secure cpu will crash.
+   * Also, the ReturnAddress is very important, so move it to R12.
+   */
+
+  putreg32(getreg32(nsp + OFFSET_R15), nsp + OFFSET_R12);
+  putreg32(0, nsp + OFFSET_R15);
+
+  return 1;
+}
diff --git a/arch/arm/src/armv8-m/arm_securefault.c 
b/arch/arm/src/armv8-m/arm_securefault.c
index 45c18375d7..fb0f2a4736 100644
--- a/arch/arm/src/armv8-m/arm_securefault.c
+++ b/arch/arm/src/armv8-m/arm_securefault.c
@@ -43,38 +43,6 @@
 
 #ifdef CONFIG_DEBUG_SECUREFAULT
 #  define sfalert(format, ...)  _alert(format, ##__VA_ARGS__)
-
-#  define OFFSET_R0              (0 * 4) /* R0 */
-#  define OFFSET_R1              (1 * 4) /* R1 */
-#  define OFFSET_R2              (2 * 4) /* R2 */
-#  define OFFSET_R3              (3 * 4) /* R3 */
-#  define OFFSET_R12             (4 * 4) /* R12 */
-#  define OFFSET_R14             (5 * 4) /* R14 = LR */
-#  define OFFSET_R15             (6 * 4) /* R15 = PC */
-#  define OFFSET_XPSR            (7 * 4) /* xPSR */
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-static void generate_nonsecure_busfault(void)
-{
-  uint32_t nsp;
-
-  /* Get non-secure SP */
-
-  __asm__ __volatile__ ("mrs %0, msp_ns" : "=r" (nsp));
-
-  sfalert("Non-sec sp %08" PRIx32 "\n", nsp);
-  syslog_flush();
-
-  /* Force set return ReturnAddress to 0, then non-secure cpu will crash.
-   * Also, the ReturnAddress is very important, so move it to R12.
-   */
-
-  putreg32(getreg32(nsp + OFFSET_R15), nsp + OFFSET_R12);
-  putreg32(0, nsp + OFFSET_R15);
-}
 #else
 #  define sfalert(...)
 #endif
@@ -83,19 +51,6 @@ static void generate_nonsecure_busfault(void)
  * Public Functions
  ****************************************************************************/
 
-/****************************************************************************
- * Name: arm_securefault_should_generate
- *
- * Description:
- *   Check whether should generate non-secure IRQ from securefault
- *
- ****************************************************************************/
-
-bool weak_function arm_should_generate_nonsecure_busfault(void)
-{
-  return true;
-}
-
 /****************************************************************************
  * Name: arm_securefault
  *
@@ -161,9 +116,8 @@ int arm_securefault(int irq, void *context, void *arg)
   putreg32(0xff, SAU_SFSR);
 
 #ifdef CONFIG_DEBUG_SECUREFAULT
-  if (arm_should_generate_nonsecure_busfault())
+  if (arm_gen_nonsecurefault(irq, context))
     {
-      generate_nonsecure_busfault();
       return OK;
     }
 #endif
diff --git a/arch/arm/src/common/arm_internal.h 
b/arch/arm/src/common/arm_internal.h
index 7c625d847b..75918424c6 100644
--- a/arch/arm/src/common/arm_internal.h
+++ b/arch/arm/src/common/arm_internal.h
@@ -522,6 +522,12 @@ size_t arm_stack_check(void *stackbase, size_t nbytes);
 void arm_stack_color(void *stackbase, size_t nbytes);
 #endif
 
+#ifdef CONFIG_ARCH_TRUSTZONE_SECURE
+int arm_gen_nonsecurefault(int irq, uint32_t *regs);
+#else
+# define arm_gen_nonsecurefault(i, r)  (0)
+#endif
+
 #undef EXTERN
 #ifdef __cplusplus
 }

Reply via email to