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 8cd52bee2ed286c56541812ad7a455701389b086
Author: hujun5 <[email protected]>
AuthorDate: Fri Jul 5 20:53:49 2024 +0800

    arm64: g_current_regs is only used to determine if we are in irq, with 
other functionalities removed.
    
    Signed-off-by: hujun5 <[email protected]>
---
 arch/arm64/src/common/arm64_cpupause.c          |  12 +-
 arch/arm64/src/common/arm64_doirq.c             |  10 +-
 arch/arm64/src/common/arm64_internal.h          |   7 -
 arch/arm64/src/common/arm64_schedulesigaction.c | 207 +++---------------------
 arch/arm64/src/common/arm64_switchcontext.c     |  12 --
 5 files changed, 31 insertions(+), 217 deletions(-)

diff --git a/arch/arm64/src/common/arm64_cpupause.c 
b/arch/arm64/src/common/arm64_cpupause.c
index 05bdf8a324..870917ca15 100644
--- a/arch/arm64/src/common/arm64_cpupause.c
+++ b/arch/arm64/src/common/arm64_cpupause.c
@@ -116,11 +116,7 @@ int up_cpu_paused_save(void)
   sched_note_cpu_paused(tcb);
 #endif
 
-  /* Save the current context at current_regs into the TCB at the head
-   * of the assigned task list for this CPU.
-   */
-
-  arm64_savestate(tcb->xcp.regs);
+  UNUSED(tcb);
 
   return OK;
 }
@@ -210,11 +206,7 @@ int up_cpu_paused_restore(void)
 
   nxsched_resume_scheduler(tcb);
 
-  /* Then switch contexts.  Any necessary address environment changes
-   * will be made when the interrupt returns.
-   */
-
-  arm64_restorestate(tcb->xcp.regs);
+  UNUSED(tcb);
 
   return OK;
 }
