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

xiaoxiang pushed a commit to branch releases/12.7
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 669cd3aa2c858994e026179ac9c1719b1801ccf5
Author: ligd <[email protected]>
AuthorDate: Tue Oct 1 12:00:32 2024 +0300

    arm64: simply the vectors
    
    Signed-off-by: ligd <[email protected]>
---
 arch/arm64/src/common/arm64_internal.h |   3 +-
 arch/arm64/src/common/arm64_syscall.c  | 156 ++++++-----------
 arch/arm64/src/common/arm64_vectors.S  | 312 +++++++--------------------------
 3 files changed, 121 insertions(+), 350 deletions(-)

diff --git a/arch/arm64/src/common/arm64_internal.h 
b/arch/arm64/src/common/arm64_internal.h
index 6f4ab45b2c..6643117005 100644
--- a/arch/arm64/src/common/arm64_internal.h
+++ b/arch/arm64/src/common/arm64_internal.h
@@ -305,8 +305,7 @@ void arm64_pginitialize(void);
 #  define arm64_pginitialize()
 #endif /* CONFIG_LEGACY_PAGING */
 
-uint64_t * arm64_syscall_switch(uint64_t *regs);
-int arm64_syscall(uint64_t *regs);
+uint64_t *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 5a6c91b0c4..a192cabafb 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 struct regs_context * f_regs)
+                                const uint64_t *regs)
 {
-  svcinfo("SYSCALL %s: regs: %p cmd: %" PRId64 "\n", tag, f_regs, cmd);
+  svcinfo("SYSCALL %s: regs: %p cmd: %" PRId64 "\n", tag, regs, cmd);
 
   svcinfo("x0:  0x%-16lx  x1:  0x%lx\n",
-          f_regs->regs[REG_X0], f_regs->regs[REG_X1]);
+          regs[REG_X0], regs[REG_X1]);
   svcinfo("x2:  0x%-16lx  x3:  0x%lx\n",
-          f_regs->regs[REG_X2], f_regs->regs[REG_X3]);
+          regs[REG_X2], regs[REG_X3]);
   svcinfo("x4:  0x%-16lx  x5:  0x%lx\n",
-          f_regs->regs[REG_X4], f_regs->regs[REG_X5]);
+          regs[REG_X4], regs[REG_X5]);
   svcinfo("x6:  0x%-16lx  x7:  0x%lx\n",
-          f_regs->regs[REG_X6], f_regs->regs[REG_X7]);
+          regs[REG_X6], 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_switch
+ * Name: arm64_syscall
  *
  * Description:
  *   task switch syscall
  *
  ****************************************************************************/
 
-uint64_t *arm64_syscall_switch(uint64_t * regs)
+uint64_t *arm64_syscall(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 = f_regs->regs[REG_X0];
+  cmd = regs[REG_X0];
 
-  arm64_dump_syscall(__func__, cmd, f_regs);
+  arm64_dump_syscall(__func__, cmd, regs);
 
   switch (cmd)
     {
@@ -192,8 +192,8 @@ uint64_t *arm64_syscall_switch(uint64_t * regs)
            * set will determine the restored context.
            */
 
-          ret_regs = (uint64_t *)f_regs->regs[REG_X1];
-          f_regs->regs[REG_X1] = 0; /* set the saveregs = 0 */
+          ret_regs = (uint64_t *)regs[REG_X1];
+          regs[REG_X1] = 0; /* set the saveregs = 0 */
 
           DEBUGASSERT(ret_regs);
         }
@@ -217,91 +217,13 @@ uint64_t *arm64_syscall_switch(uint64_t * regs)
 
       case SYS_switch_context:
         {
-          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 *) f_regs->regs[REG_X2];
-        }
-        break;
+          DEBUGASSERT(regs[REG_X1] != 0 && regs[REG_X2] != 0);
+          *(uint64_t **)regs[REG_X1] = regs;
 
-      default:
-        {
-          svcerr("ERROR: Bad SYS call: 0x%" PRIx64 "\n", cmd);
-          ret_regs = 0;
-          return 0;
+          ret_regs = (uint64_t *)regs[REG_X2];
         }
         break;
