You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2022/04/28 18:51:46 UTC
[incubator-nuttx] branch master updated: arch/xtensa: Replace the xcp context with stack context to improve context switching
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new da273fce0b arch/xtensa: Replace the xcp context with stack context to improve context switching
da273fce0b is described below
commit da273fce0b312fecfc139d5df5a73f8f3068b1b1
Author: Abdelatif Guettouche <ab...@espressif.com>
AuthorDate: Wed Apr 20 23:50:12 2022 +0200
arch/xtensa: Replace the xcp context with stack context to improve context switching
Signed-off-by: Abdelatif Guettouche <ab...@espressif.com>
---
arch/xtensa/include/irq.h | 5 +-
arch/xtensa/include/syscall.h | 6 +-
arch/xtensa/src/common/xtensa.h | 11 +--
arch/xtensa/src/common/xtensa_blocktask.c | 2 +-
arch/xtensa/src/common/xtensa_copystate.c | 58 -------------
arch/xtensa/src/common/xtensa_dumpstate.c | 5 +-
arch/xtensa/src/common/xtensa_exit.c | 2 +-
arch/xtensa/src/common/xtensa_initialstate.c | 15 +++-
arch/xtensa/src/common/xtensa_int_handlers.S | 13 +++
arch/xtensa/src/common/xtensa_releasepending.c | 2 +-
arch/xtensa/src/common/xtensa_reprioritizertr.c | 2 +-
arch/xtensa/src/common/xtensa_schedsigaction.c | 105 ++++++++++++++++++------
arch/xtensa/src/common/xtensa_sigdeliver.c | 10 +--
arch/xtensa/src/common/xtensa_swint.c | 7 +-
arch/xtensa/src/common/xtensa_unblocktask.c | 2 +-
arch/xtensa/src/esp32/Make.defs | 2 +-
arch/xtensa/src/esp32/esp32_cpustart.c | 5 +-
arch/xtensa/src/esp32s2/Make.defs | 2 +-
arch/xtensa/src/esp32s3/Make.defs | 2 +-
arch/xtensa/src/esp32s3/esp32s3_cpustart.c | 5 +-
20 files changed, 134 insertions(+), 127 deletions(-)
diff --git a/arch/xtensa/include/irq.h b/arch/xtensa/include/irq.h
index d21539b351..d0a6f2b92c 100644
--- a/arch/xtensa/include/irq.h
+++ b/arch/xtensa/include/irq.h
@@ -149,12 +149,11 @@ struct xcptcontext
* another signal handler is executing will be ignored!
*/
- uint32_t saved_pc;
- uint32_t saved_ps;
+ uint32_t *saved_regs;
/* Register save area */
- uint32_t regs[XCPTCONTEXT_REGS];
+ uint32_t *regs;
#if XCHAL_CP_NUM > 0
/* Co-processor save area */
diff --git a/arch/xtensa/include/syscall.h b/arch/xtensa/include/syscall.h
index 2e96162157..2e82543d32 100644
--- a/arch/xtensa/include/syscall.h
+++ b/arch/xtensa/include/syscall.h
@@ -100,21 +100,21 @@
/* SYS call 0:
*
- * int xtensa_saveusercontext(uint32_t *saveregs);
+ * int up_saveusercontext(void *saveregs);
*/
#define SYS_save_context (0)
/* SYS call 1:
*
- * void xtensa_fullcontextrestore(uint32_t *restoreregs) noreturn_function;
+ * void xtensa_context_restore(uint32_t **restoreregs) noreturn_function;
*/
#define SYS_restore_context (1)
/* SYS call 2:
*
- * void xtensa_switchcontext(uint32_t *saveregs, uint32_t *restoreregs);
+ * void xtensa_switchcontext(uint32_t **saveregs, uint32_t *restoreregs);
*/
#define SYS_switch_context (2)
diff --git a/arch/xtensa/src/common/xtensa.h b/arch/xtensa/src/common/xtensa.h
index 3828cbf527..99bd28646b 100644
--- a/arch/xtensa/src/common/xtensa.h
+++ b/arch/xtensa/src/common/xtensa.h
@@ -103,15 +103,12 @@
#define IDLETHREAD_STACKSIZE ((CONFIG_IDLETHREAD_STACKSIZE + 15) & ~15)
#define IDLETHREAD_STACKWORDS (IDLETHREAD_STACKSIZE >> 2)
-/* In the XTENSA model, the state is copied from the stack to the TCB, but
- * only a referenced is passed to get the state from the TCB.
- *
- * REVISIT: It would not be too difficult to save only a pointer to the
- * state save area in the TCB and thus avoid the copy.
+/* In the Xtensa model, the state is saved in stack,
+ * only a reference stored in TCB.
*/
-#define xtensa_savestate(regs) xtensa_copystate(regs, (uint32_t*)CURRENT_REGS)
-#define xtensa_restorestate(regs) do { CURRENT_REGS = regs; } while (0)
+#define xtensa_savestate(regs) ((regs) = (uint32_t *)CURRENT_REGS)
+#define xtensa_restorestate(regs) (CURRENT_REGS = (regs))
/* Context switching via system calls ***************************************/
diff --git a/arch/xtensa/src/common/xtensa_blocktask.c b/arch/xtensa/src/common/xtensa_blocktask.c
index f090994136..c62ad63064 100644
--- a/arch/xtensa/src/common/xtensa_blocktask.c
+++ b/arch/xtensa/src/common/xtensa_blocktask.c
@@ -140,7 +140,7 @@ void up_block_task(struct tcb_s *tcb, tstate_t task_state)
/* Then switch contexts */
- xtensa_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
+ xtensa_switchcontext(&rtcb->xcp.regs, nexttcb->xcp.regs);
/* xtensa_switchcontext forces a context switch to the task at the
* head of the ready-to-run list. It does not 'return' in the
diff --git a/arch/xtensa/src/common/xtensa_copystate.c b/arch/xtensa/src/common/xtensa_copystate.c
deleted file mode 100644
index e746b4759f..0000000000
--- a/arch/xtensa/src/common/xtensa_copystate.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/****************************************************************************
- * arch/xtensa/src/common/xtensa_copystate.c
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership. The
- * ASF licenses this file to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the
- * License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- *
- ****************************************************************************/
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <stdint.h>
-#include <arch/irq.h>
-
-#include "xtensa.h"
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: xtensa_copystate
- ****************************************************************************/
-
-/* A little faster than most memcpy's */
-
-void xtensa_copystate(uint32_t *dest, uint32_t *src)
-{
- int i;
-
- /* In the XTENSA model, the state is copied from the stack to the TCB,
- * but only a reference is passed to get the state from the TCB. So the
- * following check avoids copying the TCB save area onto itself:
- */
-
- if (src != dest)
- {
- for (i = 0; i < XCPTCONTEXT_REGS; i++)
- {
- *dest++ = *src++;
- }
- }
-}
diff --git a/arch/xtensa/src/common/xtensa_dumpstate.c b/arch/xtensa/src/common/xtensa_dumpstate.c
index d2aaec56e1..13dcf03123 100644
--- a/arch/xtensa/src/common/xtensa_dumpstate.c
+++ b/arch/xtensa/src/common/xtensa_dumpstate.c
@@ -295,12 +295,11 @@ void xtensa_dumpstate(void)
if (CURRENT_REGS)
{
- memcpy(rtcb->xcp.regs,
- (uintptr_t *)CURRENT_REGS, XCPTCONTEXT_SIZE);
+ rtcb->xcp.regs = (uint32_t *)CURRENT_REGS;
}
else
{
- up_saveusercontext(rtcb->xcp.regs);
+ up_saveusercontext(&rtcb->xcp.regs);
}
/* Dump the registers (if available) */
diff --git a/arch/xtensa/src/common/xtensa_exit.c b/arch/xtensa/src/common/xtensa_exit.c
index 66f529ff8c..f6e0ee3478 100644
--- a/arch/xtensa/src/common/xtensa_exit.c
+++ b/arch/xtensa/src/common/xtensa_exit.c
@@ -145,7 +145,7 @@ void up_exit(int status)
/* Then switch contexts */
- xtensa_context_restore(tcb->xcp.regs);
+ xtensa_context_restore(&tcb->xcp.regs);
/* xtensa_context_restore() should not return but could if the
* software interrupts are disabled.
diff --git a/arch/xtensa/src/common/xtensa_initialstate.c b/arch/xtensa/src/common/xtensa_initialstate.c
index b059d62cbd..554223ba15 100644
--- a/arch/xtensa/src/common/xtensa_initialstate.c
+++ b/arch/xtensa/src/common/xtensa_initialstate.c
@@ -58,6 +58,10 @@ void up_initial_state(struct tcb_s *tcb)
{
struct xcptcontext *xcp = &tcb->xcp;
+ /* Initialize the initial exception register context structure */
+
+ memset(xcp, 0, sizeof(struct xcptcontext));
+
/* Initialize the idle thread stack */
if (tcb->pid == IDLE_PROCESS_ID)
@@ -74,11 +78,18 @@ void up_initial_state(struct tcb_s *tcb)
xtensa_stack_color(tcb->stack_alloc_ptr, 0);
#endif /* CONFIG_STACK_COLORATION */
+ return;
}
- /* Initialize the initial exception register context structure */
+ /* Initialize the context registers to stack top */
- memset(xcp, 0, sizeof(struct xcptcontext));
+ xcp->regs = (void *)((uint32_t)tcb->stack_base_ptr +
+ tcb->adj_stack_size -
+ XCPTCONTEXT_SIZE);
+
+ /* Initialize the xcp registers */
+
+ memset(xcp->regs, 0, XCPTCONTEXT_SIZE);
/* Set initial values of registers */
diff --git a/arch/xtensa/src/common/xtensa_int_handlers.S b/arch/xtensa/src/common/xtensa_int_handlers.S
index bc5d141b49..c1d2d94850 100644
--- a/arch/xtensa/src/common/xtensa_int_handlers.S
+++ b/arch/xtensa/src/common/xtensa_int_handlers.S
@@ -137,6 +137,15 @@ g_intstacktop:
.macro dispatch_c_isr level mask tmp
+ /* If the interrupt stack is disabled, reserve xcpcontext to ensure
+ * that signal processing can have a separate xcpcontext to handle
+ * signal context (ref: xtensa_schedulesigaction.c):
+ */
+
+#if CONFIG_ARCH_INTERRUPTSTACK < 15
+ addi sp, sp, -XCPTCONTEXT_SIZE
+#endif
+
/* Set up PS for C, enable interrupts above this level and clear EXCM. */
ps_setup \level \tmp
@@ -217,6 +226,10 @@ g_intstacktop:
mov a12, a6 /* Switch to the save area of the new thread */
#endif
+#if CONFIG_ARCH_INTERRUPTSTACK < 15
+ addi sp, sp, XCPTCONTEXT_SIZE
+#endif
+
/* Done */
1:
diff --git a/arch/xtensa/src/common/xtensa_releasepending.c b/arch/xtensa/src/common/xtensa_releasepending.c
index 3d8f9c801b..f88e8051aa 100644
--- a/arch/xtensa/src/common/xtensa_releasepending.c
+++ b/arch/xtensa/src/common/xtensa_releasepending.c
@@ -109,7 +109,7 @@ void up_release_pending(void)
* ready to run list.
*/
- xtensa_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
+ xtensa_switchcontext(&rtcb->xcp.regs, nexttcb->xcp.regs);
/* xtensa_switchcontext forces a context switch to the task at the
* head of the ready-to-run list. It does not 'return' in the
diff --git a/arch/xtensa/src/common/xtensa_reprioritizertr.c b/arch/xtensa/src/common/xtensa_reprioritizertr.c
index 624b73e4e3..5360f7fff4 100644
--- a/arch/xtensa/src/common/xtensa_reprioritizertr.c
+++ b/arch/xtensa/src/common/xtensa_reprioritizertr.c
@@ -163,7 +163,7 @@ void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
* ready to run list.
*/
- xtensa_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
+ xtensa_switchcontext(&rtcb->xcp.regs, nexttcb->xcp.regs);
/* xtensa_switchcontext forces a context switch to the task at
* the head of the ready-to-run list. It does not 'return' in
diff --git a/arch/xtensa/src/common/xtensa_schedsigaction.c b/arch/xtensa/src/common/xtensa_schedsigaction.c
index fc5f399424..7b376e3c44 100644
--- a/arch/xtensa/src/common/xtensa_schedsigaction.c
+++ b/arch/xtensa/src/common/xtensa_schedsigaction.c
@@ -81,6 +81,7 @@
void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
{
sinfo("tcb=0x%p sigdeliver=0x%p\n", tcb, sigdeliver);
+ DEBUGASSERT(tcb != NULL && sigdeliver != NULL);
/* Refuse to handle nested signal actions */
@@ -121,20 +122,30 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
else
{
- /* Save the return pc and ps. These will be restored by the
+ /* Save the context registers. These will be restored by the
* signal trampoline after the signals have been delivered.
*
* NOTE: that hi-priority interrupts are not disabled.
*/
- tcb->xcp.sigdeliver = sigdeliver;
- tcb->xcp.saved_pc = CURRENT_REGS[REG_PC];
- tcb->xcp.saved_ps = CURRENT_REGS[REG_PS];
+ xtensa_savestate(tcb->xcp.saved_regs);
+
+ /* Duplicate the register context. These will be
+ * restored by the signal trampoline after the signal has
+ * been delivered.
+ */
+
+ CURRENT_REGS = (void *)((uint32_t)CURRENT_REGS -
+ XCPTCONTEXT_SIZE);
+
+ memcpy((uint32_t *)CURRENT_REGS, tcb->xcp.saved_regs,
+ XCPTCONTEXT_SIZE);
/* Then set up to vector to the trampoline with interrupts
* disabled
*/
+ tcb->xcp.sigdeliver = sigdeliver;
CURRENT_REGS[REG_PC] = (uint32_t)_xtensa_sig_trampoline;
#ifdef __XTENSA_CALL0_ABI__
CURRENT_REGS[REG_PS] = (uint32_t)
@@ -144,11 +155,8 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
(PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM | PS_WOE);
#endif
- /* And make sure that the saved context in the TCB is the same
- * as the interrupt return context.
- */
-
- xtensa_savestate(tcb->xcp.regs);
+ CURRENT_REGS[REG_A1] = (uint32_t)CURRENT_REGS +
+ XCPTCONTEXT_SIZE;
}
}
@@ -159,16 +167,26 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
else
{
- /* Save the return pc and ps. These will be restored by the
+ /* Save the context registers. These will be restored by the
* signal trampoline after the signals have been delivered.
*
* NOTE: that hi-priority interrupts are not disabled.
*/
tcb->xcp.sigdeliver = sigdeliver;
- tcb->xcp.saved_pc = tcb->xcp.regs[REG_PC];
- tcb->xcp.saved_ps = tcb->xcp.regs[REG_PS];
+ tcb->xcp.saved_regs = tcb->xcp.regs;
+ /* Duplicate the register context. These will be
+ * restored by the signal trampoline after the signal has been
+ * delivered.
+ */
+
+ tcb->xcp.regs = (void *)((uint32_t)tcb->xcp.regs -
+ XCPTCONTEXT_SIZE);
+ memcpy(tcb->xcp.regs, tcb->xcp.saved_regs, XCPTCONTEXT_SIZE);
+
+ tcb->xcp.regs[REG_A1] = (uint32_t)tcb->xcp.regs +
+ XCPTCONTEXT_SIZE;
/* Then set up to vector to the trampoline with interrupts
* disabled
*/
@@ -250,7 +268,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
/* Now tcb on the other CPU can be accessed safely */
- /* Copy tcb->xcp.regs to tcp.xcp.saved. These will be
+ /* Copy tcb->xcp.regs to tcp.xcp.saved_regs. These will be
* restored by the signal trampoline after the signal has
* been delivered.
*
@@ -258,8 +276,21 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
*/
tcb->xcp.sigdeliver = sigdeliver;
- tcb->xcp.saved_pc = tcb->xcp.regs[REG_PC];
- tcb->xcp.saved_ps = tcb->xcp.regs[REG_PS];
+ tcb->xcp.saved_regs = tcb->xcp.regs;
+
+ /* Duplicate the register context. These will be
+ * restored by the signal trampoline after the signal has
+ * been delivered.
+ */
+
+ tcb->xcp.regs = (void *)
+ ((uint32_t)tcb->xcp.regs -
+ (uint32_t)XCPTCONTEXT_SIZE);
+ memcpy(tcb->xcp.regs, tcb->xcp.saved_regs,
+ XCPTCONTEXT_SIZE);
+
+ tcb->xcp.regs[REG_A1] = (uint32_t)tcb->xcp.regs +
+ (uint32_t)XCPTCONTEXT_SIZE;
/* Then set up to vector to the trampoline with interrupts
* disabled
@@ -278,7 +309,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
{
/* tcb is running on the same CPU */
- /* Copy tcb->xcp.regs to tcp.xcp.saved. These will be
+ /* Copy tcb->xcp.regs to tcp.xcp.saved_regs. These will be
* restored by the signal trampoline after the signal has
* been delivered.
*
@@ -286,8 +317,21 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
*/
tcb->xcp.sigdeliver = sigdeliver;
- tcb->xcp.saved_pc = CURRENT_REGS[REG_PC];
- tcb->xcp.saved_ps = CURRENT_REGS[REG_PS];
+ xtensa_savestate(tcb->xcp.saved_regs);
+
+ /* Duplicate the register context. These will be
+ * restored by the signal trampoline after the signal has
+ * been delivered.
+ */
+
+ CURRENT_REGS = (void *)
+ ((uint32_t)CURRENT_REGS -
+ (uint32_t)XCPTCONTEXT_SIZE);
+ memcpy((uint32_t *)CURRENT_REGS, tcb->xcp.saved_regs,
+ XCPTCONTEXT_SIZE);
+
+ CURRENT_REGS[REG_A1] = (uint32_t)CURRENT_REGS +
+ (uint32_t)XCPTCONTEXT_SIZE;
/* Then set up to vector to the trampoline with interrupts
* disabled
@@ -301,11 +345,6 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
CURRENT_REGS[REG_PS] = (uint32_t)
(PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM | PS_WOE);
#endif
- /* And make sure that the saved context in the TCB is the
- * same as the interrupt return context.
- */
-
- xtensa_savestate(tcb->xcp.regs);
}
/* Increment the IRQ lock count so that when the task is
@@ -338,15 +377,27 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
else
{
- /* Save the return pc and ps. These will be restored by the
+ /* Save the context registers. These will be restored by the
* signal trampoline after the signals have been delivered.
*
* NOTE: that hi-priority interrupts are not disabled.
*/
- tcb->xcp.sigdeliver = sigdeliver;
- tcb->xcp.saved_pc = tcb->xcp.regs[REG_PC];
- tcb->xcp.saved_ps = tcb->xcp.regs[REG_PS];
+ tcb->xcp.sigdeliver = sigdeliver;
+ tcb->xcp.saved_regs = tcb->xcp.regs;
+
+ /* Duplicate the register context. These will be
+ * restored by the signal trampoline after the signal has been
+ * delivered.
+ */
+
+ tcb->xcp.regs = (void *)
+ ((uint32_t)tcb->xcp.regs -
+ (uint32_t)XCPTCONTEXT_SIZE);
+ memcpy(tcb->xcp.regs, tcb->xcp.saved_regs, XCPTCONTEXT_SIZE);
+
+ tcb->xcp.regs[REG_A1] = (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/xtensa/src/common/xtensa_sigdeliver.c b/arch/xtensa/src/common/xtensa_sigdeliver.c
index b07f4fd4b2..9bc8013c30 100644
--- a/arch/xtensa/src/common/xtensa_sigdeliver.c
+++ b/arch/xtensa/src/common/xtensa_sigdeliver.c
@@ -54,7 +54,7 @@
void xtensa_sig_deliver(void)
{
struct tcb_s *rtcb = this_task();
- uint32_t regs[XCPTCONTEXT_REGS];
+ uint32_t *regs = rtcb->xcp.saved_regs;
#ifdef CONFIG_SMP
/* In the SMP case, we must terminate the critical section while the signal
@@ -71,10 +71,6 @@ void xtensa_sig_deliver(void)
rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head);
DEBUGASSERT(rtcb->xcp.sigdeliver != NULL);
- /* Save the return state on the stack. */
-
- xtensa_copystate(regs, rtcb->xcp.regs);
-
#ifdef CONFIG_SMP
/* In the SMP case, up_schedule_sigaction(0) will have incremented
* 'irqcount' in order to force us into a critical section. Save the
@@ -141,8 +137,6 @@ void xtensa_sig_deliver(void)
* could be modified by a hostile program.
*/
- regs[REG_PC] = rtcb->xcp.saved_pc;
- regs[REG_PS] = rtcb->xcp.saved_ps;
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
/* Issue:
@@ -184,5 +178,5 @@ void xtensa_sig_deliver(void)
*/
board_autoled_off(LED_SIGNAL);
- xtensa_context_restore(regs);
+ xtensa_context_restore(®s);
}
diff --git a/arch/xtensa/src/common/xtensa_swint.c b/arch/xtensa/src/common/xtensa_swint.c
index 42c0ef6aa7..d9a69927d7 100644
--- a/arch/xtensa/src/common/xtensa_swint.c
+++ b/arch/xtensa/src/common/xtensa_swint.c
@@ -103,7 +103,7 @@ int xtensa_swint(int irq, void *context, void *arg)
case SYS_save_context:
{
DEBUGASSERT(regs[REG_A3] != 0);
- memcpy((uint32_t *)regs[REG_A3], regs, (4 * XCPTCONTEXT_REGS));
+ memcpy(*(uint32_t **)regs[REG_A3], regs, XCPTCONTEXT_SIZE);
#if XCHAL_CP_NUM > 0
cpstate = (uintptr_t)regs[REG_A3] + cpstate_off;
xtensa_coproc_savestate((struct xtensa_cpstate_s *)cpstate);
@@ -132,7 +132,7 @@ int xtensa_swint(int irq, void *context, void *arg)
case SYS_restore_context:
{
DEBUGASSERT(regs[REG_A3] != 0);
- CURRENT_REGS = (uint32_t *)regs[REG_A3];
+ CURRENT_REGS = *(uint32_t **)regs[REG_A3];
#if XCHAL_CP_NUM > 0
cpstate = (uintptr_t)regs[REG_A3] + cpstate_off;
xtensa_coproc_restorestate((struct xtensa_cpstate_s *)cpstate);
@@ -161,8 +161,7 @@ int xtensa_swint(int irq, void *context, void *arg)
case SYS_switch_context:
{
DEBUGASSERT(regs[REG_A3] != 0 && regs[REG_A4] != 0);
-
- memcpy((uint32_t *)regs[REG_A3], regs, (4 * XCPTCONTEXT_REGS));
+ *(uint32_t **)regs[REG_A3] = regs;
CURRENT_REGS = (uint32_t *)regs[REG_A4];
}
diff --git a/arch/xtensa/src/common/xtensa_unblocktask.c b/arch/xtensa/src/common/xtensa_unblocktask.c
index 4d975fbbd1..c1bcf7afb5 100644
--- a/arch/xtensa/src/common/xtensa_unblocktask.c
+++ b/arch/xtensa/src/common/xtensa_unblocktask.c
@@ -125,7 +125,7 @@ void up_unblock_task(struct tcb_s *tcb)
* ready to run list.
*/
- xtensa_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
+ xtensa_switchcontext(&rtcb->xcp.regs, nexttcb->xcp.regs);
/* xtensa_switchcontext forces a context switch to the task at the
* head of the ready-to-run list. It does not 'return' in the
diff --git a/arch/xtensa/src/esp32/Make.defs b/arch/xtensa/src/esp32/Make.defs
index 3e084afa09..1161e8bfe4 100644
--- a/arch/xtensa/src/esp32/Make.defs
+++ b/arch/xtensa/src/esp32/Make.defs
@@ -31,7 +31,7 @@ HEAD_CSRC = esp32_start.c esp32_wdt.c
CMN_ASRCS = xtensa_context.S xtensa_coproc.S xtensa_cpuint.S xtensa_panic.S
CMN_ASRCS += xtensa_sigtramp.S
-CMN_CSRCS = xtensa_assert.c xtensa_blocktask.c xtensa_copystate.c
+CMN_CSRCS = xtensa_assert.c xtensa_blocktask.c
CMN_CSRCS += xtensa_cpenable.c xtensa_createstack.c xtensa_exit.c
CMN_CSRCS += xtensa_initialize.c xtensa_initialstate.c xtensa_interruptcontext.c
CMN_CSRCS += xtensa_irqdispatch.c xtensa_lowputs.c xtensa_mdelay.c
diff --git a/arch/xtensa/src/esp32/esp32_cpustart.c b/arch/xtensa/src/esp32/esp32_cpustart.c
index 6a9fe3ee40..bc54defc08 100644
--- a/arch/xtensa/src/esp32/esp32_cpustart.c
+++ b/arch/xtensa/src/esp32/esp32_cpustart.c
@@ -135,7 +135,8 @@ void IRAM_ATTR xtensa_appcpu_start(void)
* is to switch to a well-known IDLE thread stack.
*/
- sp = (uint32_t)tcb->stack_base_ptr + tcb->adj_stack_size;
+ sp = (uint32_t)tcb->stack_base_ptr + tcb->adj_stack_size -
+ XCPTCONTEXT_SIZE;
__asm__ __volatile__("mov sp, %0\n" : : "r"(sp));
sinfo("CPU%d Started\n", up_cpu_index());
@@ -208,7 +209,7 @@ void IRAM_ATTR xtensa_appcpu_start(void)
* be the CPUs NULL task.
*/
- xtensa_context_restore(tcb->xcp.regs);
+ xtensa_context_restore(&tcb->xcp.regs);
}
/****************************************************************************
diff --git a/arch/xtensa/src/esp32s2/Make.defs b/arch/xtensa/src/esp32s2/Make.defs
index 5cb84c637d..6e40fa7b4d 100644
--- a/arch/xtensa/src/esp32s2/Make.defs
+++ b/arch/xtensa/src/esp32s2/Make.defs
@@ -31,7 +31,7 @@ HEAD_CSRC = esp32s2_start.c esp32s2_wdt.c
CMN_ASRCS = xtensa_context.S xtensa_coproc.S xtensa_cpuint.S xtensa_panic.S
CMN_ASRCS += xtensa_sigtramp.S
-CMN_CSRCS = xtensa_assert.c xtensa_blocktask.c xtensa_copystate.c
+CMN_CSRCS = xtensa_assert.c xtensa_blocktask.c
CMN_CSRCS += xtensa_cpenable.c xtensa_createstack.c xtensa_exit.c
CMN_CSRCS += xtensa_initialize.c xtensa_initialstate.c xtensa_interruptcontext.c
CMN_CSRCS += xtensa_irqdispatch.c xtensa_lowputs.c xtensa_mdelay.c
diff --git a/arch/xtensa/src/esp32s3/Make.defs b/arch/xtensa/src/esp32s3/Make.defs
index cd5373e5c5..8987a2b6b9 100644
--- a/arch/xtensa/src/esp32s3/Make.defs
+++ b/arch/xtensa/src/esp32s3/Make.defs
@@ -31,7 +31,7 @@ HEAD_CSRC = esp32s3_start.c
CMN_ASRCS = xtensa_context.S xtensa_coproc.S xtensa_cpuint.S xtensa_panic.S
CMN_ASRCS += xtensa_sigtramp.S
-CMN_CSRCS = xtensa_assert.c xtensa_blocktask.c xtensa_copystate.c
+CMN_CSRCS = xtensa_assert.c xtensa_blocktask.c
CMN_CSRCS += xtensa_cpenable.c xtensa_createstack.c xtensa_exit.c
CMN_CSRCS += xtensa_initialize.c xtensa_initialstate.c xtensa_interruptcontext.c
CMN_CSRCS += xtensa_irqdispatch.c xtensa_lowputs.c xtensa_mdelay.c
diff --git a/arch/xtensa/src/esp32s3/esp32s3_cpustart.c b/arch/xtensa/src/esp32s3/esp32s3_cpustart.c
index 6c424fb6b5..b907b06692 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_cpustart.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_cpustart.c
@@ -115,7 +115,8 @@ void xtensa_appcpu_start(void)
* is to switch to a well-known IDLE thread stack.
*/
- sp = (uint32_t)tcb->stack_base_ptr + tcb->adj_stack_size;
+ sp = (uint32_t)tcb->stack_base_ptr + tcb->adj_stack_size -
+ XCPTCONTEXT_SIZE;
__asm__ __volatile__("mov sp, %0\n" : : "r"(sp));
sinfo("CPU%d Started\n", up_cpu_index());
@@ -168,7 +169,7 @@ void xtensa_appcpu_start(void)
* be the CPUs NULL task.
*/
- xtensa_context_restore(tcb->xcp.regs);
+ xtensa_context_restore(&tcb->xcp.regs);
}
/****************************************************************************