From e120df465eff2185fb8cbdb7f08e99a4a229a1f3 Mon Sep 17 00:00:00 2001 From: hujun5 Date: Wed, 20 Nov 2024 22:13:23 +0800 Subject: [PATCH] arch/arm: 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) Signed-off-by: hujun5 --- arch/arm/include/irq.h | 14 +++---- arch/arm/src/arm/arm_sigdeliver.c | 4 +- arch/arm/src/arm/arm_syscall.c | 39 -------------------- arch/arm/src/armv6-m/arm_sigdeliver.c | 7 +++- arch/arm/src/armv6-m/arm_svcall.c | 52 +++----------------------- arch/arm/src/armv7-a/arm_sigdeliver.c | 6 ++- arch/arm/src/armv7-a/arm_syscall.c | 40 -------------------- arch/arm/src/armv7-m/arm_sigdeliver.c | 8 +++- arch/arm/src/armv7-m/arm_svcall.c | 53 +++------------------------ arch/arm/src/armv7-r/arm_sigdeliver.c | 6 ++- arch/arm/src/armv7-r/arm_syscall.c | 39 -------------------- arch/arm/src/armv8-m/arm_sigdeliver.c | 7 +++- arch/arm/src/armv8-m/arm_svcall.c | 53 +++------------------------ arch/arm/src/armv8-r/arm_sigdeliver.c | 6 ++- arch/arm/src/armv8-r/arm_syscall.c | 39 -------------------- arch/arm/src/common/arm_exit.c | 2 +- arch/arm/src/common/arm_internal.h | 5 ++- 17 files changed, 56 insertions(+), 324 deletions(-) diff --git a/arch/arm/include/irq.h b/arch/arm/include/irq.h index 066be261d8a4d..ffddf2a76d099 100644 --- a/arch/arm/include/irq.h +++ b/arch/arm/include/irq.h @@ -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 diff --git a/arch/arm/src/arm/arm_sigdeliver.c b/arch/arm/src/arm/arm_sigdeliver.c index b55e820604f65..b6f05c1380758 100644 --- a/arch/arm/src/arm/arm_sigdeliver.c +++ b/arch/arm/src/arm/arm_sigdeliver.c @@ -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); @@ -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); } diff --git a/arch/arm/src/arm/arm_syscall.c b/arch/arm/src/arm/arm_syscall.c index a69cc31941cb5..79ccb58903dce 100644 --- a/arch/arm/src/arm/arm_syscall.c +++ b/arch/arm/src/arm/arm_syscall.c @@ -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; diff --git a/arch/arm/src/armv6-m/arm_sigdeliver.c b/arch/arm/src/armv6-m/arm_sigdeliver.c index fa6797351d086..5cb214079b8e9 100644 --- a/arch/arm/src/armv6-m/arm_sigdeliver.c +++ b/arch/arm/src/armv6-m/arm_sigdeliver.c @@ -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. @@ -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); } diff --git a/arch/arm/src/armv6-m/arm_svcall.c b/arch/arm/src/armv6-m/arm_svcall.c index 411138b3e1db9..105c9712e0a5f 100644 --- a/arch/arm/src/armv6-m/arm_svcall.c +++ b/arch/arm/src/armv6-m/arm_svcall.c @@ -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]; @@ -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; @@ -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", diff --git a/arch/arm/src/armv7-a/arm_sigdeliver.c b/arch/arm/src/armv7-a/arm_sigdeliver.c index 1867aa8844605..fe4494cf18047 100644 --- a/arch/arm/src/armv7-a/arm_sigdeliver.c +++ b/arch/arm/src/armv7-a/arm_sigdeliver.c @@ -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. @@ -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); } diff --git a/arch/arm/src/armv7-a/arm_syscall.c b/arch/arm/src/armv7-a/arm_syscall.c index dc420295ad7f0..4ba533e141a17 100644 --- a/arch/arm/src/armv7-a/arm_syscall.c +++ b/arch/arm/src/armv7-a/arm_syscall.c @@ -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; diff --git a/arch/arm/src/armv7-m/arm_sigdeliver.c b/arch/arm/src/armv7-m/arm_sigdeliver.c index 524f2c445b691..7d019e737614e 100644 --- a/arch/arm/src/armv7-m/arm_sigdeliver.c +++ b/arch/arm/src/armv7-m/arm_sigdeliver.c @@ -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. @@ -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); } diff --git a/arch/arm/src/armv7-m/arm_svcall.c b/arch/arm/src/armv7-m/arm_svcall.c index da5122e8bb8c7..15131165d0230 100644 --- a/arch/arm/src/armv7-m/arm_svcall.c +++ b/arch/arm/src/armv7-m/arm_svcall.c @@ -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]; @@ -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; @@ -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", diff --git a/arch/arm/src/armv7-r/arm_sigdeliver.c b/arch/arm/src/armv7-r/arm_sigdeliver.c index 5a63458b9b04f..e98fd4b3500d2 100644 --- a/arch/arm/src/armv7-r/arm_sigdeliver.c +++ b/arch/arm/src/armv7-r/arm_sigdeliver.c @@ -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. @@ -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); } diff --git a/arch/arm/src/armv7-r/arm_syscall.c b/arch/arm/src/armv7-r/arm_syscall.c index b4f3a5047bfd6..3485f962568c0 100644 --- a/arch/arm/src/armv7-r/arm_syscall.c +++ b/arch/arm/src/armv7-r/arm_syscall.c @@ -255,46 +255,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; diff --git a/arch/arm/src/armv8-m/arm_sigdeliver.c b/arch/arm/src/armv8-m/arm_sigdeliver.c index 2db03f17d166b..c8b2a4e9b9b8e 100644 --- a/arch/arm/src/armv8-m/arm_sigdeliver.c +++ b/arch/arm/src/armv8-m/arm_sigdeliver.c @@ -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. @@ -174,5 +175,7 @@ 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); } diff --git a/arch/arm/src/armv8-m/arm_svcall.c b/arch/arm/src/armv8-m/arm_svcall.c index fda01dd16f4b3..78d6cd11880bc 100644 --- a/arch/arm/src/armv8-m/arm_svcall.c +++ b/arch/arm/src/armv8-m/arm_svcall.c @@ -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]; @@ -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; @@ -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", diff --git a/arch/arm/src/armv8-r/arm_sigdeliver.c b/arch/arm/src/armv8-r/arm_sigdeliver.c index e4a8ad59353b1..9a3f33abf9add 100644 --- a/arch/arm/src/armv8-r/arm_sigdeliver.c +++ b/arch/arm/src/armv8-r/arm_sigdeliver.c @@ -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. @@ -157,5 +158,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); } diff --git a/arch/arm/src/armv8-r/arm_syscall.c b/arch/arm/src/armv8-r/arm_syscall.c index ab3f6cae88fb0..12c97844e7220 100644 --- a/arch/arm/src/armv8-r/arm_syscall.c +++ b/arch/arm/src/armv8-r/arm_syscall.c @@ -255,46 +255,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; diff --git a/arch/arm/src/common/arm_exit.c b/arch/arm/src/common/arm_exit.c index f238dfa5f3fb6..ee7e5440f4054 100644 --- a/arch/arm/src/common/arm_exit.c +++ b/arch/arm/src/common/arm_exit.c @@ -72,7 +72,7 @@ void up_exit(int status) /* Then switch contexts */ - arm_fullcontextrestore(tcb->xcp.regs); + arm_fullcontextrestore(tcb); /* arm_fullcontextrestore() should not return but could if the software * interrupts are disabled. diff --git a/arch/arm/src/common/arm_internal.h b/arch/arm/src/common/arm_internal.h index 5b8ee49d4fa00..87c1a8571bd73 100644 --- a/arch/arm/src/common/arm_internal.h +++ b/arch/arm/src/common/arm_internal.h @@ -147,8 +147,9 @@ /* Context switching */ #ifndef arm_fullcontextrestore -# define arm_fullcontextrestore(restoreregs) \ - sys_call1(SYS_restore_context, (uintptr_t)restoreregs); +# define arm_fullcontextrestore(tcb) \ + sys_call0(SYS_restore_context); \ + UNUSED(tcb); #else extern void arm_fullcontextrestore(uint32_t *restoreregs); #endif