You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ma...@apache.org on 2022/03/23 10:08:47 UTC

[incubator-nuttx] branch master updated (9288ed8 -> 7b73606)

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

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


    from 9288ed8  RISC-V: Add/fix implementation for arch_elf.c
     new 9ae0dcd  arch/arm: Remove the code copy register from xcpt to stack
     new a770ff2  arm/vfork: update the SP to stack top
     new 7b73606  arm/schedulesigaction: update the SP to signal context top

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


Summary of changes:
 arch/arm/src/arm/arm_schedulesigaction.c     |  18 ++---
 arch/arm/src/armv6-m/arm_exception.S         |  65 ++++-------------
 arch/arm/src/armv6-m/arm_schedulesigaction.c |  45 ++++++------
 arch/arm/src/armv7-a/arm_schedulesigaction.c |  45 ++++++------
 arch/arm/src/armv7-m/arm_schedulesigaction.c |  45 ++++++------
 arch/arm/src/armv7-m/gnu/arm_exception.S     |  92 +++++-------------------
 arch/arm/src/armv7-m/gnu/arm_lazyexception.S |  77 ++++++--------------
 arch/arm/src/armv7-r/arm_schedulesigaction.c |  18 ++---
 arch/arm/src/armv8-m/arm_exception.S         | 104 ++++++---------------------
 arch/arm/src/armv8-m/arm_lazyexception.S     |  87 +++++++---------------
 arch/arm/src/armv8-m/arm_schedulesigaction.c |  45 ++++++------
 arch/arm/src/common/arm_vfork.c              |  14 +++-
 12 files changed, 230 insertions(+), 425 deletions(-)

[incubator-nuttx] 03/03: arm/schedulesigaction: update the SP to signal context top

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

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

commit 7b736063004bf65445afaad26e9b9acee01daaba
Author: chao.an <an...@xiaomi.com>
AuthorDate: Wed Mar 23 13:13:03 2022 +0800

    arm/schedulesigaction: update the SP to signal context top
    
    Signed-off-by: chao.an <an...@xiaomi.com>
---
 arch/arm/src/arm/arm_schedulesigaction.c     | 18 ++++++-----
 arch/arm/src/armv6-m/arm_schedulesigaction.c | 45 +++++++++++++++-------------
 arch/arm/src/armv7-a/arm_schedulesigaction.c | 45 +++++++++++++++-------------
 arch/arm/src/armv7-m/arm_schedulesigaction.c | 45 +++++++++++++++-------------
 arch/arm/src/armv7-r/arm_schedulesigaction.c | 18 ++++++-----
 arch/arm/src/armv8-m/arm_schedulesigaction.c | 45 +++++++++++++++-------------
 6 files changed, 120 insertions(+), 96 deletions(-)

diff --git a/arch/arm/src/arm/arm_schedulesigaction.c b/arch/arm/src/arm/arm_schedulesigaction.c
index 9e37043..2d37ec6 100644
--- a/arch/arm/src/arm/arm_schedulesigaction.c
+++ b/arch/arm/src/arm/arm_schedulesigaction.c
@@ -134,13 +134,14 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
                * delivered.
                */
 
-              CURRENT_REGS           =
-                (FAR void *)STACK_ALIGN_DOWN((uint32_t)CURRENT_REGS -
-                                             (uint32_t)XCPTCONTEXT_SIZE);
+              CURRENT_REGS           = (FAR void *)
+                                       ((uint32_t)CURRENT_REGS -
+                                        (uint32_t)XCPTCONTEXT_SIZE);
               memcpy((FAR uint32_t *)CURRENT_REGS, tcb->xcp.saved_regs,
                      XCPTCONTEXT_SIZE);
 
-              CURRENT_REGS[REG_SP]   = (uint32_t)CURRENT_REGS;
+              CURRENT_REGS[REG_SP]   = (uint32_t)CURRENT_REGS +
+                                       (uint32_t)XCPTCONTEXT_SIZE;
 
               /* Then set up to vector to the trampoline with interrupts
                * disabled
@@ -175,12 +176,13 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
            * delivered.
            */
 
-          tcb->xcp.regs           =
-            (FAR void *)STACK_ALIGN_DOWN((uint32_t)tcb->xcp.regs -
-                                         (uint32_t)XCPTCONTEXT_SIZE);
+          tcb->xcp.regs           = (FAR void *)
+                                    ((uint32_t)tcb->xcp.regs -
+                                     (uint32_t)XCPTCONTEXT_SIZE);
           memcpy(tcb->xcp.regs, tcb->xcp.saved_regs, XCPTCONTEXT_SIZE);
 
-          tcb->xcp.regs[REG_SP]   = (uint32_t)tcb->xcp.regs;
+          tcb->xcp.regs[REG_SP]   = (uint32_t)tcb->xcp.regs +
+                                    (uint32_t)XCPTCONTEXT_SIZE;
 
           /* Then set up to vector to the trampoline with interrupts
            * disabled
diff --git a/arch/arm/src/armv6-m/arm_schedulesigaction.c b/arch/arm/src/armv6-m/arm_schedulesigaction.c
index 23e4290..1f30fed 100644
--- a/arch/arm/src/armv6-m/arm_schedulesigaction.c
+++ b/arch/arm/src/armv6-m/arm_schedulesigaction.c
@@ -136,13 +136,14 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
                * delivered.
                */
 
-              CURRENT_REGS                 =
-                (FAR void *)STACK_ALIGN_DOWN((uint32_t)CURRENT_REGS -
-                                             (uint32_t)XCPTCONTEXT_SIZE);
+              CURRENT_REGS                 = (FAR void *)
+                                             ((uint32_t)CURRENT_REGS -
+                                              (uint32_t)XCPTCONTEXT_SIZE);
               memcpy((FAR uint32_t *)CURRENT_REGS, tcb->xcp.saved_regs,
                      XCPTCONTEXT_SIZE);
 
-              CURRENT_REGS[REG_SP]         = (uint32_t)CURRENT_REGS;
+              CURRENT_REGS[REG_SP]         = (uint32_t)CURRENT_REGS +
+                                             (uint32_t)XCPTCONTEXT_SIZE;
 
               /* Then set up to vector to the trampoline with interrupts
                * disabled.  The kernel-space trampoline must run in
@@ -182,12 +183,13 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
            * delivered.
            */
 
-          tcb->xcp.regs              =
-            (FAR void *)STACK_ALIGN_DOWN((uint32_t)tcb->xcp.regs -
-                                         (uint32_t)XCPTCONTEXT_SIZE);
+          tcb->xcp.regs              = (FAR void *)
+                                       ((uint32_t)tcb->xcp.regs -
+                                        (uint32_t)XCPTCONTEXT_SIZE);
           memcpy(tcb->xcp.regs, tcb->xcp.saved_regs, XCPTCONTEXT_SIZE);
 
-          tcb->xcp.regs[REG_SP]      = (uint32_t)tcb->xcp.regs;
+          tcb->xcp.regs[REG_SP]      = (uint32_t)tcb->xcp.regs +
+                                       (uint32_t)XCPTCONTEXT_SIZE;
 
           /* Then set up to vector to the trampoline with interrupts
            * disabled.  We must already be in privileged thread mode to be
@@ -285,13 +287,14 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
                    * been delivered.
                    */
 
-                  tcb->xcp.regs              =
-                    (FAR void *)STACK_ALIGN_DOWN((uint32_t)tcb->xcp.regs -
-                                                 (uint32_t)XCPTCONTEXT_SIZE);
+                  tcb->xcp.regs              = (FAR void *)
+                                               ((uint32_t)tcb->xcp.regs -
+                                                (uint32_t)XCPTCONTEXT_SIZE);
                   memcpy(tcb->xcp.regs, tcb->xcp.saved_regs,
                          XCPTCONTEXT_SIZE);
 