-    }
-
-  if ((uint64_t *)f_regs != ret_regs)
-    {
-      cpu = this_cpu();
-      tcb = current_task(cpu);
-
-#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
-
-      /* Update scheduler parameters */
-
-      nxsched_suspend_scheduler(g_running_tasks[cpu]);
-      nxsched_resume_scheduler(tcb);
-
-      /* Record the new "running" task.  g_running_tasks[] is only used by
-       * assertion logic for reporting crashes.
-       */
-
-      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
        *
@@ -404,10 +326,44 @@ int arm64_syscall(uint64_t *regs)
 #endif
 
       default:
+        {
+          svcerr("ERROR: Bad SYS call: 0x%" PRIx64 "\n", cmd);
+          ret_regs = 0;
+          return 0;
+        }
+        break;
+    }
+
+  if ((uint64_t *)regs != ret_regs)
+    {
+      cpu = this_cpu();
+      tcb = current_task(cpu);
+
+#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
+
+      /* Update scheduler parameters */
 
-          DEBUGPANIC();
-          break;
+      nxsched_suspend_scheduler(g_running_tasks[cpu]);
+      nxsched_resume_scheduler(tcb);
+
+      /* Record the new "running" task.  g_running_tasks[] is only used by
+       * assertion logic for reporting crashes.
+       */
+
+      g_running_tasks[cpu] = tcb;
+
+      /* Restore the cpu lock */
+
+      restore_critical_section(tcb, cpu);
     }
 
-  return 0;
+  return ret_regs;
 }
diff --git a/arch/arm64/src/common/arm64_vectors.S 
b/arch/arm64/src/common/arm64_vectors.S
index e1b231976e..e23bbcff91 100644
--- a/arch/arm64/src/common/arm64_vectors.S
+++ b/arch/arm64/src/common/arm64_vectors.S
@@ -99,49 +99,6 @@ 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
-
-    /* Save the current SP_ELx */
-    add    x4, sp, #8 * XCPTCONTEXT_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_REGS
-
-    /* Return to arm64_sync_exc() or arm64_irq_handler() */
-
-    ret
-
 /****************************************************************************
  * Function: arm64_jump_to_user
  *
@@ -197,7 +154,7 @@ SECTION_FUNC(text, arm64_sync_exc)
 
     /* if this is a svc call ?*/
 
-    bne    exc_handle
+    bne    arm64_fatal_handler
 
 #ifdef CONFIG_LIB_SYSCALL
     /* Handle user system calls separately */
@@ -228,111 +185,23 @@ SECTION_FUNC(text, arm64_sync_exc)
 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
