arch: We can use an independent SIG interrupt to handle async pause, which can save processing time.
Signed-off-by: hujun5 <hujun5@xiaomi.com>
This commit is contained in:
parent
ed998c08c4
commit
a8717c6453
@ -208,6 +208,34 @@ int up_cpu_paused_restore(void)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: arm_pause_async_handler
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* This is the handler for async pause.
|
||||||
|
*
|
||||||
|
* 1. It saves the current task state at the head of the current assigned
|
||||||
|
* task list.
|
||||||
|
* 2. It porcess g_delivertasks
|
||||||
|
* 3. Returns from interrupt, restoring the state of the new task at the
|
||||||
|
* head of the ready to run list.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* Standard interrupt handling
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero on success; a negated errno value on failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int arm_pause_async_handler(int irq, void *context, void *arg)
|
||||||
|
{
|
||||||
|
int cpu = this_cpu();
|
||||||
|
|
||||||
|
nxsched_process_delivered(cpu);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: arm_pause_handler
|
* Name: arm_pause_handler
|
||||||
*
|
*
|
||||||
@ -256,8 +284,6 @@ int arm_pause_handler(int irq, void *context, void *arg)
|
|||||||
leave_critical_section(flags);
|
leave_critical_section(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
nxsched_process_delivered(cpu);
|
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,7 +308,7 @@ int arm_pause_handler(int irq, void *context, void *arg)
|
|||||||
|
|
||||||
inline_function int up_cpu_pause_async(int cpu)
|
inline_function int up_cpu_pause_async(int cpu)
|
||||||
{
|
{
|
||||||
arm_cpu_sgi(GIC_SMP_CPUPAUSE, (1 << cpu));
|
arm_cpu_sgi(GIC_SMP_CPUPAUSE_ASYNC, (1 << cpu));
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
@ -331,7 +357,7 @@ int up_cpu_pause(int cpu)
|
|||||||
spin_lock(&g_cpu_wait[cpu]);
|
spin_lock(&g_cpu_wait[cpu]);
|
||||||
spin_lock(&g_cpu_paused[cpu]);
|
spin_lock(&g_cpu_paused[cpu]);
|
||||||
|
|
||||||
up_cpu_pause_async(cpu);
|
arm_cpu_sgi(GIC_SMP_CPUPAUSE, (1 << cpu));
|
||||||
|
|
||||||
/* Wait for the other CPU to unlock g_cpu_paused meaning that
|
/* Wait for the other CPU to unlock g_cpu_paused meaning that
|
||||||
* it is fully paused and ready for up_cpu_resume();
|
* it is fully paused and ready for up_cpu_resume();
|
||||||
|
@ -215,6 +215,8 @@ void arm_gic0_initialize(void)
|
|||||||
|
|
||||||
DEBUGVERIFY(irq_attach(GIC_SMP_CPUSTART, arm_start_handler, NULL));
|
DEBUGVERIFY(irq_attach(GIC_SMP_CPUSTART, arm_start_handler, NULL));
|
||||||
DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE, arm_pause_handler, NULL));
|
DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE, arm_pause_handler, NULL));
|
||||||
|
DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE_ASYNC,
|
||||||
|
arm_pause_async_handler, NULL));
|
||||||
DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
|
DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
|
||||||
nxsched_smp_call_handler, NULL));
|
nxsched_smp_call_handler, NULL));
|
||||||
#endif
|
#endif
|
||||||
|
@ -619,10 +619,12 @@
|
|||||||
# define GIC_SMP_CPUSTART GIC_IRQ_SGI9
|
# define GIC_SMP_CPUSTART GIC_IRQ_SGI9
|
||||||
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI10
|
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI10
|
||||||
# define GIC_SMP_CPUCALL GIC_IRQ_SGI11
|
# define GIC_SMP_CPUCALL GIC_IRQ_SGI11
|
||||||
|
# define GIC_SMP_CPUPAUSE_ASYNC GIC_IRQ_SGI12
|
||||||
#else
|
#else
|
||||||
# define GIC_SMP_CPUSTART GIC_IRQ_SGI1
|
# define GIC_SMP_CPUSTART GIC_IRQ_SGI1
|
||||||
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI2
|
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI2
|
||||||
# define GIC_SMP_CPUCALL GIC_IRQ_SGI3
|
# define GIC_SMP_CPUCALL GIC_IRQ_SGI3
|
||||||
|
# define GIC_SMP_CPUPAUSE_ASYNC GIC_IRQ_SGI4
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -839,6 +841,29 @@ int arm_start_handler(int irq, void *context, void *arg);
|
|||||||
int arm_pause_handler(int irq, void *context, void *arg);
|
int arm_pause_handler(int irq, void *context, void *arg);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: arm_pause_async_handler
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* This is the handler for async pause.
|
||||||
|
*
|
||||||
|
* 1. It saves the current task state at the head of the current assigned
|
||||||
|
* task list.
|
||||||
|
* 2. It porcess g_delivertasks
|
||||||
|
* 3. Returns from interrupt, restoring the state of the new task at the
|
||||||
|
* head of the ready to run list.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* Standard interrupt handling
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero on success; a negated errno value on failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
int arm_pause_async_handler(int irq, void *context, void *arg);
|
||||||
|
#endif
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: arm_gic_dump
|
* Name: arm_gic_dump
|
||||||
*
|
*
|
||||||
|
@ -230,8 +230,6 @@ int up_cpu_paused_restore(void)
|
|||||||
|
|
||||||
int arm_pause_handler(int irq, void *context, void *arg)
|
int arm_pause_handler(int irq, void *context, void *arg)
|
||||||
{
|
{
|
||||||
int cpu = this_cpu();
|
|
||||||
|
|
||||||
/* Check for false alarms. Such false could occur as a consequence of
|
/* Check for false alarms. Such false could occur as a consequence of
|
||||||
* some deadlock breaking logic that might have already serviced the SG2
|
* some deadlock breaking logic that might have already serviced the SG2
|
||||||
* interrupt by calling up_cpu_paused(). If the pause event has already
|
* interrupt by calling up_cpu_paused(). If the pause event has already
|
||||||
@ -256,8 +254,34 @@ int arm_pause_handler(int irq, void *context, void *arg)
|
|||||||
leave_critical_section(flags);
|
leave_critical_section(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
nxsched_process_delivered(cpu);
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: arm_pause_async_handler
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* This is the handler for async pause.
|
||||||
|
*
|
||||||
|
* 1. It saves the current task state at the head of the current assigned
|
||||||
|
* task list.
|
||||||
|
* 2. It porcess g_delivertasks
|
||||||
|
* 3. Returns from interrupt, restoring the state of the new task at the
|
||||||
|
* head of the ready to run list.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* Standard interrupt handling
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero on success; a negated errno value on failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int arm_pause_async_handler(int irq, void *context, void *arg)
|
||||||
|
{
|
||||||
|
int cpu = this_cpu();
|
||||||
|
|
||||||
|
nxsched_process_delivered(cpu);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,7 +306,7 @@ int arm_pause_handler(int irq, void *context, void *arg)
|
|||||||
|
|
||||||
inline_function int up_cpu_pause_async(int cpu)
|
inline_function int up_cpu_pause_async(int cpu)
|
||||||
{
|
{
|
||||||
arm_cpu_sgi(GIC_SMP_CPUPAUSE, (1 << cpu));
|
arm_cpu_sgi(GIC_SMP_CPUPAUSE_ASYNC, (1 << cpu));
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
@ -331,7 +355,7 @@ int up_cpu_pause(int cpu)
|
|||||||
spin_lock(&g_cpu_wait[cpu]);
|
spin_lock(&g_cpu_wait[cpu]);
|
||||||
spin_lock(&g_cpu_paused[cpu]);
|
spin_lock(&g_cpu_paused[cpu]);
|
||||||
|
|
||||||
up_cpu_pause_async(cpu);
|
arm_cpu_sgi(GIC_SMP_CPUPAUSE, (1 << cpu));
|
||||||
|
|
||||||
/* Wait for the other CPU to unlock g_cpu_paused meaning that
|
/* Wait for the other CPU to unlock g_cpu_paused meaning that
|
||||||
* it is fully paused and ready for up_cpu_resume();
|
* it is fully paused and ready for up_cpu_resume();
|
||||||
|
@ -161,6 +161,8 @@ void arm_gic0_initialize(void)
|
|||||||
|
|
||||||
DEBUGVERIFY(irq_attach(GIC_SMP_CPUSTART, arm_start_handler, NULL));
|
DEBUGVERIFY(irq_attach(GIC_SMP_CPUSTART, arm_start_handler, NULL));
|
||||||
DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE, arm_pause_handler, NULL));
|
DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE, arm_pause_handler, NULL));
|
||||||
|
DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE_ASYNC,
|
||||||
|
arm_pause_async_handler, NULL));
|
||||||
DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
|
DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
|
||||||
nxsched_smp_call_handler, NULL));
|
nxsched_smp_call_handler, NULL));
|
||||||
#endif
|
#endif
|
||||||
|
@ -610,10 +610,12 @@
|
|||||||
# define GIC_SMP_CPUSTART GIC_IRQ_SGI9
|
# define GIC_SMP_CPUSTART GIC_IRQ_SGI9
|
||||||
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI10
|
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI10
|
||||||
# define GIC_SMP_CPUCALL GIC_IRQ_SGI11
|
# define GIC_SMP_CPUCALL GIC_IRQ_SGI11
|
||||||
|
# define GIC_SMP_CPUPAUSE_ASYNC GIC_IRQ_SGI12
|
||||||
#else
|
#else
|
||||||
# define GIC_SMP_CPUSTART GIC_IRQ_SGI1
|
# define GIC_SMP_CPUSTART GIC_IRQ_SGI1
|
||||||
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI2
|
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI2
|
||||||
# define GIC_SMP_CPUCALL GIC_IRQ_SGI3
|
# define GIC_SMP_CPUCALL GIC_IRQ_SGI3
|
||||||
|
# define GIC_SMP_CPUPAUSE_ASYNC GIC_IRQ_SGI4
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -827,6 +829,30 @@ int arm_start_handler(int irq, void *context, void *arg);
|
|||||||
int arm_pause_handler(int irq, void *context, void *arg);
|
int arm_pause_handler(int irq, void *context, void *arg);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: arm_pause_async_handler
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* This is the handler for async pause.
|
||||||
|
*
|
||||||
|
* 1. It saves the current task state at the head of the current assigned
|
||||||
|
* task list.
|
||||||
|
* 2. It porcess g_delivertasks
|
||||||
|
* 3. Returns from interrupt, restoring the state of the new task at the
|
||||||
|
* head of the ready to run list.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* Standard interrupt handling
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero on success; a negated errno value on failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
int arm_pause_async_handler(int irq, void *context, void *arg);
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: arm_gic_dump
|
* Name: arm_gic_dump
|
||||||
*
|
*
|
||||||
|
@ -313,10 +313,12 @@
|
|||||||
# define GIC_SMP_CPUSTART GIC_IRQ_SGI9
|
# define GIC_SMP_CPUSTART GIC_IRQ_SGI9
|
||||||
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI10
|
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI10
|
||||||
# define GIC_SMP_CPUCALL GIC_IRQ_SGI11
|
# define GIC_SMP_CPUCALL GIC_IRQ_SGI11
|
||||||
|
# define GIC_SMP_CPUPAUSE_ASYNC GIC_IRQ_SGI12
|
||||||
#else
|
#else
|
||||||
# define GIC_SMP_CPUSTART GIC_IRQ_SGI1
|
# define GIC_SMP_CPUSTART GIC_IRQ_SGI1
|
||||||
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI2
|
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI2
|
||||||
# define GIC_SMP_CPUCALL GIC_IRQ_SGI3
|
# define GIC_SMP_CPUCALL GIC_IRQ_SGI3
|
||||||
|
# define GIC_SMP_CPUPAUSE_ASYNC GIC_IRQ_SGI4
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -355,6 +357,10 @@ int arm_gic_raise_sgi(unsigned int sgi_id, uint16_t target_list);
|
|||||||
|
|
||||||
int arm_pause_handler(int irq, void *context, void *arg);
|
int arm_pause_handler(int irq, void *context, void *arg);
|
||||||
|
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
int arm_pause_async_handler(int irq, void *context, void *arg);
|
||||||
|
#endif
|
||||||
|
|
||||||
void arm_gic_secondary_init(void);
|
void arm_gic_secondary_init(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -568,6 +568,8 @@ static void gicv3_dist_init(void)
|
|||||||
/* Attach SGI interrupt handlers. This attaches the handler to all CPUs. */
|
/* Attach SGI interrupt handlers. This attaches the handler to all CPUs. */
|
||||||
|
|
||||||
DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE, arm64_pause_handler, NULL));
|
DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE, arm64_pause_handler, NULL));
|
||||||
|
DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE_ASYNC,
|
||||||
|
arm64_pause_async_handler, NULL));
|
||||||
DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
|
DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
|
||||||
nxsched_smp_call_handler, NULL));
|
nxsched_smp_call_handler, NULL));
|
||||||
#endif
|
#endif
|
||||||
@ -814,6 +816,7 @@ static void arm_gic_init(void)
|
|||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
up_enable_irq(GIC_SMP_CPUPAUSE);
|
up_enable_irq(GIC_SMP_CPUPAUSE);
|
||||||
|
up_enable_irq(GIC_SMP_CPUPAUSE_ASYNC);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,6 +211,35 @@ int up_cpu_paused_restore(void)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: arm64_pause_async_handler
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* This is the handler for async pause.
|
||||||
|
*
|
||||||
|
* 1. It saves the current task state at the head of the current assigned
|
||||||
|
* task list.
|
||||||
|
* 2. It porcess g_delivertasks
|
||||||
|
* 3. Returns from interrupt, restoring the state of the new task at the
|
||||||
|
* head of the ready to run list.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* Standard interrupt handling
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero on success; a negated errno value on failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int arm64_pause_async_handler(int irq, void *context, void *arg)
|
||||||
|
{
|
||||||
|
int cpu = this_cpu();
|
||||||
|
|
||||||
|
nxsched_process_delivered(cpu);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: arm64_pause_handler
|
* Name: arm64_pause_handler
|
||||||
*
|
*
|
||||||
@ -259,8 +288,6 @@ int arm64_pause_handler(int irq, void *context, void *arg)
|
|||||||
leave_critical_section(flags);
|
leave_critical_section(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
nxsched_process_delivered(cpu);
|
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,7 +314,7 @@ inline_function int up_cpu_pause_async(int cpu)
|
|||||||
{
|
{
|
||||||
/* Execute SGI2 */
|
/* Execute SGI2 */
|
||||||
|
|
||||||
arm64_gic_raise_sgi(GIC_SMP_CPUPAUSE, (1 << cpu));
|
arm64_gic_raise_sgi(GIC_SMP_CPUPAUSE_ASYNC, (1 << cpu));
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
@ -336,7 +363,7 @@ int up_cpu_pause(int cpu)
|
|||||||
spin_lock(&g_cpu_wait[cpu]);
|
spin_lock(&g_cpu_wait[cpu]);
|
||||||
spin_lock(&g_cpu_paused[cpu]);
|
spin_lock(&g_cpu_paused[cpu]);
|
||||||
|
|
||||||
up_cpu_pause_async(cpu);
|
arm64_gic_raise_sgi(GIC_SMP_CPUPAUSE, (1 << cpu));
|
||||||
|
|
||||||
/* Wait for the other CPU to unlock g_cpu_paused meaning that
|
/* Wait for the other CPU to unlock g_cpu_paused meaning that
|
||||||
* it is fully paused and ready for up_cpu_resume();
|
* it is fully paused and ready for up_cpu_resume();
|
||||||
|
@ -281,10 +281,12 @@
|
|||||||
#define GIC_IRQ_SGI15 15
|
#define GIC_IRQ_SGI15 15
|
||||||
|
|
||||||
#ifdef CONFIG_ARCH_TRUSTZONE_SECURE
|
#ifdef CONFIG_ARCH_TRUSTZONE_SECURE
|
||||||
|
# define GIC_SMP_CPUPAUSE_ASYNC GIC_IRQ_SGI8
|
||||||
# define GIC_SMP_CPUSTART GIC_IRQ_SGI9
|
# define GIC_SMP_CPUSTART GIC_IRQ_SGI9
|
||||||
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI10
|
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI10
|
||||||
# define GIC_SMP_CPUCALL GIC_IRQ_SGI11
|
# define GIC_SMP_CPUCALL GIC_IRQ_SGI11
|
||||||
#else
|
#else
|
||||||
|
# define GIC_SMP_CPUPAUSE_ASYNC GIC_IRQ_SGI0
|
||||||
# define GIC_SMP_CPUSTART GIC_IRQ_SGI1
|
# define GIC_SMP_CPUSTART GIC_IRQ_SGI1
|
||||||
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI2
|
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI2
|
||||||
# define GIC_SMP_CPUCALL GIC_IRQ_SGI3
|
# define GIC_SMP_CPUCALL GIC_IRQ_SGI3
|
||||||
@ -343,6 +345,28 @@ void arm64_gic_raise_sgi(unsigned int sgi_id, uint16_t target_list);
|
|||||||
|
|
||||||
int arm64_pause_handler(int irq, void *context, void *arg);
|
int arm64_pause_handler(int irq, void *context, void *arg);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: arm64_pause_async_handler
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* This is the handler for async pause.
|
||||||
|
*
|
||||||
|
* 1. It saves the current task state at the head of the current assigned
|
||||||
|
* task list.
|
||||||
|
* 2. It porcess g_delivertasks
|
||||||
|
* 3. Returns from interrupt, restoring the state of the new task at the
|
||||||
|
* head of the ready to run list.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* Standard interrupt handling
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero on success; a negated errno value on failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int arm64_pause_async_handler(int irq, void *context, void *arg);
|
||||||
|
|
||||||
void arm64_gic_secondary_init(void);
|
void arm64_gic_secondary_init(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -911,6 +911,8 @@ static void arm_gic0_initialize(void)
|
|||||||
/* Attach SGI interrupt handlers. This attaches the handler to all CPUs. */
|
/* Attach SGI interrupt handlers. This attaches the handler to all CPUs. */
|
||||||
|
|
||||||
DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE, arm64_pause_handler, NULL));
|
DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE, arm64_pause_handler, NULL));
|
||||||
|
DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE_ASYNC,
|
||||||
|
arm64_pause_async_handler, NULL));
|
||||||
DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
|
DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
|
||||||
nxsched_smp_call_handler, NULL));
|
nxsched_smp_call_handler, NULL));
|
||||||
#endif
|
#endif
|
||||||
|
@ -654,6 +654,8 @@ static void gicv3_dist_init(void)
|
|||||||
/* Attach SGI interrupt handlers. This attaches the handler to all CPUs. */
|
/* Attach SGI interrupt handlers. This attaches the handler to all CPUs. */
|
||||||
|
|
||||||
DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE, arm64_pause_handler, NULL));
|
DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE, arm64_pause_handler, NULL));
|
||||||
|
DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE_ASYNC,
|
||||||
|
arm64_pause_async_handler, NULL));
|
||||||
DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
|
DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
|
||||||
nxsched_smp_call_handler, NULL));
|
nxsched_smp_call_handler, NULL));
|
||||||
#endif
|
#endif
|
||||||
@ -952,6 +954,7 @@ static void arm64_gic_init(void)
|
|||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
up_enable_irq(GIC_SMP_CPUPAUSE);
|
up_enable_irq(GIC_SMP_CPUPAUSE);
|
||||||
|
up_enable_irq(GIC_SMP_CPUPAUSE_ASYNC);
|
||||||
up_enable_irq(GIC_SMP_CPUCALL);
|
up_enable_irq(GIC_SMP_CPUCALL);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -346,9 +346,10 @@
|
|||||||
#define HPET0_IRQ IRQ2
|
#define HPET0_IRQ IRQ2
|
||||||
#define HPET1_IRQ IRQ8
|
#define HPET1_IRQ IRQ8
|
||||||
|
|
||||||
/* Use IRQ15 for SMP */
|
/* Use IRQ15 IRQ16 for SMP */
|
||||||
|
|
||||||
#define SMP_IPI_IRQ IRQ15
|
#define SMP_IPI_IRQ IRQ15
|
||||||
|
#define SMP_IPI_ASYNC_IRQ IRQ16
|
||||||
|
|
||||||
/* Common register save structure created by up_saveusercontext() and by
|
/* Common register save structure created by up_saveusercontext() and by
|
||||||
* ISR/IRQ interrupt processing.
|
* ISR/IRQ interrupt processing.
|
||||||
|
@ -264,6 +264,35 @@ int up_pause_handler(int irq, void *c, void *arg)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: up_pause_async_handler
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* This is the handler for async pause.
|
||||||
|
*
|
||||||
|
* 1. It saves the current task state at the head of the current assigned
|
||||||
|
* task list.
|
||||||
|
* 2. It porcess g_delivertasks
|
||||||
|
* 3. Returns from interrupt, restoring the state of the new task at the
|
||||||
|
* head of the ready to run list.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* Standard interrupt handling
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero on success; a negated errno value on failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int up_pause_async_handler(int irq, void *c, void *arg)
|
||||||
|
{
|
||||||
|
int cpu = this_cpu();
|
||||||
|
|
||||||
|
nxsched_process_delivered(cpu);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: up_cpu_pause_async
|
* Name: up_cpu_pause_async
|
||||||
*
|
*
|
||||||
@ -290,7 +319,7 @@ inline_function int up_cpu_pause_async(int cpu)
|
|||||||
CPU_ZERO(&cpuset);
|
CPU_ZERO(&cpuset);
|
||||||
CPU_SET(cpu, &cpuset);
|
CPU_SET(cpu, &cpuset);
|
||||||
|
|
||||||
up_trigger_irq(SMP_IPI_IRQ, cpuset);
|
up_trigger_irq(SMP_IPI_ASYNC_IRQ, cpuset);
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
@ -336,6 +365,7 @@ void up_send_smp_call(cpu_set_t cpuset)
|
|||||||
|
|
||||||
int up_cpu_pause(int cpu)
|
int up_cpu_pause(int cpu)
|
||||||
{
|
{
|
||||||
|
cpu_set_t cpuset;
|
||||||
sinfo("cpu=%d\n", cpu);
|
sinfo("cpu=%d\n", cpu);
|
||||||
|
|
||||||
#ifdef CONFIG_SCHED_INSTRUMENTATION
|
#ifdef CONFIG_SCHED_INSTRUMENTATION
|
||||||
@ -362,7 +392,10 @@ int up_cpu_pause(int cpu)
|
|||||||
|
|
||||||
/* Execute Pause IRQ to CPU(cpu) */
|
/* Execute Pause IRQ to CPU(cpu) */
|
||||||
|
|
||||||
up_cpu_pause_async(cpu);
|
CPU_ZERO(&cpuset);
|
||||||
|
CPU_SET(cpu, &cpuset);
|
||||||
|
|
||||||
|
up_trigger_irq(SMP_IPI_IRQ, cpuset);
|
||||||
|
|
||||||
/* Wait for the other CPU to unlock g_cpu_paused meaning that
|
/* Wait for the other CPU to unlock g_cpu_paused meaning that
|
||||||
* it is fully paused and ready for up_cpu_resume();
|
* it is fully paused and ready for up_cpu_resume();
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
|
|
||||||
extern void __ap_entry(void);
|
extern void __ap_entry(void);
|
||||||
extern int up_pause_handler(int irq, void *c, void *arg);
|
extern int up_pause_handler(int irq, void *c, void *arg);
|
||||||
|
extern int up_pause_async_handler(int irq, void *c, void *arg);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Functions
|
* Private Functions
|
||||||
@ -160,7 +161,9 @@ void x86_64_ap_boot(void)
|
|||||||
/* Connect Pause IRQ to CPU */
|
/* Connect Pause IRQ to CPU */
|
||||||
|
|
||||||
irq_attach(SMP_IPI_IRQ, up_pause_handler, NULL);
|
irq_attach(SMP_IPI_IRQ, up_pause_handler, NULL);
|
||||||
|
irq_attach(SMP_IPI_ASYNC_IRQ, up_pause_async_handler, NULL);
|
||||||
up_enable_irq(SMP_IPI_IRQ);
|
up_enable_irq(SMP_IPI_IRQ);
|
||||||
|
up_enable_irq(SMP_IPI_ASYNC_IRQ);
|
||||||
|
|
||||||
/* CPU ready */
|
/* CPU ready */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user