mirror of
https://github.com/apache/nuttx.git
synced 2025-12-11 12:57:57 +08:00
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:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -160,5 +160,7 @@ retry:
|
||||
leave_critical_section(regs[REG_CPSR]);
|
||||
rtcb->irqcount--;
|
||||
#endif
|
||||
|
||||
g_running_tasks[this_cpu()] = NULL;
|
||||
arm_fullcontextrestore(regs);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -157,5 +157,7 @@ retry:
|
||||
leave_critical_section(regs[REG_CPSR]);
|
||||
rtcb->irqcount--;
|
||||
#endif
|
||||
|
||||
g_running_tasks[this_cpu()] = NULL;
|
||||
arm_fullcontextrestore(regs);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -155,5 +155,7 @@ retry:
|
||||
leave_critical_section(regs[REG_CPSR]);
|
||||
rtcb->irqcount--;
|
||||
#endif
|
||||
|
||||
g_running_tasks[this_cpu()] = NULL;
|
||||
arm_fullcontextrestore(regs);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -160,5 +160,7 @@ retry:
|
||||
leave_critical_section(flags);
|
||||
rtcb->irqcount--;
|
||||
#endif
|
||||
|
||||
g_running_tasks[this_cpu()] = NULL;
|
||||
arm64_fullcontextrestore(rtcb);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(" ")
|
||||
|
||||
Reference in New Issue
Block a user