arch/xtensa: Replace the xcp context with stack context to improve context switching
Signed-off-by: Abdelatif Guettouche <abdelatif.guettouche@espressif.com>
This commit is contained in:
parent
e674d5cb86
commit
da273fce0b
@ -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 */
|
||||
|
@ -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)
|
||||
|
@ -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 ***************************************/
|
||||
|
||||
|
@ -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
|
||||
|
@ -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++;
|
||||
}
|
||||
}
|
||||
}
|
@ -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) */
|
||||
|
@ -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.
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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];
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
Loading…
Reference in New Issue
Block a user