forked from nuttx/nuttx-update
riscv: syscall SYS_switch_context and SYS_restore_context use 0 para
reason: simplify context switch sys_call0(SYS_switch_context) sys_call0(SYS_restore_context) size nuttx before text data bss dec hex filename 148021 921 26944 175886 2af0e nuttx after text data bss dec hex filename 147995 921 26928 175844 2aee4 nuttx size reduce -42 Signed-off-by: hujun5 <hujun5@xiaomi.com>
This commit is contained in:
parent
08139fb1db
commit
3c32517b94
6 changed files with 30 additions and 73 deletions
|
@ -65,14 +65,14 @@
|
||||||
|
|
||||||
/* SYS call 1:
|
/* SYS call 1:
|
||||||
*
|
*
|
||||||
* void riscv_fullcontextrestore(uintptr_t *restoreregs) noreturn_function;
|
* void riscv_fullcontextrestore() noreturn_function;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define SYS_restore_context (1)
|
#define SYS_restore_context (1)
|
||||||
|
|
||||||
/* SYS call 2:
|
/* SYS call 2:
|
||||||
*
|
*
|
||||||
* void riscv_switchcontext(uintptr_t **saveregs, uintptr_t *restoreregs);
|
* void riscv_switchcontext();
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define SYS_switch_context (2)
|
#define SYS_switch_context (2)
|
||||||
|
|
|
@ -54,25 +54,17 @@
|
||||||
|
|
||||||
void up_exit(int status)
|
void up_exit(int status)
|
||||||
{
|
{
|
||||||
struct tcb_s *tcb = this_task();
|
|
||||||
|
|
||||||
/* Destroy the task at the head of the ready to run list. */
|
/* Destroy the task at the head of the ready to run list. */
|
||||||
|
|
||||||
nxtask_exit();
|
nxtask_exit();
|
||||||
|
|
||||||
/* Now, perform the context switch to the new ready-to-run task at the
|
|
||||||
* head of the list.
|
|
||||||
*/
|
|
||||||
|
|
||||||
tcb = this_task();
|
|
||||||
|
|
||||||
/* Scheduler parameters will update inside syscall */
|
/* Scheduler parameters will update inside syscall */
|
||||||
|
|
||||||
g_running_tasks[this_cpu()] = NULL;
|
g_running_tasks[this_cpu()] = NULL;
|
||||||
|
|
||||||
/* Then switch contexts */
|
/* Then switch contexts */
|
||||||
|
|
||||||
riscv_fullcontextrestore(tcb);
|
riscv_fullcontextrestore();
|
||||||
|
|
||||||
/* riscv_fullcontextrestore() should not return but could if the software
|
/* riscv_fullcontextrestore() should not return but could if the software
|
||||||
* interrupts are disabled.
|
* interrupts are disabled.
|
||||||
|
|
|
@ -486,36 +486,37 @@ void riscv_jump_to_user(uintptr_t entry, uintreg_t a0, uintreg_t a1,
|
||||||
* Name: riscv_fullcontextrestore
|
* Name: riscv_fullcontextrestore
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Restores the full context of the next task.
|
* Restores the full context.
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* next - Pointer to the next task control block.
|
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* None
|
* None
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#define riscv_fullcontextrestore(next) \
|
#define riscv_fullcontextrestore() \
|
||||||
sys_call1(SYS_restore_context, (uintptr_t)next)
|
do \
|
||||||
|
{ \
|
||||||
|
sys_call0(SYS_restore_context); \
|
||||||
|
} \
|
||||||
|
while (1)
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: riscv_switchcontext
|
* Name: riscv_switchcontext
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Switches the context from the previous task to the next task.
|
* Switches the context.
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* prev - Pointer to the previous task control block.
|
|
||||||
* next - Pointer to the next task control block.
|
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* None
|
* None
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#define riscv_switchcontext(prev, next) \
|
#define riscv_switchcontext() \
|
||||||
sys_call2(SYS_switch_context, (uintptr_t)prev, (uintptr_t)next)
|
do \
|
||||||
|
{ \
|
||||||
|
sys_call0(SYS_switch_context); \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
|
||||||
#undef EXTERN
|
#undef EXTERN
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -167,5 +167,5 @@ retry:
|
||||||
g_running_tasks[this_cpu()] = NULL;
|
g_running_tasks[this_cpu()] = NULL;
|
||||||
|
|
||||||
rtcb->xcp.regs = regs;
|
rtcb->xcp.regs = regs;
|
||||||
riscv_fullcontextrestore(rtcb);
|
riscv_fullcontextrestore();
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,7 +148,8 @@ uintptr_t dispatch_syscall(unsigned int nbr, uintptr_t parm1,
|
||||||
int riscv_swint(int irq, void *context, void *arg)
|
int riscv_swint(int irq, void *context, void *arg)
|
||||||
{
|
{
|
||||||
uintreg_t *regs = (uintreg_t *)context;
|
uintreg_t *regs = (uintreg_t *)context;
|
||||||
uintreg_t *new_regs = regs;
|
struct tcb_s *tcb = this_task();
|
||||||
|
int cpu = this_cpu();
|
||||||
|
|
||||||
/* Software interrupt 0 is invoked with REG_A0 (REG_X10) = system call
|
/* Software interrupt 0 is invoked with REG_A0 (REG_X10) = system call
|
||||||
* command and REG_A1-6 = variable number of
|
* command and REG_A1-6 = variable number of
|
||||||
|
@ -164,51 +165,18 @@ int riscv_swint(int irq, void *context, void *arg)
|
||||||
|
|
||||||
switch (regs[REG_A0])
|
switch (regs[REG_A0])
|
||||||
{
|
{
|
||||||
/* A0=SYS_restore_context: This a restore context command:
|
|
||||||
*
|
|
||||||
* void
|
|
||||||
* void riscv_fullcontextrestore(struct tcb_s *prev) noreturn_function;
|
|
||||||
*
|
|
||||||
* At this point, the following values are saved in context:
|
|
||||||
*
|
|
||||||
* A0 = SYS_restore_context
|
|
||||||
* A1 = next
|
|
||||||
*/
|
|
||||||
|
|
||||||
case SYS_restore_context:
|
case SYS_restore_context:
|
||||||
{
|
{
|
||||||
struct tcb_s *next = (struct tcb_s *)(uintptr_t)regs[REG_A1];
|
riscv_restorecontext(tcb);
|
||||||
|
restore_critical_section(tcb, cpu);
|
||||||
DEBUGASSERT(regs[REG_A1] != 0);
|
|
||||||
new_regs = next->xcp.regs;
|
|
||||||
riscv_restorecontext(next);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* A0=SYS_switch_context: This a switch context command:
|
|
||||||
*
|
|
||||||
* void
|
|
||||||
* riscv_switchcontext(struct tcb_s *prev, struct tcb_s *next);
|
|
||||||
*
|
|
||||||
* At this point, the following values are saved in context:
|
|
||||||
*
|
|
||||||
* A0 = SYS_switch_context
|
|
||||||
* A1 = prev
|
|
||||||
* A2 = next
|
|
||||||
*
|
|
||||||
* In this case, we save the context registers to the save register
|
|
||||||
* area referenced by the saved contents of R5.
|
|
||||||
*/
|
|
||||||
|
|
||||||
case SYS_switch_context:
|
case SYS_switch_context:
|
||||||
{
|
{
|
||||||
struct tcb_s *prev = (struct tcb_s *)(uintptr_t)regs[REG_A1];
|
riscv_savecontext(g_running_tasks[cpu]);
|
||||||
struct tcb_s *next = (struct tcb_s *)(uintptr_t)regs[REG_A2];
|
riscv_restorecontext(tcb);
|
||||||
|
restore_critical_section(tcb, cpu);
|
||||||
DEBUGASSERT(regs[REG_A1] != 0 && regs[REG_A2] != 0);
|
|
||||||
riscv_savecontext(prev);
|
|
||||||
new_regs = next->xcp.regs;
|
|
||||||
riscv_restorecontext(next);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -342,21 +310,17 @@ int riscv_swint(int irq, void *context, void *arg)
|
||||||
* switch
|
* switch
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (regs != new_regs)
|
|
||||||
{
|
|
||||||
restore_critical_section(this_task(), this_cpu());
|
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_SYSCALL_INFO
|
#ifdef CONFIG_DEBUG_SYSCALL_INFO
|
||||||
|
if (cmd <= SYS_switch_context)
|
||||||
|
{
|
||||||
svcinfo("SWInt Return: Context switch!\n");
|
svcinfo("SWInt Return: Context switch!\n");
|
||||||
up_dump_register(new_regs);
|
up_dump_register(tcb.xcp.regs);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_DEBUG_SYSCALL_INFO
|
|
||||||
svcinfo("SWInt Return: %" PRIxPTR "\n", regs[REG_A0]);
|
svcinfo("SWInt Return: %" PRIxPTR "\n", regs[REG_A0]);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,7 +80,7 @@ void up_switch_context(struct tcb_s *tcb, struct tcb_s *rtcb)
|
||||||
{
|
{
|
||||||
/* Then switch contexts */
|
/* Then switch contexts */
|
||||||
|
|
||||||
riscv_switchcontext(rtcb, tcb);
|
riscv_switchcontext();
|
||||||
|
|
||||||
/* riscv_switchcontext forces a context switch to the task at the
|
/* riscv_switchcontext forces a context switch to the task at the
|
||||||
* head of the ready-to-run list. It does not 'return' in the
|
* head of the ready-to-run list. It does not 'return' in the
|
||||||
|
|
Loading…
Reference in a new issue