You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ac...@apache.org on 2024/09/24 13:21:49 UTC

(nuttx) branch master updated (5095955591 -> dc6eeba453)

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

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


    from 5095955591 cmake(bugfix):make sure the extra lib only added once
     new 24fba43591 Revert "Kernel build: enter exception save sp_sl0,exit exception restroe sp_el0"
     new 0a2a6dfa57 Revert "arm64: simply the vectors"
     new f6f072ee1c Revert "arm64: add arm64_current_el to obtain current EL"
     new 9e8df3b3fa Revert "arm64: save FPU regs every time"
     new dc6eeba453 Revert "arm64: refine the fatal handler"

The 5 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/arm64/src/common/arm64_arch.h              |  23 -
 arch/arm64/src/common/arm64_exit.c              |   6 +
 arch/arm64/src/common/arm64_fatal.c             | 682 +++++++++---------------
 arch/arm64/src/common/arm64_fatal.h             | 158 +-----
 arch/arm64/src/common/arm64_fpu.c               | 140 ++++-
 arch/arm64/src/common/arm64_initialstate.c      |  20 +
 arch/arm64/src/common/arm64_internal.h          |   3 +-
 arch/arm64/src/common/arm64_schedulesigaction.c |  29 +
 arch/arm64/src/common/arm64_sigdeliver.c        |   9 +
 arch/arm64/src/common/arm64_syscall.c           | 163 +++---
 arch/arm64/src/common/arm64_vector_table.S      |  91 ++--
 arch/arm64/src/common/arm64_vectors.S           | 410 +++++++++++---
 12 files changed, 936 insertions(+), 798 deletions(-)


(nuttx) 03/05: Revert "arm64: add arm64_current_el to obtain current EL"

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

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

commit f6f072ee1c60ada10a49d451e7a98189fbd821d0
Author: Xiang Xiao <xi...@gmail.com>
AuthorDate: Tue Sep 24 00:32:34 2024 -0700

    Revert "arm64: add arm64_current_el to obtain current EL"
    
    This reverts commit e38f2b2a6dadd48608682184cf5e4633a5d135ce.
---
 arch/arm64/src/common/arm64_arch.h | 20 --------------------
 1 file changed, 20 deletions(-)

diff --git a/arch/arm64/src/common/arm64_arch.h b/arch/arm64/src/common/arm64_arch.h
index d2310128e8..35c4cdc105 100644
--- a/arch/arm64/src/common/arm64_arch.h
+++ b/arch/arm64/src/common/arm64_arch.h
@@ -394,26 +394,6 @@ static inline void arch_nop(void)
   __asm__ volatile ("nop");
 }
 
-/****************************************************************************
- * Name:
- *   arm64_current_el()
- *
- * Description:
- *
- *   Get current execution level
- *
- ****************************************************************************/
-
-#define arm64_current_el()                \
-  ({                                      \
-    uint64_t __el;                        \
-    int      __ret;                       \
-    __asm__ volatile ("mrs %0, CurrentEL" \
-                      : "=r" (__el));     \
-    __ret = GET_EL(__el);                 \
-    __ret;                                \
-  })
-
 /****************************************************************************
  * Name:
  *   read_/write_/zero_ sysreg


(nuttx) 05/05: Revert "arm64: refine the fatal handler"

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

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

commit dc6eeba4532abe91df6981941d855f89dd0d4230
Author: Xiang Xiao <xi...@gmail.com>
AuthorDate: Tue Sep 24 00:32:34 2024 -0700

    Revert "arm64: refine the fatal handler"
    
    This reverts commit 291d5a2acc57497b5cd0305682297a319bacdf4c.
---
 arch/arm64/src/common/arm64_fatal.c        | 682 ++++++++++-------------------
 arch/arm64/src/common/arm64_fatal.h        | 158 +------
 arch/arm64/src/common/arm64_vector_table.S |   8 +-
 arch/arm64/src/common/arm64_vectors.S      |  40 +-
 4 files changed, 284 insertions(+), 604 deletions(-)

diff --git a/arch/arm64/src/common/arm64_fatal.c b/arch/arm64/src/common/arm64_fatal.c
index 5c1b524190..3486fe1d5d 100644
--- a/arch/arm64/src/common/arm64_fatal.c
+++ b/arch/arm64/src/common/arm64_fatal.c
@@ -39,7 +39,6 @@
 #include <nuttx/syslog/syslog.h>
 #include "sched/sched.h"
 #include "irq/irq.h"
-
 #include "arm64_arch.h"
 #include "arm64_internal.h"
 #include "arm64_fatal.h"
@@ -52,527 +51,326 @@
 #endif
 
 /****************************************************************************
- * Private Type Declarations
- ****************************************************************************/
-
-struct fatal_handle_info
-{
-  fatal_handle_func_t handle_fn;
-  const char *name;
-};
-
-/****************************************************************************
- * Private Functions Declarations
- ****************************************************************************/
-
-/* Default callback handler for debug and fatal event
- * Can be override by other handler
- */
-
-static int default_debug_handler(struct regs_context *regs,
-                                 uint64_t far, uint64_t esr);
-static int default_fatal_handler(struct regs_context *regs,
-                                 uint64_t far, uint64_t esr);
-
-/****************************************************************************
- * Private Data
+ * Private Functions
  ****************************************************************************/
 
-static const char *g_esr_class_str[] =
-{
-  [0 ... ESR_ELX_EC_MAX]   = "UNRECOGNIZED EC",
-  [ESR_ELX_EC_UNKNOWN]     = "Unknown/Uncategorized",
-  [ESR_ELX_EC_WFX]         = "WFI/WFE",
-  [ESR_ELX_EC_CP15_32]     = "CP15 MCR/MRC",
-  [ESR_ELX_EC_CP15_64]     = "CP15 MCRR/MRRC",
-  [ESR_ELX_EC_CP14_MR]     = "CP14 MCR/MRC",
-  [ESR_ELX_EC_CP14_LS]     = "CP14 LDC/STC",
-  [ESR_ELX_EC_FP_ASIMD]    = "ASIMD",
-  [ESR_ELX_EC_CP10_ID]     = "CP10 MRC/VMRS",
-  [ESR_ELX_EC_PAC]         = "PAC",
-  [ESR_ELX_EC_CP14_64]     = "CP14 MCRR/MRRC",
-  [ESR_ELX_EC_BTI]         = "BTI",
-  [ESR_ELX_EC_ILL]         = "PSTATE.IL",
-  [ESR_ELX_EC_SVC32]       = "SVC (AArch32)",
-  [ESR_ELX_EC_HVC32]       = "HVC (AArch32)",
-  [ESR_ELX_EC_SMC32]       = "SMC (AArch32)",
-  [ESR_ELX_EC_SVC64]       = "SVC (AArch64)",
-  [ESR_ELX_EC_HVC64]       = "HVC (AArch64)",
-  [ESR_ELX_EC_SMC64]       = "SMC (AArch64)",
-  [ESR_ELX_EC_SYS64]       = "MSR/MRS (AArch64)",
-  [ESR_ELX_EC_SVE]         = "SVE",
-  [ESR_ELX_EC_ERET]        = "ERET/ERETAA/ERETAB",
-  [ESR_ELX_EC_FPAC]        = "FPAC",
-  [ESR_ELX_EC_SME]         = "SME",
-  [ESR_ELX_EC_IMP_DEF]     = "EL3 IMP DEF",
-  [ESR_ELX_EC_IABT_LOW]    = "IABT (lower EL)",
-  [ESR_ELX_EC_IABT_CUR]    = "IABT (current EL)",
-  [ESR_ELX_EC_PC_ALIGN]    = "PC Alignment",
-  [ESR_ELX_EC_DABT_LOW]    = "DABT (lower EL)",
-  [ESR_ELX_EC_DABT_CUR]    = "DABT (current EL)",
-  [ESR_ELX_EC_SP_ALIGN]    = "SP Alignment",
-  [ESR_ELX_EC_MOPS]        = "MOPS",
-  [ESR_ELX_EC_FP_EXC32]    = "FP (AArch32)",
-  [ESR_ELX_EC_FP_EXC64]    = "FP (AArch64)",
-  [ESR_ELX_EC_SERROR]      = "SError",
-  [ESR_ELX_EC_BREAKPT_LOW] = "Breakpoint (lower EL)",
-  [ESR_ELX_EC_BREAKPT_CUR] = "Breakpoint (current EL)",
-  [ESR_ELX_EC_SOFTSTP_LOW] = "Software Step (lower EL)",
-  [ESR_ELX_EC_SOFTSTP_CUR] = "Software Step (current EL)",
-  [ESR_ELX_EC_WATCHPT_LOW] = "Watchpoint (lower EL)",
-  [ESR_ELX_EC_WATCHPT_CUR] = "Watchpoint (current EL)",
-  [ESR_ELX_EC_BKPT32]      = "BKPT (AArch32)",
-  [ESR_ELX_EC_VECTOR32]    = "Vector catch (AArch32)",
-  [ESR_ELX_EC_BRK64]       = "BRK (AArch64)",
-};
-
-static const char *g_esr_desc_str[] =
-{
-  [0 ... ESR_ELX_EC_MAX] = "UNRECOGNIZED EC",
-  [ESR_ELX_EC_UNKNOWN]   = "Unknown/Uncategorized",
-  [ESR_ELX_EC_WFX]       = "Trapped WFI or WFE instruction execution",
-  [ESR_ELX_EC_CP15_32]   = "Trapped MCR or MRC access with"
-                           "(coproc==0b1111) "
-                           "that is not reported using EC 0b000000",
-  [ESR_ELX_EC_CP15_64]   = "Trapped MCRR or MRRC access with"
-                           "(coproc==0b1111) "
-                           "that is not reported using EC 0b000000",
-  [ESR_ELX_EC_CP14_MR]  = "Trapped MCR or MRC access with (coproc==0b1110)",
-  [ESR_ELX_EC_CP14_LS]  = "Trapped LDC or STC access",
-  [ESR_ELX_EC_FP_ASIMD] = "Trapped access to SVE, Advanced SIMD, or "
-                          "floating-point functionality",
-  [ESR_ELX_EC_CP10_ID] = "CP10 MRC/VMRS",
-  [ESR_ELX_EC_PAC]     = "PAC",
-  [ESR_ELX_EC_CP14_64] = "Trapped MRRC access with (coproc==0b1110)",
-  [ESR_ELX_EC_BTI]     = "Branch Target Exception",
-  [ESR_ELX_EC_ILL]     = "Illegal Execution state",
-  [ESR_ELX_EC_SVC32]   = "SVC instruction execution in AArch32 state",
-  [ESR_ELX_EC_HVC32]   = "HVC (AArch32)",
-  [ESR_ELX_EC_SMC32]   = "SMC (AArch32)",
-  [ESR_ELX_EC_SVC64]   = "SVC (AArch64)",
-  [ESR_ELX_EC_HVC64]   = "HVC (AArch64)",
-  [ESR_ELX_EC_SMC64]   = "SMC (AArch64)",
-  [ESR_ELX_EC_SYS64]   = "Trapped MSR, MRS or System instruction "
-                         "execution in AArch64 state, that is not "
-                         "reported using EC 0b000000, 0b000001 or 0b000111",
-  [ESR_ELX_EC_SVE]  = "Trapped access to SVE functionality",
-  [ESR_ELX_EC_ERET] = "ERET/ERETAA/ERETAB",
-  [ESR_ELX_EC_FPAC] = "Exception from a Pointer Authentication "
-                      "instruction authentication failure",
-  [ESR_ELX_EC_SME] = "SME",
-  [ESR_ELX_EC_IMP_DEF]  = "EL3 IMP DEF",
-  [ESR_ELX_EC_IABT_LOW] = "Instruction Abort from a lower Exception level, "
-                          "that might be using AArch32 or AArch64",
-  [ESR_ELX_EC_IABT_CUR] = "Instruction Abort taken without a change "
-                          "in Exception level",
-  [ESR_ELX_EC_PC_ALIGN] = "PC alignment fault exception.",
-  [ESR_ELX_EC_DABT_LOW] = "Data Abort from a lower Exception level, "
-                          "that might be using AArch32 or AArch64",
-  [ESR_ELX_EC_DABT_CUR] = "Data Abort taken without a change in "
-                          "Exception level",
-  [ESR_ELX_EC_SP_ALIGN] = "SP alignment fault exception",
-  [ESR_ELX_EC_MOPS]     = "MOPS",
-  [ESR_ELX_EC_FP_EXC32] = "Trapped floating-point exception taken from "
-                          "AArch32 state",
-  [ESR_ELX_EC_FP_EXC64] = "Trapped floating-point exception taken from "
-                          "AArch64 state",
-  [ESR_ELX_EC_SERROR]   = "SError interrupt",
-  [ESR_ELX_EC_BREAKPT_LOW] = "Breakpoint exception from a lower "
-                             "Exception level, "
-                             "that might be using AArch32 or AArch64",
-  [ESR_ELX_EC_BREAKPT_CUR] = "Breakpoint exception taken without a change "
-                             "in Exception level",
-  [ESR_ELX_EC_SOFTSTP_LOW] = "Software Step exception from a lower "
-                             "Exception level,"
-                             "that might be using AArch32 or AArch64",
-  [ESR_ELX_EC_SOFTSTP_CUR] = "Software Step exception taken without a "
-                             "change in Exception level",
-  [ESR_ELX_EC_WATCHPT_LOW] = "Watchpoint exception from a lower "
-                             "Exception level, "
-                             "that might be using AArch32 or AArch64",
-  [ESR_ELX_EC_WATCHPT_CUR] = "Watchpoint exception taken without "
-                             "a change in Exception level.",
-  [ESR_ELX_EC_BKPT32]   = "BKPT instruction execution in AArch32 state",
-  [ESR_ELX_EC_VECTOR32] = "Vector catch (AArch32)",
-  [ESR_ELX_EC_BRK64]    = "BRK instruction execution in AArch64 state.",
-};
-
-static struct fatal_handle_info g_fatal_handler[] =
-{
-  { default_fatal_handler, "ttbr address size fault" },
-  { default_fatal_handler, "level 1 address size fault" },
-  { default_fatal_handler, "level 2 address size fault" },
-  { default_fatal_handler, "level 3 address size fault" },
-  { default_fatal_handler, "level 0 translation fault" },
-  { default_fatal_handler, "level 1 translation fault" },
-  { default_fatal_handler, "level 2 translation fault" },
-  { default_fatal_handler, "level 3 translation fault" },
-  { default_fatal_handler, "unknown 8"                 },
-  { default_fatal_handler, "level 1 access flag fault" },
-  { default_fatal_handler, "level 2 access flag fault" },
-  { default_fatal_handler, "level 3 access flag fault" },
-  { default_fatal_handler, "unknown 12"                },
-  { default_fatal_handler, "level 1 permission fault"  },
-  { default_fatal_handler, "level 2 permission fault"  },
-  { default_fatal_handler, "level 3 permission fault"  },
-  { default_fatal_handler, "synchronous external abort" },
-  { default_fatal_handler, "synchronous tag check fault" },
-  { default_fatal_handler, "unknown 18" },
-  { default_fatal_handler, "unknown 19" },
-  { default_fatal_handler, "level 0 (translation table walk)" },
-  { default_fatal_handler, "level 1 (translation table walk)" },
-  { default_fatal_handler, "level 2 (translation table walk)" },
-  { default_fatal_handler, "level 3 (translation table walk)" },
-  { default_fatal_handler, "synchronous parity or ECC error" },
-  { default_fatal_handler, "unknown 25" },
-  { default_fatal_handler, "unknown 26" },
-  { default_fatal_handler, "unknown 27" },
-  { default_fatal_handler, "level 0 synchronous parity "
-                      "error (translation table walk)" },
-  { default_fatal_handler, "level 1 synchronous parity "
-                      "error (translation table walk)" },
-  { default_fatal_handler, "level 2 synchronous parity "
-                      "error (translation table walk)" },
-  { default_fatal_handler, "level 3 synchronous parity "
-                      "error (translation table walk)" },
-  { default_fatal_handler, "unknown 32"   },
-  { default_fatal_handler, "alignment fault" },
-  { default_fatal_handler, "unknown 34" },
-  { default_fatal_handler, "unknown 35" },
-  { default_fatal_handler, "unknown 36" },
-  { default_fatal_handler, "unknown 37" },
-  { default_fatal_handler, "unknown 38" },
-  { default_fatal_handler, "unknown 39" },
-  { default_fatal_handler, "unknown 40" },
-  { default_fatal_handler, "unknown 41" },
-  { default_fatal_handler, "unknown 42" },
-  { default_fatal_handler, "unknown 43" },
-  { default_fatal_handler, "unknown 44" },
-  { default_fatal_handler, "unknown 45" },
-  { default_fatal_handler, "unknown 46" },
-  { default_fatal_handler, "unknown 47" },
-  { default_fatal_handler, "TLB conflict abort" },
-  { default_fatal_handler, "Unsupported atomic hardware update fault" },
-  { default_fatal_handler, "unknown 50" },
-  { default_fatal_handler, "unknown 51" },
-  { default_fatal_handler, "implementation fault (lockdown abort)" },
-  { default_fatal_handler, "implementation fault (unsupported exclusive)" },
-  { default_fatal_handler, "unknown 54" },
-  { default_fatal_handler, "unknown 55" },
-  { default_fatal_handler, "unknown 56" },
-  { default_fatal_handler, "unknown 57" },
-  { default_fatal_handler, "unknown 58" },
-  { default_fatal_handler, "unknown 59" },
-  { default_fatal_handler, "unknown 60" },
-  { default_fatal_handler, "section domain fault" },
-  { default_fatal_handler, "page domain fault" },
-  { default_fatal_handler, "unknown 63" },
-};
-
-static struct fatal_handle_info g_debug_handler[] =
-{
-  { default_debug_handler, "hardware breakpoint"  },
-  { default_debug_handler, "hardware single-step" },
-  { default_debug_handler, "hardware watchpoint"  },
-  { default_debug_handler, "unknown 3"            },
-  { default_debug_handler, "aarch32 BKPT"         },
-  { default_debug_handler, "aarch32 vector catch" },
-  { default_debug_handler, "aarch64 BRK"          },
-  { default_debug_handler, "unknown 7"            },
-};
-
 /****************************************************************************
- * Private Functions
+ * Name: print_ec_cause
  ****************************************************************************/
 