-                  tcb->xcp.regs[REG_SP]      = (uint32_t)tcb->xcp.regs;
+                  tcb->xcp.regs[REG_SP]      = (uint32_t)tcb->xcp.regs +
+                                               (uint32_t)XCPTCONTEXT_SIZE;
 
                   /* Then set up vector to the trampoline with interrupts
                    * disabled.  We must already be in privileged thread mode
@@ -328,13 +331,14 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
                    * been delivered.
                    */
 
-                  CURRENT_REGS              =
-                    (FAR void *)STACK_ALIGN_DOWN((uint32_t)CURRENT_REGS -
-                                                 (uint32_t)XCPTCONTEXT_SIZE);
+                  CURRENT_REGS              = (FAR void *)
+                                              ((uint32_t)CURRENT_REGS -
+                                               (uint32_t)XCPTCONTEXT_SIZE);
                   memcpy((FAR uint32_t *)CURRENT_REGS, tcb->xcp.saved_regs,
                          XCPTCONTEXT_SIZE);
 
-                  CURRENT_REGS[REG_SP]      = (uint32_t)CURRENT_REGS;
+                  CURRENT_REGS[REG_SP]      = (uint32_t)CURRENT_REGS +
+                                              (uint32_t)XCPTCONTEXT_SIZE;
 
                   /* Then set up vector to the trampoline with interrupts
                    * disabled.  The kernel-space trampoline must run in
@@ -395,12 +399,13 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
            * delivered.
            */
 
-          tcb->xcp.regs              =
-            (FAR void *)STACK_ALIGN_DOWN((uint32_t)tcb->xcp.regs -
-                                         (uint32_t)XCPTCONTEXT_SIZE);
+          tcb->xcp.regs              = (FAR void *)
+                                       ((uint32_t)tcb->xcp.regs -
+                                        (uint32_t)XCPTCONTEXT_SIZE);
           memcpy(tcb->xcp.regs, tcb->xcp.saved_regs, XCPTCONTEXT_SIZE);
 
-          tcb->xcp.regs[REG_SP]      = (uint32_t)tcb->xcp.regs;
+          tcb->xcp.regs[REG_SP]      = (uint32_t)tcb->xcp.regs +
+                                       (uint32_t)XCPTCONTEXT_SIZE;
 
           /* Increment the IRQ lock count so that when the task is restarted,
            * it will hold the IRQ spinlock.
diff --git a/arch/arm/src/armv7-a/arm_schedulesigaction.c b/arch/arm/src/armv7-a/arm_schedulesigaction.c
index aaf03c0..497cec2 100644
--- a/arch/arm/src/armv7-a/arm_schedulesigaction.c
+++ b/arch/arm/src/armv7-a/arm_schedulesigaction.c
@@ -139,13 +139,14 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
                * delivered.
                */
 
-              CURRENT_REGS            =
-                (FAR void *)STACK_ALIGN_DOWN((uint32_t)CURRENT_REGS -
-                                             (uint32_t)XCPTCONTEXT_SIZE);
+              CURRENT_REGS            = (FAR void *)
+                                        ((uint32_t)CURRENT_REGS -
+                                         (uint32_t)XCPTCONTEXT_SIZE);
               memcpy((FAR uint32_t *)CURRENT_REGS, tcb->xcp.saved_regs,
                      XCPTCONTEXT_SIZE);
 
-              CURRENT_REGS[REG_SP]    = (uint32_t)CURRENT_REGS;
+              CURRENT_REGS[REG_SP]    = (uint32_t)CURRENT_REGS +
+                                        (uint32_t)XCPTCONTEXT_SIZE;
 
               /* Then set up to vector to the trampoline with interrupts
                * disabled
@@ -183,12 +184,13 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
            * delivered.
            */
 
-          tcb->xcp.regs            =
-            (FAR void *)STACK_ALIGN_DOWN((uint32_t)tcb->xcp.regs -
-                                         (uint32_t)XCPTCONTEXT_SIZE);
+          tcb->xcp.regs            = (FAR void *)
+                                     ((uint32_t)tcb->xcp.regs -
+                                      (uint32_t)XCPTCONTEXT_SIZE);
           memcpy(tcb->xcp.regs, tcb->xcp.saved_regs, XCPTCONTEXT_SIZE);
 
-          tcb->xcp.regs[REG_SP]    = (uint32_t)tcb->xcp.regs;
+          tcb->xcp.regs[REG_SP]    = (uint32_t)tcb->xcp.regs +
+                                     (uint32_t)XCPTCONTEXT_SIZE;
 
           /* Then set up to vector to the trampoline with interrupts
            * disabled
@@ -284,13 +286,14 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
                    * been delivered.
                    */
 
-                  tcb->xcp.regs            =
-                    (FAR void *)STACK_ALIGN_DOWN((uint32_t)tcb->xcp.regs -
-                                                 (uint32_t)XCPTCONTEXT_SIZE);
+                  tcb->xcp.regs            = (FAR void *)
+                                             ((uint32_t)tcb->xcp.regs -
+                                              (uint32_t)XCPTCONTEXT_SIZE);
                   memcpy(tcb->xcp.regs, tcb->xcp.saved_regs,
                          XCPTCONTEXT_SIZE);
 
-                  tcb->xcp.regs[REG_SP]    = (uint32_t)tcb->xcp.regs;
+                  tcb->xcp.regs[REG_SP]    = (uint32_t)tcb->xcp.regs +
+                                             (uint32_t)XCPTCONTEXT_SIZE;
 
                   /* Then set up to vector to the trampoline with interrupts
                    * disabled
@@ -326,13 +329,14 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
                    * been delivered.
                    */
 
-                  CURRENT_REGS            =
-                    (FAR void *)STACK_ALIGN_DOWN((uint32_t)CURRENT_REGS -
-                                                 (uint32_t)XCPTCONTEXT_SIZE);
+                  CURRENT_REGS            = (FAR void *)
+                                            ((uint32_t)CURRENT_REGS -
+                                             (uint32_t)XCPTCONTEXT_SIZE);
                   memcpy((FAR uint32_t *)CURRENT_REGS, tcb->xcp.saved_regs,
                          XCPTCONTEXT_SIZE);
 
-                  CURRENT_REGS[REG_SP]    = (uint32_t)CURRENT_REGS;
+                  CURRENT_REGS[REG_SP]    = (uint32_t)CURRENT_REGS +
+                                            (uint32_t)XCPTCONTEXT_SIZE;
 
                   /* Then set up vector to the trampoline with interrupts
                    * disabled.  The kernel-space trampoline must run in
@@ -393,12 +397,13 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
            * delivered.
            */
 
-          tcb->xcp.regs            =
-            (FAR void *)STACK_ALIGN_DOWN((uint32_t)tcb->xcp.regs -
-                                         (uint32_t)XCPTCONTEXT_SIZE);
+          tcb->xcp.regs            = (FAR void *)
+                                     ((uint32_t)tcb->xcp.regs -
+                                      (uint32_t)XCPTCONTEXT_SIZE);
           memcpy(tcb->xcp.regs, tcb->xcp.saved_regs, XCPTCONTEXT_SIZE);
 
-          tcb->xcp.regs[REG_SP]    = (uint32_t)tcb->xcp.regs;
+          tcb->xcp.regs[REG_SP]    = (uint32_t)tcb->xcp.regs +
+                                     (uint32_t)XCPTCONTEXT_SIZE;
 
           /* Increment the IRQ lock count so that when the task is restarted,
            * it will hold the IRQ spinlock.
diff --git a/arch/arm/src/armv7-m/arm_schedulesigaction.c b/arch/arm/src/armv7-m/arm_schedulesigaction.c
index 9bcf40e..b8c224f 100644
--- a/arch/arm/src/armv7-m/arm_schedulesigaction.c
+++ b/arch/arm/src/armv7-m/arm_schedulesigaction.c
@@ -137,13 +137,14 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
                * delivered.
                */
 
-              CURRENT_REGS                 =
-                (FAR void *)STACK_ALIGN_DOWN((uint32_t)CURRENT_REGS -
-                                             (uint32_t)XCPTCONTEXT_SIZE);
+              CURRENT_REGS                 = (FAR void *)
+                                             ((uint32_t)CURRENT_REGS -
+                                              (uint32_t)XCPTCONTEXT_SIZE);
               memcpy((FAR uint32_t *)CURRENT_REGS, tcb->xcp.saved_regs,
                      XCPTCONTEXT_SIZE);
 
