arch: remove up_current_regs in common code

reason:

When entering an exception or interrupt, there are two sets of registers:
one is the "running regs", which we need to save,
and the other is the "ready to running regs", which we may soon use.
For consistency in logic, we can always store the "running regs" in the regs field of g_running_tasks,
otherwise it may lead to errors in the storage location of the "running regs."

When we need to access the "running regs," we should uniformly retrieve them from the regs field of g_running_tasks.

As the next step, we will rename the set_current_regs/up_current_regs functions
for each architecture to more appropriate names, solely for the purpose of identifying interrupts.

Signed-off-by: hujun5 <hujun5@xiaomi.com>
This commit is contained in:
hujun5
2024-09-24 16:46:08 +08:00
committed by Xiang Xiao
parent 5300d77398
commit 19b4911d7f
51 changed files with 305 additions and 171 deletions

View File

@@ -97,5 +97,7 @@ void arm_sigdeliver(void)
/* Then restore the correct state for this thread of execution. */
board_autoled_off(LED_SIGNAL);
g_running_tasks[this_cpu()] = NULL;
arm_fullcontextrestore(regs);
}

View File

@@ -54,19 +54,23 @@
uint32_t *arm_syscall(uint32_t *regs)
{
struct tcb_s *tcb = this_task();
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
FAR struct tcb_s *tcb = this_task();
uint32_t cmd;
int cpu;
/* Nested interrupts are not supported */
DEBUGASSERT(up_current_regs() == NULL);
if (*running_task != NULL)
{
(*running_task)->xcp.regs = regs;
}
/* Current regs non-zero indicates that we are processing an interrupt;
* current_regs is also used to manage interrupt level context switches.
*/
tcb->xcp.regs = regs;
up_set_current_regs(regs);
/* The SYSCALL command is in R0 on entry. Parameters follow in R1..R7 */
@@ -118,11 +122,6 @@ uint32_t *arm_syscall(uint32_t *regs)
*/
case SYS_switch_context:
{
DEBUGASSERT(regs[REG_R1] != 0 && regs[REG_R2] != 0);
*(uint32_t **)regs[REG_R1] = regs;
up_set_current_regs((uint32_t *)regs[REG_R2]);
}
break;
default:
@@ -134,7 +133,7 @@ uint32_t *arm_syscall(uint32_t *regs)
break;
}
if (regs != tcb->xcp.regs)
if (*running_task != tcb)
{
#ifdef CONFIG_ARCH_ADDRENV
/* Make sure that the address environment for the previously
@@ -145,25 +144,16 @@ uint32_t *arm_syscall(uint32_t *regs)
addrenv_switch(NULL);
#endif
/* Record the new "running" task. g_running_tasks[] is only used by
* assertion logic for reporting crashes.
*/
cpu = this_cpu();
tcb = current_task(cpu);
/* Update scheduler parameters */
nxsched_suspend_scheduler(g_running_tasks[cpu]);
nxsched_suspend_scheduler(*running_task);
nxsched_resume_scheduler(tcb);
g_running_tasks[cpu] = tcb;
*running_task = tcb;
/* Restore the cpu lock */
restore_critical_section(tcb, cpu);
regs = up_current_regs();
restore_critical_section(tcb, this_cpu());
}
/* Set current_regs to NULL to indicate that we are no longer in an

View File

@@ -56,7 +56,13 @@ void exception_direct(void)
uint32_t *arm_doirq(int irq, uint32_t *regs)
{
struct tcb_s *tcb = this_task();
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
FAR struct tcb_s *tcb;
if (*running_task != NULL)
{
(*running_task)->xcp.regs = regs;
}
board_autoled_on(LED_INIRQ);
#ifdef CONFIG_SUPPRESS_INTERRUPTS
@@ -80,13 +86,9 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
#endif
up_irq_save();
g_running_tasks[this_cpu()]->xcp.regs = regs;
}
else
{
/* Dispatch irq */
tcb->xcp.regs = regs;
irq_dispatch(irq, regs);
}
@@ -100,7 +102,7 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
/* Update scheduler parameters */
nxsched_suspend_scheduler(g_running_tasks[this_cpu()]);
nxsched_suspend_scheduler(*running_task);
nxsched_resume_scheduler(tcb);
/* Record the new "running" task when context switch occurred.
@@ -108,7 +110,7 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
* crashes.
*/
g_running_tasks[this_cpu()] = tcb;
*running_task = tcb;
regs = tcb->xcp.regs;
#endif

View File