-static const char *esr_get_class_string(uint64_t esr)
-{
-  uint32_t ec = ESR_ELX_EC(esr);
-
-  return g_esr_class_str[ec];
-}
-
-static const char *esr_get_desc_string(uint64_t esr)
-{
-  uint32_t ec = ESR_ELX_EC(esr);
-
-  return g_esr_desc_str[ec];
-}
-
 static void print_ec_cause(uint64_t esr)
 {
-  sinfo("%s\n", esr_get_class_string(esr));
-  sinfo("%s\n", esr_get_desc_string(esr));
-}
-
-static int default_fatal_handler(struct regs_context *regs,
-                                 uint64_t far, uint64_t esr)
-{
-  struct fatal_handle_info *inf = g_fatal_handler + (esr & ESR_ELX_FSC);
-
-  /* Data Fault Status Code. */
-
-  sinfo("(IFSC/DFSC) for Data/Instruction aborts: %s\n", inf->name);
-
-  return -EINVAL; /* "fault" */
-}
-
-static int default_debug_handler(struct regs_context *regs,
-                                 uint64_t far, uint64_t esr)
-{
-  struct fatal_handle_info *inf = g_debug_handler + DBG_ESR_EVT(esr);
-
-  sinfo("Default Debug Handler: %s\n", inf->name);
-  return -1; /* "fault" */
-}
-
-static int arm64_el1_abort(struct regs_context *regs, uint64_t esr)
-{
-  uint64_t                  far = read_sysreg(far_el1);
-  struct fatal_handle_info *inf = g_fatal_handler + (esr & ESR_ELX_FSC);
-
-  return inf->handle_fn(regs, far, esr);
-}
-
-static int arm64_el1_pc(struct regs_context *regs, uint64_t esr)
-{
-  uint64_t far = read_sysreg(far_el1);
-
-  sinfo("SP/PC alignment exception at 0x%" PRIx64 "\n", far);
-  return -EINVAL; /* "fault" */
-}
-
-static int arm64_el1_bti(struct regs_context *regs, uint64_t esr)
-{
-  uint64_t far = read_sysreg(far_el1);
+  uint32_t ec = (uint32_t)esr >> 26;
 
-  sinfo("BTI exception at 0x%" PRIx64 "\n", far);
-  return -EINVAL; /* "fault" */
-}
+  switch (ec)
+    {
+      case 0b000000:
+        {
+          sinfo("Unknown reason\n");
+          break;
+        }
 
-static int arm64_el1_undef(struct regs_context *regs, uint64_t esr)
-{
-  uint32_t insn;
-
-  sinfo("Undefined instruction at 0x%" PRIx64 ", dump:\n", regs->elr);
-  memcpy(&insn, (void *)(regs->elr - 8), 4);
-  sinfo("0x%" PRIx64 " : 0x%" PRIx32 "\n", regs->elr - 8, insn);
-  memcpy(&insn, (void *)(regs->elr - 4), 4);
-  sinfo("0x%" PRIx64 " : 0x%" PRIx32 "\n", regs->elr - 4, insn);
-  memcpy(&insn, (void *)(regs->elr), 4);
-  sinfo("0x%" PRIx64 " : 0x%" PRIx32 "\n", regs->elr, insn);
-  memcpy(&insn, (void *)(regs->elr + 4), 4);
-  sinfo("0x%" PRIx64 " : 0x%" PRIx32 "\n", regs->elr + 4, insn);
-  memcpy(&insn, (void *)(regs->elr + 8), 4);
-  sinfo("0x%" PRIx64 " : 0x%" PRIx32 "\n", regs->elr + 8, insn);
-
-  return -1;
-}
+      case 0b000001:
+        {
+          sinfo("Trapped WFI or WFE instruction execution\n");
+          break;
+        }
 
-static int arm64_el1_fpac(struct regs_context *regs, uint64_t esr)
-{
-  uint64_t far = read_sysreg(far_el1);
+      case 0b000011:
+        {
+          sinfo(
+             "Trapped MCR or MRC access with (coproc==0b1111) that "
+             "is not reported using EC 0b000000\n");
+          break;
+        }
 
-  /* Unexpected FPAC exception in the kernel. */
+      case 0b000100:
+        {
+          sinfo(
+             "Trapped MCRR or MRRC access with (coproc==0b1111) "
+             "that is not reported using EC 0b000000\n");
+          break;
+        }
 
-  sinfo("Unexpected FPAC exception at 0x%" PRIx64 "\n", far);
-  return -EINVAL;
-}
+      case 0b000101:
+        {
+          sinfo("Trapped MCR or MRC access with (coproc==0b1110)\n");
+          break;
+        }
 
-static int arm64_el1_dbg(struct regs_context *regs, uint64_t esr)
-{
-  uint64_t                  far = read_sysreg(far_el1);
-  struct fatal_handle_info *inf = g_debug_handler + DBG_ESR_EVT(esr);
+      case 0b000110:
+        {
+          sinfo("Trapped LDC or STC access\n");
+          break;
+        }
 
-  return inf->handle_fn(regs, far, esr);
-}
+      case 0b000111:
+        {
+          sinfo(
+             "Trapped access to SVE, Advanced SIMD, or "
+             "floating-point functionality\n");
+          break;
+        }
 
-static int arm64_el1_exception_handler(uint64_t esr,
-                                       struct regs_context *regs)
-{
-  uint32_t  ec = ESR_ELX_EC(esr);
-  int       ret;
+      case 0b001100:
+        {
+          sinfo("Trapped MRRC access with (coproc==0b1110)\n");
+          break;
+        }
 
-  switch (ec)
-    {
-      /* Data/Instruction Abort at EL1 */
+      case 0b001101:
+        {
+          sinfo("Branch Target Exception\n");
+          break;
+        }
 
-      case ESR_ELX_EC_DABT_CUR:
-      case ESR_ELX_EC_IABT_CUR:
+      case 0b001110:
         {
-          ret = arm64_el1_abort(regs, esr);
+          sinfo("Illegal Execution state\n");
           break;
         }
 
-      /* PC alignment fault exception. */
+      case 0b010001:
+        {
+          sinfo("SVC instruction execution in AArch32 state\n");
+          break;
+        }
 
-      case ESR_ELX_EC_PC_ALIGN:
+      case 0b011000:
         {
-          ret = arm64_el1_pc(regs, esr);
+          sinfo(
+             "Trapped MSR, MRS or System instruction execution in "
+             "AArch64 state, that is not reported using EC "
+             "0b000000, 0b000001 or 0b000111\n");
           break;
         }
 
-      /* Trapped MSR, MRS or System instruction execution
-       * in AArch64 state
-       */
+      case 0b011001:
+        {
+          sinfo("Trapped access to SVE functionality\n");
+          break;
+        }
 
-      case ESR_ELX_EC_SYS64:
-      case ESR_ELX_EC_UNKNOWN:
+      case 0b100000:
         {
-          ret = arm64_el1_undef(regs, esr);
+          sinfo(
+             "Instruction Abort from a lower Exception level, that "
+             "might be using AArch32 or AArch64\n");
           break;
         }
 
-      /* Branch Target Exception */
+      case 0b100001:
+        {
+          sinfo(
+             "Instruction Abort taken without a change "
+             "in Exception level.\n");
+          break;
+        }
 
-      case ESR_ELX_EC_BTI:
+      case 0b100010:
         {
-          ret = arm64_el1_bti(regs, esr);
+          sinfo("PC alignment fault exception.\n");
           break;
         }
 
-      case ESR_ELX_EC_BREAKPT_CUR:
+      case 0b100100:
+        {
+          sinfo(
+             "Data Abort from a lower Exception level, that might "
+             "be using AArch32 or AArch64\n");
+          break;
+        }
 
-      /* Breakpoint exception taken in current Exception level */
+      case 0b100101:
+        {
+          sinfo("Data Abort taken without a change in Exception level\n");
+          break;
+        }
 
-      case ESR_ELX_EC_SOFTSTP_CUR:
+      case 0b100110:
+        {
+          sinfo("SP alignment fault exception\n");
+          break;
+        }
 
-      /* Software Step exception taken in current Exception level */
+      case 0b101000:
+        {
+          sinfo(
+             "Trapped floating-point exception "
+             "taken from AArch32 state\n");
+          break;
+        }
 
-      case ESR_ELX_EC_WATCHPT_CUR:
+      case 0b101100:
+        {
+          sinfo(
+             "Trapped floating-point exception "
+             "taken from AArch64 state.\n");
+          break;
+        }
 
-      /* Watchpoint exception taken in current Exception level */
+      case 0b101111:
+        {
+          sinfo("SError interrupt\n");
+          break;
+        }
 
-      case ESR_ELX_EC_BRK64:
+      case 0b110000:
         {
-          /* BRK instruction execution in AArch64 state */
+          sinfo(
+             "Breakpoint exception from a lower Exception level, "
+             "that might be using AArch32 or AArch64\n");
+          break;
+        }
 
-          ret = arm64_el1_dbg(regs, esr);
+      case 0b110001:
+        {
+          sinfo(
+             "Breakpoint exception taken without a change in "
+             "Exception level\n");
           break;
         }
 
-      case ESR_ELX_EC_FPAC:
+      case 0b110010:
         {
-          /* Exception from a Pointer Authentication
-           * instruction authentication failure
-           */
+          sinfo(
+             "Software Step exception from a lower Exception level, "
+             "that might be using AArch32 or AArch64\n");
+          break;
+        }
 
-          ret = arm64_el1_fpac(regs, esr);
+      case 0b110011:
+        {
+          sinfo(
+             "Software Step exception taken without a change in "
+             "Exception level\n");
           break;
         }
 
-      default:
+      case 0b110100:
         {
-          sinfo("64-bit el1h sync, esr = 0x%x", ec);
-          ret = -EINVAL;
+          sinfo(
+             "Watchpoint exception from a lower Exception level, "
+             "that might be using AArch32 or AArch64\n");
+          break;
         }
-  }
 
-  return ret;
-}
+      case 0b110101:
+        {
+          sinfo(
+             "Watchpoint exception taken without a change in "
+             "Exception level.\n");
+          break;
+        }
 
-static int arm64_exception_handler(struct regs_context *regs)
-{
-  uint64_t    el;
-  uint64_t    esr;
-  uint64_t    elr;
-  uint64_t    far;
-  const char *el_str;
-  int         ret = -EINVAL;
-
-  el = arm64_current_el();
-
-  switch (el)
-  {
-    case MODE_EL1:
-    {
-      el_str = "MODE_EL1";
-      esr    = read_sysreg(esr_el1);
-      far    = read_sysreg(far_el1);
-      elr    = read_sysreg(elr_el1);
-      ret    = arm64_el1_exception_handler(esr, regs);
-      break;
-    }
+      case 0b111000:
+        {
+          sinfo("BKPT instruction execution in AArch32 state\n");
+          break;
+        }
 
-    case MODE_EL2:
-    {
-      el_str = "MODE_EL2";
-      esr    = read_sysreg(esr_el2);
-      far    = read_sysreg(far_el2);
-      elr    = read_sysreg(elr_el2);
-      break;
-    }
+      case 0b111100:
+        {
+          sinfo("BRK instruction execution in AArch64 state.\n");
+          break;
+        }
 
-#ifdef CONFIG_ARCH_HAVE_EL3
-    case MODE_EL3:
-    {
-      el_str = "MODE_EL3";
-      esr    = read_sysreg(esr_el3);
-      far    = read_sysreg(far_el3);
-      elr    = read_sysreg(elr_el3);
-      break;
+      default:
+        break;
     }
+}
 
-#endif
-    default:
-    {
-      el_str = "Unknown";
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
 
-      /* Just to keep the compiler happy */
+/****************************************************************************
+ * Name: up_mdelay
+ ****************************************************************************/
 
-      esr = elr = far = 0;
-      break;
-    }
-  }
+void up_mdelay(unsigned int milliseconds)
+{
+  volatile unsigned int i;
+  volatile unsigned int j;
 
-  if (ret != 0)
+  for (i = 0; i < milliseconds; i++)
     {
-      sinfo("CurrentEL: %s\n", el_str);
-      sinfo("ESR_ELn: 0x%" PRIx64 "\n", esr);
-      sinfo("FAR_ELn: 0x%" PRIx64 "\n", far);
-      sinfo("ELR_ELn: 0x%" PRIx64 "\n", elr);
-
-      print_ec_cause(esr);
+      for (j = 0; j < CONFIG_BOARD_LOOPSPERMSEC; j++)
+        {
+        }
     }
-
-  return ret;
 }
 
 /****************************************************************************
- * Public Functions
+ * Name: arm64_fatal_error
+ *
+ * Description:
+ *
  ****************************************************************************/
 
-void arm64_fatal_handler(struct regs_context *regs)
+void arm64_fatal_error(unsigned int reason, struct regs_context * reg)
 {
-  int ret;
+  uint64_t el, esr, elr, far;
 
-  /* Nested exception are not supported */
+  sinfo("reason = %d\n", reason);
 
-  DEBUGASSERT(up_current_regs() == NULL);
+  up_set_current_regs((uint64_t *)reg);
 
-  up_set_current_regs((uint64_t *)regs);
+  if (reason != K_ERR_SPURIOUS_IRQ)
+    {
+      __asm__ volatile ("mrs %0, CurrentEL" : "=r" (el));
 
-  ret = arm64_exception_handler(regs);
+      switch (GET_EL(el))
+        {
+          case MODE_EL1:
+            {
+              sinfo("CurrentEL: MODE_EL1\n");
+              __asm__ volatile ("mrs %0, esr_el1" : "=r" (esr));
+              __asm__ volatile ("mrs %0, far_el1" : "=r" (far));
+              __asm__ volatile ("mrs %0, elr_el1" : "=r" (elr));
+              break;
+            }
+
+          case MODE_EL2:
+            {
+              sinfo("CurrentEL: MODE_EL2\n");
+              __asm__ volatile ("mrs %0, esr_el2" : "=r" (esr));
+              __asm__ volatile ("mrs %0, far_el2" : "=r" (far));
+              __asm__ volatile ("mrs %0, elr_el2" : "=r" (elr));
+              break;
+            }
 
-  if (ret != 0)
-    {
-      /* The fatal is not handled, print error and hung */
+#ifdef CONFIG_ARCH_HAVE_EL3
+          case MODE_EL3:
+            {
+              sinfo("CurrentEL: MODE_EL3\n");
+              __asm__ volatile ("mrs %0, esr_el3" : "=r" (esr));
+              __asm__ volatile ("mrs %0, far_el3" : "=r" (far));
+              __asm__ volatile ("mrs %0, elr_el3" : "=r" (elr));
+              break;
+            }
+#endif
 
-      PANIC_WITH_REGS("panic", regs);
-    }
+          default:
+            {
+              sinfo("CurrentEL: unknown\n");
 
-  /* Set CURRENT_REGS to NULL to indicate that we are no longer in an
-   * Exception handler.
-   */
+              /* Just to keep the compiler happy */
 
-  up_set_current_regs(NULL);
-}
+              esr = elr = far = 0;
+              break;
+            }
+        }
 
-void arm64_register_debug_hook(int nr, fatal_handle_func_t fn)
-{
-  DEBUGVERIFY(nr > 0 && nr <= nitems(g_debug_handler));
+      if (GET_EL(el) != MODE_EL0)
+        {
+          sinfo("ESR_ELn: 0x%"PRIx64"\n", esr);
+          sinfo("FAR_ELn: 0x%"PRIx64"\n", far);
+          sinfo("ELR_ELn: 0x%"PRIx64"\n", elr);
 
-  /* Override the default handler */
+          print_ec_cause(esr);
+        }
+    }
 
-  g_debug_handler[nr].handle_fn = fn;
+  PANIC_WITH_REGS("panic", reg);
 }
diff --git a/arch/arm64/src/common/arm64_fatal.h b/arch/arm64/src/common/arm64_fatal.h
index 301e158f00..360a28e8fa 100644
--- a/arch/arm64/src/common/arm64_fatal.h
+++ b/arch/arm64/src/common/arm64_fatal.h
@@ -21,6 +21,12 @@
 #ifndef __ARCH_ARM64_SRC_COMMON_ARM64_FATAL_H
 #define __ARCH_ARM64_SRC_COMMON_ARM64_FATAL_H
 
+/* Fatal error APIs */
+
+#define K_ERR_CPU_EXCEPTION     (0)
+#define K_ERR_CPU_MODE32        (1)
+#define K_ERR_SPURIOUS_IRQ      (2)
+
 #ifndef __ASSEMBLY__
 
 /****************************************************************************
@@ -37,123 +43,6 @@
  * Pre-processor Definitions
  ****************************************************************************/
 
-#define ESR_ELX_EC_UNKNOWN      (0x00)
-#define ESR_ELX_EC_WFX          (0x01)
-
-/* Unallocated EC: 0x02 */
-
-#define ESR_ELX_EC_CP15_32      (0x03)
-#define ESR_ELX_EC_CP15_64      (0x04)
-#define ESR_ELX_EC_CP14_MR      (0x05)
-#define ESR_ELX_EC_CP14_LS      (0x06)
-#define ESR_ELX_EC_FP_ASIMD     (0x07)
-#define ESR_ELX_EC_CP10_ID      (0x08)  /* EL2 only */
-#define ESR_ELX_EC_PAC          (0x09)  /* EL2 and above */
-
-/* Unallocated EC: 0x0A - 0x0B */
-
-#define ESR_ELX_EC_CP14_64      (0x0C)
-#define ESR_ELX_EC_BTI          (0x0D)
-#define ESR_ELX_EC_ILL          (0x0E)
-
-/* Unallocated EC: 0x0F - 0x10 */
-
-#define ESR_ELX_EC_SVC32        (0x11)
-#define ESR_ELX_EC_HVC32        (0x12)  /* EL2 only */
-#define ESR_ELX_EC_SMC32        (0x13)  /* EL2 and above */
-
-/* Unallocated EC: 0x14 */
-
-#define ESR_ELX_EC_SVC64        (0x15)
-#define ESR_ELX_EC_HVC64        (0x16)  /* EL2 and above */
-#define ESR_ELX_EC_SMC64        (0x17)  /* EL2 and above */
-#define ESR_ELX_EC_SYS64        (0x18)
-#define ESR_ELX_EC_SVE          (0x19)
-#define ESR_ELX_EC_ERET         (0x1a)  /* EL2 only */
-
-/* Unallocated EC: 0x1B */
-
-#define ESR_ELX_EC_FPAC         (0x1C)  /* EL1 and above */
-#define ESR_ELX_EC_SME          (0x1D)
-
-/* Unallocated EC: 0x1D - 0x1E */
-
-#define ESR_ELX_EC_IMP_DEF      (0x1f)  /* EL3 only */
-#define ESR_ELX_EC_IABT_LOW     (0x20)
-#define ESR_ELX_EC_IABT_CUR     (0x21)
-#define ESR_ELX_EC_PC_ALIGN     (0x22)
-
-/* Unallocated EC: 0x23 */
-
-#define ESR_ELX_EC_DABT_LOW     (0x24)
-#define ESR_ELX_EC_DABT_CUR     (0x25)
-#define ESR_ELX_EC_SP_ALIGN     (0x26)
-#define ESR_ELX_EC_MOPS         (0x27)
-#define ESR_ELX_EC_FP_EXC32     (0x28)
-
-/* Unallocated EC: 0x29 - 0x2B */
-
-#define ESR_ELX_EC_FP_EXC64     (0x2C)
-
-/* Unallocated EC: 0x2D - 0x2E */
-
-#define ESR_ELX_EC_SERROR       (0x2F)
-#define ESR_ELX_EC_BREAKPT_LOW  (0x30)
-#define ESR_ELX_EC_BREAKPT_CUR  (0x31)
-#define ESR_ELX_EC_SOFTSTP_LOW  (0x32)
-#define ESR_ELX_EC_SOFTSTP_CUR  (0x33)
-#define ESR_ELX_EC_WATCHPT_LOW  (0x34)
-#define ESR_ELX_EC_WATCHPT_CUR  (0x35)
-
-/* Unallocated EC: 0x36 - 0x37 */
-
-#define ESR_ELX_EC_BKPT32       (0x38)
-
-/* Unallocated EC: 0x39 */
-
-#define ESR_ELX_EC_VECTOR32     (0x3A) /* EL2 only */
-
-/* Unallocated EC: 0x3B */
-
-#define ESR_ELX_EC_BRK64        (0x3C)
-
-/* Unallocated EC: 0x3D - 0x3F */
-
-#define ESR_ELX_EC_MAX          (0x3F)
-
-#define ESR_ELX_EC_SHIFT        (26)
-#define ESR_ELX_EC_WIDTH        (6)
-#define ESR_ELX_EC_MASK         (0x3F << ESR_ELX_EC_SHIFT)
-#define ESR_ELX_EC(esr)         (((esr) & ESR_ELX_EC_MASK) \
-                                >> ESR_ELX_EC_SHIFT)
-
-/* Shared ISS fault status code(IFSC/DFSC) for Data/Instruction aborts */
-
-#define ESR_ELX_FSC             (0x3F)
-#define ESR_ELX_FSC_TYPE        (0x3C)
-#define ESR_ELX_FSC_LEVEL       (0x03)
-#define ESR_ELX_FSC_EXTABT      (0x10)
-#define ESR_ELX_FSC_MTE         (0x11)
-#define ESR_ELX_FSC_SERROR      (0x11)
-#define ESR_ELX_FSC_ACCESS      (0x08)
-#define ESR_ELX_FSC_FAULT       (0x04)
-#define ESR_ELX_FSC_PERM        (0x0C)
-#define ESR_ELX_FSC_SEA_TTW0    (0x14)
-#define ESR_ELX_FSC_SEA_TTW1    (0x15)
-#define ESR_ELX_FSC_SEA_TTW2    (0x16)
-#define ESR_ELX_FSC_SEA_TTW3    (0x17)
-#define ESR_ELX_FSC_SECC        (0x18)
-#define ESR_ELX_FSC_SECC_TTW0   (0x1c)
-#define ESR_ELX_FSC_SECC_TTW1   (0x1d)
-#define ESR_ELX_FSC_SECC_TTW2   (0x1e)
-#define ESR_ELX_FSC_SECC_TTW3   (0x1f)
-
-#define DBG_ESR_EVT(x)          (((x) >> 27) & 0x7)
-#define DBG_ESR_EVT_HWBP        (0x0)
-#define DBG_ESR_EVT_HWSS        (0x1)
-#define DBG_ESR_EVT_HWWP        (0x2)
-#define DBG_ESR_EVT_BRK         (0x6)
-
 #define __builtin_unreachable()    \
   do                               \
     {                              \
@@ -162,49 +51,28 @@
     } while (true)
 
 /****************************************************************************
- * Public Type Declarations
+ * Public Data
  ****************************************************************************/
 