-              CURRENT_REGS[REG_SP]         = (uint32_t)CURRENT_REGS;
+              CURRENT_REGS[REG_SP]         = (uint32_t)CURRENT_REGS +
+                                             (uint32_t)XCPTCONTEXT_SIZE;
 
               /* Then set up to vector to the trampoline with interrupts
                * disabled.  The kernel-space trampoline must run in
@@ -187,12 +188,13 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
            * delivered.
            */
 
-          tcb->xcp.regs              =
-            (FAR void *)STACK_ALIGN_DOWN((uint32_t)tcb->xcp.regs -
-                                         (uint32_t)XCPTCONTEXT_SIZE);
+          tcb->xcp.regs              = (FAR void *)
+                                       ((uint32_t)tcb->xcp.regs -
+                                        (uint32_t)XCPTCONTEXT_SIZE);
           memcpy(tcb->xcp.regs, tcb->xcp.saved_regs, XCPTCONTEXT_SIZE);
 
-          tcb->xcp.regs[REG_SP]      = (uint32_t)tcb->xcp.regs;
+          tcb->xcp.regs[REG_SP]      = (uint32_t)tcb->xcp.regs +
+                                       (uint32_t)XCPTCONTEXT_SIZE;
 
           /* Then set up to vector to the trampoline with interrupts
            * disabled.  We must already be in privileged thread mode to be
@@ -294,13 +296,14 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
                    * been delivered.
                    */
 
-                  tcb->xcp.regs              =
-                    (FAR void *)STACK_ALIGN_DOWN((uint32_t)tcb->xcp.regs -
-                                                 (uint32_t)XCPTCONTEXT_SIZE);
+                  tcb->xcp.regs              = (FAR void *)
+                                               ((uint32_t)tcb->xcp.regs -
+                                                (uint32_t)XCPTCONTEXT_SIZE);
                   memcpy(tcb->xcp.regs, tcb->xcp.saved_regs,
                          XCPTCONTEXT_SIZE);
 
-                  tcb->xcp.regs[REG_SP]      = (uint32_t)tcb->xcp.regs;
+                  tcb->xcp.regs[REG_SP]      = (uint32_t)tcb->xcp.regs +
+                                               (uint32_t)XCPTCONTEXT_SIZE;
 
                   /* Then set up vector to the trampoline with interrupts
                    * disabled.  We must already be in privileged thread mode
@@ -341,13 +344,14 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
                    * been delivered.
                    */
 
-                  CURRENT_REGS              =
-                    (FAR void *)STACK_ALIGN_DOWN((uint32_t)CURRENT_REGS -
-                                                 (uint32_t)XCPTCONTEXT_SIZE);
+                  CURRENT_REGS              = (FAR void *)
+                                              ((uint32_t)CURRENT_REGS -
+                                               (uint32_t)XCPTCONTEXT_SIZE);
                   memcpy((FAR uint32_t *)CURRENT_REGS, tcb->xcp.saved_regs,
                          XCPTCONTEXT_SIZE);
 
-                  CURRENT_REGS[REG_SP]      = (uint32_t)CURRENT_REGS;
+                  CURRENT_REGS[REG_SP]      = (uint32_t)CURRENT_REGS +
+                                              (uint32_t)XCPTCONTEXT_SIZE;
 
                   /* Then set up vector to the trampoline with interrupts
                    * disabled.  The kernel-space trampoline must run in
@@ -412,12 +416,13 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
            * delivered.
            */
 
-          tcb->xcp.regs              =
-            (FAR void *)STACK_ALIGN_DOWN((uint32_t)tcb->xcp.regs -
-                                         (uint32_t)XCPTCONTEXT_SIZE);
+          tcb->xcp.regs              = (FAR void *)
+                                       ((uint32_t)tcb->xcp.regs -
+                                        (uint32_t)XCPTCONTEXT_SIZE);
           memcpy(tcb->xcp.regs, tcb->xcp.saved_regs, XCPTCONTEXT_SIZE);
 
-          tcb->xcp.regs[REG_SP]      = (uint32_t)tcb->xcp.regs;
+          tcb->xcp.regs[REG_SP]      = (uint32_t)tcb->xcp.regs +
+                                       (uint32_t)XCPTCONTEXT_SIZE;
 
           /* Increment the IRQ lock count so that when the task is restarted,
            * it will hold the IRQ spinlock.
diff --git a/arch/arm/src/armv7-r/arm_schedulesigaction.c b/arch/arm/src/armv7-r/arm_schedulesigaction.c
index 284ca3d..2456963 100644
--- a/arch/arm/src/armv7-r/arm_schedulesigaction.c
+++ b/arch/arm/src/armv7-r/arm_schedulesigaction.c
@@ -134,13 +134,14 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
                * delivered.
                */
 
-              CURRENT_REGS              =
-                (FAR void *)STACK_ALIGN_DOWN((uint32_t)CURRENT_REGS -
-                                             (uint32_t)XCPTCONTEXT_SIZE);
+              CURRENT_REGS              = (FAR void *)
+                                          ((uint32_t)CURRENT_REGS -
+                                           (uint32_t)XCPTCONTEXT_SIZE);
               memcpy((FAR uint32_t *)CURRENT_REGS, tcb->xcp.saved_regs,
                      XCPTCONTEXT_SIZE);
 
-              CURRENT_REGS[REG_SP]      = (uint32_t)CURRENT_REGS;
+              CURRENT_REGS[REG_SP]      = (uint32_t)CURRENT_REGS +
+                                          (uint32_t)XCPTCONTEXT_SIZE;
 
               /* Then set up to vector to the trampoline with interrupts
                * disabled
@@ -179,12 +180,13 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
            * delivered.
            */
 
-          tcb->xcp.regs              =
-            (FAR void *)STACK_ALIGN_DOWN((uint32_t)tcb->xcp.regs -
-                                         (uint32_t)XCPTCONTEXT_SIZE);
+          tcb->xcp.regs              = (FAR void *)
+                                       ((uint32_t)tcb->xcp.regs -
+                                        (uint32_t)XCPTCONTEXT_SIZE);
           memcpy(tcb->xcp.regs, tcb->xcp.saved_regs, XCPTCONTEXT_SIZE);
 
-          tcb->xcp.regs[REG_SP]      = (uint32_t)tcb->xcp.regs;
+          tcb->xcp.regs[REG_SP]      = (uint32_t)tcb->xcp.regs +
+                                       (uint32_t)XCPTCONTEXT_SIZE;
 
           /* Then set up to vector to the trampoline with interrupts
            * disabled
diff --git a/arch/arm/src/armv8-m/arm_schedulesigaction.c b/arch/arm/src/armv8-m/arm_schedulesigaction.c
index 228efad..495aed8 100644
--- a/arch/arm/src/armv8-m/arm_schedulesigaction.c
+++ b/arch/arm/src/armv8-m/arm_schedulesigaction.c
@@ -137,13 +137,14 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
                * delivered.
                */
 
-              CURRENT_REGS                 =
-                (FAR void *)STACK_ALIGN_DOWN((uint32_t)CURRENT_REGS -
-                                             (uint32_t)XCPTCONTEXT_SIZE);
+              CURRENT_REGS                 = (FAR void *)
+                                             ((uint32_t)CURRENT_REGS -
+                                              (uint32_t)XCPTCONTEXT_SIZE);
               memcpy((FAR uint32_t *)CURRENT_REGS, tcb->xcp.saved_regs,
                      XCPTCONTEXT_SIZE);
 
-              CURRENT_REGS[REG_SP]         = (uint32_t)CURRENT_REGS;
+              CURRENT_REGS[REG_SP]         = (uint32_t)CURRENT_REGS +
+                                             (uint32_t)XCPTCONTEXT_SIZE;
 
               /* Then set up to vector to the trampoline with interrupts
                * disabled.  The kernel-space trampoline must run in
@@ -187,12 +188,13 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
            * delivered.
            */
 
