Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 54 additions & 2 deletions arch/arm/src/armv7-a/arm_cpupause.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,34 @@ int up_cpu_paused_restore(void)
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
*
Expand Down Expand Up @@ -259,6 +287,32 @@ int arm_pause_handler(int irq, void *context, void *arg)
return OK;
}

/****************************************************************************
* Name: up_cpu_pause_async
*
* Description:
* pause task execution on the CPU
* check whether there are tasks delivered to specified cpu
* and try to run them.
*
* Input Parameters:
* cpu - The index of the CPU to be paused.
*
* Returned Value:
* Zero on success; a negated errno value on failure.
*
* Assumptions:
* Called from within a critical section;
*
****************************************************************************/

inline_function int up_cpu_pause_async(int cpu)
{
arm_cpu_sgi(GIC_SMP_CPUPAUSE_ASYNC, (1 << cpu));

return OK;
}

/****************************************************************************
* Name: up_cpu_pause
*
Expand Down Expand Up @@ -303,8 +357,6 @@ int up_cpu_pause(int cpu)
spin_lock(&g_cpu_wait[cpu]);
spin_lock(&g_cpu_paused[cpu]);

/* Execute SGI2 */

arm_cpu_sgi(GIC_SMP_CPUPAUSE, (1 << cpu));

/* Wait for the other CPU to unlock g_cpu_paused meaning that
Expand Down
2 changes: 2 additions & 0 deletions arch/arm/src/armv7-a/arm_gicv2.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,8 @@ void arm_gic0_initialize(void)

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_ASYNC,
arm_pause_async_handler, NULL));
DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
nxsched_smp_call_handler, NULL));
#endif
Expand Down
25 changes: 25 additions & 0 deletions arch/arm/src/armv7-a/gic.h
Original file line number Diff line number Diff line change
Expand Up @@ -619,10 +619,12 @@
# define GIC_SMP_CPUSTART GIC_IRQ_SGI9
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI10
# define GIC_SMP_CPUCALL GIC_IRQ_SGI11
# define GIC_SMP_CPUPAUSE_ASYNC GIC_IRQ_SGI12
#else
# define GIC_SMP_CPUSTART GIC_IRQ_SGI1
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI2
# define GIC_SMP_CPUCALL GIC_IRQ_SGI3
# define GIC_SMP_CPUPAUSE_ASYNC GIC_IRQ_SGI4
#endif

/****************************************************************************
Expand Down Expand Up @@ -839,6 +841,29 @@ int arm_start_handler(int irq, void *context, void *arg);
int arm_pause_handler(int irq, void *context, void *arg);
#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
*
Expand Down
58 changes: 54 additions & 4 deletions arch/arm/src/armv7-r/arm_cpupause.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,8 +230,6 @@ int up_cpu_paused_restore(void)

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
* some deadlock breaking logic that might have already serviced the SG2
* interrupt by calling up_cpu_paused(). If the pause event has already
Expand Down Expand Up @@ -259,6 +257,60 @@ int arm_pause_handler(int irq, void *context, void *arg)
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: up_cpu_pause_async
*
* Description:
* pause task execution on the CPU
* check whether there are tasks delivered to specified cpu
* and try to run them.
*
* Input Parameters:
* cpu - The index of the CPU to be paused.
*
* Returned Value:
* Zero on success; a negated errno value on failure.
*
* Assumptions:
* Called from within a critical section;
*
****************************************************************************/

inline_function int up_cpu_pause_async(int cpu)
{
arm_cpu_sgi(GIC_SMP_CPUPAUSE_ASYNC, (1 << cpu));

return OK;
}

/****************************************************************************
* Name: up_cpu_pause
*
Expand Down Expand Up @@ -303,8 +355,6 @@ int up_cpu_pause(int cpu)
spin_lock(&g_cpu_wait[cpu]);
spin_lock(&g_cpu_paused[cpu]);

/* Execute SGI2 */

arm_cpu_sgi(GIC_SMP_CPUPAUSE, (1 << cpu));