-typedef int (*fatal_handle_func_t)(struct regs_context *regs,
-                                   uint64_t far, uint64_t esr);
-
 /****************************************************************************
  * Public Function Prototypes
  ****************************************************************************/
 
 /****************************************************************************
- * Name: arm64_fatal_handler
+ * Name: arm64_fatal_error
  *
  * Description:
- *   Fatal handle for arm64
+ *       fatal error handle for arm64
  * Input Parameters:
+ *   reason: error reason
  *   reg:    exception stack reg context
  *
- * Returned Value: None
- *   If the function return, the exception has been handled
- *
- ****************************************************************************/
-
-void arm64_fatal_handler(struct regs_context *reg);
-
-/****************************************************************************
- * Name: arm64_register_debug_hook
- *
- * Description:
- *   Register a hook function for DEBUG event
- * Input Parameters:
- *   nr:   DEBUG event
- *           DBG_ESR_EVT_HWBP : Hardware BreakPoint
- *           DBG_ESR_EVT_HWSS : Hardware SingleStep
- *           DBG_ESR_EVT_HWWP : Hardware WatchPoint
- *           DBG_ESR_EVT_BRK  : Brk instruction trigger
- *   fn:   hook function
- *
- * Returned Value: none
+ * Returned Value:
  *
  ****************************************************************************/
 