-          tcb->xcp.regs              =
-            (FAR void *)STACK_ALIGN_DOWN((uint32_t)tcb->xcp.regs -
-                                         (uint32_t)XCPTCONTEXT_SIZE);
+          tcb->xcp.regs              = (FAR void *)
+                                       ((uint32_t)tcb->xcp.regs -
+                                        (uint32_t)XCPTCONTEXT_SIZE);
           memcpy(tcb->xcp.regs, tcb->xcp.saved_regs, XCPTCONTEXT_SIZE);
 
-          tcb->xcp.regs[REG_SP]      = (uint32_t)tcb->xcp.regs;
+          tcb->xcp.regs[REG_SP]      = (uint32_t)tcb->xcp.regs +
+                                       (uint32_t)XCPTCONTEXT_SIZE;
 
           /* Then set up to vector to the trampoline with interrupts
            * disabled.  We must already be in privileged thread mode to be
@@ -294,13 +296,14 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
                    * been delivered.
                    */
 
-                  tcb->xcp.regs              =
-                    (FAR void *)STACK_ALIGN_DOWN((uint32_t)tcb->xcp.regs -
-                                                 (uint32_t)XCPTCONTEXT_SIZE);
+                  tcb->xcp.regs              = (FAR void *)
+                                               ((uint32_t)tcb->xcp.regs -
+                                                (uint32_t)XCPTCONTEXT_SIZE);
                   memcpy(tcb->xcp.regs, tcb->xcp.saved_regs,
                          XCPTCONTEXT_SIZE);
 
-                  tcb->xcp.regs[REG_SP]      = (uint32_t)tcb->xcp.regs;
+                  tcb->xcp.regs[REG_SP]      = (uint32_t)tcb->xcp.regs +
+                                               (uint32_t)XCPTCONTEXT_SIZE;
 
                   /* Then set up vector to the trampoline with interrupts
                    * disabled.  We must already be in privileged thread mode
@@ -341,13 +344,14 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
                    * been delivered.
                    */
 
-                  CURRENT_REGS              =
-                    (FAR void *)STACK_ALIGN_DOWN((uint32_t)CURRENT_REGS -
-                                                 (uint32_t)XCPTCONTEXT_SIZE);
+                  CURRENT_REGS              = (FAR void *)
+                                              ((uint32_t)CURRENT_REGS -
+                                               (uint32_t)XCPTCONTEXT_SIZE);
                   memcpy((FAR uint32_t *)CURRENT_REGS, tcb->xcp.saved_regs,
                          XCPTCONTEXT_SIZE);
 
-                  CURRENT_REGS[REG_SP]      = (uint32_t)CURRENT_REGS;
+                  CURRENT_REGS[REG_SP]      = (uint32_t)CURRENT_REGS +
+                                              (uint32_t)XCPTCONTEXT_SIZE;
 
                   /* Then set up vector to the trampoline with interrupts
                    * disabled.  The kernel-space trampoline must run in
@@ -416,12 +420,13 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
            * delivered.
            */
 
-          tcb->xcp.regs              =
-            (FAR void *)STACK_ALIGN_DOWN((uint32_t)tcb->xcp.regs -
-                                         (uint32_t)XCPTCONTEXT_SIZE);
+          tcb->xcp.regs              = (FAR void *)
+                                       ((uint32_t)tcb->xcp.regs -
+                                        (uint32_t)XCPTCONTEXT_SIZE);
           memcpy(tcb->xcp.regs, tcb->xcp.saved_regs, XCPTCONTEXT_SIZE);
 
-          tcb->xcp.regs[REG_SP]      = (uint32_t)tcb->xcp.regs;
+          tcb->xcp.regs[REG_SP]      = (uint32_t)tcb->xcp.regs +
+                                       (uint32_t)XCPTCONTEXT_SIZE;
 
           /* Increment the IRQ lock count so that when the task is restarted,
            * it will hold the IRQ spinlock.

[incubator-nuttx] 01/03: arch/arm: Remove the code copy register from xcpt to stack

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

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

commit 9ae0dcd4a231424f4968947988cb2865ef90681b
Author: Xiang Xiao <xi...@xiaomi.com>
AuthorDate: Thu Mar 17 02:38:03 2022 +0800

    arch/arm: Remove the code copy register from xcpt to stack
    
    since xcpt always point to the stack after the below change:
    commit 7b9978883c46569068ba5dac5755f998fbd237b2
    Author: chao.an <an...@xiaomi.com>
    Date:   Tue Mar 1 01:06:24 2022 +0800
    
        arch/arm: optimize context switch speed
    
        The current context save implementation saves registers of each task
        to xcp context, which is unnecessary because most of the arm registers are
        already saved in the task stack, this commit replace the xcp context with
        stack context to improve context switching performance and reduce the tcb
        space occupation of tcb instance.
    
    Signed-off-by: Xiang Xiao <xi...@xiaomi.com>
---
 arch/arm/src/armv6-m/arm_exception.S         |  65 ++++-------------
 arch/arm/src/armv7-m/gnu/arm_exception.S     |  92 +++++-------------------
 arch/arm/src/armv7-m/gnu/arm_lazyexception.S |  77 ++++++--------------
 arch/arm/src/armv8-m/arm_exception.S         | 104 ++++++---------------------
 arch/arm/src/armv8-m/arm_lazyexception.S     |  87 +++++++---------------
 5 files changed, 99 insertions(+), 326 deletions(-)

diff --git a/arch/arm/src/armv6-m/arm_exception.S b/arch/arm/src/armv6-m/arm_exception.S
index c438bf5..224ecdd 100644
--- a/arch/arm/src/armv6-m/arm_exception.S
+++ b/arch/arm/src/armv6-m/arm_exception.S
@@ -167,10 +167,7 @@ exception_common:
 	 */
 
 #if CONFIG_ARCH_INTERRUPTSTACK > 3
-	setintstack     r7, r6					/* SP = IRQ stack top */
-	push		{r1}					/* Save the MSP on the interrupt stack */
-	bl		arm_doirq				/* R0=IRQ, R1=register save area on stack */
-	pop		{r1}					/* Recover R1=main stack pointer */
+	setintstack	r7, r6					/* SP = IRQ stack top */
 #else
 	/* If the interrupt stack is disabled, reserve xcpcontext to ensure
 	 * that signal processing can have a separate xcpcontext to handle
@@ -183,64 +180,30 @@ exception_common:
 	 * also the sp should be restore after arm_doirq()
 	 */
 
-	sub		r1, r1, #XCPTCONTEXT_SIZE		/* Reserve signal context */
-
-	msr		msp, r1					/* We are using the main stack pointer */
-
-	add		r1, r1, #XCPTCONTEXT_SIZE		/* Restore signal context */
+	mov		r2, r1					/* Reserve signal context */
+	sub		r2, r2, #XCPTCONTEXT_SIZE
+	msr		msp, r2					/* We are using the main stack pointer */
+#endif
 
 	bl		arm_doirq				/* R0=IRQ, R1=register save area on stack */
 