@@ -119,6 +119,7 @@ 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;
uint32_t cmd;
cmd = regs[REG_R0];
@@ -167,6 +168,7 @@ int arm_svcall(int irq, void *context, void *arg)
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;
@@ -191,8 +193,7 @@ int arm_svcall(int irq, void *context, void *arg)
case SYS_switch_context:
{
DEBUGASSERT(regs[REG_R1] != 0 && regs[REG_R2] != 0);
*(uint32_t **)regs[REG_R1] = regs;
tcb->xcp.regs = (uint32_t *)regs[REG_R2];
new_regs = (uint32_t *)regs[REG_R2];
}
break;
@@ -446,12 +447,12 @@ int arm_svcall(int irq, void *context, void *arg)
* switch.
*/
if (regs != tcb->xcp.regs)
if (regs != new_regs)
{
restore_critical_section(tcb, this_cpu());
#ifdef CONFIG_DEBUG_SYSCALL_INFO
regs = (uint32_t *)tcb->xcp.regs;
regs = new_regs;
svcinfo("SVCall Return:\n");
svcinfo(" R0: %08x %08x %08x %08x %08x %08x %08x %08x\n",

View File

@@ -160,5 +160,7 @@ retry:
leave_critical_section(regs[REG_CPSR]);
rtcb->irqcount--;
#endif
g_running_tasks[this_cpu()] = NULL;
arm_fullcontextrestore(regs);
}

View File

@@ -159,9 +159,9 @@ static void dispatch_syscall(void)
uint32_t *arm_syscall(uint32_t *regs)
{
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
struct tcb_s *tcb = this_task();
uint32_t cmd;
int cpu;
#ifdef CONFIG_BUILD_KERNEL
uint32_t cpsr;
#endif
@@ -170,7 +170,10 @@ uint32_t *arm_syscall(uint32_t *regs)
DEBUGASSERT(up_current_regs() == NULL);
tcb->xcp.regs = regs;
if (*running_task != NULL)
{
(*running_task)->xcp.regs = regs;
}
/* Current regs non-zero indicates that we are processing an interrupt;
* current_regs is also used to manage interrupt level context switches.
@@ -296,11 +299,6 @@ uint32_t *arm_syscall(uint32_t *regs)
*/
case SYS_switch_context:
{
DEBUGASSERT(regs[REG_R1] != 0 && regs[REG_R2] != 0);
*(uint32_t **)regs[REG_R1] = regs;
tcb->xcp.regs = (uint32_t *)regs[REG_R2];
}
break;
/* R0=SYS_task_start: This a user task start
@@ -566,7 +564,7 @@ uint32_t *arm_syscall(uint32_t *regs)
break;
}
if (regs != tcb->xcp.regs)
if (*running_task != tcb)
{
#ifdef CONFIG_ARCH_ADDRENV
/* Make sure that the address environment for the previously
@@ -578,23 +576,20 @@ uint32_t *arm_syscall(uint32_t *regs)
addrenv_switch(NULL);
#endif
cpu = this_cpu();
tcb = current_task(cpu);
/* Update scheduler parameters */
nxsched_suspend_scheduler(g_running_tasks[cpu]);
nxsched_suspend_scheduler(*running_task);
nxsched_resume_scheduler(tcb);
/* Record the new "running" task. g_running_tasks[] is only used by
* assertion logic for reporting crashes.
*/
g_running_tasks[cpu] = tcb;
*running_task = tcb;
/* Restore the cpu lock */
restore_critical_section(tcb, cpu);
restore_critical_section(tcb, this_cpu());
regs = tcb->xcp.regs;
}

View File

@@ -56,7 +56,13 @@ void exception_direct(void)
uint32_t *arm_doirq(int irq, uint32_t *regs)
{
struct tcb_s *tcb = this_task();
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
FAR struct tcb_s *tcb;
if (*running_task != NULL)
{
(*running_task)->xcp.regs = regs;
}
board_autoled_on(LED_INIRQ);
#ifdef CONFIG_SUPPRESS_INTERRUPTS
@@ -80,13 +86,9 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
#endif
up_irq_save();
g_running_tasks[this_cpu()]->xcp.regs = regs;
}
else
{
/* Dispatch irq */
tcb->xcp.regs = regs;
irq_dispatch(irq, regs);
}
@@ -100,7 +102,7 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
/* Update scheduler parameters */
nxsched_suspend_scheduler(g_running_tasks[this_cpu()]);
nxsched_suspend_scheduler(*running_task);
nxsched_resume_scheduler(tcb);
/* Record the new "running" task when context switch occurred.
@@ -108,7 +110,7 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
* crashes.
*/
g_running_tasks[this_cpu()] = tcb;
*running_task = tcb;
regs = tcb->xcp.regs;
#endif

View File

@@ -127,6 +127,7 @@ 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;
uint32_t cmd;
cmd = regs[REG_R0];
@@ -176,6 +177,7 @@ int arm_svcall(int irq, void *context, void *arg)
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;
@@ -200,8 +202,7 @@ int arm_svcall(int irq, void *context, void *arg)
case SYS_switch_context:
{
DEBUGASSERT(regs[REG_R1] != 0 && regs[REG_R2] != 0);
*(uint32_t **)regs[REG_R1] = regs;
tcb->xcp.regs = (uint32_t *)regs[REG_R2];
new_regs = (uint32_t *)regs[REG_R2];
}
break;
@@ -456,12 +457,12 @@ int arm_svcall(int irq, void *context, void *arg)
* switch.
*/
if (regs != tcb->xcp.regs)
if (regs != new_regs)
{
restore_critical_section(tcb, this_cpu());
#ifdef CONFIG_DEBUG_SYSCALL_INFO
regs = (uint32_t *)tcb->xcp.regs;
regs = new_regs;
svcinfo("SVCall Return:\n");
svcinfo(" R0: %08x %08x %08x %08x %08x %08x %08x %08x\n",

View File

@@ -157,5 +157,7 @@ retry:
leave_critical_section(regs[REG_CPSR]);
rtcb->irqcount--;
#endif
g_running_tasks[this_cpu()] = NULL;
arm_fullcontextrestore(regs);
}

View File

@@ -156,10 +156,9 @@ static void dispatch_syscall(void)
uint32_t *arm_syscall(uint32_t *regs)
{
struct tcb_s *tcb = this_task();
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
FAR struct tcb_s *tcb = this_task();
uint32_t cmd;
int cpu;
#ifdef CONFIG_BUILD_PROTECTED
uint32_t cpsr;
#endif
@@ -168,7 +167,10 @@ uint32_t *arm_syscall(uint32_t *regs)
DEBUGASSERT(up_current_regs() == NULL);
tcb->xcp.regs = regs;
if (*running_task != NULL)
{
(*running_task)->xcp.regs = regs;
}
/* Current regs non-zero indicates that we are processing an interrupt;
* current_regs is also used to manage interrupt level context switches.
@@ -294,11 +296,6 @@ uint32_t *arm_syscall(uint32_t *regs)
*/
case SYS_switch_context:
{
DEBUGASSERT(regs[REG_R1] != 0 && regs[REG_R2] != 0);
*(uint32_t **)regs[REG_R1] = regs;
tcb->xcp.regs = (uint32_t *)regs[REG_R2];
}
break;
/* R0=SYS_task_start: This a user task start
@@ -564,24 +561,22 @@ uint32_t *arm_syscall(uint32_t *regs)
break;
}
if (regs != tcb->xcp.regs)
if (*running_task != tcb)
{
cpu = this_cpu();
/* Update scheduler parameters */
nxsched_suspend_scheduler(g_running_tasks[cpu]);
nxsched_suspend_scheduler(*running_task);
nxsched_resume_scheduler(tcb);
/* Record the new "running" task. g_running_tasks[] is only used by
* assertion logic for reporting crashes.
*/
g_running_tasks[cpu] = tcb;
*running_task = tcb;
/* Restore the cpu lock */
restore_critical_section(tcb, cpu);
restore_critical_section(tcb, this_cpu());
regs = tcb->xcp.regs;
}

View File

@@ -67,7 +67,13 @@ void exception_direct(void)
uint32_t *arm_doirq(int irq, uint32_t *regs)
{
struct tcb_s *tcb = this_task();
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
FAR struct tcb_s *tcb;
if (*running_task != NULL)
{
(*running_task)->xcp.regs = regs;
}
board_autoled_on(LED_INIRQ);
#ifdef CONFIG_SUPPRESS_INTERRUPTS
@@ -91,13 +97,9 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
#endif
up_irq_save();
g_running_tasks[this_cpu()]->xcp.regs = regs;
}
else
{
/* Dispatch irq */
tcb->xcp.regs = regs;
irq_dispatch(irq, regs);
}
@@ -111,7 +113,7 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
/* Update scheduler parameters */
nxsched_suspend_scheduler(g_running_tasks[this_cpu()]);
nxsched_suspend_scheduler(*running_task);
nxsched_resume_scheduler(tcb);
/* Record the new "running" task when context switch occurred.
@@ -119,7 +121,7 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
* crashes.
*/
g_running_tasks[this_cpu()] = tcb;
*running_task = tcb;
regs = tcb->xcp.regs;
#endif

View File

@@ -127,6 +127,7 @@ 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;
uint32_t cmd;
cmd = regs[REG_R0];
@@ -176,6 +177,7 @@ int arm_svcall(int irq, void *context, void *arg)
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;
@@ -200,8 +202,7 @@ int arm_svcall(int irq, void *context, void *arg)
case SYS_switch_context:
{
DEBUGASSERT(regs[REG_R1] != 0 && regs[REG_R2] != 0);
*(uint32_t **)regs[REG_R1] = regs;
tcb->xcp.regs = (uint32_t *)regs[REG_R2];
new_regs = (uint32_t *)regs[REG_R2];
}
break;
@@ -456,12 +457,12 @@ int arm_svcall(int irq, void *context, void *arg)
* switch.
*/
if (regs != tcb->xcp.regs)
if (regs != new_regs)
{
restore_critical_section(tcb, this_cpu());
#ifdef CONFIG_DEBUG_SYSCALL_INFO
regs = (uint32_t *)tcb->xcp.regs;
regs = new_regs;
svcinfo("SVCall Return:\n");
svcinfo(" R0: %08x %08x %08x %08x %08x %08x %08x %08x\n",

View File

@@ -155,5 +155,7 @@ retry:
leave_critical_section(regs[REG_CPSR]);
rtcb->irqcount--;
#endif
g_running_tasks[this_cpu()] = NULL;
arm_fullcontextrestore(regs);
}

View File

@@ -156,9 +156,9 @@ static void dispatch_syscall(void)
uint32_t *arm_syscall(uint32_t *regs)
{
struct tcb_s *tcb = this_task();
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
FAR struct tcb_s *tcb = this_task();
uint32_t cmd;
int cpu;
#ifdef CONFIG_BUILD_PROTECTED
uint32_t cpsr;
#endif
@@ -167,7 +167,10 @@ uint32_t *arm_syscall(uint32_t *regs)
DEBUGASSERT(up_current_regs() == NULL);
tcb->xcp.regs = regs;
if (*running_task != NULL)
{
(*running_task)->xcp.regs = regs;
}
/* Current regs non-zero indicates that we are processing an interrupt;
* current_regs is also used to manage interrupt level context switches.
@@ -293,11 +296,6 @@ uint32_t *arm_syscall(uint32_t *regs)
*/
case SYS_switch_context:
{
DEBUGASSERT(regs[REG_R1] != 0 && regs[REG_R2] != 0);
*(uint32_t **)regs[REG_R1] = regs;
tcb->xcp.regs = (uint32_t *)regs[REG_R2];
}
break;
/* R0=SYS_task_start: This a user task start
@@ -563,24 +561,22 @@ uint32_t *arm_syscall(uint32_t *regs)
break;
}
if (regs != tcb->xcp.regs)
if (*running_task != tcb)
{
cpu = this_cpu();
/* Update scheduler parameters */
nxsched_suspend_scheduler(g_running_tasks[cpu]);
nxsched_suspend_scheduler(*running_task);
nxsched_resume_scheduler(tcb);
/* Record the new "running" task. g_running_tasks[] is only used by
* assertion logic for reporting crashes.
*/
g_running_tasks[cpu] = tcb;
*running_task = tcb;
/* Restore the cpu lock */
restore_critical_section(tcb, cpu);
restore_critical_section(tcb, this_cpu());
regs = tcb->xcp.regs;
}

View File

@@ -160,5 +160,7 @@ retry:
leave_critical_section(flags);
rtcb->irqcount--;
#endif
g_running_tasks[this_cpu()] = NULL;
arm64_fullcontextrestore(rtcb);
}

View File

@@ -154,14 +154,19 @@ uintptr_t dispatch_syscall(unsigned int nbr, uintptr_t parm1,
uint64_t *arm64_syscall(uint64_t *regs)
{
uint64_t *ret_regs = regs;
uint64_t cmd;
struct tcb_s *tcb;
int cpu;
int cpu = this_cpu();
struct tcb_s **running_task = &g_running_tasks[cpu];
struct tcb_s *tcb = this_task();
uint64_t cmd;
#ifdef CONFIG_BUILD_KERNEL
uint64_t spsr;
#endif
if (*running_task != NULL)
{
(*running_task)->xcp.regs = regs;
}
/* Nested interrupts are not supported */
DEBUGASSERT(regs);
@@ -186,17 +191,6 @@ uint64_t *arm64_syscall(uint64_t *regs)
*/
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 = (struct tcb_s *)regs[REG_X1];
ret_regs = tcb->xcp.regs;
DEBUGASSERT(ret_regs);
}
break;
/* x0 = SYS_switch_context: This a switch context command:
@@ -216,15 +210,6 @@ uint64_t *arm64_syscall(uint64_t *regs)
*/
case SYS_switch_context:
{
struct tcb_s *rtcb = (struct tcb_s *)regs[REG_X1];
tcb = (struct tcb_s *)regs[REG_X2];
DEBUGASSERT(regs[REG_X1] != 0 && regs[REG_X2] != 0);
rtcb->xcp.regs = regs;
ret_regs = tcb->xcp.regs;
}
break;
#ifdef CONFIG_BUILD_KERNEL
@@ -331,15 +316,13 @@ uint64_t *arm64_syscall(uint64_t *regs)
default:
{
svcerr("ERROR: Bad SYS call: 0x%" PRIx64 "\n", cmd);
ret_regs = 0;
return 0;
}
break;
}
if ((uint64_t *)regs != ret_regs)
if (*running_task != tcb)
{
cpu = this_cpu();
tcb = current_task(cpu);
#ifdef CONFIG_ARCH_ADDRENV
@@ -354,19 +337,19 @@ uint64_t *arm64_syscall(uint64_t *regs)
/* Update scheduler parameters */
nxsched_suspend_scheduler(g_running_tasks[cpu]);
nxsched_suspend_scheduler(*running_task);
nxsched_resume_scheduler(tcb);
/* Record the new "running" task. g_running_tasks[] is only used by
* assertion logic for reporting crashes.
*/
g_running_tasks[cpu] = tcb;
*running_task = tcb;
/* Restore the cpu lock */
restore_critical_section(tcb, cpu);
}
return ret_regs;
return tcb->xcp.regs;
}

View File

@@ -57,6 +57,13 @@
uint8_t *avr_doirq(uint8_t irq, uint8_t *regs)
{
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
if (*running_task != NULL)
{
avr_copystate((*running_task)->xcp.regs, regs);
}
board_autoled_on(LED_INIRQ);
#ifdef CONFIG_SUPPRESS_INTERRUPTS
PANIC();

View File

@@ -58,6 +58,13 @@
uint32_t *avr_doirq(int irq, uint32_t *regs)
{
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
if (*running_task != NULL)
{
avr_copystate((*running_task)->xcp.regs, regs);
}
board_autoled_on(LED_INIRQ);
#ifdef CONFIG_SUPPRESS_INTERRUPTS
PANIC();

View File

@@ -59,6 +59,13 @@ uint32_t *ceva_doirq(int irq, uint32_t *regs)
}
else
{
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
if (*running_task != NULL)
{
(*running_task)->xcp.regs = regs;
}
/* Current regs non-zero indicates that we are processing an interrupt;
* current_regs is also used to manage interrupt level context
* switches.
@@ -80,7 +87,7 @@ uint32_t *ceva_doirq(int irq, uint32_t *regs)
{
/* Update scheduler parameters */
nxsched_suspend_scheduler(g_running_tasks[this_cpu()]);
nxsched_suspend_scheduler(*running_task);
nxsched_resume_scheduler(this_task());
/* Record the new "running" task when context switch occurred.

View File

@@ -78,6 +78,8 @@ void _exit(int status)
sched_resume_scheduler(tcb);
g_running_tasks[this_cpu()] = tcb;
/* Then switch contexts */
ceva_fullcontextrestore(tcb->xcp.regs);

View File

@@ -58,6 +58,13 @@
uint8_t *hc_doirq(int irq, uint8_t *regs)
{
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
if (*running_task != NULL)
{
hc_copystate((*running_task)->xcp.regs);
}
board_autoled_on(LED_INIRQ);
#ifdef CONFIG_SUPPRESS_INTERRUPTS
PANIC();

View File

@@ -58,6 +58,13 @@
uint32_t *mips_doirq(int irq, uint32_t *regs)
{
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
if (*running_task != NULL)
{
mips_copystate((*running_task)->xcp.regs, regs);
}
board_autoled_on(LED_INIRQ);
#ifdef CONFIG_SUPPRESS_INTERRUPTS
PANIC();

View File

@@ -70,12 +70,18 @@
uint32_t *pic32mx_decodeirq(uint32_t *regs)
{
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
#ifdef CONFIG_PIC32MX_NESTED_INTERRUPTS
uint32_t *savestate;
#endif
uint32_t regval;
int irq;
if (*running_task != NULL)
{
mips_copystate((*running_task)->xcp.regs, regs);
}
/* If the board supports LEDs, turn on an LED now to indicate that we are
* processing an interrupt.
*/

View File

@@ -53,11 +53,17 @@
uint32_t *pic32mx_exception(uint32_t *regs)
{
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
#ifdef CONFIG_DEBUG_FEATURES
uint32_t cause;
uint32_t epc;
#endif
if (*running_task != NULL)
{
mips_copystate((*running_task)->xcp.regs, regs);
}
/* If the board supports LEDs, turn on an LED now to indicate that we are
* processing an interrupt.
*/

View File

@@ -69,6 +69,13 @@
uint32_t *pic32mz_decodeirq(uint32_t *regs)
{
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
if (*running_task != NULL)
{
mips_copystate((*running_task)->xcp.regs, regs);
}
#ifdef CONFIG_PIC32MZ_NESTED_INTERRUPTS
uint32_t *savestate;
#endif

View File

@@ -52,11 +52,17 @@
uint32_t *pic32mz_exception(uint32_t *regs)
{
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
#ifdef CONFIG_DEBUG_FEATURES
uint32_t cause;
uint32_t epc;
#endif
if (*running_task != NULL)
{
mips_copystate((*running_task)->xcp.regs, regs);
}
/* If the board supports LEDs, turn on an LED now to indicate that we are
* processing an interrupt.
*/

View File

@@ -45,6 +45,13 @@
uint32_t *lm32_doirq(int irq, uint32_t *regs)
{
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
if (*running_task != NULL)
{
lm32_copystate((*running_task)->xcp.regs, regs);
}
board_autoled_on(LED_INIRQ);
/* Current regs non-zero indicates that we are processing an interrupt;

View File

@@ -45,6 +45,13 @@
uint32_t *minerva_doirq(int irq, uint32_t * regs)
{
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
if (*running_task != NULL)
{
minerva_copystate((*running_task)->xcp.regs, regs);
}
board_autoled_on(LED_INIRQ);
/* Current regs non-zero indicates that we are processing an interrupt;

View File

@@ -41,6 +41,13 @@
uint32_t *or1k_doirq(int irq, uint32_t *regs)
{
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
if (*running_task != NULL)
{
or1k_copyfullstate((*running_task)->xcp.regs, regs);
}
board_autoled_on(LED_INIRQ);
#ifdef CONFIG_SUPPRESS_INTERRUPTS
PANIC();

View File

@@ -58,6 +58,13 @@
uint32_t *renesas_doirq(int irq, uint32_t * regs)
{
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
if (*running_task != NULL)
{
renesas_copystate((*running_task)->xcp.regs, regs);
}
board_autoled_on(LED_INIRQ);
#ifdef CONFIG_SUPPRESS_INTERRUPTS
PANIC();

View File

@@ -99,7 +99,7 @@ uintreg_t *riscv_doirq(int irq, uintreg_t *regs)
* returning from the interrupt.
*/
if ((*running_task) != tcb)
if (*running_task != tcb)
{
#ifdef CONFIG_ARCH_ADDRENV
/* Make sure that the address environment for the previously
@@ -113,7 +113,7 @@ uintreg_t *riscv_doirq(int irq, uintreg_t *regs)
/* Update scheduler parameters */
nxsched_suspend_scheduler(g_running_tasks[this_cpu()]);
nxsched_suspend_scheduler(*running_task);
nxsched_resume_scheduler(tcb);
/* Record the new "running" task when context switch occurred.

View File

@@ -54,7 +54,7 @@ void *riscv_perform_syscall(uintreg_t *regs)
riscv_swint(0, regs, NULL);
tcb = this_task();
if ((*running_task) != tcb)
if (*running_task != tcb)
{
#ifdef CONFIG_ARCH_ADDRENV
/* Make sure that the address environment for the previously
@@ -67,7 +67,7 @@ void *riscv_perform_syscall(uintreg_t *regs)
#endif
/* Update scheduler parameters */
nxsched_suspend_scheduler(g_running_tasks[this_cpu()]);
nxsched_suspend_scheduler(*running_task);
nxsched_resume_scheduler(tcb);
/* Record the new "running" task. g_running_tasks[] is only used by

View File

@@ -63,6 +63,13 @@ void *sim_doirq(int irq, void *context)
sim_saveusercontext(regs, ret);
if (ret == 0)
{
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
if (*running_task != NULL)
{
sim_copyfullstate((*running_task)->xcp.regs, regs);
}
up_set_current_regs(regs);
/* Deliver the IRQ */

View File

@@ -58,6 +58,13 @@
uint32_t *sparc_doirq(int irq, uint32_t *regs)
{
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
if (*running_task != NULL)
{
trap_flush_task((*running_task)->xcp.regs, regs);
}
board_autoled_on(LED_INIRQ);
#ifdef CONFIG_SUPPRESS_INTERRUPTS
PANIC();

View File

@@ -44,12 +44,19 @@
IFX_INTERRUPT_INTERNAL(tricore_doirq, 0, 255)
{
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
#ifdef CONFIG_SUPPRESS_INTERRUPTS
PANIC();
#else
Ifx_CPU_ICR icr;
uintptr_t *regs;
if (*running_task != NULL)
{
(*running_task)->xcp.regs = regs;
}
icr.U = __mfcr(CPU_ICR);
regs = (uintptr_t *)__mfcr(CPU_PCXI);

View File

@@ -76,6 +76,7 @@ static void idt_outb(uint8_t val, uint16_t addr)
#ifndef CONFIG_SUPPRESS_INTERRUPTS
static uint32_t *common_handler(int irq, uint32_t *regs)
{
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
board_autoled_on(LED_INIRQ);
/* Current regs non-zero indicates that we are processing an interrupt;
@@ -87,6 +88,11 @@ static uint32_t *common_handler(int irq, uint32_t *regs)
DEBUGASSERT(up_current_regs() == NULL);
up_set_current_regs(regs);
if (*running_task != NULL)
{
x86_savestate((*running_task)->xcp.regs);
}
/* Deliver the IRQ */
irq_dispatch(irq, regs);
@@ -118,7 +124,7 @@ static uint32_t *common_handler(int irq, uint32_t *regs)
/* Update scheduler parameters */
nxsched_suspend_scheduler(g_running_tasks[this_cpu()]);
nxsched_suspend_scheduler(*running_task);
nxsched_resume_scheduler(this_task());
/* Record the new "running" task when context switch occurred.
@@ -126,7 +132,7 @@ static uint32_t *common_handler(int irq, uint32_t *regs)
* crashes.
*/
g_running_tasks[this_cpu()] = this_task();
*running_task = this_task();
}
/* If a context switch occurred while processing the interrupt then

View File

@@ -62,9 +62,15 @@
#ifndef CONFIG_SUPPRESS_INTERRUPTS
static uint64_t *common_handler(int irq, uint64_t *regs)
{
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
struct tcb_s *tcb;
int cpu;
if (*running_task != NULL)
{
(*running_task)->xcp.regs = regs;
}
/* Current regs non-zero indicates that we are processing an interrupt;
* g_current_regs is also used to manage interrupt level context switches.
*
@@ -99,7 +105,7 @@ static uint64_t *common_handler(int irq, uint64_t *regs)
/* Update scheduler parameters */
cpu = this_cpu();
nxsched_suspend_scheduler(g_running_tasks[cpu]);
nxsched_suspend_scheduler(*running_task);
nxsched_resume_scheduler(this_task());
/* Record the new "running" task when context switch occurred.
@@ -146,6 +152,13 @@ static uint64_t *common_handler(int irq, uint64_t *regs)
uint64_t *isr_handler(uint64_t *regs, uint64_t irq)
{
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
if (*running_task != NULL)
{
(*running_task)->xcp.regs = regs;
}
board_autoled_on(LED_INIRQ);
#ifdef CONFIG_SUPPRESS_INTERRUPTS

View File

@@ -65,6 +65,13 @@
void xtensa_panic(int xptcode, uint32_t *regs)
{
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
if (*running_task != NULL)
{
(*running_task)->xcp.regs = regs;
}
up_set_current_regs(regs);
/* We get here when a un-dispatch-able, irrecoverable exception occurs */

View File

@@ -44,7 +44,8 @@
uint32_t *xtensa_irq_dispatch(int irq, uint32_t *regs)
{
struct tcb_s *tcb = this_task();
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
struct tcb_s *tcb;
#ifdef CONFIG_SUPPRESS_INTERRUPTS
board_autoled_on(LED_INIRQ);
@@ -64,11 +65,9 @@ uint32_t *xtensa_irq_dispatch(int irq, uint32_t *regs)
up_set_current_regs(regs);
if (irq != XTENSA_IRQ_SWINT)
if (*running_task != NULL)
{
/* we are not trigger by syscall */
tcb->xcp.regs = regs;
(*running_task)->xcp.regs = regs;
}
/* Deliver the IRQ */
@@ -80,7 +79,7 @@ uint32_t *xtensa_irq_dispatch(int irq, uint32_t *regs)
* current_regs will have a different value than it did on entry.
*/
if (regs != tcb->xcp.regs)
if (*running_task != tcb)
{
#ifdef CONFIG_ARCH_ADDRENV
/* Make sure that the address environment for the previously
@@ -94,16 +93,15 @@ uint32_t *xtensa_irq_dispatch(int irq, uint32_t *regs)
/* Update scheduler parameters */
nxsched_suspend_scheduler(g_running_tasks[this_cpu()]);
nxsched_resume_scheduler(this_task());
nxsched_suspend_scheduler(*running_task);
nxsched_resume_scheduler(tcb);
/* Record the new "running" task when context switch occurred.
* g_running_tasks[] is only used by assertion logic for reporting
* crashes.
*/
g_running_tasks[this_cpu()] = tcb;
regs = tcb->xcp.regs;
*running_task = tcb;
}
/* Set current_regs to NULL to indicate that we are no longer in an
@@ -114,5 +112,5 @@ uint32_t *xtensa_irq_dispatch(int irq, uint32_t *regs)
#endif
board_autoled_off(LED_INIRQ);
return regs;
return tcb->xcp.regs;
}

View File

@@ -59,12 +59,12 @@ int xtensa_swint(int irq, void *context, void *arg)
{
uint32_t *regs = (uint32_t *)context;
struct tcb_s *tcb = this_task();
uintptr_t *new_regs = regs;
uint32_t cmd;
DEBUGASSERT(regs != NULL);
cmd = regs[REG_A2];
tcb->xcp.regs = regs;
/* The syscall software interrupt is called with A2 = system call command
* and A3..A9 = variable number of arguments depending on the system call.
@@ -119,6 +119,7 @@ int xtensa_swint(int irq, void *context, void *arg)
case SYS_restore_context:
{
DEBUGASSERT(regs[REG_A3] != 0);
new_regs = (uint32_t *)regs[REG_A3];
tcb->xcp.regs = (uint32_t *)regs[REG_A3];
}
break;
@@ -142,9 +143,8 @@ int xtensa_swint(int irq, void *context, void *arg)
case SYS_switch_context:
{
DEBUGASSERT(regs[REG_A3] != 0 && regs[REG_A4] != 0);
*(uint32_t **)regs[REG_A3] = regs;
tcb->xcp.regs = (uint32_t *)regs[REG_A4];
DEBUGASSERT(regs[REG_A4] != 0);
new_regs = (uint32_t *)regs[REG_A4];
}
break;
@@ -432,10 +432,10 @@ int xtensa_swint(int irq, void *context, void *arg)
*/
#ifdef CONFIG_DEBUG_SYSCALL_INFO
if (regs != tcb->xcp.regs)
if (regs != new_regs)
{
svcinfo("SYSCALL Return: Context switch!\n");
up_dump_register(tcb->xcp.regs);
up_dump_register(new_regs);
}
else
{
@@ -443,7 +443,7 @@ int xtensa_swint(int irq, void *context, void *arg)
}
#endif
if (regs != tcb->xcp.regs)
if (regs != new_regs)
{
restore_critical_section(this_task(), this_cpu());
}

View File

@@ -58,8 +58,14 @@ FAR chipreg_t *z16_doirq(int irq, FAR chipreg_t *regs)
#else
if ((unsigned)irq < NR_IRQS)
{
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
FAR chipreg_t *savestate;
if (*running_task != NULL)
{
z16_copystate((*running_task)->xcp.regs, regs)
}
/* Nested interrupts are not supported in this implementation. If
* you want to implement nested interrupts, you would have to (1)
* change the way that g_current_regs is handled and (2) the design

View File

@@ -47,8 +47,14 @@
void z16f_sysexec(FAR chipreg_t *regs)
{
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
uint16_t excp;
if (*running_task != NULL)
{
z16_copystate((*running_task)->xcp.regs, regs)
}
/* Save that register reference so that it can be used for built-in
* diagnostics.
*/

View File

@@ -44,6 +44,13 @@
FAR chipreg_t *z80_doirq(uint8_t irq, FAR chipreg_t *regs)
{
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
if (*running_task != NULL)
{
z80_copystate((*running_task)->xcp.regs, regs)
}
board_autoled_on(LED_INIRQ);
DECL_SAVESTATE();

View File

@@ -181,17 +181,17 @@ static int tcbinfo_close(FAR struct file *filep)
}
/****************************************************************************
* Name: tcbinfo_current_regs
* Name: tcbinfo_running_regs
*
* Description:
* A special version of up_current_regs() that is non-optimized.
* A special version of running_regs() that is non-optimized.
*
****************************************************************************/
nooptimiziation_function
FAR static void *tcbinfo_current_regs(void)
FAR static void *tcbinfo_running_regs(void)
{
return up_current_regs();
return running_regs();
}
/****************************************************************************
@@ -217,8 +217,8 @@ static ssize_t tcbinfo_read(FAR struct file *filep, FAR char *buffer,
{
linesize = procfs_snprintf(attr->line, TCBINFO_LINELEN,
"pointer %p size %zu current regs %p\n",
&g_tcbinfo, sizeof(struct tcbinfo_s),
tcbinfo_current_regs());
&g_tcbinfo, sizeof(struct tcbinfo_s),
tcbinfo_running_regs());
/* Save the linesize in case we are re-entered with f_pos > 0 */

View File

@@ -244,6 +244,8 @@
# define this_cpu() (0)
#endif
#define running_regs() ((void *)(g_running_tasks[this_cpu()]->xcp.regs))
/****************************************************************************
* Public Type Definitions
****************************************************************************/
@@ -872,6 +874,12 @@ EXTERN clock_t g_premp_max[CONFIG_SMP_NCPUS];
EXTERN clock_t g_crit_max[CONFIG_SMP_NCPUS];
#endif /* CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0 */
/* g_running_tasks[] holds a references to the running task for each CPU.
* It is valid only when up_interrupt_context() returns true.
*/
EXTERN FAR struct tcb_s *g_running_tasks[CONFIG_SMP_NCPUS];
EXTERN const struct tcbinfo_s g_tcbinfo;
/****************************************************************************

View File

@@ -1039,7 +1039,7 @@ static void gdb_get_registers(FAR struct gdb_state_s *state)
{
if (up_interrupt_context())
{
reg = (FAR uint8_t *)up_current_regs();
reg = (FAR uint8_t *)running_regs();
}
else
{

View File

@@ -129,7 +129,7 @@ dq_queue_t g_assignedtasks[CONFIG_SMP_NCPUS];
FAR struct tcb_s *g_delivertasks[CONFIG_SMP_NCPUS];
#endif
/* g_running_tasks[] holds a references to the running task for each cpu.
/* g_running_tasks[] holds a references to the running task for each CPU.
* It is valid only when up_interrupt_context() returns true.
*/

View File

@@ -304,7 +304,7 @@ static void dump_stacks(FAR struct tcb_s *rtcb, uintptr_t sp)
/* Try to restore SP from current_regs if assert from interrupt. */
tcbstack_sp = up_interrupt_context() ?
up_getusrsp((FAR void *)up_current_regs()) : 0;
up_getusrsp((FAR void *)running_regs()) : 0;
if (tcbstack_sp < tcbstack_base || tcbstack_sp >= tcbstack_top)
{
tcbstack_sp = 0;
@@ -607,7 +607,7 @@ static void dump_deadlock(void)
static noreturn_function int pause_cpu_handler(FAR void *arg)
{
memcpy(g_last_regs[this_cpu()], up_current_regs(), sizeof(g_last_regs[0]));
memcpy(g_last_regs[this_cpu()], running_regs(), sizeof(g_last_regs[0]));
g_cpu_paused[this_cpu()] = true;
up_flush_dcache_all();
while (1);

View File

@@ -309,7 +309,7 @@ static void elf_emit_tcb_note(FAR struct elf_dumpinfo_s *cinfo,
{
if (up_interrupt_context())
{
regs = (FAR uintptr_t *)up_current_regs();
regs = (FAR uintptr_t *)running_regs();
}
else
{

View File

@@ -197,12 +197,6 @@ extern dq_queue_t g_assignedtasks[CONFIG_SMP_NCPUS];
extern FAR struct tcb_s *g_delivertasks[CONFIG_SMP_NCPUS];
/* g_running_tasks[] holds a references to the running task for each cpu.
* It is valid only when up_interrupt_context() returns true.
*/
extern FAR struct tcb_s *g_running_tasks[CONFIG_SMP_NCPUS];
/* This is the list of all tasks that are ready-to-run, but cannot be placed
* in the g_readytorun list because: (1) They are higher priority than the
* currently active task at the head of the g_readytorun list, and (2) the

View File

@@ -82,7 +82,7 @@ class Nxsetregs(gdb.Command):
super(Nxsetregs, self).__init__("nxsetregs", gdb.COMMAND_USER)
def invoke(self, args, from_tty):
gdb.execute("set $_current_regs=tcbinfo_current_regs()")
gdb.execute("set $_current_regs=tcbinfo_running_regs()")
current_regs = gdb.parse_and_eval("$_current_regs")
tcbinfo = gdb.parse_and_eval("g_tcbinfo")
arg = args.split(" ")