-    bl    arm64_syscall_switch
-
-    /* get save task reg context pointer */
-
-    ldr    x1, [sp, #8 * REG_X1]
-    cmp    x1, #0x0
-
-    beq do_switch
-    ldr x1, [x1]
-
-do_switch:
+    /* Switch to IRQ stack and save current sp on it. */
 #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
+    get_cpu_id x0
+    ldr    x1, =(g_cpu_int_stacktop)
+    lsl    x0, x0, #3
+    ldr    x1, [x1, x0]
+#else
+    ldr    x1, =(g_interrupt_stack + CONFIG_ARCH_INTERRUPTSTACK)
 #endif
 
-    bl    arm64_context_switch
-
-    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
+    mov    sp, x1
 
-    /* void arm64_fatal_handler(struct regs_context * reg);
-     * x0 = Exception stack frame
-     */
-
-    bl    arm64_fatal_handler
-
-    /* Return here only in case of recoverable error */
+    bl     arm64_syscall        /* Call the handler */
 
-    b    arm64_exit_exception
+    mov    sp, x0
+    b      arm64_exit_exception
 
 /****************************************************************************
  * Name: arm64_irq_handler
@@ -346,20 +215,16 @@ 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 x1
-    ldr    x0, =(g_cpu_int_stacktop)
-    lsl    x1, x1, #3
-    ldr    x0, [x0, x1]
+    get_cpu_id x0
+    ldr    x1, =(g_cpu_int_stacktop)
+    lsl    x0, x0, #3
+    ldr    x1, [x1, x0]
 #else
-    ldr    x0, =(g_interrupt_stack + CONFIG_ARCH_INTERRUPTSTACK)
+    ldr    x1, =(g_interrupt_stack + CONFIG_ARCH_INTERRUPTSTACK)
 #endif
-    /* Save the task's stack and switch irq stack */
-
-    mov    x1, sp
-    mov    sp, x0
-    str    x1, [sp, #-16]!
 
-    mov    x0, x1 /* x0 = reg frame */
+    mov    x0, sp
+    mov    sp, x1
 
     /* Call arm64_decodeirq() on the interrupt stack
      * with interrupts disabled
@@ -367,128 +232,79 @@ SECTION_FUNC(text, arm64_irq_handler)
 
     bl     arm64_decodeirq
 
-    /* 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.
-     */
-
-    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
-     * the thread migrates to a different CPU.
-     * This full barrier is also required by the membarrier system
-     * call.
-     */
-    dsb   ish
-
-#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
-
-irq_exit:
-    b     arm64_exit_exception
+    mov    sp, x0
+    b      arm64_exit_exception
 
-/* TODO: if the arm64_fatal_handler return success, maybe need context switch 
*/
+/****************************************************************************
+ * Name: arm64_serror_handler
+ *
+ * Description:
+ *   SError exception handler
+ *
+ ****************************************************************************/
 
 GTEXT(arm64_serror_handler)
 SECTION_FUNC(text, arm64_serror_handler)
-    mov   x0, sp
-    bl    arm64_fatal_handler
+    mov    x0, sp
+    bl     arm64_fatal_handler
     /* Return here only in case of recoverable error */
 
-    b    arm64_exit_exception
+    b      arm64_exit_exception
+
+/****************************************************************************
+ * Name: arm64_mode32_handler
+ *
+ * Description:
+ *   Mode32 exception handler
+ *
+ ****************************************************************************/
 
 GTEXT(arm64_mode32_handler)
 SECTION_FUNC(text, arm64_mode32_handler)
-    mov   x0, sp
-    bl    arm64_fatal_handler
+    mov    x0, sp
+    bl     arm64_fatal_handler
     /* Return here only in case of recoverable error */
 
-    b    arm64_exit_exception
+    b      arm64_exit_exception
+
+/****************************************************************************
+ * Name: arm64_fiq_handler
+ *
+ * Description:
+ *   Interrupt exception handler
+ *
+ ****************************************************************************/
 
 GTEXT(arm64_fiq_handler)
 SECTION_FUNC(text, arm64_fiq_handler)
 #ifndef CONFIG_ARM64_DECODEFIQ
 
-    mov   x0, sp
-    bl    arm64_fatal_handler
+    mov    x0, sp
+    bl     arm64_fatal_handler
 
     /* Return here only in case of recoverable error */
 
-    b    arm64_exit_exception
+    b      arm64_exit_exception
 #else
    /* Switch to FIQ stack and save current sp on it. */
 #ifdef CONFIG_SMP
-    get_cpu_id x1
-    ldr    x0, =(g_cpu_int_fiq_stacktop)
-    lsl    x1, x1, #3
-    ldr    x0, [x0, x1]
+    get_cpu_id x0
+    ldr    x1, =(g_cpu_int_fiq_stacktop)
+    lsl    x0, x0, #3
+    ldr    x1, [x1, x0]
 #else
-    ldr    x0, =(g_interrupt_fiq_stack + CONFIG_ARCH_INTERRUPTSTACK)
+    ldr    x1, =(g_interrupt_fiq_stack + CONFIG_ARCH_INTERRUPTSTACK)
 #endif
-    /* Save the task's stack and switch fiq stack */
-
-    mov    x1, sp
-    mov    sp, x0
-    str    x1, [sp, #-16]!
-
-    mov    x0, x1 /* x0 = reg frame */
-
-    /* Call arm64_decodefiq() on the interrupt stack
-     * with interrupts disabled
-     */
-
-    bl     arm64_decodefiq
-
-    /* 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
-
-    /* retrieve the task's stack. */
 
+    mov    x0, sp
     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
-     * the thread migrates to a different CPU.
-     * This full barrier is also required by the membarrier system
-     * call.
+    /* Call arm64_decodeirq() on the interrupt stack
+     * with interrupts disabled
      */
-    dsb   ish
 
-#endif
+    bl     arm64_decodeirq
 
-    /*  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
-fiq_exit:
-    b     arm64_exit_exception
+    mov    sp, x0
+    b      arm64_exit_exception
 #endif

Reply via email to