Skip to content

Commit

Permalink
arch/arm: syscall SYS_switch_context and SYS_restore_context use 0 para
Browse files Browse the repository at this point in the history
reason:
simplify context switch
sys_call0(SYS_switch_context)
sys_call0(SYS_restore_context)

Signed-off-by: hujun5 <[email protected]>
  • Loading branch information
hujun260 committed Nov 21, 2024
1 parent 9cd0ea3 commit e120df4
Show file tree
Hide file tree
Showing 17 changed files with 56 additions and 324 deletions.
14 changes: 7 additions & 7 deletions arch/arm/include/irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,13 @@
#ifndef __ASSEMBLY__

#ifndef up_switch_context
#define up_switch_context(tcb, rtcb) \
do { \
if (!up_interrupt_context()) \
{ \
sys_call2(SYS_switch_context, (uintptr_t)&rtcb->xcp.regs, \
(uintptr_t)tcb->xcp.regs); \
} \
#define up_switch_context(tcb, rtcb) \
do { \
if (!up_interrupt_context()) \
{ \
sys_call0(SYS_switch_context); \
} \
UNUSED(rtcb); \
} while (0)
#endif

Expand Down
4 changes: 2 additions & 2 deletions arch/arm/src/arm/arm_sigdeliver.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@
void arm_sigdeliver(void)
{
struct tcb_s *rtcb = this_task();
uint32_t *regs = rtcb->xcp.saved_regs;

board_autoled_on(LED_SIGNAL);

Expand Down Expand Up @@ -99,5 +98,6 @@ void arm_sigdeliver(void)
board_autoled_off(LED_SIGNAL);

g_running_tasks[this_cpu()] = NULL;
arm_fullcontextrestore(regs);
rtcb->xcp.regs = rtcb->xcp.saved_regs;
arm_fullcontextrestore(rtcb);
}
39 changes: 0 additions & 39 deletions arch/arm/src/arm/arm_syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,46 +81,7 @@ uint32_t *arm_syscall(uint32_t *regs)

switch (cmd)
{
/* R0=SYS_restore_context: Restore task context
*
* void arm_fullcontextrestore(uint32_t *restoreregs)
* noreturn_function;
*
* At this point, the following values are saved in context:
*
* R0 = SYS_restore_context
* R1 = restoreregs
*/

case SYS_restore_context:
{
/* Replace 'regs' with the pointer to the register set in
* regs[REG_R1]. On return from the system call, that register
* set will determine the restored context.
*/

tcb->xcp.regs = (uint32_t *)regs[REG_R1];
DEBUGASSERT(up_current_regs());
}
break;

/* R0=SYS_switch_context: This a switch context command:
*
* void arm_switchcontext(uint32_t **saveregs,
* uint32_t *restoreregs);
*
* At this point, the following values are saved in context:
*
* R0 = SYS_switch_context
* R1 = saveregs
* R2 = restoreregs
*
* In this case, we do both: We save the context registers to the save
* register area reference by the saved contents of R1 and then set
* regs to the save register area referenced by the saved
* contents of R2.
*/

case SYS_switch_context:
break;

Expand Down
7 changes: 5 additions & 2 deletions arch/arm/src/armv6-m/arm_sigdeliver.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,10 @@
void arm_sigdeliver(void)
{
struct tcb_s *rtcb = this_task();
uint32_t *regs = rtcb->xcp.saved_regs;

#ifdef CONFIG_SMP
uint32_t *regs = rtcb->xcp.saved_regs;

/* In the SMP case, we must terminate the critical section while the signal
* handler executes, but we also need to restore the irqcount when the
* we resume the main thread of the task.
Expand Down Expand Up @@ -162,5 +163,7 @@ void arm_sigdeliver(void)
leave_critical_section((uint16_t)regs[REG_PRIMASK]);
rtcb->irqcount--;
#endif
arm_fullcontextrestore(regs);
g_running_tasks[this_cpu()] = NULL;
rtcb->xcp.regs = rtcb->xcp.saved_regs;
arm_fullcontextrestore(rtcb);
}
52 changes: 5 additions & 47 deletions arch/arm/src/armv6-m/arm_svcall.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,8 @@ static void dispatch_syscall(void)

int arm_svcall(int irq, void *context, void *arg)
{
struct tcb_s *tcb = this_task();
uint32_t *regs = (uint32_t *)context;
uint32_t *new_regs = regs;
bool need_switch = false;
uint32_t cmd;

cmd = regs[REG_R0];
Expand Down Expand Up @@ -149,51 +148,10 @@ int arm_svcall(int irq, void *context, void *arg)

switch (cmd)
{
/* R0=SYS_restore_context: This a restore context command:
*
* void arm_fullcontextrestore(uint32_t *restoreregs)
* noreturn_function;
*
* At this point, the following values are saved in context:
*
* R0 = SYS_restore_context
* R1 = restoreregs
*
* In this case, we simply need to set current_regs to restore register
* area referenced in the saved R1. context == current_regs is the
* normal exception return. By setting current_regs = context[R1], we
* force the return to the saved context referenced in R1.
*/

case SYS_restore_context:
{
DEBUGASSERT(regs[REG_R1] != 0);
new_regs = (uint32_t *)regs[REG_R1];
tcb->xcp.regs = (uint32_t *)regs[REG_R1];
}
break;

/* R0=SYS_switch_context: This a switch context command:
*
* void arm_switchcontext(uint32_t **saveregs,
* uint32_t *restoreregs);
*
* At this point, the following values are saved in context:
*
* R0 = SYS_switch_context
* R1 = saveregs
* R2 = restoreregs
*
* In this case, we do both: We save the context registers to the save
* register area reference by the saved contents of R1 and then set
* current_regs to the save register area referenced by the saved
* contents of R2.
*/

case SYS_switch_context:
{
DEBUGASSERT(regs[REG_R1] != 0 && regs[REG_R2] != 0);
new_regs = (uint32_t *)regs[REG_R2];
need_switch = true;
}
break;

Expand Down Expand Up @@ -447,12 +405,12 @@ int arm_svcall(int irq, void *context, void *arg)
* switch.
*/

if (regs != new_regs)
if (need_switch)
{
restore_critical_section(tcb, this_cpu());
restore_critical_section(this_task(), this_cpu());

#ifdef CONFIG_DEBUG_SYSCALL_INFO
regs = new_regs;
regs = this_task()->xcp.regs;

svcinfo("SVCall Return:\n");
svcinfo(" R0: %08x %08x %08x %08x %08x %08x %08x %08x\n",
Expand Down
6 changes: 4 additions & 2 deletions arch/arm/src/armv7-a/arm_sigdeliver.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,10 @@
void arm_sigdeliver(void)
{
struct tcb_s *rtcb = this_task();
uint32_t *regs = rtcb->xcp.saved_regs;

#ifdef CONFIG_SMP
uint32_t *regs = rtcb->xcp.saved_regs;

/* In the SMP case, we must terminate the critical section while the signal
* handler executes, but we also need to restore the irqcount when the
* we resume the main thread of the task.
Expand Down Expand Up @@ -162,5 +163,6 @@ void arm_sigdeliver(void)
#endif

g_running_tasks[this_cpu()] = NULL;
arm_fullcontextrestore(regs);
rtcb->xcp.regs = rtcb->xcp.saved_regs;
arm_fullcontextrestore(rtcb);
}
40 changes: 0 additions & 40 deletions arch/arm/src/armv7-a/arm_syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,47 +257,7 @@ uint32_t *arm_syscall(uint32_t *regs)
}
break;
#endif

/* R0=SYS_restore_context: Restore task context
*
* void arm_fullcontextrestore(uint32_t *restoreregs)
* noreturn_function;
*
* At this point, the following values are saved in context:
*
* R0 = SYS_restore_context
* R1 = restoreregs
*/

case SYS_restore_context:
{
/* Replace 'regs' with the pointer to the register set in
* regs[REG_R1]. On return from the system call, that register
* set will determine the restored context.
*/

tcb->xcp.regs = (uint32_t *)regs[REG_R1];
DEBUGASSERT(up_current_regs());
}
break;

/* R0=SYS_switch_context: This a switch context command:
*
* void arm_switchcontext(uint32_t **saveregs,
* uint32_t *restoreregs);
*
* At this point, the following values are saved in context:
*
* R0 = SYS_switch_context
* R1 = saveregs
* R2 = restoreregs
*
* In this case, we do both: We save the context registers to the save
* register area reference by the saved contents of R1 and then set
* regs to the save register area referenced by the saved
* contents of R2.
*/

case SYS_switch_context:
break;

Expand Down
8 changes: 6 additions & 2 deletions arch/arm/src/armv7-m/arm_sigdeliver.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,10 @@
void arm_sigdeliver(void)
{
struct tcb_s *rtcb = this_task();
uint32_t *regs = rtcb->xcp.saved_regs;

#ifdef CONFIG_SMP
uint32_t *regs = rtcb->xcp.saved_regs;

/* In the SMP case, we must terminate the critical section while the signal
* handler executes, but we also need to restore the irqcount when the
* we resume the main thread of the task.
Expand Down Expand Up @@ -174,5 +175,8 @@ void arm_sigdeliver(void)
#endif
rtcb->irqcount--;
#endif
arm_fullcontextrestore(regs);

g_running_tasks[this_cpu()] = NULL;
rtcb->xcp.regs = rtcb->xcp.saved_regs;
arm_fullcontextrestore(rtcb);
}
53 changes: 5 additions & 48 deletions arch/arm/src/armv7-m/arm_svcall.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,8 @@ static void dispatch_syscall(void)

int arm_svcall(int irq, void *context, void *arg)
{
struct tcb_s *tcb = this_task();
uint32_t *regs = (uint32_t *)context;
uint32_t *new_regs = regs;
bool need_switch = false;
uint32_t cmd;

cmd = regs[REG_R0];
Expand Down Expand Up @@ -157,52 +156,10 @@ int arm_svcall(int irq, void *context, void *arg)

switch (cmd)
{
/* R0=SYS_restore_context: This a restore context command:
*
* void arm_fullcontextrestore(uint32_t *restoreregs)
* noreturn_function;
*
* At this point, the following values are saved in context:
*
* R0 = SYS_restore_context
* R1 = restoreregs
*
* In this case, we simply need to set current_regs to restore
* register area referenced in the saved R1. context == current_regs
* is the normal exception return. By setting current_regs =
* context[R1], we force the return to the saved context referenced
* in R1.
*/

case SYS_restore_context:
{
DEBUGASSERT(regs[REG_R1] != 0);
new_regs = (uint32_t *)regs[REG_R1];
tcb->xcp.regs = (uint32_t *)regs[REG_R1];
}
break;

/* R0=SYS_switch_context: This a switch context command:
*
* void arm_switchcontext(uint32_t **saveregs,
* uint32_t *restoreregs);
*
* At this point, the following values are saved in context:
*
* R0 = SYS_switch_context
* R1 = saveregs
* R2 = restoreregs
*
* In this case, we do both: We save the context registers to the save
* register area reference by the saved contents of R1 and then set
* current_regs to the save register area referenced by the saved
* contents of R2.
*/

case SYS_switch_context:
{
DEBUGASSERT(regs[REG_R1] != 0 && regs[REG_R2] != 0);
new_regs = (uint32_t *)regs[REG_R2];
need_switch = true;
}
break;

Expand Down Expand Up @@ -457,12 +414,12 @@ int arm_svcall(int irq, void *context, void *arg)
* switch.
*/

if (regs != new_regs)
if (need_switch)
{
restore_critical_section(tcb, this_cpu());
restore_critical_section(this_task(), this_cpu());

#ifdef CONFIG_DEBUG_SYSCALL_INFO
regs = new_regs;
regs = this_task()->xcp.regs;

svcinfo("SVCall Return:\n");
svcinfo(" R0: %08x %08x %08x %08x %08x %08x %08x %08x\n",
Expand Down
6 changes: 4 additions & 2 deletions arch/arm/src/armv7-r/arm_sigdeliver.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,10 @@
void arm_sigdeliver(void)
{
struct tcb_s *rtcb = this_task();
uint32_t *regs = rtcb->xcp.saved_regs;

#ifdef CONFIG_SMP
uint32_t *regs = rtcb->xcp.saved_regs;

/* In the SMP case, we must terminate the critical section while the signal
* handler executes, but we also need to restore the irqcount when the
* we resume the main thread of the task.
Expand Down Expand Up @@ -159,5 +160,6 @@ void arm_sigdeliver(void)
#endif

g_running_tasks[this_cpu()] = NULL;
arm_fullcontextrestore(regs);
rtcb->xcp.regs = rtcb->xcp.saved_regs;
arm_fullcontextrestore(rtcb);
}
Loading

0 comments on commit e120df4

Please sign in to comment.