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:
zhangyu117
2024-12-10 15:45:41 +08:00
committed by Xiang Xiao
parent 8a15aebfea
commit 6b755dea45
5 changed files with 20 additions and 51 deletions
+4 -4
View File
@@ -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);
}
}
+6 -8
View File
@@ -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.
*/
}
}