arch/risc-v: Improve performance of context switch
Signed-off-by: Huang Qi <huangqi3@xiaomi.com>
This commit is contained in:
parent
b59dd92528
commit
494230a841
@ -498,8 +498,7 @@ struct xcptcontext
|
||||
* another signal handler is executing will be ignored!
|
||||
*/
|
||||
|
||||
uintptr_t saved_epc; /* Trampoline PC */
|
||||
uintptr_t saved_int_ctx; /* Interrupt context with interrupts disabled. */
|
||||
uintptr_t *saved_regs;
|
||||
|
||||
#ifndef CONFIG_BUILD_FLAT
|
||||
/* This is the saved address to use when returning from a user-space
|
||||
@ -537,7 +536,7 @@ struct xcptcontext
|
||||
|
||||
/* Register save area */
|
||||
|
||||
uintptr_t regs[XCPTCONTEXT_REGS];
|
||||
uintptr_t *regs;
|
||||
};
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
@ -74,7 +74,7 @@
|
||||
|
||||
/* SYS call 2:
|
||||
*
|
||||
* void riscv_switchcontext(uintptr_t *saveregs, uintptr_t *restoreregs);
|
||||
* void riscv_switchcontext(uintptr_t **saveregs, uintptr_t *restoreregs);
|
||||
*/
|
||||
|
||||
#define SYS_switch_context (2)
|
||||
@ -150,7 +150,7 @@
|
||||
|
||||
/* SYS call 2:
|
||||
*
|
||||
* void riscv_switchcontext(uintptr_t *saveregs, uintptr_t *restoreregs);
|
||||
* void riscv_switchcontext(uintptr_t **saveregs, uintptr_t *restoreregs);
|
||||
*/
|
||||
|
||||
#define riscv_switchcontext(saveregs, restoreregs) \
|
||||
|
@ -30,7 +30,7 @@ CMN_CSRCS += riscv_initialize.c riscv_swint.c
|
||||
CMN_CSRCS += riscv_createstack.c riscv_exit.c
|
||||
CMN_CSRCS += riscv_assert.c riscv_blocktask.c riscv_copystate.c riscv_initialstate.c
|
||||
CMN_CSRCS += riscv_interruptcontext.c riscv_modifyreg32.c riscv_puts.c riscv_mdelay.c
|
||||
CMN_CSRCS += riscv_releasepending.c riscv_reprioritizertr.c riscv_copyfullstate.c
|
||||
CMN_CSRCS += riscv_releasepending.c riscv_reprioritizertr.c
|
||||
CMN_CSRCS += riscv_releasestack.c riscv_stackframe.c riscv_schedulesigaction.c
|
||||
CMN_CSRCS += riscv_sigdeliver.c riscv_udelay.c riscv_unblocktask.c riscv_usestack.c
|
||||
CMN_CSRCS += riscv_idle.c riscv_tcbinfo.c riscv_getnewintctx.c
|
||||
|
@ -33,7 +33,7 @@ CMN_CSRCS += riscv_interruptcontext.c riscv_modifyreg32.c riscv_puts.c
|
||||
CMN_CSRCS += riscv_releasepending.c riscv_reprioritizertr.c
|
||||
CMN_CSRCS += riscv_releasestack.c riscv_stackframe.c riscv_schedulesigaction.c
|
||||
CMN_CSRCS += riscv_sigdeliver.c riscv_unblocktask.c riscv_usestack.c
|
||||
CMN_CSRCS += riscv_mdelay.c riscv_copyfullstate.c riscv_idle.c
|
||||
CMN_CSRCS += riscv_mdelay.c riscv_idle.c
|
||||
CMN_CSRCS += riscv_tcbinfo.c riscv_getnewintctx.c
|
||||
|
||||
ifeq ($(CONFIG_SCHED_BACKTRACE),y)
|
||||
|
@ -151,7 +151,7 @@ void up_block_task(struct tcb_s *tcb, tstate_t task_state)
|
||||
|
||||
/* Then switch contexts */
|
||||
|
||||
riscv_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
|
||||
riscv_switchcontext(&rtcb->xcp.regs, nexttcb->xcp.regs);
|
||||
|
||||
/* riscv_switchcontext forces a context switch to the task at the
|
||||
* head of the ready-to-run list. It does not 'return' in the
|
||||
|
@ -1,62 +0,0 @@
|
||||
/****************************************************************************
|
||||
* arch/risc-v/src/common/riscv_copyfullstate.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 "riscv_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: riscv_copyfullstate
|
||||
*
|
||||
* Description:
|
||||
* Copy the entire register save area (including the floating point
|
||||
* registers if applicable). This is a little faster than most memcpy's
|
||||
* since it does 32-bit transfers.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void riscv_copyfullstate(uintptr_t *dest, uintptr_t *src)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* In the RV32 targets, 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++;
|
||||
}
|
||||
}
|
||||
}
|
@ -119,12 +119,25 @@ exception_common:
|
||||
la sp, g_intstacktop
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/* Call interrupt handler in C */
|
||||
|
||||
jal x1, riscv_dispatch_irq
|
||||
|
||||
#else
|
||||
/* Reserve some space for CURRENT_REGS if interrupt stack disabled */
|
||||
|
||||
addi sp, sp, -XCPTCONTEXT_SIZE
|
||||
|
||||
/* Call interrupt handler in C */
|
||||
|
||||
jal x1, riscv_dispatch_irq
|
||||
|
||||
/* Restore sp */
|
||||
|
||||
addi sp, sp, XCPTCONTEXT_SIZE
|
||||
#endif
|
||||
|
||||
|
||||
/* If context switch is needed, return a new sp */
|
||||
|
||||
mv sp, a0
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <arch/irq.h>
|
||||
|
||||
#include "riscv_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -55,6 +56,10 @@ void up_initial_state(struct tcb_s *tcb)
|
||||
struct xcptcontext *xcp = &tcb->xcp;
|
||||
uintptr_t regval;
|
||||
|
||||
/* Initialize the initial exception register context structure */
|
||||
|
||||
memset(xcp, 0, sizeof(struct xcptcontext));
|
||||
|
||||
/* Initialize the idle thread stack */
|
||||
|
||||
if (tcb->pid == IDLE_PROCESS_ID)
|
||||
@ -72,11 +77,13 @@ void up_initial_state(struct tcb_s *tcb)
|
||||
|
||||
riscv_stack_color(tcb->stack_alloc_ptr, 0);
|
||||
#endif /* CONFIG_STACK_COLORATION */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Initialize the initial exception register context structure */
|
||||
xcp->regs = (uintptr_t *)(
|
||||
(uintptr_t)tcb->stack_base_ptr + tcb->adj_stack_size - XCPTCONTEXT_SIZE);
|
||||
|
||||
memset(xcp, 0, sizeof(struct xcptcontext));
|
||||
memset(xcp->regs, 0, XCPTCONTEXT_SIZE);
|
||||
|
||||
/* Save the initial stack pointer. Hmmm.. the stack is set to the very
|
||||
* beginning of the stack region. Some functions may want to store data on
|
||||
|
@ -68,7 +68,11 @@
|
||||
* only a referenced is passed to get the state from the TCB.
|
||||
*/
|
||||
|
||||
#define riscv_savestate(regs) riscv_copystate(regs, (uintptr_t*)CURRENT_REGS)
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
#define riscv_savestate(regs) (regs = (uintptr_t *)CURRENT_REGS, riscv_savefpu(regs))
|
||||
#else
|
||||
#define riscv_savestate(regs) (regs = (uintptr_t *)CURRENT_REGS)
|
||||
#endif
|
||||
#define riscv_restorestate(regs) (CURRENT_REGS = regs)
|
||||
|
||||
#define _START_TEXT &_stext
|
||||
@ -193,7 +197,6 @@ void riscv_addregion(void);
|
||||
void riscv_ack_irq(int irq);
|
||||
|
||||
void riscv_copystate(uintptr_t *dest, uintptr_t *src);
|
||||
void riscv_copyfullstate(uintptr_t *dest, uintptr_t *src);
|
||||
|
||||
void riscv_sigdeliver(void);
|
||||
int riscv_swint(int irq, void *context, void *arg);
|
||||
|
@ -122,7 +122,7 @@ void up_release_pending(void)
|
||||
|
||||
/* Then switch contexts */
|
||||
|
||||
riscv_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
|
||||
riscv_switchcontext(&rtcb->xcp.regs, nexttcb->xcp.regs);
|
||||
|
||||
/* riscv_switchcontext forces a context switch to the task at the
|
||||
* head of the ready-to-run list. It does not 'return' in the
|
||||
|
@ -174,7 +174,7 @@ void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
|
||||
|
||||
/* Then switch contexts */
|
||||
|
||||
riscv_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
|
||||
riscv_switchcontext(&rtcb->xcp.regs, nexttcb->xcp.regs);
|
||||
|
||||
/* riscv_switchcontext forces a context switch to the task at
|
||||
* the head of the ready-to-run list. It does not 'return' in
|
||||
|
@ -35,6 +35,7 @@
|
||||
|
||||
#include "sched/sched.h"
|
||||
#include "riscv_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -120,22 +121,33 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
|
||||
|
||||
else
|
||||
{
|
||||
/* Save the return EPC and STATUS registers. These will be
|
||||
/* Save the context registers. These will be
|
||||
* restored by the signal trampoline after the signals have
|
||||
* been delivered.
|
||||
*/
|
||||
|
||||
tcb->xcp.sigdeliver = sigdeliver;
|
||||
tcb->xcp.saved_epc = CURRENT_REGS[REG_EPC];
|
||||
tcb->xcp.saved_int_ctx = CURRENT_REGS[REG_INT_CTX];
|
||||
tcb->xcp.saved_regs = (uintptr_t *)CURRENT_REGS;
|
||||
|
||||
riscv_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 = (uintptr_t *)((uintptr_t)CURRENT_REGS -
|
||||
XCPTCONTEXT_SIZE);
|
||||
|
||||
memcpy((uintptr_t *)CURRENT_REGS, tcb->xcp.saved_regs,
|
||||
XCPTCONTEXT_SIZE);
|
||||
|
||||
/* Then set up to vector to the trampoline with interrupts
|
||||
* disabled. The kernel-space trampoline must run in
|
||||
* privileged thread mode.
|
||||
*/
|
||||
|
||||
CURRENT_REGS[REG_EPC] = (uintptr_t)riscv_sigdeliver;
|
||||
|
||||
tcb->xcp.sigdeliver = sigdeliver;
|
||||
CURRENT_REGS[REG_EPC] = (uintptr_t)riscv_sigdeliver;
|
||||
int_ctx = CURRENT_REGS[REG_INT_CTX];
|
||||
int_ctx &= ~MSTATUS_MPIE;
|
||||
#ifndef CONFIG_BUILD_FLAT
|
||||
@ -144,15 +156,13 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
|
||||
|
||||
CURRENT_REGS[REG_INT_CTX] = int_ctx;
|
||||
|
||||
/* And make sure that the saved context in the TCB
|
||||
* is the same as the interrupt return context.
|
||||
*/
|
||||
|
||||
riscv_savestate(tcb->xcp.regs);
|
||||
CURRENT_REGS[REG_SP] = (uintptr_t)CURRENT_REGS +
|
||||
XCPTCONTEXT_SIZE;
|
||||
|
||||
sinfo("PC/STATUS Saved: %" PRIxREG "/%" PRIxREG
|
||||
" New: %" PRIxREG "/%" PRIxREG "\n",
|
||||
tcb->xcp.saved_epc, tcb->xcp.saved_int_ctx,
|
||||
tcb->xcp.saved_regs[REG_EPC],
|
||||
tcb->xcp.saved_regs[REG_INT_CTX],
|
||||
CURRENT_REGS[REG_EPC], CURRENT_REGS[REG_INT_CTX]);
|
||||
}
|
||||
}
|
||||
@ -170,17 +180,26 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
|
||||
* been delivered.
|
||||
*/
|
||||
|
||||
tcb->xcp.sigdeliver = sigdeliver;
|
||||
tcb->xcp.saved_epc = tcb->xcp.regs[REG_EPC];
|
||||
tcb->xcp.saved_int_ctx = tcb->xcp.regs[REG_INT_CTX];
|
||||
tcb->xcp.sigdeliver = sigdeliver;
|
||||
|
||||
/* Then set up to vector to the trampoline with interrupts
|
||||
* disabled. We must already be in privileged thread mode to be
|
||||
* here.
|
||||
/* Save the current register context location */
|
||||
|
||||
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[REG_EPC] = (uintptr_t)riscv_sigdeliver;
|
||||
tcb->xcp.regs = (uintptr_t *)((uintptr_t)tcb->xcp.regs -
|
||||
XCPTCONTEXT_SIZE);
|
||||
|
||||
memcpy(tcb->xcp.regs, tcb->xcp.saved_regs, XCPTCONTEXT_SIZE);
|
||||
|
||||
tcb->xcp.regs[REG_SP] = (uintptr_t)tcb->xcp.regs +
|
||||
XCPTCONTEXT_SIZE;
|
||||
|
||||
tcb->xcp.regs[REG_EPC] = (uintptr_t)riscv_sigdeliver;
|
||||
int_ctx = tcb->xcp.regs[REG_INT_CTX];
|
||||
int_ctx &= ~MSTATUS_MPIE;
|
||||
|
||||
@ -188,7 +207,8 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
|
||||
|
||||
sinfo("PC/STATUS Saved: %" PRIxREG "/%" PRIxREG
|
||||
" New: %" PRIxREG "/%" PRIxREG "\n",
|
||||
tcb->xcp.saved_epc, tcb->xcp.saved_int_ctx,
|
||||
tcb->xcp.saved_regs[REG_EPC],
|
||||
tcb->xcp.saved_regs[REG_INT_CTX],
|
||||
tcb->xcp.regs[REG_EPC], tcb->xcp.regs[REG_INT_CTX]);
|
||||
}
|
||||
}
|
||||
@ -265,34 +285,65 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
|
||||
* been delivered.
|
||||
*/
|
||||
|
||||
tcb->xcp.sigdeliver = (void *)sigdeliver;
|
||||
tcb->xcp.saved_epc = tcb->xcp.regs[REG_EPC];
|
||||
tcb->xcp.saved_int_ctx = tcb->xcp.regs[REG_INT_CTX];
|
||||
tcb->xcp.sigdeliver = sigdeliver;
|
||||
|
||||
/* Then set up vector to the trampoline with interrupts
|
||||
* disabled. We must already be in privileged thread mode
|
||||
* to be here.
|
||||
*/
|
||||
|
||||
tcb->xcp.regs[REG_EPC] = (uintptr_t)riscv_sigdeliver;
|
||||
/* Save the current register context location */
|
||||
|
||||
int_ctx = tcb->xcp.regs[REG_INT_CTX];
|
||||
int_ctx &= ~MSTATUS_MPIE;
|
||||
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 = (uintptr_t *)((uintptr_t)tcb->xcp.regs -
|
||||
XCPTCONTEXT_SIZE);
|
||||
|
||||
memcpy(tcb->xcp.regs, tcb->xcp.saved_regs,
|
||||
XCPTCONTEXT_SIZE);
|
||||
|
||||
tcb->xcp.regs[REG_SP] = (uintptr_t)tcb->xcp.regs +
|
||||
XCPTCONTEXT_SIZE;
|
||||
|
||||
tcb->xcp.regs[REG_EPC] = (uintptr_t)riscv_sigdeliver;
|
||||
int_ctx = tcb->xcp.regs[REG_INT_CTX];
|
||||
int_ctx &= ~MSTATUS_MPIE;
|
||||
#ifdef CONFIG_BUILD_PROTECTED
|
||||
int_ctx |= MSTATUS_MPPM;
|
||||
#endif
|
||||
tcb->xcp.regs[REG_INT_CTX] = int_ctx;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* tcb is running on the same CPU */
|
||||
|
||||
/* Save the return EPC and STATUS registers. These will be
|
||||
/* Save the context registers. These will be
|
||||
* restored by the signal trampoline after the signal has
|
||||
* been delivered.
|
||||
*/
|
||||
|
||||
tcb->xcp.sigdeliver = (void *)sigdeliver;
|
||||
tcb->xcp.saved_epc = CURRENT_REGS[REG_EPC];
|
||||
tcb->xcp.saved_int_ctx = CURRENT_REGS[REG_INT_CTX];
|
||||
tcb->xcp.sigdeliver = (void *)sigdeliver;
|
||||
|
||||
tcb->xcp.saved_regs = (uintptr_t *)CURRENT_REGS;
|
||||
|
||||
/* Duplicate the register context. These will be
|
||||
* restored by the signal trampoline after the signal has
|
||||
* been delivered.
|
||||
*/
|
||||
|
||||
CURRENT_REGS = (uintptr_t *)((uintptr_t)CURRENT_REGS -
|
||||
XCPTCONTEXT_SIZE);
|
||||
|
||||
memcpy((uintptr_t *)CURRENT_REGS, tcb->xcp.saved_regs,
|
||||
XCPTCONTEXT_SIZE);
|
||||
|
||||
CURRENT_REGS[REG_SP] = (uintptr_t)CURRENT_REGS +
|
||||
XCPTCONTEXT_SIZE;
|
||||
|
||||
/* Then set up vector to the trampoline with interrupts
|
||||
* disabled. The kernel-space trampoline must run in
|
||||
@ -308,12 +359,6 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
|
||||
#endif
|
||||
|
||||
CURRENT_REGS[REG_INT_CTX] = int_ctx;
|
||||
|
||||
/* And make sure that the saved context in the TCB is the
|
||||
* same as the interrupt return context.
|
||||
*/
|
||||
|
||||
riscv_savestate(tcb->xcp.regs);
|
||||
}
|
||||
|
||||
/* Increment the IRQ lock count so that when the task is
|
||||
@ -351,8 +396,23 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
|
||||
*/
|
||||
|
||||
tcb->xcp.sigdeliver = (void *)sigdeliver;
|
||||
tcb->xcp.saved_epc = tcb->xcp.regs[REG_EPC];
|
||||
tcb->xcp.saved_int_ctx = tcb->xcp.regs[REG_INT_CTX];
|
||||
|
||||
/* Save the current register context location */
|
||||
|
||||
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 = (uintptr_t *)((uintptr_t)tcb->xcp.regs -
|
||||
XCPTCONTEXT_SIZE);
|
||||
|
||||
memcpy(tcb->xcp.regs, tcb->xcp.saved_regs, XCPTCONTEXT_SIZE);
|
||||
|
||||
tcb->xcp.regs[REG_SP] = (uintptr_t)tcb->xcp.regs +
|
||||
XCPTCONTEXT_SIZE;
|
||||
|
||||
/* Increment the IRQ lock count so that when the task is restarted,
|
||||
* it will hold the IRQ spinlock.
|
||||
|
@ -55,7 +55,7 @@
|
||||
void riscv_sigdeliver(void)
|
||||
{
|
||||
struct tcb_s *rtcb = this_task();
|
||||
uintptr_t regs[XCPTCONTEXT_REGS];
|
||||
uintptr_t *regs = rtcb->xcp.saved_regs;
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/* In the SMP case, we must terminate the critical section while the signal
|
||||
@ -72,10 +72,6 @@ void riscv_sigdeliver(void)
|
||||
rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head);
|
||||
DEBUGASSERT(rtcb->xcp.sigdeliver != NULL);
|
||||
|
||||
/* Save the return state on the stack. */
|
||||
|
||||
riscv_copyfullstate(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
|
||||
@ -142,8 +138,6 @@ void riscv_sigdeliver(void)
|
||||
* could be modified by a hostile program.
|
||||
*/
|
||||
|
||||
regs[REG_EPC] = rtcb->xcp.saved_epc;
|
||||
regs[REG_INT_CTX] = rtcb->xcp.saved_int_ctx;
|
||||
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
|
||||
|
||||
/* Then restore the correct state for this thread of
|
||||
|
@ -206,7 +206,7 @@ int riscv_swint(int irq, void *context, void *arg)
|
||||
/* A0=SYS_restore_context: This a restore context command:
|
||||
*
|
||||
* void
|
||||
* riscv_fullcontextrestore(uintptr_t *restoreregs) noreturn_function;
|
||||
* riscv_fullcontextrestore(uintptr_t *restoreregs) noreturn_function;
|
||||
*
|
||||
* At this point, the following values are saved in context:
|
||||
*
|
||||
@ -228,7 +228,8 @@ int riscv_swint(int irq, void *context, void *arg)
|
||||
|
||||
/* A0=SYS_switch_context: This a switch context command:
|
||||
*
|
||||
* void riscv_switchcontext(uintptr_t *saveregs, uintptr_t *restoreregs);
|
||||
* void
|
||||
* riscv_switchcontext(uintptr_t *saveregs, uintptr_t *restoreregs);
|
||||
*
|
||||
* At this point, the following values are saved in context:
|
||||
*
|
||||
@ -245,7 +246,10 @@ int riscv_swint(int irq, void *context, void *arg)
|
||||
case SYS_switch_context:
|
||||
{
|
||||
DEBUGASSERT(regs[REG_A1] != 0 && regs[REG_A2] != 0);
|
||||
riscv_copystate((uintptr_t *)regs[REG_A1], regs);
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
riscv_savefpu(regs);
|
||||
#endif
|
||||
*(uintptr_t **)regs[REG_A1] = (uintptr_t *)regs;
|
||||
CURRENT_REGS = (uintptr_t *)regs[REG_A2];
|
||||
}
|
||||
break;
|
||||
|
@ -137,7 +137,7 @@ void up_unblock_task(struct tcb_s *tcb)
|
||||
|
||||
/* Then switch contexts */
|
||||
|
||||
riscv_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs);
|
||||
riscv_switchcontext(&rtcb->xcp.regs, nexttcb->xcp.regs);
|
||||
|
||||
/* riscv_switchcontext forces a context switch to the task at the
|
||||
* head of the ready-to-run list. It does not 'return' in the
|
||||
|
@ -33,7 +33,7 @@ CMN_CSRCS += riscv_initialize.c riscv_swint.c
|
||||
CMN_CSRCS += riscv_allocateheap.c riscv_createstack.c riscv_exit.c riscv_exception.c
|
||||
CMN_CSRCS += riscv_assert.c riscv_blocktask.c riscv_copystate.c riscv_initialstate.c
|
||||
CMN_CSRCS += riscv_interruptcontext.c riscv_modifyreg32.c riscv_puts.c riscv_mdelay.c
|
||||
CMN_CSRCS += riscv_releasepending.c riscv_reprioritizertr.c riscv_copyfullstate.c
|
||||
CMN_CSRCS += riscv_releasepending.c riscv_reprioritizertr.c
|
||||
CMN_CSRCS += riscv_releasestack.c riscv_stackframe.c riscv_schedulesigaction.c
|
||||
CMN_CSRCS += riscv_sigdeliver.c riscv_udelay.c riscv_unblocktask.c riscv_usestack.c
|
||||
CMN_CSRCS += riscv_tcbinfo.c riscv_getnewintctx.c
|
||||
|
@ -30,7 +30,7 @@ CMN_CSRCS += riscv_initialize.c riscv_swint.c
|
||||
CMN_CSRCS += riscv_allocateheap.c riscv_createstack.c riscv_exit.c
|
||||
CMN_CSRCS += riscv_assert.c riscv_blocktask.c riscv_copystate.c riscv_initialstate.c
|
||||
CMN_CSRCS += riscv_interruptcontext.c riscv_modifyreg32.c riscv_puts.c riscv_mdelay.c
|
||||
CMN_CSRCS += riscv_releasepending.c riscv_reprioritizertr.c riscv_copyfullstate.c
|
||||
CMN_CSRCS += riscv_releasepending.c riscv_reprioritizertr.c
|
||||
CMN_CSRCS += riscv_releasestack.c riscv_stackframe.c riscv_schedulesigaction.c
|
||||
CMN_CSRCS += riscv_sigdeliver.c riscv_udelay.c riscv_unblocktask.c riscv_usestack.c
|
||||
CMN_CSRCS += riscv_idle.c riscv_tcbinfo.c riscv_getnewintctx.c
|
||||
|
@ -33,7 +33,7 @@ CMN_CSRCS += riscv_interruptcontext.c riscv_modifyreg32.c riscv_puts.c
|
||||
CMN_CSRCS += riscv_releasepending.c riscv_reprioritizertr.c
|
||||
CMN_CSRCS += riscv_releasestack.c riscv_stackframe.c riscv_schedulesigaction.c
|
||||
CMN_CSRCS += riscv_sigdeliver.c riscv_unblocktask.c riscv_usestack.c
|
||||
CMN_CSRCS += riscv_mdelay.c riscv_copyfullstate.c riscv_idle.c
|
||||
CMN_CSRCS += riscv_mdelay.c riscv_idle.c
|
||||
CMN_CSRCS += riscv_tcbinfo.c riscv_cpuidlestack.c riscv_getnewintctx.c
|
||||
|
||||
ifeq ($(CONFIG_SMP), y)
|
||||
|
@ -73,9 +73,14 @@ __start:
|
||||
|
||||
ld sp, 0(t0)
|
||||
|
||||
/* sp (stack top) = sp + idle stack size */
|
||||
/*
|
||||
* sp (stack top) = sp + idle stack size - XCPTCONTEXT_SIZE
|
||||
*
|
||||
* Note: Reserve some space used by up_initial_state since we are already
|
||||
* running and using the per CPU idle stack.
|
||||
*/
|
||||
|
||||
li t0, CONFIG_IDLETHREAD_STACKSIZE
|
||||
li t0, STACK_ALIGN_UP(CONFIG_IDLETHREAD_STACKSIZE - XCPTCONTEXT_SIZE)
|
||||
add sp, sp, t0
|
||||
|
||||
2:
|
||||
|
@ -30,7 +30,7 @@ CMN_CSRCS += riscv_initialize.c riscv_swint.c
|
||||
CMN_CSRCS += riscv_allocateheap.c riscv_createstack.c riscv_exit.c
|
||||
CMN_CSRCS += riscv_assert.c riscv_blocktask.c riscv_copystate.c riscv_initialstate.c
|
||||
CMN_CSRCS += riscv_interruptcontext.c riscv_modifyreg32.c riscv_puts.c riscv_mdelay.c
|
||||
CMN_CSRCS += riscv_releasepending.c riscv_reprioritizertr.c riscv_copyfullstate.c
|
||||
CMN_CSRCS += riscv_releasepending.c riscv_reprioritizertr.c
|
||||
CMN_CSRCS += riscv_releasestack.c riscv_stackframe.c riscv_schedulesigaction.c
|
||||
CMN_CSRCS += riscv_sigdeliver.c riscv_udelay.c riscv_unblocktask.c riscv_usestack.c
|
||||
CMN_CSRCS += riscv_idle.c riscv_tcbinfo.c riscv_getnewintctx.c
|
||||
|
@ -30,7 +30,7 @@ CMN_CSRCS += riscv_interruptcontext.c riscv_modifyreg32.c riscv_puts.c
|
||||
CMN_CSRCS += riscv_releasepending.c riscv_reprioritizertr.c
|
||||
CMN_CSRCS += riscv_releasestack.c riscv_stackframe.c riscv_schedulesigaction.c
|
||||
CMN_CSRCS += riscv_sigdeliver.c riscv_unblocktask.c riscv_usestack.c
|
||||
CMN_CSRCS += riscv_mdelay.c riscv_udelay.c riscv_copyfullstate.c
|
||||
CMN_CSRCS += riscv_mdelay.c riscv_udelay.c
|
||||
CMN_CSRCS += riscv_idle.c riscv_tcbinfo.c riscv_getnewintctx.c
|
||||
CMN_CSRCS += riscv_cpuindex.c
|
||||
|
||||
|
@ -30,7 +30,7 @@ CMN_CSRCS += riscv_initialize.c riscv_swint.c
|
||||
CMN_CSRCS += riscv_allocateheap.c riscv_createstack.c riscv_exit.c
|
||||
CMN_CSRCS += riscv_assert.c riscv_blocktask.c riscv_copystate.c riscv_initialstate.c
|
||||
CMN_CSRCS += riscv_interruptcontext.c riscv_modifyreg32.c riscv_puts.c
|
||||
CMN_CSRCS += riscv_releasepending.c riscv_reprioritizertr.c riscv_copyfullstate.c
|
||||
CMN_CSRCS += riscv_releasepending.c riscv_reprioritizertr.c
|
||||
CMN_CSRCS += riscv_releasestack.c riscv_stackframe.c riscv_schedulesigaction.c
|
||||
CMN_CSRCS += riscv_sigdeliver.c riscv_unblocktask.c riscv_usestack.c
|
||||
CMN_CSRCS += riscv_idle.c riscv_tcbinfo.c riscv_cpuidlestack.c
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <arch/irq.h>
|
||||
|
||||
#include "chip.h"
|
||||
#include "riscv_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Symbols
|
||||
@ -77,9 +78,14 @@ __start:
|
||||
ld sp, 0(t0)
|
||||
#endif
|
||||
|
||||
/* sp (stack top) = sp + idle stack size */
|
||||
/*
|
||||
* sp (stack top) = sp + idle stack size - XCPTCONTEXT_SIZE
|
||||
*
|
||||
* Note: Reserve some space used by up_initial_state since we are already
|
||||
* running and using the per CPU idle stack.
|
||||
*/
|
||||
|
||||
li t0, CONFIG_IDLETHREAD_STACKSIZE
|
||||
li t0, STACK_ALIGN_UP(CONFIG_IDLETHREAD_STACKSIZE - XCPTCONTEXT_SIZE)
|
||||
add sp, sp, t0
|
||||
|
||||
2:
|
||||
|
@ -30,7 +30,7 @@ CMN_CSRCS += riscv_initialize.c riscv_swint.c
|
||||
CMN_CSRCS += riscv_allocateheap.c riscv_createstack.c riscv_exit.c
|
||||
CMN_CSRCS += riscv_assert.c riscv_blocktask.c riscv_copystate.c riscv_initialstate.c
|
||||
CMN_CSRCS += riscv_interruptcontext.c riscv_modifyreg32.c riscv_puts.c
|
||||
CMN_CSRCS += riscv_releasepending.c riscv_reprioritizertr.c riscv_copyfullstate.c
|
||||
CMN_CSRCS += riscv_releasepending.c riscv_reprioritizertr.c
|
||||
CMN_CSRCS += riscv_releasestack.c riscv_stackframe.c riscv_schedulesigaction.c
|
||||
CMN_CSRCS += riscv_sigdeliver.c riscv_unblocktask.c riscv_usestack.c
|
||||
CMN_CSRCS += riscv_idle.c riscv_tcbinfo.c riscv_getnewintctx.c
|
||||
|
Loading…
Reference in New Issue
Block a user