-void arm64_register_debug_hook(int nr, fatal_handle_func_t fn);
+void arm64_fatal_error(unsigned int reason, struct regs_context * reg);
+void arm64_dump_fatal(struct regs_context * reg);
 
 #endif /* __ASSEMBLY__ */
 
diff --git a/arch/arm64/src/common/arm64_vector_table.S b/arch/arm64/src/common/arm64_vector_table.S
index 1c05814c87..fa81c4e888 100644
--- a/arch/arm64/src/common/arm64_vector_table.S
+++ b/arch/arm64/src/common/arm64_vector_table.S
@@ -216,25 +216,25 @@ SECTION_SUBSEC_FUNC(exc_vector_table,_vector_table_section,_vector_table)
 
     .align 7
     arm64_enter_exception x0, x1
-    b    arm64_mode32_handler
+    b    arm64_mode32_error
 
     /* Lower EL using AArch32 / IRQ */
 
     .align 7
     arm64_enter_exception x0, x1
-    b    arm64_mode32_handler
+    b    arm64_mode32_error
 
     /* Lower EL using AArch32 / FIQ */
 
     .align 7
     arm64_enter_exception x0, x1
-    b    arm64_mode32_handler
+    b    arm64_mode32_error
 
     /* Lower EL using AArch32 / SError */
 
     .align 7
     arm64_enter_exception x0, x1
-    b    arm64_mode32_handler
+    b    arm64_mode32_error
 
 /* Restore Corruptible Registers and exception context
  * from the task stack.
diff --git a/arch/arm64/src/common/arm64_vectors.S b/arch/arm64/src/common/arm64_vectors.S
index 26aa2888b9..d2d1e5c95a 100644
--- a/arch/arm64/src/common/arm64_vectors.S
+++ b/arch/arm64/src/common/arm64_vectors.S
@@ -355,13 +355,16 @@ save_context:
     b    arm64_exit_exception
 
 exc_handle:
-    mov    x0, sp
+    arm64_exception_context_save x0 x1 sp
+    mov    x0, #K_ERR_CPU_EXCEPTION
+    mov    x1, sp
 
-    /* void arm64_fatal_handler(struct regs_context * reg);
-     * x0 = Exception stack frame
+    /* void arm64_fatal_error(unsigned int reason, const uint64_t *regs)
+     * x0 = reason
+     * x1 = Exception stack frame
      */
 
-    bl    arm64_fatal_handler
+    bl    arm64_fatal_error
 
     /* Return here only in case of recoverable error */
 
@@ -442,20 +445,28 @@ irq_context_switch:
 irq_exit:
     b     arm64_exit_exception
 
-/* TODO: if the arm64_fatal_handler return success, maybe need context switch */
+/* TODO: if the arm64_fatal_error return success, maybe need context switch */
 
 GTEXT(arm64_serror_handler)
 SECTION_FUNC(text, arm64_serror_handler)
-    mov   x0, sp
-    bl    arm64_fatal_handler
+    arm64_exception_context_save x0 x1 sp
+
+    mov    x0, #K_ERR_CPU_EXCEPTION
+    mov    x1, sp
+
+    bl    arm64_fatal_error
     /* Return here only in case of recoverable error */
 
     b    arm64_exit_exception
 
-GTEXT(arm64_mode32_handler)
-SECTION_FUNC(text, arm64_mode32_handler)
-    mov    x0, sp
-    bl    arm64_fatal_handler
+GTEXT(arm64_mode32_error)
+SECTION_FUNC(text, arm64_mode32_error)
+    arm64_exception_context_save x0 x1 sp
+
+    mov    x1, sp
+    mov    x0, #K_ERR_CPU_MODE32
+
+    bl    arm64_fatal_error
     /* Return here only in case of recoverable error */
 
     b    arm64_exit_exception
@@ -463,9 +474,12 @@ SECTION_FUNC(text, arm64_mode32_handler)
 GTEXT(arm64_fiq_handler)
 SECTION_FUNC(text, arm64_fiq_handler)
 #ifndef CONFIG_ARM64_DECODEFIQ
+    arm64_exception_context_save x0 x1 sp
 
-    mov    x0, sp
-    bl    arm64_fatal_handler
+    mov    x1, sp
+    mov    x0, #K_ERR_SPURIOUS_IRQ /* K_ERR_SPURIOUS_IRQ */
+
+    bl    arm64_fatal_error
 
     /* Return here only in case of recoverable error */
 


(nuttx) 01/05: Revert "Kernel build: enter exception save sp_sl0,exit exception restroe sp_el0"

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

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

commit 24fba435910a5276d8a4eedc9b12f0678c81c0bd
Author: Xiang Xiao <xi...@gmail.com>
AuthorDate: Tue Sep 24 00:32:34 2024 -0700

    Revert "Kernel build: enter exception save sp_sl0,exit exception restroe sp_el0"
    
    This reverts commit 52a4fb6fabd74c78cc6a33cba9a84eb4a3c72a48.
---
 arch/arm64/src/common/arm64_vector_table.S | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/arch/arm64/src/common/arm64_vector_table.S b/arch/arm64/src/common/arm64_vector_table.S