-	mrs		r1, msp					/* Recover R1=main stack pointer */
-#endif
-
 	/* On return from arm_doirq, R0 will hold a pointer to register context
-	 * array to use for the interrupt return.  If that return value is the same
-	 * as current stack pointer, then things are relatively easy.
-	 */
-
-	cmp		r0, r1					/* Context switch? */
-	beq		3f					/* Branch if no context switch */
-
-	/* We are returning with a pending context switch.  This case is different
-	 * because in this case, the register save structure does not lie on the
-	 * stack but, rather within a TCB structure.  We'll have to copy some
-	 * values to the stack.
-	 */
-
-	/* Copy the hardware-saved context to the new stack */
-
-	mov		r2, #SW_XCPT_SIZE		/* R2=Size of software-saved portion of the context array */
-	add		r1, r0, r2			/* R1=Address of HW save area in reg array */
-	ldr		r2, [r0, #(4*REG_SP)]		/* R2=Value of SP before the interrupt */
-	sub		r2, #HW_XCPT_SIZE		/* R2=Address of HW save area on the return stack */
-	ldmia		r1!, {r4-r7}			/* Fetch four registers from the HW save area */
-	stmia		r2!, {r4-r7}			/* Copy four registers to the return stack */
-	ldmia		r1!, {r4-r7}			/* Fetch four registers from the HW save area */
-	stmia		r2!, {r4-r7}			/* Copy four registers to the return stack */
-
-	/* Restore the register contents */
-
-	mov		r1, r0
-
-3:
-	/* We are returning with no context switch.  We simply need to "unwind"
-	 * the same stack frame that we created at entry.
+	 * array to use for the interrupt return.
 	 */
 
 	/* Recover R8-R11 and EXEC_RETURN (5 registers) */
 
 	mov		r2, #(4*REG_R8)				/* R2=Offset to R8 storage */
-	add		r0, r1, r2				/* R0=Address of R8 storage */
+	add		r1, r0, r2				/* R1=Address of R8 storage */
 #ifdef CONFIG_BUILD_PROTECTED
-	ldmia		r0!, {r2-r6}				/* Recover R8-R11 and R14 (5 registers)*/
+	ldmia		r1!, {r2-r6}				/* Recover R8-R11 and R14 (5 registers)*/
 	mov		r8, r2					/* Move to position in high registers */
 	mov		r9, r3
 	mov		r10, r4
 	mov		r11, r5
 	mov		r14, r6					/* EXEC_RETURN */
 #else
-	ldmia		r0!, {r2-r5}				/* Recover R8-R11 and R14 (5 registers)*/
+	ldmia		r1!, {r2-r5}				/* Recover R8-R11 (4 registers)*/
 	mov		r8, r2					/* Move to position in high registers */
 	mov		r9, r3
 	mov		r10, r4
@@ -251,7 +214,7 @@ exception_common:
 	 * the stack pointer as it was on entry to the exception handler.
 	 */
 
-	ldmia		r1!, {r2-r7}				/* Recover R4-R7 + 2 temp values */
+	ldmia		r0!, {r2-r7}				/* Recover R4-R7 + 2 temp values */
 	mov		r1, #HW_XCPT_SIZE			/* R1=Size of hardware-saved portion of the context array */
 	sub		r1, r2, r1				/* R1=Value of MSP/PSP on exception entry */
 
@@ -262,14 +225,14 @@ exception_common:
 #ifdef CONFIG_BUILD_PROTECTED
 	mov		r0, r14					/* Copy high register to low register */
 	lsl		r0, #(31 - EXC_RETURN_PROCESS_BITNO)	/* Move to bit 31 */
-	bmi		5f					/* Test bit 31 */
+	bmi		3f					/* Test bit 31 */
 	msr		msp, r1					/* R1=The main stack pointer */
-	b		6f
+	b		4f
 
-5:
+3:
 	msr		psp, r1					/* R1=The process stack pointer */
 
-6:
+4:
 #else
 	msr		msp, r1					/* R1=The main stack pointer */
 	ldr		r0, =EXC_RETURN_PRIVTHR			/* R0=EXC_RETURN to privileged mode */
diff --git a/arch/arm/src/armv7-m/gnu/arm_exception.S b/arch/arm/src/armv7-m/gnu/arm_exception.S
index 8836f40..be6cc94 100644
--- a/arch/arm/src/armv7-m/gnu/arm_exception.S
+++ b/arch/arm/src/armv7-m/gnu/arm_exception.S
@@ -188,10 +188,6 @@ exception_common:
 
 	mov		r1, sp
 
-	/* Also save the top of the stack in a preserved register */
-
-	mov		r4, sp
-
 #if CONFIG_ARCH_INTERRUPTSTACK > 7
 	/* If CONFIG_ARCH_INTERRUPTSTACK is defined, we will set the MSP to use
 	 * a special special interrupt stack pointer.  The way that this is done
@@ -199,9 +195,12 @@ exception_common:
 	 */
 
 	setintstack	r2, r3			/* SP = IRQ stack top */
-
-	bl		arm_doirq				/* R0=IRQ, R1=register save (msp) */
 #else
+	/* Otherwise, we will re-use the interrupted thread's stack.  That may
+	 * mean using either MSP or PSP stack for interrupt level processing (in
+	 * kernel mode).
+	 */
+
 	/* If the interrupt stack is disabled, reserve xcpcontext to ensure
 	 * that signal processing can have a separate xcpcontext to handle
 	 * signal context (reference: arm_schedulesigaction.c):
@@ -213,77 +212,22 @@ exception_common:
 	 * also the sp should be restore after arm_doirq()
 	 */
 
-	sub		r4, r4, #XCPTCONTEXT_SIZE		/* Reserve signal context */
-
-	/* Otherwise, we will re-use the interrupted thread's stack.  That may
-	 * mean using either MSP or PSP stack for interrupt level processing (in
-	 * kernel mode).
-	 */
-
-	bic		r2, r4, #7				/* Get the stack pointer with 8-byte alignment */
+	sub		r2, r1, #XCPTCONTEXT_SIZE		/* Reserve signal context */
+	bic		r2, r2, #7				/* Get the stack pointer with 8-byte alignment */
 	mov		sp, r2					/* Instantiate the aligned stack */
-
-	bl		arm_doirq				/* R0=IRQ, R1=register save (msp) */
-
-	/* If the interrupt stack is disabled, restore the signal context */
-
-	add		r4, r4, #XCPTCONTEXT_SIZE		/* Restore signal context */
 #endif
 
-	mov		r1, r4					/* Recover R1=main stack pointer */
+	bl		arm_doirq				/* R0=IRQ, R1=register save (msp) */
 
 	/* On return from arm_doirq, R0 will hold a pointer to register context
-	 * array to use for the interrupt return.  If that return value is the same
-	 * as current stack pointer, then things are relatively easy.
+	 * array to use for the interrupt return.
 	 */
 
-	cmp		r0, r1					/* Context switch? */
-	beq		2f					/* Branch if no context switch */
-
-	/* We are returning with a pending context switch.  This case is different
-	 * because in this case, the register save structure does not lie on the
-	 * stack but, rather within a TCB structure.  We'll have to copy some
-	 * values to the stack.
-	 */
-
-	/* Copy the hardware-saved context to the stack, and restore the software
-	 * saved context directly.
-	 *
-	 * XXX In the normal case, it appears that this entire operation is unnecessary;
-	 *     context switch time would be improved if we could work out when the stack
-	 *     is dirty and avoid the work...
-	 */
-
-	add		r1, r0, #SW_XCPT_SIZE 	/* R1=Address of HW save area in reg array */
-	ldmia		r1!, {r4-r11}		/* Fetch eight registers in HW save area */
-#ifdef CONFIG_ARCH_FPU
-	vldmia		r1!, {s0-s15}		/* Fetch sixteen FP registers in HW save area */
-	ldmia		r1, {r2-r3}		/* Fetch FPSCR and Reserved in HW save area */
-#endif
-	ldr		r1, [r0, #(4*REG_SP)]	/* R1=Value of SP before interrupt */
-#ifdef CONFIG_ARCH_FPU
-	stmdb		r1!, {r2-r3}		/* Store FPSCR and Reserved on the return stack */
-	vstmdb		r1!, {s0-s15}		/* Store sixteen FP registers on the return stack */
-#endif
-	stmdb		r1!, {r4-r11}		/* Store eight registers on the return stack */
 	ldmia		r0!, {r2-r11,r14}	/* Recover R4-R11, r14 + 2 temp values */
 #ifdef CONFIG_ARCH_FPU
-	vldmia		r0, {s16-s31}		/* Recover S16-S31 */
+	vldmia		r0!, {s16-s31}		/* Recover S16-S31 */
 #endif
 
-	b		3f			/* Re-join common logic */
-
-2:
-	/* We are returning with no context switch.  We simply need to "unwind"
-	 * the same stack frame that we created at entry.
-	 */
-
-	ldmia		r1!, {r2-r11,r14}	/* Recover R4-R11, r14 + 2 temp values */
-#ifdef CONFIG_ARCH_FPU
-	vldmia		r1!, {s16-s31}		/* Recover S16-S31 */
-#endif
-
-3:
 	/* The EXC_RETURN value tells us whether we are returning on the MSP or PSP
 	 */
 
@@ -295,21 +239,21 @@ exception_common:
 
 	mrs		r2, control				/* R2=Contents of the control register */
 	tst		r14, #EXC_RETURN_PROCESS_STACK		/* nonzero if context on process stack */
-	beq		4f					/* Branch if privileged */
+	beq		2f					/* Branch if privileged */
 
 	orr		r2, r2, #1				/* Unprivileged mode */
-	msr		psp, r1					/* R1=The process stack pointer */
-	b		5f
-4:
+	msr		psp, r0					/* R0=The process stack pointer */
+	b		3f
+2:
 	bic		r2, r2, #1				/* Privileged mode */
-	msr		msp, r1					/* R1=The main stack pointer */
-5:
+	msr		msp, r0					/* R0=The main stack pointer */
+3:
 	msr		control, r2				/* Save the updated control register */
 #else
 	tst		r14, #EXC_RETURN_PROCESS_STACK		/* nonzero if context on process stack */
 	ite		eq					/* Next two instructions conditional */
-	msreq		msp, r1					/* R1=The main stack pointer */
-	msrne		psp, r1					/* R1=The process stack pointer */
+	msreq		msp, r0					/* R0=The main stack pointer */
+	msrne		psp, r0					/* R0=The process stack pointer */
 #endif
 
 	/* Restore the interrupt state */
diff --git a/arch/arm/src/armv7-m/gnu/arm_lazyexception.S b/arch/arm/src/armv7-m/gnu/arm_lazyexception.S
index 9cf5781..29b88f6 100644
--- a/arch/arm/src/armv7-m/gnu/arm_lazyexception.S
+++ b/arch/arm/src/armv7-m/gnu/arm_lazyexception.S
@@ -193,9 +193,12 @@ exception_common:
 	 */
 
 	setintstack	r2, r3				/* SP = IRQ stack top */
-
-	bl		arm_doirq				/* R0=IRQ, R1=register save (msp) */
 #else
+	/* Otherwise, we will re-use the interrupted thread's stack.  That may
+	 * mean using either MSP or PSP stack for interrupt level processing (in
+	 * kernel mode).
+	 */
+
 	/* If the interrupt stack is disabled, reserve xcpcontext to ensure
 	 * that signal processing can have a separate xcpcontext to handle
 	 * signal context (reference: arm_schedulesigaction.c):
@@ -207,31 +210,19 @@ exception_common:
 	 * also the sp should be restore after arm_doirq()
 	 */
 
-	sub		r4, r4, #XCPTCONTEXT_SIZE		/* Reserve signal context */
-
-	/* Otherwise, we will re-use the interrupted thread's stack.  That may
-	 * mean using either MSP or PSP stack for interrupt level processing (in
-	 * kernel mode).
-	 */
-
-	bic		r2, r4, #7				/* Get the stack pointer with 8-byte alignment */
+	sub		r2, r4, #XCPTCONTEXT_SIZE		/* Reserve signal context */
+	bic		r2, r2, #7				/* Get the stack pointer with 8-byte alignment */
 	mov		sp, r2					/* Instantiate the aligned stack */
-
-	bl		arm_doirq				/* R0=IRQ, R1=register save (msp) */
-
-	/* If the interrupt stack is disabled, restore the signal context */
-
-	add		r4, r4, #XCPTCONTEXT_SIZE		/* Restore signal context */
 #endif
 
-	mov		r1, r4					/* Recover R1=main stack pointer */
+	bl		arm_doirq				/* R0=IRQ, R1=register save (msp) */
 
 	/* On return from arm_doirq, R0 will hold a pointer to register context
 	 * array to use for the interrupt return.  If that return value is the same
 	 * as current stack pointer, then things are relatively easy.
 	 */
 
-	cmp		r0, r1					/* Context switch? */
+	cmp		r0, r4					/* Context switch? */
 	beq		2f					/* Branch if no context switch */
 
 	/* We are returning with a pending context switch.
@@ -253,56 +244,30 @@ exception_common:
 	bl		arm_restorefpu			/* Restore the FPU registers */
 #endif
 
-	/* We are returning with a pending context switch.  This case is different
-	 * because in this case, the register save structure does not lie in the
-	 * stack but, rather, within a TCB structure.  We'll have to copy some
-	 * values to the stack.
-	 */
-
-	add		r1, r0, #SW_XCPT_SIZE		/* R1=Address of HW save area in reg array */
-	ldmia		r1, {r4-r11}			/* Fetch eight registers in HW save area */
-	ldr		r1, [r0, #(4*REG_SP)]		/* R1=Value of SP before interrupt */
-	stmdb		r1!, {r4-r11}			/* Store eight registers in HW save area */
-#ifdef CONFIG_BUILD_PROTECTED
-	ldmia		r0, {r2-r11,r14}		/* Recover R4-R11, r14 + 2 temp values */
-#else
-	ldmia		r0, {r2-r11}			/* Recover R4-R11 + 2 temp values */
-#endif
-	b		3f				/* Re-join common logic */
-
-	/* We are returning with no context switch.  We simply need to "unwind"
-	 * the same stack frame that we created
-	 *
-	 * Here:
-	 *   r1 = Address of the return stack (same as r0)
-	 */
-
 2:
 #ifdef CONFIG_BUILD_PROTECTED
-	ldmia		r1!, {r2-r11,r14}		/* Recover R4-R11, r14 + 2 temp values */
+	ldmia		r0!, {r2-r11,r14}		/* Recover R4-R11, r14 + 2 temp values */
 #else
-	ldmia		r1!, {r2-r11}			/* Recover R4-R11 + 2 temp values */
+	ldmia		r0!, {r2-r11}			/* Recover R4-R11 + 2 temp values */
 #endif
 
 #ifdef CONFIG_ARCH_FPU
 	/* Skip over the block of memory reserved for floating pointer register
-	 * save. Then R1 is the address of the HW save area
+	 * save. Then R0 is the address of the HW save area
 	 */
 
-	add		r1, #(4*SW_FPU_REGS)
+	add		r0, #(4*SW_FPU_REGS)
 #endif
 
 	/* Set up to return from the exception
 	 *
 	 * Here:
-	 *   r1 = Address on the target thread's stack position at the start of
+	 *   r0 = Address on the target thread's stack position at the start of
 	 *        the registers saved by hardware
 	 *   r3 = primask or basepri
 	 *   r4-r11 = restored register values
 	 */
 
-3:
-
 #ifdef CONFIG_BUILD_PROTECTED
 	/* The EXC_RETURN value will be 0xfffffff9 (privileged thread) or 0xfffffff1
 	 * (handler mode) if the stack is on the MSP.  It can only be on the PSP if
@@ -311,18 +276,18 @@ exception_common:
 
 	mrs		r2, control				/* R2=Contents of the control register */
 	tst		r14, #EXC_RETURN_PROCESS_STACK		/* nonzero if context on process stack */
-	beq		4f					/* Branch if privileged */
+	beq		3f					/* Branch if privileged */
 
 	orr		r2, r2, #1				/* Unprivileged mode */
-	msr		psp, r1					/* R1=The process stack pointer */
-	b		5f
-4:
+	msr		psp, r0					/* R0=The process stack pointer */
+	b		4f
+3:
 	bic		r2, r2, #1				/* Privileged mode */
-	msr		msp, r1					/* R1=The main stack pointer */
-5:
+	msr		msp, r0					/* R0=The main stack pointer */
+4:
 	msr		control, r2				/* Save the updated control register */
 #else
-	msr		msp, r1					/* Recover the return MSP value */
+	msr		msp, r0					/* Recover the return MSP value */
 
 	/* Preload r14 with the special return value first (so that the return
 	 * actually occurs with interrupts still disabled).
diff --git a/arch/arm/src/armv8-m/arm_exception.S b/arch/arm/src/armv8-m/arm_exception.S
index aa81280..042b360 100644
--- a/arch/arm/src/armv8-m/arm_exception.S
+++ b/arch/arm/src/armv8-m/arm_exception.S
@@ -204,10 +204,6 @@ exception_common:
 
 	mov		r1, sp
 
-	/* Also save the top of the stack in a preserved register */
-
-	mov		r4, sp
-
 #if CONFIG_ARCH_INTERRUPTSTACK > 7
 	/* If CONFIG_ARCH_INTERRUPTSTACK is defined, we will set the MSP to use
 	 * a special special interrupt stack pointer.  The way that this is done
@@ -215,9 +211,12 @@ exception_common:
 	 */
 
 	setintstack	r2, r3			/* SP = IRQ stack top */
-
-	bl		arm_doirq				/* R0=IRQ, R1=register save (msp) */
 #else
+	/* Otherwise, we will re-use the interrupted thread's stack.  That may
+	 * mean using either MSP or PSP stack for interrupt level processing (in
+	 * kernel mode).
+	 */
+
 	/* If the interrupt stack is disabled, reserve xcpcontext to ensure
 	 * that signal processing can have a separate xcpcontext to handle
 	 * signal context (reference: arm_schedulesigaction.c):
@@ -229,85 +228,26 @@ exception_common:
 	 * also the sp should be restore after arm_doirq()
 	 */
 
-	sub		r4, r4, #XCPTCONTEXT_SIZE		/* Reserve signal context */
-
-	/* Otherwise, we will re-use the interrupted thread's stack.  That may
-	 * mean using either MSP or PSP stack for interrupt level processing (in
-	 * kernel mode).
-	 */
-
-	bic		r2, r4, #7				/* Get the stack pointer with 8-byte alignment */
+	sub		r2, r1, #XCPTCONTEXT_SIZE		/* Reserve signal context */
+	bic		r2, r2, #7				/* Get the stack pointer with 8-byte alignment */
 	mov		sp, r2					/* Instantiate the aligned stack */
-
-	bl		arm_doirq				/* R0=IRQ, R1=register save (msp) */
-
-	/* If the interrupt stack is disabled, restore the signal context */
-
-	add		r4, r4, #XCPTCONTEXT_SIZE		/* Restore signal context */
 #endif
 
-	mov		r1, r4					/* Recover R1=main stack pointer */
+	bl		arm_doirq				/* R0=IRQ, R1=register save (msp) */
 
 	/* On return from arm_doirq, R0 will hold a pointer to register context
-	 * array to use for the interrupt return.  If that return value is the same
-	 * as current stack pointer, then things are relatively easy.
+	 * array to use for the interrupt return.
 	 */
 
-	cmp		r0, r1					/* Context switch? */
-	beq		2f					/* Branch if no context switch */
-
-	/* We are returning with a pending context switch.  This case is different
-	 * because in this case, the register save structure does not lie on the
-	 * stack but, rather within a TCB structure.  We'll have to copy some
-	 * values to the stack.
-	 */
-
-	/* Copy the hardware-saved context to the stack, and restore the software
-	 * saved context directly.
-	 *
-	 * XXX In the normal case, it appears that this entire operation is unnecessary;
-	 *     context switch time would be improved if we could work out when the stack
-	 *     is dirty and avoid the work...
-	 */
-
-	add		r1, r0, #SW_XCPT_SIZE 	/* R1=Address of HW save area in reg array */
-	ldmia		r1!, {r4-r11}		/* Fetch eight registers in HW save area */
-#ifdef CONFIG_ARCH_FPU
-	vldmia		r1!, {s0-s15}		/* Fetch sixteen FP registers in HW save area */
-	ldmia		r1, {r2-r3}		/* Fetch FPSCR and Reserved in HW save area */
-#endif
-	ldr		r1, [r0, #(4*REG_SP)]	/* R1=Value of SP before interrupt */
-#ifdef CONFIG_ARCH_FPU
-	stmdb		r1!, {r2-r3}		/* Store FPSCR and Reserved on the return stack */
-	vstmdb		r1!, {s0-s15}		/* Store sixteen FP registers on the return stack */
-#endif
-	stmdb		r1!, {r4-r11}		/* Store eight registers on the return stack */
 	ldmia		r0!, {r2-r11,r14}	/* Recover R4-R11, r14 + 2 temp values */
 #ifdef CONFIG_ARCH_FPU
 	vldmia		r0!, {s16-s31}		/* Recover S16-S31 */
 #endif
 
 #ifdef CONFIG_ARMV8M_STACKCHECK_HARDWARE
-	ldmia		r0, {r0}		/* Get psplim/msplim */
+	ldmia		r0!, {r1}		/* Get psplim/msplim */
 #endif
 
-	b		3f			/* Re-join common logic */
-
-2:
-	/* We are returning with no context switch.  We simply need to "unwind"
-	 * the same stack frame that we created at entry.
-	 */
-
-	ldmia		r1!, {r2-r11,r14}	/* Recover R4-R11, r14 + 2 temp values */
-#ifdef CONFIG_ARCH_FPU
-	vldmia		r1!, {s16-s31}		/* Recover S16-S31 */
-#endif
-
-#ifdef CONFIG_ARMV8M_STACKCHECK_HARDWARE
-	ldmia		r1!, {r0}		/* Get psplim/msplim */
-#endif
-
-3:
 	/* The EXC_RETURN value tells us whether we are returning on the MSP or PSP
 	 */
 
@@ -319,33 +259,33 @@ exception_common:
 
 	mrs		r2, control				/* R2=Contents of the control register */
 	tst		r14, #EXC_RETURN_PROCESS_STACK		/* nonzero if context on process stack */
-	beq		4f					/* Branch if privileged */
+	beq		2f					/* Branch if privileged */
 
 	orr		r2, r2, #1				/* Unprivileged mode */
 #ifdef CONFIG_ARMV8M_STACKCHECK_HARDWARE
-	msr		psplim, r0
+	msr		psplim, r1
 #endif
-	msr		psp, r1					/* R1=The process stack pointer */
-	b		5f
-4:
+	msr		psp, r0					/* R0=The process stack pointer */
+	b		3f
+2:
 	bic		r2, r2, #1				/* Privileged mode */
 #ifdef CONFIG_ARMV8M_STACKCHECK_HARDWARE
-	msr		msplim, r0
+	msr		msplim, r1
 #endif
-	msr		msp, r1					/* R1=The main stack pointer */
-5:
+	msr		msp, r0					/* R0=The main stack pointer */
+3:
 	msr		control, r2				/* Save the updated control register */
 #else
 	tst		r14, #EXC_RETURN_PROCESS_STACK		/* nonzero if context on process stack */
 #ifdef CONFIG_ARMV8M_STACKCHECK_HARDWARE
 	itete		eq
-	msreq		msplim, r0
-	msrne		psplim, r0
+	msreq		msplim, r1
+	msrne		psplim, r1
 #else
 	ite		eq					/* Next two instructions conditional */
 #endif
-	msreq		msp, r1					/* R1=The main stack pointer */
-	msrne		psp, r1					/* R1=The process stack pointer */
+	msreq		msp, r0					/* R0=The main stack pointer */
+	msrne		psp, r0					/* R0=The process stack pointer */
 #endif
 
 	/* Restore the interrupt state */
diff --git a/arch/arm/src/armv8-m/arm_lazyexception.S b/arch/arm/src/armv8-m/arm_lazyexception.S
index d70e2bd..cc9b994 100644
--- a/arch/arm/src/armv8-m/arm_lazyexception.S
+++ b/arch/arm/src/armv8-m/arm_lazyexception.S
@@ -210,9 +210,12 @@ exception_common:
 	 */
 
 	setintstack	r2, r3				/* SP = IRQ stack top */
-
-	bl		arm_doirq				/* R0=IRQ, R1=register save (msp) */
 #else
+	/* Otherwise, we will re-use the interrupted thread's stack.  That may
+	 * mean using either MSP or PSP stack for interrupt level processing (in
+	 * kernel mode).
+	 */
+
 	/* If the interrupt stack is disabled, reserve xcpcontext to ensure
 	 * that signal processing can have a separate xcpcontext to handle
 	 * signal context (reference: arm_schedulesigaction.c):
@@ -224,31 +227,18 @@ exception_common:
 	 * also the sp should be restore after arm_doirq()
 	 */
 
-	sub		r4, r4, #XCPTCONTEXT_SIZE		/* Reserve signal context */
-
-	/* Otherwise, we will re-use the interrupted thread's stack.  That may
-	 * mean using either MSP or PSP stack for interrupt level processing (in
-	 * kernel mode).
-	 */
-
-	bic		r2, r4, #7				/* Get the stack pointer with 8-byte alignment */
+	sub		r2, r4, #XCPTCONTEXT_SIZE		/* Reserve signal context */
+	bic		r2, r2, #7				/* Get the stack pointer with 8-byte alignment */
 	mov		sp, r2					/* Instantiate the aligned stack */
-
-	bl		arm_doirq				/* R0=IRQ, R1=register save (msp) */
-
-	/* If the interrupt stack is disabled, restore the signal context */
-
-	add		r4, r4, #XCPTCONTEXT_SIZE		/* Restore signal context */
 #endif
 
-	mov		r1, r4					/* Recover R1=main stack pointer */
+	bl		arm_doirq				/* R0=IRQ, R1=register save (msp) */
 
 	/* On return from arm_doirq, R0 will hold a pointer to register context
-	 * array to use for the interrupt return.  If that return value is the same
-	 * as current stack pointer, then things are relatively easy.
+	 * array to use for the interrupt return.
 	 */
 
-	cmp		r0, r1					/* Context switch? */
+	cmp		r0, r4					/* Context switch? */
 	beq		2f					/* Branch if no context switch */
 
 	/* We are returning with a pending context switch.
@@ -270,63 +260,34 @@ exception_common:
 	bl		arm_restorefpu			/* Restore the FPU registers */
 #endif
 
-	/* We are returning with a pending context switch.  This case is different
-	 * because in this case, the register save structure does not lie in the
-	 * stack but, rather, within a TCB structure.  We'll have to copy some
-	 * values to the stack.
-	 */
-
-	add		r1, r0, #SW_XCPT_SIZE		/* R1=Address of HW save area in reg array */
-	ldmia		r1, {r4-r11}			/* Fetch eight registers in HW save area */
-	ldr		r1, [r0, #(4*REG_SP)]		/* R1=Value of SP before interrupt */
-	stmdb		r1!, {r4-r11}			/* Store eight registers in HW save area */
+2:
 #ifdef CONFIG_BUILD_PROTECTED
 	ldmia		r0!, {r2-r11,r14}		/* Recover R4-R11, r14 + 2 temp values */
 #else
 	ldmia		r0!, {r2-r11}			/* Recover R4-R11 + 2 temp values */
 #endif
-#ifdef CONFIG_ARMV8M_STACKCHECK_HARDWARE
-	ldmia		r0, {r0}			/* Get psplim/msplim*/
-#endif
-	b		3f				/* Re-join common logic */
-
-	/* We are returning with no context switch.  We simply need to "unwind"
-	 * the same stack frame that we created
-	 *
-	 * Here:
-	 *   r1 = Address of the return stack (same as r0)
-	 */
-
-2:
-#ifdef CONFIG_BUILD_PROTECTED
-	ldmia		r1!, {r2-r11,r14}		/* Recover R4-R11, r14 + 2 temp values */
-#else
-	ldmia		r1!, {r2-r11}			/* Recover R4-R11 + 2 temp values */
-#endif
 
 #ifdef CONFIG_ARCH_FPU
 	/* Skip over the block of memory reserved for floating pointer register
 	 * save. Then R1 is the address of the HW save area
 	 */
 
-	add		r1, #(4*SW_FPU_REGS)
+	add		r0, #(4*SW_FPU_REGS)
 #endif
 
 #ifdef CONFIG_ARMV8M_STACKCHECK_HARDWARE
-	ldmia		r1!, {r0}			/* Get psplim/msplim */
+	ldmia		r0!, {r1}			/* Get psplim/msplim */
 #endif
 
 	/* Set up to return from the exception
 	 *
 	 * Here:
-	 *   r1 = Address on the target thread's stack position at the start of
+	 *   r0 = Address on the target thread's stack position at the start of
 	 *        the registers saved by hardware
 	 *   r3 = primask or basepri
 	 *   r4-r11 = restored register values
 	 */
 
-3:
-
 #ifdef CONFIG_BUILD_PROTECTED
 	/* The EXC_RETURN value will be 0xfffffff9 (privileged thread) or 0xfffffff1
 	 * (handler mode) if the stack is on the MSP.  It can only be on the PSP if
@@ -335,27 +296,27 @@ exception_common:
 
 	mrs		r2, control				/* R2=Contents of the control register */
 	tst		r14, #EXC_RETURN_PROCESS_STACK		/* nonzero if context on process stack */
-	beq		4f					/* Branch if privileged */
+	beq		3f					/* Branch if privileged */
 
 	orr		r2, r2, #1				/* Unprivileged mode */
 #ifdef CONFIG_ARMV8M_STACKCHECK_HARDWARE
-	msr		psplim, r0
+	msr		psplim, r1
 #endif
-	msr		psp, r1					/* R1=The process stack pointer */
-	b		5f
-4:
+	msr		psp, r0					/* R1=The process stack pointer */
+	b		4f
+3:
 	bic		r2, r2, #1				/* Privileged mode */
 #ifdef CONFIG_ARMV8M_STACKCHECK_HARDWARE
-	msr		msplim, r0
+	msr		msplim, r1
 #endif
-	msr		msp, r1					/* R1=The main stack pointer */
-5:
+	msr		msp, r0					/* R1=The main stack pointer */
+4:
 	msr		control, r2				/* Save the updated control register */
 #else
 #ifdef CONFIG_ARMV8M_STACKCHECK_HARDWARE
-	msr		msplim, r0
+	msr		msplim, r1
 #endif
-	msr		msp, r1					/* Recover the return MSP value */
+	msr		msp, r0					/* Recover the return MSP value */
 
 	/* Preload r14 with the special return value first (so that the return
 	 * actually occurs with interrupts still disabled).

[incubator-nuttx] 02/03: arm/vfork: update the SP to stack top

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

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

commit a770ff20174c4d8fdcf60f8147f768d65a367292
Author: chao.an <an...@xiaomi.com>
AuthorDate: Fri Mar 18 21:54:01 2022 +0800

    arm/vfork: update the SP to stack top
    
    Signed-off-by: chao.an <an...@xiaomi.com>
---
 arch/arm/src/common/arm_vfork.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/arch/arm/src/common/arm_vfork.c b/arch/arm/src/common/arm_vfork.c
index f265aaf..edad4cc 100644
--- a/arch/arm/src/common/arm_vfork.c
+++ b/arch/arm/src/common/arm_vfork.c
@@ -137,10 +137,18 @@ pid_t up_vfork(const struct vfork_s *context)
    * effort is overkill.
    */
 
-  newtop = STACK_ALIGN_DOWN((uint32_t)child->cmn.stack_base_ptr +
-                                      child->cmn.adj_stack_size -
-                                      XCPTCONTEXT_SIZE);
+  newtop = (uint32_t)child->cmn.stack_base_ptr +
+                     child->cmn.adj_stack_size;
+
   newsp = newtop - stackutil;
+
+  /* Move the register context to newtop. */
+
+  memcpy((void *)(newsp - XCPTCONTEXT_SIZE),
+         child->cmn.xcp.regs, XCPTCONTEXT_SIZE);
+
+  child->cmn.xcp.regs = (void *)(newsp - XCPTCONTEXT_SIZE);
+
   memcpy((void *)newsp, (const void *)context->sp, stackutil);
 
   /* Was there a frame pointer in place before? */