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:
|
||||
*
|
||||
* void riscv_fullcontextrestore(uintptr_t *restoreregs) noreturn_function;
|
||||
* void riscv_fullcontextrestore() noreturn_function;
|
||||
*/
|
||||
|
||||
#define SYS_restore_context (1)
|
||||
|
||||
/* SYS call 2:
|
||||
*
|
||||
* void riscv_switchcontext(uintptr_t **saveregs, uintptr_t *restoreregs);
|
||||
* void riscv_switchcontext();
|
||||
*/
|
||||
|
||||
#define SYS_switch_context (2)
|
||||
|
|
|
@ -54,25 +54,17 @@
|
|||
|
||||
void up_exit(int status)
|
||||
{
|
||||
struct tcb_s *tcb = this_task();
|
||||
|
||||
/* Destroy the task at the head of the ready to run list. */
|
||||
|
||||
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 */
|
||||
|
||||
g_running_tasks[this_cpu()] = NULL;
|
||||
|
||||
/* Then switch contexts */
|
||||
|
||||
riscv_fullcontextrestore(tcb);
|
||||
riscv_fullcontextrestore();
|
||||
|
||||
/* riscv_fullcontextrestore() should not return but could if the software
|
||||
* interrupts are disabled.
|
||||
|
|
|
@ -486,36 +486,37 @@ void riscv_jump_to_user(uintptr_t entry, uintreg_t a0, uintreg_t a1,
|
|||
* Name: riscv_fullcontextrestore
|
||||
*
|
||||
* Description:
|
||||
* Restores the full context of the next task.
|
||||
*
|
||||
* Parameters:
|
||||
* next - Pointer to the next task control block.
|
||||
* Restores the full context.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#define riscv_fullcontextrestore(next) \
|
||||
sys_call1(SYS_restore_context, (uintptr_t)next)
|
||||
#define riscv_fullcontextrestore() \
|
||||
do \
|
||||
{ \
|
||||
sys_call0(SYS_restore_context); \
|
||||
} \
|
||||
while (1)
|
||||
|
||||
/****************************************************************************
|
||||
* Name: riscv_switchcontext
|
||||
*
|
||||
* Description:
|
||||
* Switches the context from the previous task to the next task.
|
||||
*
|
||||
* Parameters:
|
||||
* prev - Pointer to the previous task control block.
|
||||
* next - Pointer to the next task control block.
|
||||
* Switches the context.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#define riscv_switchcontext(prev, next) \
|
||||
sys_call2(SYS_switch_context, (uintptr_t)prev, (uintptr_t)next)
|
||||
#define riscv_switchcontext() \
|
||||
do \
|
||||
{ \
|
||||
sys_call0(SYS_switch_context); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -167,5 +167,5 @@ retry:
|
|||
g_running_tasks[this_cpu()] = NULL;
|
||||
|
||||
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)
|
||||
{
|
||||
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
|
||||
* 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])
|
||||
{
|
||||
/* 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:
|
||||
{
|
||||
struct tcb_s *next = (struct tcb_s *)(uintptr_t)regs[REG_A1];
|
||||
|
||||
DEBUGASSERT(regs[REG_A1] != 0);
|
||||
new_regs = next->xcp.regs;
|
||||
riscv_restorecontext(next);
|
||||
riscv_restorecontext(tcb);
|
||||
restore_critical_section(tcb, cpu);
|
||||
}
|
||||
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:
|
||||
{
|
||||
struct tcb_s *prev = (struct tcb_s *)(uintptr_t)regs[REG_A1];
|
||||
struct tcb_s *next = (struct tcb_s *)(uintptr_t)regs[REG_A2];
|
||||
|
||||
DEBUGASSERT(regs[REG_A1] != 0 && regs[REG_A2] != 0);
|
||||
riscv_savecontext(prev);
|
||||
new_regs = next->xcp.regs;
|
||||
riscv_restorecontext(next);
|
||||
riscv_savecontext(g_running_tasks[cpu]);
|
||||
riscv_restorecontext(tcb);
|
||||
restore_critical_section(tcb, cpu);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -342,21 +310,17 @@ int riscv_swint(int irq, void *context, void *arg)
|
|||
* switch
|
||||
*/
|
||||
|
||||
if (regs != new_regs)
|
||||
{
|
||||
restore_critical_section(this_task(), this_cpu());
|
||||
|
||||
#ifdef CONFIG_DEBUG_SYSCALL_INFO
|
||||
if (cmd <= SYS_switch_context)
|
||||
{
|
||||
svcinfo("SWInt Return: Context switch!\n");
|
||||
up_dump_register(new_regs);
|
||||
#endif
|
||||
up_dump_register(tcb.xcp.regs);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef CONFIG_DEBUG_SYSCALL_INFO
|
||||
svcinfo("SWInt Return: %" PRIxPTR "\n", regs[REG_A0]);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ void up_switch_context(struct tcb_s *tcb, struct tcb_s *rtcb)
|
|||
{
|
||||
/* Then switch contexts */
|
||||
|
||||
riscv_switchcontext(rtcb, tcb);
|
||||
riscv_switchcontext();
|
||||
|
||||
/* riscv_switchcontext forces a context switch to the task at the
|
||||
* head of the ready-to-run list. It does not 'return' in the
|
||||
|
|
Loading…
Reference in a new issue