mirror of
https://github.com/apache/nuttx.git
synced 2026-05-21 13:13:08 +08:00
arch/tricore: optimize task switching process
g_current_regs is only used to determine if we are in irq, with other functionalities removed. Signed-off-by: zhangyu117 <zhangyu117@xiaomi.com>
This commit is contained in:
@@ -79,6 +79,8 @@ IFX_INTERRUPT_INTERNAL(tricore_doirq, 0, 255)
|
||||
|
||||
irq_dispatch(icr.B.CCPN, regs);
|
||||
|
||||
tcb = this_task();
|
||||
|
||||
/* Check for a context switch. If a context switch occurred, then
|
||||
* g_current_regs will have a different value than it did on entry. If an
|
||||
* interrupt level context switch has occurred, then restore the floating
|
||||
@@ -86,10 +88,8 @@ IFX_INTERRUPT_INTERNAL(tricore_doirq, 0, 255)
|
||||
* returning from the interrupt.
|
||||
*/
|
||||
|
||||
if (regs != up_current_regs())
|
||||
if (regs != tcb->xcp.regs)
|
||||
{
|
||||
tcb = this_task();
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
/* Make sure that the address environment for the previously
|
||||
* running task is closed down gracefully (data caches dump,
|
||||
@@ -112,7 +112,7 @@ IFX_INTERRUPT_INTERNAL(tricore_doirq, 0, 255)
|
||||
running_task = tcb;
|
||||
g_running_tasks[this_cpu()] = running_task;
|
||||
|
||||
__mtcr(CPU_PCXI, tricore_addr2csa(up_current_regs()));
|
||||
__mtcr(CPU_PCXI, tricore_addr2csa(tcb->xcp.regs));
|
||||
__isync();
|
||||
}
|
||||
|
||||
|
||||
@@ -204,11 +204,6 @@ extern uintptr_t __A0_MEM[]; /* End+1 of .data */
|
||||
* Inline Functions
|
||||
****************************************************************************/
|
||||
|
||||
/* Macros to handle saving and restoring interrupt state. */
|
||||
|
||||
#define tricore_savestate(regs) (regs = up_current_regs())
|
||||
#define tricore_restorestate(regs) (up_set_current_regs(regs))
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
@@ -117,16 +117,16 @@ void up_schedule_sigaction(struct tcb_s *tcb)
|
||||
* been delivered.
|
||||
*/
|
||||
|
||||
tricore_savestate(tcb->xcp.saved_regs);
|
||||
tcb->xcp.saved_regs = tcb->xcp.regs;
|
||||
|
||||
/* Create a new CSA for signal delivery. The new context
|
||||
* will borrow the process stack of the current tcb.
|
||||
*/
|
||||
|
||||
up_set_current_regs(tricore_alloc_csa((uintptr_t)
|
||||
tricore_sigdeliver,
|
||||
STACK_ALIGN_DOWN(up_getusrsp(tcb->xcp.regs)),
|
||||
PSW_IO_SUPERVISOR | PSW_CDE, true));
|
||||
tcb->xcp.regs =
|
||||
tricore_alloc_csa((uintptr_t)tricore_sigdeliver,
|
||||
STACK_ALIGN_DOWN(up_getusrsp(tcb->xcp.regs)),
|
||||
PSW_IO_SUPERVISOR | PSW_CDE, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,8 +151,9 @@ void up_schedule_sigaction(struct tcb_s *tcb)
|
||||
* will borrow the process stack of the current tcb.
|
||||
*/
|
||||
|
||||
tcb->xcp.regs = tricore_alloc_csa((uintptr_t)tricore_sigdeliver,
|
||||
STACK_ALIGN_DOWN(up_getusrsp(tcb->xcp.regs)),
|
||||
PSW_IO_SUPERVISOR | PSW_CDE, true);
|
||||
tcb->xcp.regs =
|
||||
tricore_alloc_csa((uintptr_t)tricore_sigdeliver,
|
||||
STACK_ALIGN_DOWN(up_getusrsp(tcb->xcp.regs)),
|
||||
PSW_IO_SUPERVISOR | PSW_CDE, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,14 +58,12 @@ void tricore_svcall(volatile void *trap)
|
||||
{
|
||||
struct tcb_s *running_task;
|
||||
struct tcb_s *tcb;
|
||||
int cpu = this_cpu();
|
||||
|
||||
uintptr_t *regs;
|
||||
uint32_t cmd;
|
||||
|
||||
regs = (uintptr_t *)__mfcr(CPU_PCXI);
|
||||
|
||||
running_task = g_running_tasks[cpu];
|
||||
running_task = g_running_tasks[this_cpu()];
|
||||
tcb = this_task();
|
||||
|
||||
/* DSYNC instruction should be executed immediately prior to the MTCR */
|
||||
@@ -102,14 +100,14 @@ void tricore_svcall(volatile void *trap)
|
||||
case SYS_restore_context:
|
||||
{
|
||||
tricore_reclaim_csa(regs[REG_UPCXI]);
|
||||
up_set_current_regs((uintptr_t *)regs[REG_D9]);
|
||||
tcb->xcp.regs = (uintptr_t *)regs[REG_D9];
|
||||
}
|
||||
break;
|
||||
|
||||
case SYS_switch_context:
|
||||
{
|
||||
*(uintptr_t **)regs[REG_D9] = tricore_csa2addr(regs[REG_UPCXI]);
|
||||
up_set_current_regs((uintptr_t *)regs[REG_D10]);
|
||||
tcb->xcp.regs = (uintptr_t *)regs[REG_D10];
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -120,7 +118,7 @@ void tricore_svcall(volatile void *trap)
|
||||
break;
|
||||
}
|
||||
|
||||
if (regs != up_current_regs())
|
||||
if (regs != tcb->xcp.regs)
|
||||
{
|
||||
/* Update scheduler parameters */
|
||||
|
||||
@@ -131,9 +129,9 @@ void tricore_svcall(volatile void *trap)
|
||||
* crashes.
|
||||
*/
|
||||
|
||||
g_running_tasks[cpu] = this_task();
|
||||
g_running_tasks[this_cpu()] = this_task();
|
||||
|
||||
regs[REG_UPCXI] = tricore_addr2csa(up_current_regs());
|
||||
regs[REG_UPCXI] = tricore_addr2csa(tcb->xcp.regs);
|
||||
|
||||
__isync();
|
||||
}
|
||||
|
||||
@@ -59,35 +59,10 @@
|
||||
|
||||
void up_switch_context(struct tcb_s *tcb, struct tcb_s *rtcb)
|
||||
{
|
||||
/* Are we in an interrupt handler? */
|
||||
|
||||
if (up_current_regs())
|
||||
{
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the g_current_regs into the OLD rtcb.
|
||||
*/
|
||||
|
||||
tricore_savestate(rtcb->xcp.regs);
|
||||
|
||||
/* Then switch contexts. Any necessary address environment
|
||||
* changes will be made when the interrupt returns.
|
||||
*/
|
||||
|
||||
tricore_restorestate(tcb->xcp.regs);
|
||||
}
|
||||
|
||||
/* No, then we will need to perform the user context switch */
|
||||
|
||||
else
|
||||
if (!up_current_regs())
|
||||
{
|
||||
/* Then switch contexts */
|
||||
|
||||
tricore_switchcontext(&rtcb->xcp.regs, tcb->xcp.regs);
|
||||
|
||||
/* tricore_switchcontext forces a context switch to the task at the
|
||||
* head of the ready-to-run list. It does not 'return' in the
|
||||
* normal sense. When it does return, it is because the blocked
|
||||
* task is again ready to run and has execution priority.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user