index 34d77f787d..21b70d2575 100644
--- a/arch/arm64/src/common/arm64_vector_table.S
+++ b/arch/arm64/src/common/arm64_vector_table.S
@@ -78,10 +78,6 @@
 #endif
     stp    x0, x1,  [sp, #8 * REG_ELR]
 
-    mrs    x0, sp_el0
-    mrs    x1, tpidrro_el0
-    stp    x0, x1,  [sp, #8 * REG_SP_EL0]
-
     /* Increment exception depth */
 
     mrs    x0, tpidrro_el0
@@ -266,10 +262,6 @@ SECTION_FUNC(text, arm64_exit_exception)
     msr    spsr_el1,  x1
 #endif
 
-    ldp    x0, x1,   [sp, #8 * REG_SP_EL0]
-    msr    sp_el0,   x0
-    msr    tpidrro_el0,  x1
-
     /* decrement exception depth */
 
     mrs    x0, tpidrro_el0


(nuttx) 04/05: Revert "arm64: save FPU regs every time"

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

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

commit 9e8df3b3fa3abd192fd4445ab7f2d6c70db90e14
Author: Xiang Xiao <xi...@gmail.com>
AuthorDate: Tue Sep 24 00:32:34 2024 -0700

    Revert "arm64: save FPU regs every time"
    
    This reverts commit 3c4f3c10083ac5769a9805ed48bf71904f000edd.
---
 arch/arm64/src/common/arm64_arch.h              |   3 -
 arch/arm64/src/common/arm64_exit.c              |   6 +
 arch/arm64/src/common/arm64_fpu.c               | 140 +++++++++++++++++++++++-
 arch/arm64/src/common/arm64_initialstate.c      |  20 ++++
 arch/arm64/src/common/arm64_schedulesigaction.c |  29 +++++
 arch/arm64/src/common/arm64_sigdeliver.c        |   9 ++
 arch/arm64/src/common/arm64_syscall.c           |   1 +
 arch/arm64/src/common/arm64_vector_table.S      |  75 ++++++-------
 arch/arm64/src/common/arm64_vectors.S           | 129 ++++++++++++++++++++--
 9 files changed, 359 insertions(+), 53 deletions(-)

diff --git a/arch/arm64/src/common/arm64_arch.h b/arch/arm64/src/common/arm64_arch.h
index 35c4cdc105..06935472fb 100644
--- a/arch/arm64/src/common/arm64_arch.h
+++ b/arch/arm64/src/common/arm64_arch.h
@@ -299,9 +299,6 @@ struct regs_context
   uint64_t  spsr;
   uint64_t  sp_el0;
   uint64_t  exe_depth;
-#ifdef CONFIG_ARCH_FPU
-  struct fpu_reg fpu_regs;
-#endif
 };
 
 /****************************************************************************
diff --git a/arch/arm64/src/common/arm64_exit.c b/arch/arm64/src/common/arm64_exit.c
index cb0d4bd24a..0052adac94 100644
--- a/arch/arm64/src/common/arm64_exit.c
+++ b/arch/arm64/src/common/arm64_exit.c
@@ -65,6 +65,12 @@ void up_exit(int status)
    */
 
   enter_critical_section();
+
+  /* Destroy the task at the head of the ready to run list. */
+#ifdef CONFIG_ARCH_FPU
+  arm64_destory_fpu(tcb);
+#endif
+
   nxtask_exit();
 
   /* Now, perform the context switch to the new ready-to-run task at the
diff --git a/arch/arm64/src/common/arm64_fpu.c b/arch/arm64/src/common/arm64_fpu.c
index e80e7240ae..c1accb48eb 100644
--- a/arch/arm64/src/common/arm64_fpu.c
+++ b/arch/arm64/src/common/arm64_fpu.c
@@ -77,10 +77,11 @@ struct arm64_fpu_procfs_file_s
  * Private Data
  ***************************************************************************/
 
-#ifdef CONFIG_FS_PROCFS_REGISTER
-
+static struct fpu_reg g_idle_thread_fpu[CONFIG_SMP_NCPUS];
 static struct arm64_cpu_fpu_context g_cpu_fpu_ctx[CONFIG_SMP_NCPUS];
 
+#ifdef CONFIG_FS_PROCFS_REGISTER
+
 /* procfs methods */
 
 static int arm64_fpu_procfs_open(struct file *filep, const char *relpath,
@@ -261,6 +262,141 @@ static int arm64_fpu_procfs_stat(const char *relpath, struct stat *buf)
 }
 #endif
 
+/***************************************************************************
+ * Public Functions
+ ***************************************************************************/
+
+void arm64_init_fpu(struct tcb_s *tcb)
+{
+  if (tcb->pid < CONFIG_SMP_NCPUS)
+    {
+#ifdef CONFIG_SMP
+      int cpu = tcb->cpu;
+#else
+      int cpu = 0;
+#endif
+      memset(&g_cpu_fpu_ctx[cpu], 0,
+             sizeof(struct arm64_cpu_fpu_context));
+      g_cpu_fpu_ctx[cpu].idle_thread = tcb;
+
+      tcb->xcp.fpu_regs = (uint64_t *)&g_idle_thread_fpu[cpu];
+    }
+
+  memset(tcb->xcp.fpu_regs, 0, sizeof(struct fpu_reg));
+}
+
+void arm64_destory_fpu(struct tcb_s *tcb)
+{
+  struct tcb_s *owner;
+
+  /* save current fpu owner's context */
+
+  owner = g_cpu_fpu_ctx[this_cpu()].fpu_owner;
+
+  if (owner == tcb)
+    {
+      g_cpu_fpu_ctx[this_cpu()].fpu_owner = NULL;
+    }
+}
+
+/***************************************************************************
+ * Name: arm64_fpu_enter_exception
+ *
+ * Description:
+ *   called at every time get into a exception
+ *
+ ***************************************************************************/
+
+void arm64_fpu_enter_exception(void)
+{
+}
+
+void arm64_fpu_exit_exception(void)
+{
+}
+
+void arm64_fpu_trap(struct regs_context *regs)
+{
+  struct tcb_s *owner;
+
+  UNUSED(regs);
+
+  /* disable fpu trap access */
+
+  arm64_fpu_access_trap_disable();
+
+  /* save current fpu owner's context */
+
+  owner = g_cpu_fpu_ctx[this_cpu()].fpu_owner;
+
+  if (owner != NULL)
+    {
+      arm64_fpu_save((struct fpu_reg *)owner->xcp.fpu_regs);
+      ARM64_DSB();
+      g_cpu_fpu_ctx[this_cpu()].save_count++;
+      g_cpu_fpu_ctx[this_cpu()].fpu_owner = NULL;
+    }
+
+  if (arch_get_exception_depth() > 1)
+    {
+      /* if get_exception_depth > 1
+       * it means FPU access exception occurred in exception context
+       * switch FPU owner to idle thread
+       */
+
+      owner = g_cpu_fpu_ctx[this_cpu()].idle_thread;
+    }
+  else
+    {
+      owner = running_task();
+    }
+
+  /* restore our context */
+
+  arm64_fpu_restore((struct fpu_reg *)owner->xcp.fpu_regs);
+  g_cpu_fpu_ctx[this_cpu()].restore_count++;
+
+  /* become new owner */
+
+  g_cpu_fpu_ctx[this_cpu()].fpu_owner = owner;
+}
+
+void arm64_fpu_context_restore(void)
+{
+  struct tcb_s *new_tcb = running_task();
+
+  arm64_fpu_access_trap_disable();
+
+  /* FPU trap has happened at this task */
+
+  if (new_tcb == g_cpu_fpu_ctx[this_cpu()].fpu_owner)
+    {
+      arm64_fpu_access_trap_disable();
+    }
+  else
+    {
+      arm64_fpu_access_trap_enable();
+    }
+
+  g_cpu_fpu_ctx[this_cpu()].switch_count++;
+}
+
+#ifdef CONFIG_SMP
+void arm64_fpu_context_save(void)
+{
+  struct tcb_s *tcb = running_task();
+
+  if (tcb == g_cpu_fpu_ctx[this_cpu()].fpu_owner)
+    {
+      arm64_fpu_access_trap_disable();
+      arm64_fpu_save((struct fpu_reg *)tcb->xcp.fpu_regs);
+      ARM64_DSB();
+      g_cpu_fpu_ctx[this_cpu()].save_count++;
+      g_cpu_fpu_ctx[this_cpu()].fpu_owner = NULL;
+    }
+}
+#endif
+
 void arm64_fpu_enable(void)
 {
   irqstate_t flags = up_irq_save();
diff --git a/arch/arm64/src/common/arm64_initialstate.c b/arch/arm64/src/common/arm64_initialstate.c
index 32058db485..93aa822fff 100644
--- a/arch/arm64/src/common/arm64_initialstate.c
+++ b/arch/arm64/src/common/arm64_initialstate.c
@@ -47,6 +47,10 @@
 #include "chip.h"
 #include "arm64_fatal.h"
 
+#ifdef CONFIG_ARCH_FPU
+#include "arm64_fpu.h"
+#endif
+
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -66,6 +70,17 @@ void arm64_new_task(struct tcb_s * tcb)
     }
 #endif
 
+#ifdef CONFIG_ARCH_FPU
+  struct fpu_reg *pfpuctx;
+  pfpuctx = STACK_PTR_TO_FRAME(struct fpu_reg, stack_ptr);
+  tcb->xcp.fpu_regs   = (uint64_t *)pfpuctx;
+
+  /* set fpu context */
+
+  arm64_init_fpu(tcb);
+  stack_ptr  = (uintptr_t)pfpuctx;
+#endif
+
   pinitctx = STACK_PTR_TO_FRAME(struct regs_context, stack_ptr);
   memset(pinitctx, 0, sizeof(struct regs_context));
   pinitctx->elr       = (uint64_t)tcb->start;
@@ -135,6 +150,11 @@ void up_initial_state(struct tcb_s *tcb)
       tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
       tcb->adj_stack_size  = CONFIG_IDLETHREAD_STACKSIZE;
 
+#ifdef CONFIG_ARCH_FPU
+      /* set fpu context */
+
+      arm64_init_fpu(tcb);
+#endif
       /* set initialize idle thread tcb and exception depth
        * core 0, idle0
        */
diff --git a/arch/arm64/src/common/arm64_schedulesigaction.c b/arch/arm64/src/common/arm64_schedulesigaction.c
index 4f0534345a..888c810626 100644
--- a/arch/arm64/src/common/arm64_schedulesigaction.c
+++ b/arch/arm64/src/common/arm64_schedulesigaction.c
@@ -38,6 +38,10 @@
 #include "irq/irq.h"
 #include "arm64_fatal.h"
 
+#ifdef CONFIG_ARCH_FPU
+#include "arm64_fpu.h"
+#endif
+
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -54,6 +58,16 @@ void arm64_init_signal_process(struct tcb_s *tcb, struct regs_context *regs)
   struct regs_context  *psigctx;
   char *stack_ptr    = (char *)pctx->sp_elx - sizeof(struct regs_context);
 
+#ifdef CONFIG_ARCH_FPU
+  struct fpu_reg      *pfpuctx;
+  pfpuctx            = STACK_PTR_TO_FRAME(struct fpu_reg, stack_ptr);
+  tcb->xcp.fpu_regs  = (uint64_t *)pfpuctx;
+
+  /* set fpu context */
+
+  arm64_init_fpu(tcb);
+  stack_ptr          = (char *)pfpuctx;
+#endif
   psigctx            = STACK_PTR_TO_FRAME(struct regs_context, stack_ptr);
   memset(psigctx, 0, sizeof(struct regs_context));
   psigctx->elr       = (uint64_t)arm64_sigdeliver;
@@ -163,6 +177,9 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
               /* create signal process context */
 
               tcb->xcp.saved_reg = up_current_regs();
+#ifdef CONFIG_ARCH_FPU
+              tcb->xcp.saved_fpu_regs = tcb->xcp.fpu_regs;
+#endif
               arm64_init_signal_process(tcb,
               (struct regs_context *)up_current_regs());
 
@@ -184,6 +201,9 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
            * have been delivered.
            */
 
+#ifdef CONFIG_ARCH_FPU
+          tcb->xcp.saved_fpu_regs = tcb->xcp.fpu_regs;
+#endif
           /* create signal process context */
 
           tcb->xcp.saved_reg = tcb->xcp.regs;
@@ -259,6 +279,9 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
                    * been delivered.
                    */
 
+#ifdef CONFIG_ARCH_FPU
+                  tcb->xcp.saved_fpu_regs = tcb->xcp.fpu_regs;
+#endif
                   /* create signal process context */
 
                   tcb->xcp.saved_reg = tcb->xcp.regs;
@@ -277,6 +300,9 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
                   /* create signal process context */
 
                   tcb->xcp.saved_reg = up_current_regs();
+#ifdef CONFIG_ARCH_FPU
+                  tcb->xcp.saved_fpu_regs = tcb->xcp.fpu_regs;
+#endif
                   arm64_init_signal_process(tcb,
                   (struct regs_context *)up_current_regs());
 
@@ -313,6 +339,9 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
            * have been delivered.
            */
 
+#ifdef CONFIG_ARCH_FPU
+          tcb->xcp.saved_fpu_regs = tcb->xcp.fpu_regs;
+#endif
           tcb->xcp.saved_reg = tcb->xcp.regs;
 
           /* create signal process context */
diff --git a/arch/arm64/src/common/arm64_sigdeliver.c b/arch/arm64/src/common/arm64_sigdeliver.c
index 0d46a98410..15e7946c7c 100644
--- a/arch/arm64/src/common/arm64_sigdeliver.c
+++ b/arch/arm64/src/common/arm64_sigdeliver.c
@@ -38,6 +38,10 @@
 #include "irq/irq.h"
 #include "arm64_fatal.h"
 
+#ifdef CONFIG_ARCH_FPU
+#include "arm64_fpu.h"
+#endif
+
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -153,6 +157,11 @@ retry:
   rtcb->xcp.sigdeliver = NULL;  /* Allows next handler to be scheduled */
   rtcb->xcp.regs = rtcb->xcp.saved_reg;
 
+#ifdef CONFIG_ARCH_FPU
+  arm64_destory_fpu(rtcb);
+  rtcb->xcp.fpu_regs = rtcb->xcp.saved_fpu_regs;
+#endif
+
   /* Then restore the correct state for this thread of execution. */
 
 #ifdef CONFIG_SMP
diff --git a/arch/arm64/src/common/arm64_syscall.c b/arch/arm64/src/common/arm64_syscall.c
index c59aef35cb..318e7e0cf6 100644
--- a/arch/arm64/src/common/arm64_syscall.c
+++ b/arch/arm64/src/common/arm64_syscall.c
@@ -193,6 +193,7 @@ uint64_t *arm64_syscall_switch(uint64_t * regs)
            */
 
           ret_regs = (uint64_t *)f_regs->regs[REG_X1];
+          f_regs->regs[REG_X1] = 0; /* set the saveregs = 0 */
 
           DEBUGASSERT(ret_regs);
         }
diff --git a/arch/arm64/src/common/arm64_vector_table.S b/arch/arm64/src/common/arm64_vector_table.S
index 21b70d2575..1c05814c87 100644
--- a/arch/arm64/src/common/arm64_vector_table.S
+++ b/arch/arm64/src/common/arm64_vector_table.S
@@ -45,8 +45,8 @@
  *     but only save ARM64_ESF_REGS
  */
 
-.macro arm64_enter_exception
-    sub    sp, sp, #8 * XCPTCONTEXT_REGS
+.macro arm64_enter_exception xreg0, xreg1
+    sub    sp, sp, #8 * XCPTCONTEXT_GP_REGS
 
     stp    x0,  x1,  [sp, #8 * REG_X0]
     stp    x2,  x3,  [sp, #8 * REG_X2]
@@ -65,32 +65,30 @@
     stp    x28, x29, [sp, #8 * REG_X28]
 
     /* Save the current task's SP_ELx and x30 */
-    add    x0, sp, #8 * XCPTCONTEXT_REGS
-    stp    x30, x0,  [sp, #8 * REG_X30]
+    add    \xreg0, sp, #8 * XCPTCONTEXT_GP_REGS
+    stp    x30, \xreg0,  [sp, #8 * REG_X30]
 
     /* ELR and SPSR */
 #if CONFIG_ARCH_ARM64_EXCEPTION_LEVEL == 3
-    mrs    x0, elr_el3
-    mrs    x1, spsr_el3
+    mrs    \xreg0, elr_el3
+    mrs    \xreg1, spsr_el3
 #else
-    mrs    x0, elr_el1
-    mrs    x1, spsr_el1
+    mrs    \xreg0, elr_el1
+    mrs    \xreg1, spsr_el1
 #endif
-    stp    x0, x1,  [sp, #8 * REG_ELR]
+    stp    \xreg0, \xreg1,  [sp, #8 * REG_ELR]
 
-    /* Increment exception depth */
+    /* increment exception depth */
 
-    mrs    x0, tpidrro_el0
-    mov    x1, #1
-    add    x0, x0, x1
-    msr    tpidrro_el0, x0
+    mrs    \xreg0, tpidrro_el0
+    mov    \xreg1, #1
+    add    \xreg0, \xreg0, \xreg1
+    msr    tpidrro_el0, \xreg0
 
-    /* Save the FPU registers */
-
-    add    x0, sp, #8 * XCPTCONTEXT_GP_REGS
 #ifdef CONFIG_ARCH_FPU
-    bl     arm64_fpu_save
+    bl    arm64_fpu_enter_exception
 #endif
+
 .endm
 
 /****************************************************************************
@@ -145,97 +143,97 @@ SECTION_SUBSEC_FUNC(exc_vector_table,_vector_table_section,_vector_table)
     /* Current EL with SP0 / Synchronous */
 
     .align 7
-    arm64_enter_exception
+    arm64_enter_exception x9, x10
     b    arm64_sync_exc
 
     /* Current EL with SP0 / IRQ */
 
     .align 7
-    arm64_enter_exception
+    arm64_enter_exception x0, x1
     b    arm64_irq_handler
 
     /* Current EL with SP0 / FIQ */
 
     .align 7
-    arm64_enter_exception
+    arm64_enter_exception x0, x1
     b     arm64_fiq_handler
 
     /* Current EL with SP0 / SError */
 
     .align 7
-    arm64_enter_exception
+    arm64_enter_exception x0, x1
     b    arm64_serror_handler
 
     /* Current EL with SPx / Synchronous */
 
     .align 7
-    arm64_enter_exception
+    arm64_enter_exception x9, x10
     b    arm64_sync_exc
 
     /* Current EL with SPx / IRQ */
 
     .align 7
-    arm64_enter_exception
+    arm64_enter_exception x0, x1
     b    arm64_irq_handler
 
     /* Current EL with SPx / FIQ */
 
     .align 7
-    arm64_enter_exception
+    arm64_enter_exception x0, x1
     b     arm64_fiq_handler
 
     /* Current EL with SPx / SError */
 
     .align 7
-    arm64_enter_exception
+    arm64_enter_exception x0, x1
     b    arm64_serror_handler
 
     /* Lower EL using AArch64 / Synchronous */
 
     .align 7
-    arm64_enter_exception
+    arm64_enter_exception x9, x10
     b    arm64_sync_exc
 
     /* Lower EL using AArch64 / IRQ */
 
     .align 7
-    arm64_enter_exception
+    arm64_enter_exception x0, x1
     b    arm64_irq_handler
 
     /* Lower EL using AArch64 / FIQ */
 
     .align 7
-    arm64_enter_exception
+    arm64_enter_exception x0, x1
     b     arm64_fiq_handler
 
     /* Lower EL using AArch64 / SError */
 
     .align 7
-    arm64_enter_exception
+    arm64_enter_exception x0, x1
     b    arm64_serror_handler
 
     /* Lower EL using AArch32 / Synchronous */
 
     .align 7
-    arm64_enter_exception
+    arm64_enter_exception x0, x1
     b    arm64_mode32_handler
 
     /* Lower EL using AArch32 / IRQ */
 
     .align 7
-    arm64_enter_exception
+    arm64_enter_exception x0, x1
     b    arm64_mode32_handler
 
     /* Lower EL using AArch32 / FIQ */
 
     .align 7
-    arm64_enter_exception
+    arm64_enter_exception x0, x1
     b    arm64_mode32_handler
 
     /* Lower EL using AArch32 / SError */
 
     .align 7
-    arm64_enter_exception
+    arm64_enter_exception x0, x1
     b    arm64_mode32_handler
 
 /* Restore Corruptible Registers and exception context
@@ -244,11 +242,10 @@ SECTION_SUBSEC_FUNC(exc_vector_table,_vector_table_section,_vector_table)
 
 GTEXT(arm64_exit_exception)
 SECTION_FUNC(text, arm64_exit_exception)
-
-    mov    sp, x0
-    add    x0, x0, #8 * XCPTCONTEXT_GP_REGS
 #ifdef CONFIG_ARCH_FPU
-    bl     arm64_fpu_restore
+    bl    arm64_fpu_exit_exception
+GTEXT(arm64_exit_exc_fpu_done)
+arm64_exit_exc_fpu_done:
 #endif
 
     /* restore spsr and elr at el1*/
@@ -286,6 +283,6 @@ SECTION_FUNC(text, arm64_exit_exception)
     ldp    x28, x29, [sp, #8 * REG_X28]
     ldp    x30, xzr, [sp, #8 * REG_X30]
 
-    add    sp, sp, #8 * XCPTCONTEXT_REGS
+    add    sp, sp, #8 * XCPTCONTEXT_GP_REGS
 
     eret
diff --git a/arch/arm64/src/common/arm64_vectors.S b/arch/arm64/src/common/arm64_vectors.S
index 05e874262e..26aa2888b9 100644
--- a/arch/arm64/src/common/arm64_vectors.S
+++ b/arch/arm64/src/common/arm64_vectors.S
@@ -99,6 +99,63 @@ SECTION_FUNC(text, up_saveusercontext)
 
     ret
 
+/****************************************************************************
+ * Function: arm64_context_switch
+ *
+ * Description:
+ *  Routine to handle context switch
+ *
+ * arm64_context_switch( x0, x1)
+ *     x0: restore thread stack context
+ *     x1: save thread stack context
+ * note:
+ *     x1 = 0, only restore x0
+ *
+ ****************************************************************************/
+
+GTEXT(arm64_context_switch)
+SECTION_FUNC(text, arm64_context_switch)
+    cmp    x1, #0x0
+    beq    restore_new
+
+#if defined(CONFIG_ARCH_FPU) && defined(CONFIG_SMP)
+    stp    x0, x1, [sp, #-16]!
+    stp    xzr, x30, [sp, #-16]!
+    bl     arm64_fpu_context_save
+    ldp    xzr, x30, [sp], #16
+    ldp    x0, x1, [sp], #16
+#endif
+
+    /* Save the current SP_ELx */
+    add    x4, sp, #8 * XCPTCONTEXT_GP_REGS
+    str    x4, [x1, #8 * REG_SP_ELX]
+
+    /* Save the current task's SP_EL0 and exception depth */
+    mrs    x4, sp_el0
+    mrs    x5, tpidrro_el0
+    stp    x4, x5, [x1, #8 * REG_SP_EL0]
+
+restore_new:
+
+    /* Restore SP_EL0 and thread's exception dept */
+    ldp    x4,  x5,  [x0, #8 * REG_SP_EL0]
+    msr    tpidrro_el0, x5
+    msr    sp_el0, x4
+
+    /* retrieve new thread's SP_ELx */
+    ldr    x4, [x0, #8 * REG_SP_ELX]
+    sub    sp, x4, #8 * XCPTCONTEXT_GP_REGS
+
+#ifdef CONFIG_ARCH_FPU
+    stp    xzr, x30, [sp, #-16]!
+    bl     arm64_fpu_context_restore
+    ldp    xzr, x30, [sp], #16
+#endif
+
+    /* Return to arm64_sync_exc() or arm64_irq_handler() */
+
+    ret
+
 /****************************************************************************
  * Function: arm64_jump_to_user
  *
@@ -142,27 +199,28 @@ SECTION_FUNC(text, arm64_sync_exc)
     /* checking the EC value to see which exception need to be handle */
 
 #if CONFIG_ARCH_ARM64_EXCEPTION_LEVEL == 3
-    mrs    x0, esr_el3
+    mrs    x9, esr_el3
 #else
-    mrs    x0, esr_el1
+    mrs    x9, esr_el1
 #endif
-    lsr    x1, x0, #26
+    lsr    x10, x9, #26
 
 #ifdef CONFIG_ARCH_FPU
     /* fpu trap */
 
-    cmp    x1, #0x07 /*Access to SIMD or floating-point */
+    cmp    x10, #0x07 /* Access to SIMD or floating-point */
     bne    1f
-    mov    x0, sp
+    mov    x0, sp     /* x0 = context */
+    bl     arm64_fpu_trap
 
     /* when the fpu trap is handled */
 
-    b      arm64_exit_exception
+    b      arm64_exit_exc_fpu_done
 1:
 #endif
     /* 0x15 = SVC system call */
 
-    cmp    x1, #0x15
+    cmp    x10, #0x15
 
     /* if this is a svc call ?*/
 
@@ -250,13 +308,17 @@ context_switch:
      */
 
     mov    x0, sp
-    str    x0, [sp, #-16]!
     bl    arm64_syscall_switch
 
     /* get save task reg context pointer */
 
-    ldr    x1, [sp], #16
+    ldr    x1, [sp, #8 * REG_X1]
+    cmp    x1, #0x0
+
+    beq do_switch
+    ldr x1, [x1]
 
+do_switch:
 #ifdef CONFIG_SMP
     /* Notes:
      * Complete any pending TLB or cache maintenance on this CPU in case
@@ -268,7 +330,15 @@ context_switch:
     dsb   ish
 #endif
 
+    bl    arm64_context_switch
+
+#ifdef CONFIG_ARCH_FPU
+    /* when the fpu trap is handled */
+
+    b    arm64_exit_exc_fpu_done
+#else
     b    arm64_exit_exception
+#endif
 
 save_context:
     arm64_exception_context_save x0 x1 sp
@@ -338,6 +408,14 @@ SECTION_FUNC(text, arm64_irq_handler)
 
     ldr    x1, [sp], #16
 
+    /* retrieve the task's stack. */
+
+    mov    sp, x1
+
+    cmp    x0, x1
+    beq    irq_exit
+
+irq_context_switch:
 #ifdef CONFIG_SMP
     /* Notes:
      * Complete any pending TLB or cache maintenance on this CPU in case
@@ -349,6 +427,19 @@ SECTION_FUNC(text, arm64_irq_handler)
 
 #endif
 
+    /*  Switch thread
+     *  - x0: restore task reg context, return by arm64_decodeirq,
+     *  - x1: save task reg context, save before call arm64_decodeirq
+     *    call arm64_context_switch(x0) to switch
+     */
+    bl    arm64_context_switch
+#ifdef CONFIG_ARCH_FPU
+    /* when the fpu trap is handled */
+
+    b     arm64_exit_exc_fpu_done
+#endif
+
+irq_exit:
     b     arm64_exit_exception
 
 /* TODO: if the arm64_fatal_handler return success, maybe need context switch */
@@ -411,6 +502,14 @@ SECTION_FUNC(text, arm64_fiq_handler)
 
     ldr    x1, [sp], #16
 
+    /* retrieve the task's stack. */
+
+    mov    sp, x1
+
+    cmp    x0, x1
+    beq    fiq_exit
+
+
 #ifdef CONFIG_SMP
     /* Notes:
      * Complete any pending TLB or cache maintenance on this CPU in case
@@ -422,5 +521,17 @@ SECTION_FUNC(text, arm64_fiq_handler)
 
 #endif
 
+    /*  Switch thread
+     *  - x0: restore task reg context, return by arm64_decodefiq,
+     *  - x1: save task reg context, save before call arm64_decodefiq
+     *    call arm64_context_switch(x0) to switch
+     */
+    bl    arm64_context_switch
+#ifdef CONFIG_ARCH_FPU
+    /* when the fpu trap is handled */
+
+    b     arm64_exit_exc_fpu_done
+#endif
+fiq_exit:
     b     arm64_exit_exception
 #endif


(nuttx) 02/05: Revert "arm64: simply the vectors"

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

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

commit 0a2a6dfa575a2bc72ad53373bedbe026df2ba04d
Author: Xiang Xiao <xi...@gmail.com>
AuthorDate: Tue Sep 24 00:32:34 2024 -0700

    Revert "arm64: simply the vectors"
    
    This reverts commit 370679c65bb6b492cdad86bdfbd4ace2d7ea0908.
---
 arch/arm64/src/common/arm64_internal.h |   3 +-
 arch/arm64/src/common/arm64_syscall.c  | 162 +++++++++++---------
 arch/arm64/src/common/arm64_vectors.S  | 271 ++++++++++++++++++++++++++-------
 3 files changed, 308 insertions(+), 128 deletions(-)

diff --git a/arch/arm64/src/common/arm64_internal.h b/arch/arm64/src/common/arm64_internal.h
index 594a644ce0..19c8b9eb69 100644
--- a/arch/arm64/src/common/arm64_internal.h
+++ b/arch/arm64/src/common/arm64_internal.h
@@ -312,7 +312,8 @@ void arm64_pginitialize(void);
 #  define arm64_pginitialize()
 #endif /* CONFIG_LEGACY_PAGING */
 
-uint64_t *arm64_syscall(uint64_t *regs);
+uint64_t * arm64_syscall_switch(uint64_t *regs);
+int arm64_syscall(uint64_t *regs);
 
 /* Low level serial output **************************************************/
 
diff --git a/arch/arm64/src/common/arm64_syscall.c b/arch/arm64/src/common/arm64_syscall.c
index d75a207ee9..c59aef35cb 100644
--- a/arch/arm64/src/common/arm64_syscall.c
+++ b/arch/arm64/src/common/arm64_syscall.c
@@ -53,18 +53,18 @@ typedef uintptr_t (*syscall_t)(unsigned int, ...);
  ****************************************************************************/
 
 static void  arm64_dump_syscall(const char *tag, uint64_t cmd,
-                                const uint64_t *regs)
+                                const struct regs_context * f_regs)
 {
-  svcinfo("SYSCALL %s: regs: %p cmd: %" PRId64 "\n", tag, regs, cmd);
+  svcinfo("SYSCALL %s: regs: %p cmd: %" PRId64 "\n", tag, f_regs, cmd);
 
   svcinfo("x0:  0x%-16lx  x1:  0x%lx\n",
-          regs[REG_X0], regs[REG_X1]);
+          f_regs->regs[REG_X0], f_regs->regs[REG_X1]);
   svcinfo("x2:  0x%-16lx  x3:  0x%lx\n",
-          regs[REG_X2], regs[REG_X3]);
+          f_regs->regs[REG_X2], f_regs->regs[REG_X3]);
   svcinfo("x4:  0x%-16lx  x5:  0x%lx\n",
-          regs[REG_X4], regs[REG_X5]);
+          f_regs->regs[REG_X4], f_regs->regs[REG_X5]);
   svcinfo("x6:  0x%-16lx  x7:  0x%lx\n",
-          regs[REG_X6], regs[REG_X7]);
+          f_regs->regs[REG_X6], f_regs->regs[REG_X7]);
 }
 
 #ifdef CONFIG_LIB_SYSCALL
@@ -145,32 +145,32 @@ uintptr_t dispatch_syscall(unsigned int nbr, uintptr_t parm1,
 #endif
 
 /****************************************************************************
- * Name: arm64_syscall
+ * Name: arm64_syscall_switch
  *
  * Description:
  *   task switch syscall
  *
  ****************************************************************************/
 
-uint64_t *arm64_syscall(uint64_t *regs)
+uint64_t *arm64_syscall_switch(uint64_t * regs)
 {
-  uint64_t            *ret_regs = regs;
   uint64_t             cmd;
+  struct regs_context *f_regs;
+  uint64_t            *ret_regs;
   struct tcb_s        *tcb;
   int cpu;
-#ifdef CONFIG_BUILD_KERNEL
-  uint64_t             spsr;
-#endif
 
   /* Nested interrupts are not supported */
 
   DEBUGASSERT(regs);
 
+  f_regs = (struct regs_context *)regs;
+
   /* The SYSCALL command is in x0 on entry.  Parameters follow in x1..x7 */
 
-  cmd = regs[REG_X0];
+  cmd = f_regs->regs[REG_X0];
 
-  arm64_dump_syscall(__func__, cmd, regs);
+  arm64_dump_syscall(__func__, cmd, f_regs);
 
   switch (cmd)
     {
@@ -192,7 +192,7 @@ uint64_t *arm64_syscall(uint64_t *regs)
            * set will determine the restored context.
            */
 
-          ret_regs = (uint64_t *)regs[REG_X1];
+          ret_regs = (uint64_t *)f_regs->regs[REG_X1];
 
           DEBUGASSERT(ret_regs);
         }
@@ -216,13 +216,85 @@ uint64_t *arm64_syscall(uint64_t *regs)
 
       case SYS_switch_context:
         {
-          DEBUGASSERT(regs[REG_X1] != 0 && regs[REG_X2] != 0);
-          *(uint64_t **)regs[REG_X1] = regs;
+          DEBUGASSERT(f_regs->regs[REG_X1] != 0 &&
+                      f_regs->regs[REG_X2] != 0);
+          *(uint64_t **)f_regs->regs[REG_X1] = regs;
 
-          ret_regs = (uint64_t *)regs[REG_X2];
+          ret_regs = (uint64_t *) f_regs->regs[REG_X2];
         }
         break;
 
+      default:
+        {
+          svcerr("ERROR: Bad SYS call: 0x%" PRIx64 "\n", cmd);
+          ret_regs = 0;
+          return 0;
+        }
+        break;
+    }
+
+  if ((uint64_t *)f_regs != ret_regs)
+    {
+#ifdef CONFIG_ARCH_ADDRENV
+      /* Make sure that the address environment for the previously
+       * running task is closed down gracefully (data caches dump,
+       * MMU flushed) and set up the address environment for the new
+       * thread at the head of the ready-to-run list.
+       */
+
+      addrenv_switch(NULL);
+#endif
+
+      /* Record the new "running" task.  g_running_tasks[] is only used by
+       * assertion logic for reporting crashes.
+       */
+
+      cpu = this_cpu();
+      tcb = current_task(cpu);
+      g_running_tasks[cpu] = tcb;
+
+      /* Restore the cpu lock */
+
+      restore_critical_section(tcb, cpu);
+    }
+
+  return ret_regs;
+}
+
+/****************************************************************************
+ * Name: arm64_syscall
+ *
+ * Description:
+ *   SVC interrupts will vector here with insn=the SVC instruction and
+ *   xcp=the interrupt context
+ *
+ *   The handler may get the SVC number be de-referencing the return
+ *   address saved in the xcp and decoding the SVC instruction
+ *
+ ****************************************************************************/
+
+int arm64_syscall(uint64_t *regs)
+{
+  uint64_t             cmd;
+  struct regs_context *f_regs;
+#ifdef CONFIG_BUILD_KERNEL
+  uint64_t             spsr;
+#endif
+
+  /* Nested interrupts are not supported */
+
+  DEBUGASSERT(regs);
+
+  f_regs = (struct regs_context *)regs;
+
+  /* The SYSCALL command is in x0 on entry.  Parameters follow in x1..x7 */
+
+  cmd = f_regs->regs[REG_X0];
+
+  arm64_dump_syscall(__func__, cmd, f_regs);
+
+  switch (cmd)
+    {
 #ifdef CONFIG_BUILD_KERNEL
       /* R0=SYS_signal_handler:  This a user signal handler callback
        *
@@ -324,59 +396,11 @@ uint64_t *arm64_syscall(uint64_t *regs)
         break;
 #endif
 
-      /* This is not an architecture-specific system call.  If NuttX is built
-       * as a standalone kernel with a system call interface, then all of the
-       * additional system calls must be handled as in the default case.
-       */
-
       default:
-        {
-#ifdef CONFIG_LIB_SYSCALL
 
-          /* Verify that the SYS call number is within range */
-
-          DEBUGASSERT(cmd >= CONFIG_SYS_RESERVED && cmd < SYS_maxsyscall);
-
-          /* Make sure that there is a no saved SYSCALL return address.  We
-           * cannot yet handle nested system calls.
-           */
-
-          regs[REG_X0] = dispatch_syscall(regs[REG_X0], regs[REG_X1],
-                                          regs[REG_X2], regs[REG_X3],
-                                          regs[REG_X4], regs[REG_X5],
-                                          regs[REG_X6]);
-
-#else
-          svcerr("ERROR: Bad SYS call: 0x%" PRIx64 "\n", cmd);
-#endif
-        }
-        break;
+          DEBUGPANIC();
+          break;
     }
 
-  if (regs != ret_regs)
-    {
-#ifdef CONFIG_ARCH_ADDRENV
-      /* Make sure that the address environment for the previously
-       * running task is closed down gracefully (data caches dump,
-       * MMU flushed) and set up the address environment for the new
-       * thread at the head of the ready-to-run list.
-       */
-
-      addrenv_switch(NULL);
-#endif
-
-      /* Record the new "running" task.  g_running_tasks[] is only used by
-       * assertion logic for reporting crashes.
-       */
-
-      cpu = this_cpu();
-      tcb = current_task(cpu);
-      g_running_tasks[cpu] = tcb;
-
-      /* Restore the cpu lock */
-
-      restore_critical_section(tcb, cpu);
-    }
-
-  return ret_regs;
+  return 0;
 }
diff --git a/arch/arm64/src/common/arm64_vectors.S b/arch/arm64/src/common/arm64_vectors.S
index 5f65caa608..05e874262e 100644
--- a/arch/arm64/src/common/arm64_vectors.S
+++ b/arch/arm64/src/common/arm64_vectors.S
@@ -139,33 +139,164 @@ SECTION_FUNC(text, arm64_jump_to_user)
 
 GTEXT(arm64_sync_exc)
 SECTION_FUNC(text, arm64_sync_exc)
-    /* Switch to IRQ stack and save current sp on it. */
-#ifdef CONFIG_SMP
-    get_cpu_id x0
-    ldr    x1, =(g_cpu_int_stacktop)
-    lsl    x0, x0, #3
-    ldr    x1, [x1, x0]
+    /* checking the EC value to see which exception need to be handle */
+
+#if CONFIG_ARCH_ARM64_EXCEPTION_LEVEL == 3
+    mrs    x0, esr_el3
 #else
-    ldr    x1, =(g_interrupt_stack + CONFIG_ARCH_INTERRUPTSTACK)
+    mrs    x0, esr_el1
 #endif
+    lsr    x1, x0, #26
 
+#ifdef CONFIG_ARCH_FPU
+    /* fpu trap */
+
+    cmp    x1, #0x07 /*Access to SIMD or floating-point */
+    bne    1f
     mov    x0, sp
-    mov    sp, x1
 
-#if CONFIG_ARCH_ARM64_EXCEPTION_LEVEL == 3
-    mrs    x4, esr_el3
-#else
-    mrs    x4, esr_el1
+    /* when the fpu trap is handled */
+
+    b      arm64_exit_exception
+1:
 #endif
+    /* 0x15 = SVC system call */
+
+    cmp    x1, #0x15
+
+    /* if this is a svc call ?*/
+
+    bne    exc_handle
+
+#ifdef CONFIG_LIB_SYSCALL
+    /* Handle user system calls separately */
+
+    cmp    x0, #CONFIG_SYS_RESERVED
+    blt    reserved_syscall
 
-    lsr    x5, x4, #26
-    cmp    x5, #0x15
-    bne    arm64_fatal_handler
+    /* Call dispatch_syscall() on the kernel stack with interrupts enabled */
 
-    bl     arm64_syscall        /* Call the handler */
+    mrs    x10, spsr_el1
+    and    x10, x10, #IRQ_SPSR_MASK
+    cmp    x10, xzr
+    bne    1f
+    msr    daifclr, #IRQ_DAIF_MASK /* Re-enable interrupts */
+
+1:
+    bl     dispatch_syscall
+    msr    daifset, #IRQ_DAIF_MASK /* Disable interrupts */
+
+    /* Save the return value into the user context */
+
+    str    x0, [sp, #8 * REG_X0]
+
+    /* Return from exception */
 
     b      arm64_exit_exception
 
+reserved_syscall:
+#endif
+
+    /* x0 = syscall_cmd
+     * if ( x0 <= SYS_switch_context ) {
+     *     call context_switch
+     *     it's a context switch syscall, so context need to be done
+     * }
+     * #define SYS_save_context          (0)
+     * #define SYS_restore_context       (1)
+     * #define SYS_switch_context        (2)
+     */
+
+    ldr    x0, [sp, #8 * REG_X0]
+    cmp    x0, #SYS_save_context
+    beq  save_context
+
+    cmp    x0, #SYS_switch_context
+    beq  context_switch
+
+    cmp    x0, #SYS_restore_context
+    beq  context_switch
+
+    /* Normal syscall, thread context will not switch
+     *
+     * call the SVC handler with interrupts disabled.
+     * void arm64_syscall(uint64_t *regs)
+     * in:
+     *      regs = pointer to struct reg_context allocating
+     *         from stack, esf_reg has put on it
+     *      regs[REG_X0]: syscall cmd
+     *      regs[REG_X1] ~ regs[REG_X6]: syscall parameter
+     * out:
+     *      x0: return by arm64_syscall
+     */
+
+    mov    x0, sp /* x0 = reg frame */
+
+    /* Call arm64_syscall() on the user stack */
+
+    bl    arm64_syscall        /* Call the handler */
+
+    /* Return from exception */
+
+    b    arm64_exit_exception
+
+context_switch:
+    /* Call arm64_syscall_switch() for context switch
+     *
+     * uint64_t * arm64_syscall_switch(uint64_t * regs)
+     * out:
+     *      x0: return by arm64_syscall_switch, restore task context
+     *      regs[REG_X1]: save task context, if x1 = 0, only restore x0
+     */
+
+    mov    x0, sp
+    str    x0, [sp, #-16]!
+    bl    arm64_syscall_switch
+
+    /* get save task reg context pointer */
+
+    ldr    x1, [sp], #16
+
+#ifdef CONFIG_SMP
+    /* Notes:
+     * Complete any pending TLB or cache maintenance on this CPU in case
+     * the thread migrates to a different CPU.
+     * This full barrier is also required by the membarrier system
+     * call.
+     */
+
+    dsb   ish
+#endif
+
+    b    arm64_exit_exception
+
+save_context:
+    arm64_exception_context_save x0 x1 sp
+
+    mov    x0, sp
+    bl    arm64_syscall_save_context
+
+    /* Save the return value into the ESF */
+
+    str    x0, [sp, #8 * REG_X0]
+
+    /* Return from exception */
+
+    b    arm64_exit_exception
+
+exc_handle:
+    mov    x0, sp
+
+    /* void arm64_fatal_handler(struct regs_context * reg);
+     * x0 = Exception stack frame
+     */
+
+    bl    arm64_fatal_handler
+
+    /* Return here only in case of recoverable error */
+
+    b    arm64_exit_exception
+
 /****************************************************************************
  * Name: arm64_irq_handler
  *
@@ -178,16 +309,20 @@ GTEXT(arm64_irq_handler)
 SECTION_FUNC(text, arm64_irq_handler)
     /* Switch to IRQ stack and save current sp on it. */
 #ifdef CONFIG_SMP
-    get_cpu_id x0
-    ldr    x1, =(g_cpu_int_stacktop)
-    lsl    x0, x0, #3
-    ldr    x1, [x1, x0]
+    get_cpu_id x1
+    ldr    x0, =(g_cpu_int_stacktop)
+    lsl    x1, x1, #3
+    ldr    x0, [x0, x1]
 #else
-    ldr    x1, =(g_interrupt_stack + CONFIG_ARCH_INTERRUPTSTACK)
+    ldr    x0, =(g_interrupt_stack + CONFIG_ARCH_INTERRUPTSTACK)
 #endif
+    /* Save the task's stack and switch irq stack */
 
-    mov    x0, sp
-    mov    sp, x1
+    mov    x1, sp
+    mov    sp, x0
+    str    x1, [sp, #-16]!
+
+    mov    x0, x1 /* x0 = reg frame */
 
     /* Call arm64_decodeirq() on the interrupt stack
      * with interrupts disabled
@@ -195,15 +330,28 @@ SECTION_FUNC(text, arm64_irq_handler)
 
     bl     arm64_decodeirq
 
-    b      arm64_exit_exception
+    /* Upon return from arm64_decodeirq, x0 holds the pointer to the
+     * call reg context area, which can be use to restore context.
+     * This may or may not be the same value that was passed to arm64_decodeirq:
+     * It will differ if a context switch is required.
+     */
 
-/****************************************************************************
- * Name: arm64_serror_handler
- *
- * Description:
- *   SError exception handler
- *
- ****************************************************************************/
+    ldr    x1, [sp], #16
+
+#ifdef CONFIG_SMP
+    /* Notes:
+     * Complete any pending TLB or cache maintenance on this CPU in case
+     * the thread migrates to a different CPU.
+     * This full barrier is also required by the membarrier system
+     * call.
+     */
+    dsb   ish
+
+#endif
+
+    b     arm64_exit_exception
+
+/* TODO: if the arm64_fatal_handler return success, maybe need context switch */
 
 GTEXT(arm64_serror_handler)
 SECTION_FUNC(text, arm64_serror_handler)
@@ -211,15 +359,7 @@ SECTION_FUNC(text, arm64_serror_handler)
     bl    arm64_fatal_handler
     /* Return here only in case of recoverable error */
 
-    b     arm64_exit_exception
-
-/****************************************************************************
- * Name: arm64_mode32_handler
- *
- * Description:
- *   Mode32 exception handler
- *
- ****************************************************************************/
+    b    arm64_exit_exception
 
 GTEXT(arm64_mode32_handler)
 SECTION_FUNC(text, arm64_mode32_handler)
@@ -229,14 +369,6 @@ SECTION_FUNC(text, arm64_mode32_handler)
 
     b    arm64_exit_exception
 
-/****************************************************************************
- * Name: arm64_frq_handler
- *
- * Description:
- *   Interrupt exception handler
- *
- ****************************************************************************/
-
 GTEXT(arm64_fiq_handler)
 SECTION_FUNC(text, arm64_fiq_handler)
 #ifndef CONFIG_ARM64_DECODEFIQ
@@ -250,22 +382,45 @@ SECTION_FUNC(text, arm64_fiq_handler)
 #else
    /* Switch to FIQ stack and save current sp on it. */
 #ifdef CONFIG_SMP
-    get_cpu_id x0
-    ldr    x1, =(g_cpu_int_fiq_stacktop)
-    lsl    x0, x0, #3
-    ldr    x1, [x1, x0]
+    get_cpu_id x1
+    ldr    x0, =(g_cpu_int_fiq_stacktop)
+    lsl    x1, x1, #3
+    ldr    x0, [x0, x1]
 #else
-    ldr    x1, =(g_interrupt_fiq_stack + CONFIG_ARCH_INTERRUPTSTACK)
+    ldr    x0, =(g_interrupt_fiq_stack + CONFIG_ARCH_INTERRUPTSTACK)
 #endif
+    /* Save the task's stack and switch fiq stack */
 
-    mov    x0, sp
-    mov    sp, x1
+    mov    x1, sp
+    mov    sp, x0
+    str    x1, [sp, #-16]!
 
-    /* Call arm64_decodeirq() on the interrupt stack
+    mov    x0, x1 /* x0 = reg frame */
+
+    /* Call arm64_decodefiq() on the interrupt stack
      * with interrupts disabled
      */
 
-    bl     arm64_decodeirq
+    bl     arm64_decodefiq
 
-    b      arm64_exit_exception
+    /* Upon return from arm64_decodefiq, x0 holds the pointer to the
+     * call reg context area, which can be use to restore context.
+     * This may or may not be the same value that was passed to arm64_decodefiq:
+     * It will differ if a context switch is required.
+     */
+
+    ldr    x1, [sp], #16
+
+#ifdef CONFIG_SMP
+    /* Notes:
+     * Complete any pending TLB or cache maintenance on this CPU in case
+     * the thread migrates to a different CPU.
+     * This full barrier is also required by the membarrier system
+     * call.
+     */
+    dsb   ish
+
+#endif
+
+    b     arm64_exit_exception
 #endif