diff --git a/arch/arm64/src/common/arm64_doirq.c 
b/arch/arm64/src/common/arm64_doirq.c
index 5a45a40d26..af0a5abe44 100644
--- a/arch/arm64/src/common/arm64_doirq.c
+++ b/arch/arm64/src/common/arm64_doirq.c
@@ -57,6 +57,8 @@
 
 uint64_t *arm64_doirq(int irq, uint64_t * regs)
 {
+  struct tcb_s *tcb = this_task();
+
   /* Nested interrupts are not supported */
 
   DEBUGASSERT(up_current_regs() == NULL);
@@ -66,10 +68,12 @@ uint64_t *arm64_doirq(int irq, uint64_t * regs)
    */
 
   up_set_current_regs(regs);
+  tcb->xcp.regs = regs;
 
   /* Deliver the IRQ */
 
   irq_dispatch(irq, regs);
+  tcb = this_task();
 
   /* Check for a context switch.  If a context switch occurred, then
    * current_regs will have a different value than it did on entry.  If an
@@ -78,7 +82,7 @@ uint64_t *arm64_doirq(int irq, uint64_t * regs)
    * returning from the interrupt.
    */
 
-  if (regs != up_current_regs())
+  if (regs != tcb->xcp.regs)
     {
       /* need to do a context switch */
 
@@ -97,8 +101,8 @@ uint64_t *arm64_doirq(int irq, uint64_t * regs)
        * crashes.
        */
 
-      g_running_tasks[this_cpu()] = this_task();
-      regs = up_current_regs();
+      g_running_tasks[this_cpu()] = tcb;
+      regs = tcb->xcp.regs;
     }
 
   /* Set current_regs to NULL to indicate that we are no longer in an
diff --git a/arch/arm64/src/common/arm64_internal.h 
b/arch/arm64/src/common/arm64_internal.h
index 19c8b9eb69..6f4ab45b2c 100644
--- a/arch/arm64/src/common/arm64_internal.h
+++ b/arch/arm64/src/common/arm64_internal.h
@@ -84,13 +84,6 @@
 #  define CONFIG_ARCH_INTERRUPTSTACK 0
 #endif
 
-/* If the floating point unit is present and enabled, then save the
- * floating point registers as well as normal ARM registers.
- */
-
-#define arm64_savestate(regs) (regs = up_current_regs())
-#define arm64_restorestate(regs) up_set_current_regs(regs)
-
 /* This is the value used to mark the stack for subsequent stack monitoring
  * logic.
  */
diff --git a/arch/arm64/src/common/arm64_schedulesigaction.c 
b/arch/arm64/src/common/arm64_schedulesigaction.c
index 888c810626..6301f0bb6f 100644
--- a/arch/arm64/src/common/arm64_schedulesigaction.c
+++ b/arch/arm64/src/common/arm64_schedulesigaction.c
@@ -126,9 +126,10 @@ void arm64_init_signal_process(struct tcb_s *tcb, struct 
regs_context *regs)
  *
  ****************************************************************************/
 
-#ifndef CONFIG_SMP
 void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
 {
+  sinfo("tcb=%p sigdeliver=%p\n", tcb, sigdeliver);
+
   /* Refuse to handle nested signal actions */
 
   if (!tcb->xcp.sigdeliver)
@@ -136,204 +137,32 @@ void up_schedule_sigaction(struct tcb_s *tcb, 
sig_deliver_t sigdeliver)
       tcb->xcp.sigdeliver = sigdeliver;
 
       /* First, handle some special cases when the signal is being delivered
-       * to task that is currently executing on this CPU.
+       * to task that is currently executing on any CPU.
        */
 
-      if (tcb == this_task())
+      if (tcb == this_task() && !up_interrupt_context())
         {
-          /* CASE 1:  We are not in an interrupt handler and a task is
-           * signaling itself for some reason.
+          /* In this case just deliver the signal now.
+           * REVISIT:  Signal handler will run in a critical section!
            */
 
-          if (!up_current_regs())
-            {
-              /* In this case just deliver the signal now.
-               * REVISIT:  Signal handler will run in a critical section!
-               */
-
-              sigdeliver(tcb);
-              tcb->xcp.sigdeliver = NULL;
-            }
-
-          /* CASE 2:  We are in an interrupt handler AND the interrupted
-           * task is the same as the one that must receive the signal, then
-           * we will have to modify the return state as well as the state
-           * in the TCB.
-           *
-           * Hmmm... there looks like a latent bug here: The following logic
-           * would fail in the strange case where we are in an interrupt
-           * handler, the thread is signaling itself, but a context switch
-           * to another task has occurred so that current_regs does not
-           * refer to the thread of this_task()!
-           */
-
-          else
-            {
-              /* Save the return lr and cpsr and one scratch register
-               * These will be restored by the signal trampoline after
-               * the signals have been delivered.
-               */
-
-              /* 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());
-
-              /* trigger switch to signal process */
-
-              up_set_current_regs(tcb->xcp.regs);
-            }
+          sigdeliver(tcb);
+          tcb->xcp.sigdeliver = NULL;
         }
-
-      /* Otherwise, we are (1) signaling a task is not running from an
-       * interrupt handler or (2) we are not in an interrupt handler and the
-       * running task is signaling some other non-running task.
-       */
-
       else
         {
-          /* Save the return lr and cpsr and one scratch register.  These
-           * will be restored by the signal trampoline after the signals
-           * 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;
-          arm64_init_signal_process(tcb, NULL);
-        }
-    }
-}
-#endif /* !CONFIG_SMP */
-
 #ifdef CONFIG_SMP
-void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
-{
-  int cpu;
-  int me;
-
-  sinfo("tcb=%p sigdeliver=%p\n", tcb, sigdeliver);
-
-  /* Refuse to handle nested signal actions */
-
-  if (!tcb->xcp.sigdeliver)
-    {
-      tcb->xcp.sigdeliver = sigdeliver;
-
-      /* First, handle some special cases when the signal is being delivered
-       * to task that is currently executing on any CPU.
-       */
-
-      sinfo("rtcb=%p current_regs=%p\n", this_task(), up_current_regs());
-
-      if (tcb->task_state == TSTATE_TASK_RUNNING)
-        {
-          me  = this_cpu();
-          cpu = tcb->cpu;
-
-          /* CASE 1:  We are not in an interrupt handler and a task is
-           * signaling itself for some reason.
-           */
+          int cpu = tcb->cpu;
+          int me  = this_cpu();
 
-          if (cpu == me && !up_current_regs())
+          if (cpu != me)
             {
-              /* In this case just deliver the signal now.
-               * REVISIT:  Signal handler will run in a critical section!
-               */
+              /* Pause the CPU */
 
-              sigdeliver(tcb);
-              tcb->xcp.sigdeliver = NULL;
+              up_cpu_pause(cpu);
             }
-
-          /* CASE 2:  The task that needs to receive the signal is running.
-           * This could happen if the task is running on another CPU OR if
-           * we are in an interrupt handler and the task is running on this
-           * CPU.  In the former case, we will have to PAUSE the other CPU
-           * first.  But in either case, we will have to modify the return
-           * state as well as the state in the TCB.
-           */
-
-          else
-            {
-              /* If we signaling a task running on the other CPU, we have
-               * to PAUSE the other CPU.
-               */
-
-              if (cpu != me)
-                {
-                  /* Pause the CPU */
-
-                  up_cpu_pause(cpu);
-
-                  /* Now tcb on the other CPU can be accessed safely */
-
-                  /* Copy tcb->xcp.regs to tcp.xcp.saved. These will be
-                   * restored by the signal trampoline after the signal has
-                   * 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;
-                  arm64_init_signal_process(tcb, NULL);
-                }
-              else
-                {
-                  /* tcb is running on the same CPU */
-
-                  /* Save the return PC, CPSR and either the BASEPRI or
-                   * PRIMASK registers (and perhaps also the LR).  These will
-                   * be restored by the signal trampoline after the signal
-                   * has been delivered.
-                   */
-
-                  /* 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());
-
-                  /* trigger switch to signal process */
-
-                  up_set_current_regs(tcb->xcp.regs);
-                }
-
-              /* NOTE: If the task runs on another CPU(cpu), adjusting
-               * global IRQ controls will be done in the pause handler
-               * on the CPU(cpu) by taking a critical section.
-               * If the task is scheduled on this CPU(me), do nothing
-               * because this CPU already took a critical section
-               */
-
-              /* RESUME the other CPU if it was PAUSED */
-
-              if (cpu != me)
-                {
-                  up_cpu_resume(cpu);
-                }
-            }
-        }
-
-      /* Otherwise, we are (1) signaling a task is not running from an
-       * interrupt handler or (2) we are not in an interrupt handler and the
-       * running task is signaling some other non-running task.
-       */
 
-      else
-        {
           /* Save the return lr and cpsr and one scratch register.  These
            * will be restored by the signal trampoline after the signals
            * have been delivered.
@@ -347,7 +176,15 @@ void up_schedule_sigaction(struct tcb_s *tcb, 
sig_deliver_t sigdeliver)
           /* create signal process context */
 
           arm64_init_signal_process(tcb, NULL);
+
+#ifdef CONFIG_SMP
+          /* RESUME the other CPU if it was PAUSED */
+
+          if (cpu != me)
+            {
+              up_cpu_resume(cpu);
+            }
+#endif
         }
     }
 }
-#endif /* CONFIG_SMP */
diff --git a/arch/arm64/src/common/arm64_switchcontext.c 
b/arch/arm64/src/common/arm64_switchcontext.c
index 78b9784e70..b5ab2234d1 100644
--- a/arch/arm64/src/common/arm64_switchcontext.c
+++ b/arch/arm64/src/common/arm64_switchcontext.c
@@ -63,21 +63,9 @@ void up_switch_context(struct tcb_s *tcb, struct tcb_s *rtcb)
 
   if (up_interrupt_context())
     {
-      /* Yes, then we have to do things differently.
-       * Just copy the current_regs into the OLD rtcb.
-       */
-
-      arm64_savestate(rtcb->xcp.regs);
-
       /* Update scheduler parameters */
 
       nxsched_resume_scheduler(tcb);
-
-      /* Then switch contexts.  Any necessary address environment
-       * changes will be made when the interrupt returns.
-       */
-
-      arm64_restorestate(tcb->xcp.regs);
     }
 
   /* No, then we will need to perform the user context switch */

Reply via email to