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? */