arch/risc-v: Improve performance of context switch

Signed-off-by: Huang Qi <huangqi3@xiaomi.com>
This commit is contained in:
Huang Qi 2022-03-10 23:12:50 +08:00 committed by Masayuki Ishikawa
parent b59dd92528
commit 494230a841
24 changed files with 166 additions and 137 deletions

View File

@ -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__ */

View File

@ -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) \

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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++;
}
}
}

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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