Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

arch/arm: syscall SYS_switch_context and SYS_restore_context use 0 para #14881

Merged
merged 3 commits into from
Dec 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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) \
xiaoxiang781216 marked this conversation as resolved.
Show resolved Hide resolved
do { \
if (!up_interrupt_context()) \
{ \
sys_call0(SYS_switch_context); \
} \
UNUSED(rtcb); \
} while (0)
#endif

Expand Down
2 changes: 1 addition & 1 deletion arch/arm/src/arm/arm_allocpage.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@

#include <nuttx/page.h>

#include "pg_macros.h"
#include "arm_internal.h"
#include "pg_macros.h"

/****************************************************************************
* Pre-processor Definitions
Expand Down
5 changes: 2 additions & 3 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 @@ -98,6 +97,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();
}
93 changes: 26 additions & 67 deletions arch/arm/src/arm/arm_syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,72 +54,54 @@

uint32_t *arm_syscall(uint32_t *regs)
{
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
int cpu = this_cpu();
struct tcb_s **running_task = &g_running_tasks[cpu];
FAR struct tcb_s *tcb = this_task();
uint32_t cmd;

/* Nested interrupts are not supported */

DEBUGASSERT(!up_interrupt_context());

if (*running_task != NULL)
{
(*running_task)->xcp.regs = regs;
}

/* Set irq flag */
/* Current regs non-zero indicates that we are processing an interrupt;
* current_regs is also used to manage interrupt level context switches.
*/

up_set_interrupt_context(true);

/* The SYSCALL command is in R0 on entry. Parameters follow in R1..R7 */

cmd = regs[REG_R0];

/* if cmd == SYS_restore_context (*running_task)->xcp.regs is valid
* should not be overwriten
*/

if (cmd != SYS_restore_context)
{
(*running_task)->xcp.regs = regs;
}

/* Handle the SVCall according to the command in R0 */

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_switch_context:

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.
*/
/* Update scheduler parameters */

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

case SYS_restore_context:
nxsched_suspend_scheduler(*running_task);
*running_task = tcb;

/* 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.
*/
/* Restore the cpu lock */

case SYS_switch_context:
restore_critical_section(tcb, cpu);
#ifdef CONFIG_ARCH_ADDRENV
addrenv_switch(tcb);
#endif
break;

default:
Expand All @@ -131,29 +113,6 @@ uint32_t *arm_syscall(uint32_t *regs)
break;
}

if (*running_task != tcb)
{
#ifdef CONFIG_ARCH_ADDRENV
/* Make sure that the address environment for the previously
* running task is closed down gracefully (data caches dump,
* MMU flushed) and set up the address environment for the new
* thread at the head of the ready-to-run list.
*/

addrenv_switch(NULL);
#endif
/* Update scheduler parameters */

nxsched_suspend_scheduler(*running_task);
nxsched_resume_scheduler(tcb);

*running_task = tcb;

/* Restore the cpu lock */

restore_critical_section(tcb, this_cpu());
}

/* Set irq flag */

up_set_interrupt_context(false);
Expand Down
6 changes: 5 additions & 1 deletion arch/arm/src/armv6-m/arm_doirq.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,11 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
FAR struct tcb_s *tcb;

if (*running_task != NULL)
/* This judgment proves that (*running_task)->xcp.regs
* is invalid, and we can safely overwrite it.
*/

if (!(NVIC_IRQ_SVCALL == irq && regs[REG_R0] == SYS_restore_context))
{
(*running_task)->xcp.regs = regs;
}
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);

rtcb->xcp.regs = rtcb->xcp.saved_regs;
arm_fullcontextrestore();
UNUSED(regs);
}
58 changes: 12 additions & 46 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,41 +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
*/

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
*/

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 @@ -437,13 +410,11 @@ 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;

# ifndef CONFIG_DEBUG_SVCALL
if (cmd > SYS_switch_context)
# endif
{
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],
Expand All @@ -453,14 +424,9 @@ int arm_svcall(int irq, void *context, void *arg)
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
{
svcinfo("SVCall Return: %d\n", regs[REG_R0]);
}
#endif

UNUSED(tcb);
return OK;
}
5 changes: 3 additions & 2 deletions arch/arm/src/armv7-a/arm_sigdeliver.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ void arm_sigdeliver(void)
rtcb->irqcount--;
#endif

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