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 23, 2024
1 parent 1485ecd commit 62e747f
Show file tree
Hide file tree
Showing 17 changed files with 94 additions and 377 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();
}
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
5 changes: 4 additions & 1 deletion arch/arm/src/armv6-m/arm_sigdeliver.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,5 +162,8 @@ 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();
UNUSED(regs);
}
84 changes: 20 additions & 64 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;
struct tcb_s *tcb;
uint32_t cmd;

cmd = regs[REG_R0];
Expand Down Expand Up @@ -149,51 +148,15 @@ 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];
tcb = this_task();
restore_critical_section(tcb, this_cpu());

#ifdef CONFIG_DEBUG_SYSCALL_INFO
regs = tcb->xcp.regs;
#endif
}
break;

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

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

#ifdef CONFIG_DEBUG_SYSCALL_INFO
regs = new_regs;

svcinfo("SVCall Return:\n");
svcinfo(" R0: %08x %08x %08x %08x %08x %08x %08x %08x\n",
regs[REG_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3],
regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]);
svcinfo(" R8: %08x %08x %08x %08x %08x %08x %08x %08x\n",
regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11],
regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]);
svcinfo(" PSR: %08x EXC_RETURN: %08x CONTROL: %08x\n",
regs[REG_XPSR], regs[REG_EXC_RETURN], regs[REG_CONTROL]);
#endif
}
#ifdef CONFIG_DEBUG_SYSCALL_INFO
else
# ifndef CONFIG_DEBUG_SVCALL
if (cmd > SYS_switch_context)
# endif
{
svcinfo("SVCall Return: %d\n", regs[REG_R0]);
svcinfo("SVCall Return:\n");
svcinfo(" R0: %08x %08x %08x %08x %08x %08x %08x %08x\n",
regs[REG_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3],
regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]);
svcinfo(" R8: %08x %08x %08x %08x %08x %08x %08x %08x\n",
regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11],
regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]);
svcinfo(" PSR: %08x EXC_RETURN: %08x CONTROL: %08x\n",
regs[REG_XPSR], regs[REG_EXC_RETURN], regs[REG_CONTROL]);
}
#endif

UNUSED(tcb);
return OK;
}
4 changes: 3 additions & 1 deletion arch/arm/src/armv7-a/arm_sigdeliver.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,5 +162,7 @@ void arm_sigdeliver(void)
#endif

g_running_tasks[this_cpu()] = NULL;
arm_fullcontextrestore(regs);
rtcb->xcp.regs = rtcb->xcp.saved_regs;
arm_fullcontextrestore();
UNUSED(regs);
}
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
6 changes: 5 additions & 1 deletion arch/arm/src/armv7-m/arm_sigdeliver.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,5 +174,9 @@ 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();
UNUSED(regs);
}
85 changes: 20 additions & 65 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;
struct tcb_s *tcb;
uint32_t cmd;

cmd = regs[REG_R0];
Expand Down Expand Up @@ -157,52 +156,15 @@ 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];
tcb = this_task();
restore_critical_section(tcb, this_cpu());

#ifdef CONFIG_DEBUG_SYSCALL_INFO
regs = tcb->xcp.regs;
#endif
}
break;

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

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

#ifdef CONFIG_DEBUG_SYSCALL_INFO
regs = new_regs;

svcinfo("SVCall Return:\n");
svcinfo(" R0: %08x %08x %08x %08x %08x %08x %08x %08x\n",
regs[REG_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3],
regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]);
svcinfo(" R8: %08x %08x %08x %08x %08x %08x %08x %08x\n",
regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11],
regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]);
svcinfo(" PSR: %08x EXC_RETURN: %08x CONTROL: %08x\n",
regs[REG_XPSR], regs[REG_EXC_RETURN], regs[REG_CONTROL]);
#endif
}
#ifdef CONFIG_DEBUG_SYSCALL_INFO
else
# ifndef CONFIG_DEBUG_SVCALL
if (cmd > SYS_switch_context)
# endif
{
svcinfo("SVCall Return: %d\n", regs[REG_R0]);
svcinfo("SVCall Return:\n");
svcinfo(" R0: %08x %08x %08x %08x %08x %08x %08x %08x\n",
regs[REG_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3],
regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]);
svcinfo(" R8: %08x %08x %08x %08x %08x %08x %08x %08x\n",
regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11],
regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]);
svcinfo(" PSR: %08x EXC_RETURN: %08x CONTROL: %08x\n",
regs[REG_XPSR], regs[REG_EXC_RETURN], regs[REG_CONTROL]);
}
#endif

UNUSED(tcb);
return OK;
}
4 changes: 3 additions & 1 deletion arch/arm/src/armv7-r/arm_sigdeliver.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,5 +159,7 @@ void arm_sigdeliver(void)
#endif

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

0 comments on commit 62e747f

Please sign in to comment.