mirror of
https://github.com/apache/nuttx.git
synced 2026-05-31 14:27:37 +08:00
arch/tricore: syscall SYS_switch_context and SYS_restore_context use 0 para
after task switch optimization, we can just use g_running_tasks and this_task() without pass params Signed-off-by: zhangyu117 <zhangyu117@xiaomi.com>
This commit is contained in:
@@ -220,10 +220,9 @@ static inline_function uintptr_t up_getusrsp(void *regs)
|
|||||||
do { \
|
do { \
|
||||||
if (!up_interrupt_context()) \
|
if (!up_interrupt_context()) \
|
||||||
{ \
|
{ \
|
||||||
nxsched_switch_context(rtcb, tcb); \
|
sys_call0(SYS_switch_context); \
|
||||||
sys_call2(SYS_switch_context, (uintptr_t)&rtcb->xcp.regs, \
|
|
||||||
(uintptr_t)tcb->xcp.regs); \
|
|
||||||
} \
|
} \
|
||||||
|
UNUSED(rtcb); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
|||||||
@@ -46,8 +46,8 @@
|
|||||||
|
|
||||||
IFX_INTERRUPT_INTERNAL(tricore_doirq, 0, 255)
|
IFX_INTERRUPT_INTERNAL(tricore_doirq, 0, 255)
|
||||||
{
|
{
|
||||||
struct tcb_s *running_task = g_running_tasks[this_cpu()];
|
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
|
||||||
struct tcb_s *tcb;
|
struct tcb_s *tcb = this_task();
|
||||||
|
|
||||||
#ifdef CONFIG_SUPPRESS_INTERRUPTS
|
#ifdef CONFIG_SUPPRESS_INTERRUPTS
|
||||||
PANIC();
|
PANIC();
|
||||||
@@ -58,9 +58,9 @@ IFX_INTERRUPT_INTERNAL(tricore_doirq, 0, 255)
|
|||||||
icr.U = __mfcr(CPU_ICR);
|
icr.U = __mfcr(CPU_ICR);
|
||||||
regs = tricore_csa2addr(__mfcr(CPU_PCXI));
|
regs = tricore_csa2addr(__mfcr(CPU_PCXI));
|
||||||
|
|
||||||
if (running_task != NULL)
|
if (*running_task != NULL)
|
||||||
{
|
{
|
||||||
running_task->xcp.regs = regs;
|
(*running_task)->xcp.regs = regs;
|
||||||
}
|
}
|
||||||
|
|
||||||
board_autoled_on(LED_INIRQ);
|
board_autoled_on(LED_INIRQ);
|
||||||
@@ -77,11 +77,9 @@ IFX_INTERRUPT_INTERNAL(tricore_doirq, 0, 255)
|
|||||||
|
|
||||||
irq_dispatch(icr.B.CCPN, regs);
|
irq_dispatch(icr.B.CCPN, regs);
|
||||||
|
|
||||||
tcb = this_task();
|
|
||||||
|
|
||||||
/* Check for a context switch. */
|
/* Check for a context switch. */
|
||||||
|
|
||||||
if (regs != tcb->xcp.regs)
|
if (*running_task != tcb)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_ARCH_ADDRENV
|
#ifdef CONFIG_ARCH_ADDRENV
|
||||||
/* Make sure that the address environment for the previously
|
/* Make sure that the address environment for the previously
|
||||||
@@ -95,15 +93,14 @@ IFX_INTERRUPT_INTERNAL(tricore_doirq, 0, 255)
|
|||||||
|
|
||||||
/* Update scheduler parameters */
|
/* Update scheduler parameters */
|
||||||
|
|
||||||
nxsched_switch_context(running_task, tcb);
|
nxsched_switch_context(*running_task, tcb);
|
||||||
|
|
||||||
/* Record the new "running" task when context switch occurred.
|
/* Record the new "running" task when context switch occurred.
|
||||||
* g_running_tasks[] is only used by assertion logic for reporting
|
* g_running_tasks[] is only used by assertion logic for reporting
|
||||||
* crashes.
|
* crashes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
running_task = tcb;
|
*running_task = tcb;
|
||||||
g_running_tasks[this_cpu()] = running_task;
|
|
||||||
|
|
||||||
__mtcr(CPU_PCXI, tricore_addr2csa(tcb->xcp.regs));
|
__mtcr(CPU_PCXI, tricore_addr2csa(tcb->xcp.regs));
|
||||||
__isync();
|
__isync();
|
||||||
@@ -117,7 +114,7 @@ IFX_INTERRUPT_INTERNAL(tricore_doirq, 0, 255)
|
|||||||
* and will be marked as NULL to avoid misusage.
|
* and will be marked as NULL to avoid misusage.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
running_task->xcp.regs = NULL;
|
(*running_task)->xcp.regs = NULL;
|
||||||
board_autoled_off(LED_INIRQ);
|
board_autoled_off(LED_INIRQ);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,25 +56,17 @@
|
|||||||
|
|
||||||
void up_exit(int status)
|
void up_exit(int status)
|
||||||
{
|
{
|
||||||
struct tcb_s *tcb = this_task();
|
|
||||||
|
|
||||||
/* Destroy the task at the head of the ready to run list. */
|
/* Destroy the task at the head of the ready to run list. */
|
||||||
|
|
||||||
nxtask_exit();
|
nxtask_exit();
|
||||||
|
|
||||||
/* Now, perform the context switch to the new ready-to-run task at the
|
|
||||||
* head of the list.
|
|
||||||
*/
|
|
||||||
|
|
||||||
tcb = this_task();
|
|
||||||
|
|
||||||
/* Scheduler parameters will update inside syscall */
|
/* Scheduler parameters will update inside syscall */
|
||||||
|
|
||||||
g_running_tasks[this_cpu()] = NULL;
|
g_running_tasks[this_cpu()] = NULL;
|
||||||
|
|
||||||
/* Then switch contexts */
|
/* Then switch contexts */
|
||||||
|
|
||||||
tricore_fullcontextrestore(tcb->xcp.regs);
|
tricore_fullcontextrestore();
|
||||||
|
|
||||||
/* tricore_fullcontextrestore() should not return but could if the software
|
/* tricore_fullcontextrestore() should not return but could if the software
|
||||||
* interrupts are disabled.
|
* interrupts are disabled.
|
||||||
|
|||||||
@@ -129,10 +129,7 @@
|
|||||||
#define modreg32(v,m,a) putreg32((getreg32(a) & ~(m)) | ((v) & (m)), (a))
|
#define modreg32(v,m,a) putreg32((getreg32(a) & ~(m)) | ((v) & (m)), (a))
|
||||||
#define modreg64(v,m,a) putreg64((getreg64(a) & ~(m)) | ((v) & (m)), (a))
|
#define modreg64(v,m,a) putreg64((getreg64(a) & ~(m)) | ((v) & (m)), (a))
|
||||||
|
|
||||||
/* Context switching */
|
#define tricore_fullcontextrestore() sys_call0(SYS_restore_context)
|
||||||
|
|
||||||
#define tricore_fullcontextrestore(restoreregs) \
|
|
||||||
sys_call1(SYS_restore_context, (uintptr_t)restoreregs);
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Types
|
* Public Types
|
||||||
|
|||||||
@@ -116,5 +116,6 @@ retry:
|
|||||||
|
|
||||||
board_autoled_off(LED_SIGNAL);
|
board_autoled_off(LED_SIGNAL);
|
||||||
|
|
||||||
tricore_fullcontextrestore(regs);
|
rtcb->xcp.regs = regs;
|
||||||
|
tricore_fullcontextrestore();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,16 +56,13 @@
|
|||||||
|
|
||||||
void tricore_svcall(volatile void *trap)
|
void tricore_svcall(volatile void *trap)
|
||||||
{
|
{
|
||||||
struct tcb_s *running_task;
|
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
|
||||||
struct tcb_s *tcb;
|
struct tcb_s *tcb = this_task();
|
||||||
uintptr_t *regs;
|
uintptr_t *regs;
|
||||||
uint32_t cmd;
|
uint32_t cmd;
|
||||||
|
|
||||||
regs = (uintptr_t *)__mfcr(CPU_PCXI);
|
regs = (uintptr_t *)__mfcr(CPU_PCXI);
|
||||||
|
|
||||||
running_task = g_running_tasks[this_cpu()];
|
|
||||||
tcb = this_task();
|
|
||||||
|
|
||||||
/* DSYNC instruction should be executed immediately prior to the MTCR */
|
/* DSYNC instruction should be executed immediately prior to the MTCR */
|
||||||
|
|
||||||
__dsync();
|
__dsync();
|
||||||
@@ -78,66 +75,33 @@ void tricore_svcall(volatile void *trap)
|
|||||||
|
|
||||||
cmd = regs[REG_D8];
|
cmd = regs[REG_D8];
|
||||||
|
|
||||||
|
if (cmd != SYS_restore_context)
|
||||||
|
{
|
||||||
|
(*running_task)->xcp.regs = tricore_csa2addr(regs[REG_UPCXI]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tricore_reclaim_csa(regs[REG_UPCXI]);
|
||||||
|
}
|
||||||
|
|
||||||
/* Handle the SVCall according to the command in R0 */
|
/* Handle the SVCall according to the command in R0 */
|
||||||
|
|
||||||
switch (cmd)
|
switch (cmd)
|
||||||
{
|
{
|
||||||
/* R0=SYS_restore_context: This a restore context command:
|
case SYS_switch_context:
|
||||||
*
|
nxsched_switch_context(*running_task, tcb);
|
||||||
* void tricore_fullcontextrestore(uint32_t *restoreregs)
|
|
||||||
* noreturn_function;
|
|
||||||
*
|
|
||||||
* At this point, the following values are saved in context:
|
|
||||||
*
|
|
||||||
* R0 = SYS_restore_context
|
|
||||||
* R1 = restoreregs
|
|
||||||
*
|
|
||||||
* In this case, we simply need to set g_current_regs to restore
|
|
||||||
* register area referenced in the saved R1. context == g_current_regs
|
|
||||||
* is the normal exception return. By setting g_current_regs =
|
|
||||||
* context[R1], we force the return to the saved context referenced
|
|
||||||
* in R1.
|
|
||||||
*/
|
|
||||||
|
|
||||||
case SYS_restore_context:
|
case SYS_restore_context:
|
||||||
{
|
*running_task = tcb;
|
||||||
tricore_reclaim_csa(regs[REG_UPCXI]);
|
regs[REG_UPCXI] = tricore_addr2csa(tcb->xcp.regs);
|
||||||
tcb->xcp.regs = (uintptr_t *)regs[REG_D9];
|
__isync();
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SYS_switch_context:
|
|
||||||
{
|
|
||||||
*(uintptr_t **)regs[REG_D9] = tricore_csa2addr(regs[REG_UPCXI]);
|
|
||||||
tcb->xcp.regs = (uintptr_t *)regs[REG_D10];
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
svcerr("ERROR: Bad SYS call: %d\n", (int)regs[REG_D0]);
|
||||||
svcerr("ERROR: Bad SYS call: %d\n", (int)regs[REG_D0]);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (regs != tcb->xcp.regs)
|
|
||||||
{
|
|
||||||
/* Update scheduler parameters */
|
|
||||||
|
|
||||||
nxsched_switch_context(running_task, 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()] = this_task();
|
|
||||||
|
|
||||||
regs[REG_UPCXI] = tricore_addr2csa(tcb->xcp.regs);
|
|
||||||
|
|
||||||
__isync();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set irq flag */
|
/* Set irq flag */
|
||||||
|
|
||||||
up_set_interrupt_context(false);
|
up_set_interrupt_context(false);
|
||||||
|
|||||||
Reference in New Issue
Block a user