/* Wait for the other CPU to unlock g_cpu_paused meaning that
Expand Down
2 changes: 2 additions & 0 deletions arch/arm/src/armv7-r/arm_gicv2.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ void arm_gic0_initialize(void)

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_ASYNC,
arm_pause_async_handler, NULL));
DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
nxsched_smp_call_handler, NULL));
#endif
Expand Down
26 changes: 26 additions & 0 deletions arch/arm/src/armv7-r/gic.h
Original file line number Diff line number Diff line change
Expand Up @@ -610,10 +610,12 @@
# define GIC_SMP_CPUSTART GIC_IRQ_SGI9
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI10
# define GIC_SMP_CPUCALL GIC_IRQ_SGI11
# define GIC_SMP_CPUPAUSE_ASYNC GIC_IRQ_SGI12
#else
# define GIC_SMP_CPUSTART GIC_IRQ_SGI1
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI2
# define GIC_SMP_CPUCALL GIC_IRQ_SGI3
# define GIC_SMP_CPUPAUSE_ASYNC GIC_IRQ_SGI4
#endif

/****************************************************************************
Expand Down Expand Up @@ -827,6 +829,30 @@ int arm_start_handler(int irq, void *context, void *arg);
int arm_pause_handler(int irq, void *context, void *arg);
#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
*
Expand Down
6 changes: 6 additions & 0 deletions arch/arm/src/armv8-r/arm_gic.h
Original file line number Diff line number Diff line change
Expand Up @@ -313,10 +313,12 @@
# define GIC_SMP_CPUSTART GIC_IRQ_SGI9
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI10
# define GIC_SMP_CPUCALL GIC_IRQ_SGI11
# define GIC_SMP_CPUPAUSE_ASYNC GIC_IRQ_SGI12
#else
# define GIC_SMP_CPUSTART GIC_IRQ_SGI1
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI2
# define GIC_SMP_CPUCALL GIC_IRQ_SGI3
# define GIC_SMP_CPUPAUSE_ASYNC GIC_IRQ_SGI4
#endif

/****************************************************************************
Expand Down Expand Up @@ -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);

#ifdef CONFIG_SMP
int arm_pause_async_handler(int irq, void *context, void *arg);
#endif

void arm_gic_secondary_init(void);

#endif
Expand Down
3 changes: 3 additions & 0 deletions arch/arm/src/armv8-r/arm_gicv3.c
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,8 @@ static void gicv3_dist_init(void)
/* 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_ASYNC,
arm64_pause_async_handler, NULL));
DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
nxsched_smp_call_handler, NULL));
#endif
Expand Down Expand Up @@ -814,6 +816,7 @@ static void arm_gic_init(void)

#ifdef CONFIG_SMP
up_enable_irq(GIC_SMP_CPUPAUSE);
up_enable_irq(GIC_SMP_CPUPAUSE_ASYNC);
#endif
}

Expand Down
2 changes: 2 additions & 0 deletions arch/arm/src/cxd56xx/cxd56_cpupause.c
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,8 @@ int arm_pause_handler(int irq, void *c, void *arg)
leave_critical_section(flags);
}

nxsched_process_delivered(cpu);

return ret;
}

Expand Down
2 changes: 2 additions & 0 deletions arch/arm/src/lc823450/lc823450_cpupause.c
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,8 @@ int lc823450_pause_handler(int irq, void *c, void *arg)
leave_critical_section(flags);
}

nxsched_process_delivered(cpu);

return OK;
}

Expand Down
2 changes: 2 additions & 0 deletions arch/arm/src/rp2040/rp2040_cpupause.c
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,8 @@ int arm_pause_handler(int irq, void *c, void *arg)
leave_critical_section(flags);
}

nxsched_process_delivered(cpu);

return OK;
}

Expand Down
2 changes: 2 additions & 0 deletions arch/arm/src/sam34/sam4cm_cpupause.c
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,8 @@ int arm_pause_handler(int irq, void *c, void *arg)
return up_cpu_paused(cpu);
}

nxsched_process_delivered(cpu);

return OK;
}

Expand Down
Loading