mirror of
https://github.com/apache/nuttx.git
synced 2026-05-27 03:05:40 +08:00
smp: enable smp_call in all smp arch
reason: In subsequent implementations, we will replace up_cpu_pause with smp_call. Signed-off-by: hujun5 <hujun5@xiaomi.com>
This commit is contained in:
committed by
Masayuki Ishikawa
parent
ea181e2621
commit
608b59e401
@@ -167,11 +167,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));
|
||||||
|
|
||||||
# ifdef CONFIG_SMP_CALL
|
|
||||||
DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
|
DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
|
||||||
nxsched_smp_call_handler, NULL));
|
nxsched_smp_call_handler, NULL));
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
arm_gic_dump("Exit arm_gic0_initialize", true, 0);
|
arm_gic_dump("Exit arm_gic0_initialize", true, 0);
|
||||||
@@ -672,7 +669,21 @@ int arm_gic_irq_trigger(int irq, bool edge)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SMP_CALL
|
#ifdef CONFIG_SMP
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: up_send_smp_call
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Send smp call to target cpu.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* cpuset - The set of CPUs to receive the SGI.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
void up_send_smp_call(cpu_set_t cpuset)
|
void up_send_smp_call(cpu_set_t cpuset)
|
||||||
{
|
{
|
||||||
up_trigger_irq(GIC_SMP_CPUCALL, cpuset);
|
up_trigger_irq(GIC_SMP_CPUCALL, cpuset);
|
||||||
|
|||||||
@@ -161,11 +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));
|
||||||
|
|
||||||
# ifdef CONFIG_SMP_CALL
|
|
||||||
DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
|
DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
|
||||||
nxsched_smp_call_handler, NULL));
|
nxsched_smp_call_handler, NULL));
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
arm_gic_dump("Exit arm_gic0_initialize", true, 0);
|
arm_gic_dump("Exit arm_gic0_initialize", true, 0);
|
||||||
@@ -662,7 +659,21 @@ int arm_gic_irq_trigger(int irq, bool edge)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
# ifdef CONFIG_SMP_CALL
|
# ifdef CONFIG_SMP
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: up_send_smp_call
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Send smp call to target cpu.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* cpuset - The set of CPUs to receive the SGI.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
void up_send_smp_call(cpu_set_t cpuset)
|
void up_send_smp_call(cpu_set_t cpuset)
|
||||||
{
|
{
|
||||||
up_trigger_irq(GIC_SMP_CPUCALL, cpuset);
|
up_trigger_irq(GIC_SMP_CPUCALL, cpuset);
|
||||||
|
|||||||
@@ -569,11 +569,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));
|
||||||
|
|
||||||
# ifdef CONFIG_SMP_CALL
|
|
||||||
DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
|
DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
|
||||||
nxsched_smp_call_handler, NULL));
|
nxsched_smp_call_handler, NULL));
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -845,7 +842,21 @@ void arm_gic_secondary_init(void)
|
|||||||
arm_gic_init();
|
arm_gic_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
# ifdef CONFIG_SMP_CALL
|
# ifdef CONFIG_SMP
|
||||||
|
/***************************************************************************
|
||||||
|
* Name: up_send_smp_call
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Send smp call to target cpu.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* cpuset - The set of CPUs to receive the SGI.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None.
|
||||||
|
*
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
void up_send_smp_call(cpu_set_t cpuset)
|
void up_send_smp_call(cpu_set_t cpuset)
|
||||||
{
|
{
|
||||||
up_trigger_irq(GIC_SMP_CPUCALL, cpuset);
|
up_trigger_irq(GIC_SMP_CPUCALL, cpuset);
|
||||||
|
|||||||
@@ -318,6 +318,8 @@ int arm_pause_handler(int irq, void *c, void *arg)
|
|||||||
int cpu = this_cpu();
|
int cpu = this_cpu();
|
||||||
int ret = OK;
|
int ret = OK;
|
||||||
|
|
||||||
|
nxsched_smp_call_handler(irq, c, arg);
|
||||||
|
|
||||||
DPRINTF("cpu%d will be paused\n", cpu);
|
DPRINTF("cpu%d will be paused\n", cpu);
|
||||||
|
|
||||||
/* Clear SW_INT for APP_DSP(cpu) */
|
/* Clear SW_INT for APP_DSP(cpu) */
|
||||||
@@ -362,6 +364,59 @@ int arm_pause_handler(int irq, void *c, void *arg)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
/* Generate IRQ for CPU(cpu) */
|
||||||
|
|
||||||
|
putreg32(1, CXD56_CPU_P2_INT + (4 * cpu));
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: up_send_smp_call
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Send smp call to target cpu.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* cpuset - The set of CPUs to receive the SGI.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void up_send_smp_call(cpu_set_t cpuset)
|
||||||
|
{
|
||||||
|
int cpu;
|
||||||
|
|
||||||
|
for (; cpuset != 0; cpuset &= ~(1 << cpu))
|
||||||
|
{
|
||||||
|
cpu = ffs(cpuset) - 1;
|
||||||
|
up_cpu_pause_async(cpu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: up_cpu_pause
|
* Name: up_cpu_pause
|
||||||
*
|
*
|
||||||
@@ -410,7 +465,7 @@ int up_cpu_pause(int cpu)
|
|||||||
|
|
||||||
/* Generate IRQ for CPU(cpu) */
|
/* Generate IRQ for CPU(cpu) */
|
||||||
|
|
||||||
putreg32(1, CXD56_CPU_P2_INT + (4 * cpu));
|
up_cpu_pause_async(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();
|
||||||
|
|||||||
@@ -238,6 +238,8 @@ int lc823450_pause_handler(int irq, void *c, void *arg)
|
|||||||
{
|
{
|
||||||
int cpu = this_cpu();
|
int cpu = this_cpu();
|
||||||
|
|
||||||
|
nxsched_smp_call_handler(irq, c, arg);
|
||||||
|
|
||||||
/* Clear : Pause IRQ */
|
/* Clear : Pause IRQ */
|
||||||
|
|
||||||
if (irq == LC823450_IRQ_CTXM3_01)
|
if (irq == LC823450_IRQ_CTXM3_01)
|
||||||
@@ -277,6 +279,66 @@ int lc823450_pause_handler(int irq, void *c, void *arg)
|
|||||||
return OK;
|
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)
|
||||||
|
{
|
||||||
|
/* Execute Pause IRQ to CPU(cpu) */
|
||||||
|
|
||||||
|
if (cpu == 1)
|
||||||
|
{
|
||||||
|
putreg32(IPIREG_INTISR0_1, IPIREG);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
putreg32(IPIREG_INTISR1_1, IPIREG);
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: up_send_smp_call
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Send smp call to target cpu.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* cpuset - The set of CPUs to receive the SGI.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void up_send_smp_call(cpu_set_t cpuset)
|
||||||
|
{
|
||||||
|
int cpu;
|
||||||
|
|
||||||
|
for (; cpuset != 0; cpuset &= ~(1 << cpu))
|
||||||
|
{
|
||||||
|
cpu = ffs(cpuset) - 1;
|
||||||
|
up_cpu_pause_async(cpu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: up_cpu_pause
|
* Name: up_cpu_pause
|
||||||
*
|
*
|
||||||
@@ -325,14 +387,7 @@ int up_cpu_pause(int cpu)
|
|||||||
|
|
||||||
/* Execute Pause IRQ to CPU(cpu) */
|
/* Execute Pause IRQ to CPU(cpu) */
|
||||||
|
|
||||||
if (cpu == 1)
|
up_cpu_pause_async(cpu);
|
||||||
{
|
|
||||||
putreg32(IPIREG_INTISR0_1, IPIREG);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
putreg32(IPIREG_INTISR1_1, IPIREG);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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();
|
||||||
|
|||||||
@@ -280,6 +280,8 @@ int arm_pause_handler(int irq, void *c, void *arg)
|
|||||||
int irqreq;
|
int irqreq;
|
||||||
uint32_t stat;
|
uint32_t stat;
|
||||||
|
|
||||||
|
nxsched_smp_call_handler(irq, c, arg);
|
||||||
|
|
||||||
stat = getreg32(RP2040_SIO_FIFO_ST);
|
stat = getreg32(RP2040_SIO_FIFO_ST);
|
||||||
if (stat & (RP2040_SIO_FIFO_ST_ROE | RP2040_SIO_FIFO_ST_WOF))
|
if (stat & (RP2040_SIO_FIFO_ST_ROE | RP2040_SIO_FIFO_ST_WOF))
|
||||||
{
|
{
|
||||||
@@ -333,6 +335,61 @@ int arm_pause_handler(int irq, void *c, void *arg)
|
|||||||
return OK;
|
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)
|
||||||
|
{
|
||||||
|
/* Generate IRQ for CPU(cpu) */
|
||||||
|
|
||||||
|
while (!(getreg32(RP2040_SIO_FIFO_ST) & RP2040_SIO_FIFO_ST_RDY))
|
||||||
|
;
|
||||||
|
putreg32(0, RP2040_SIO_FIFO_WR);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: up_send_smp_call
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Send smp call to target cpu.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* cpuset - The set of CPUs to receive the SGI.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void up_send_smp_call(cpu_set_t cpuset)
|
||||||
|
{
|
||||||
|
int cpu;
|
||||||
|
|
||||||
|
for (; cpuset != 0; cpuset &= ~(1 << cpu))
|
||||||
|
{
|
||||||
|
cpu = ffs(cpuset) - 1;
|
||||||
|
up_cpu_pause_async(cpu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: up_cpu_pause
|
* Name: up_cpu_pause
|
||||||
*
|
*
|
||||||
@@ -383,9 +440,7 @@ int up_cpu_pause(int cpu)
|
|||||||
|
|
||||||
/* Generate IRQ for CPU(cpu) */
|
/* Generate IRQ for CPU(cpu) */
|
||||||
|
|
||||||
while (!(getreg32(RP2040_SIO_FIFO_ST) & RP2040_SIO_FIFO_ST_RDY))
|
up_cpu_pause_async(cpu);
|
||||||
;
|
|
||||||
putreg32(0, RP2040_SIO_FIFO_WR);
|
|
||||||
|
|
||||||
/* 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();
|
||||||
|
|||||||
@@ -240,6 +240,8 @@ int arm_pause_handler(int irq, void *c, void *arg)
|
|||||||
{
|
{
|
||||||
int cpu = this_cpu();
|
int cpu = this_cpu();
|
||||||
|
|
||||||
|
nxsched_smp_call_handler(irq, c, arg);
|
||||||
|
|
||||||
/* Clear : Pause IRQ */
|
/* Clear : Pause IRQ */
|
||||||
|
|
||||||
/* IPC Interrupt Clear Command Register (write-only) */
|
/* IPC Interrupt Clear Command Register (write-only) */
|
||||||
@@ -268,6 +270,68 @@ int arm_pause_handler(int irq, void *c, void *arg)
|
|||||||
return OK;
|
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)
|
||||||
|
{
|
||||||
|
/* Execute Pause IRQ to CPU(cpu) */
|
||||||
|
|
||||||
|
/* Set IPC Interrupt (IRQ0) (write-only) */
|
||||||
|
|
||||||
|
if (cpu == 1)
|
||||||
|
{
|
||||||
|
putreg32(0x1, SAM_IPC1_ISCR);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
putreg32(0x1, SAM_IPC0_ISCR);
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: up_send_smp_call
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Send smp call to target cpu.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* cpuset - The set of CPUs to receive the SGI.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void up_send_smp_call(cpu_set_t cpuset)
|
||||||
|
{
|
||||||
|
int cpu;
|
||||||
|
|
||||||
|
for (; cpuset != 0; cpuset &= ~(1 << cpu))
|
||||||
|
{
|
||||||
|
cpu = ffs(cpuset) - 1;
|
||||||
|
up_cpu_pause_async(cpu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: up_cpu_pause
|
* Name: up_cpu_pause
|
||||||
*
|
*
|
||||||
@@ -318,14 +382,7 @@ int up_cpu_pause(int cpu)
|
|||||||
|
|
||||||
/* Set IPC Interrupt (IRQ0) (write-only) */
|
/* Set IPC Interrupt (IRQ0) (write-only) */
|
||||||
|
|
||||||
if (cpu == 1)
|
up_cpu_pause_async(cpu);
|
||||||
{
|
|
||||||
putreg32(0x1, SAM_IPC1_ISCR);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
putreg32(0x1, SAM_IPC0_ISCR);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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();
|
||||||
|
|||||||
@@ -911,11 +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));
|
||||||
|
|
||||||
# ifdef CONFIG_SMP_CALL
|
|
||||||
DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
|
DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
|
||||||
nxsched_smp_call_handler, NULL));
|
nxsched_smp_call_handler, NULL));
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1487,7 +1484,21 @@ int arm64_gic_raise_sgi(unsigned int sgi, uint16_t cpuset)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
# ifdef CONFIG_SMP_CALL
|
# ifdef CONFIG_SMP
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: up_send_smp_call
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Send smp call to target cpu.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* cpuset - The set of CPUs to receive the SGI.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
void up_send_smp_call(cpu_set_t cpuset)
|
void up_send_smp_call(cpu_set_t cpuset)
|
||||||
{
|
{
|
||||||
up_trigger_irq(GIC_SMP_CPUCALL, cpuset);
|
up_trigger_irq(GIC_SMP_CPUCALL, cpuset);
|
||||||
|
|||||||
@@ -656,11 +656,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));
|
||||||
|
|
||||||
# ifdef CONFIG_SMP_CALL
|
|
||||||
DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
|
DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
|
||||||
nxsched_smp_call_handler, NULL));
|
nxsched_smp_call_handler, NULL));
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -957,9 +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);
|
||||||
# ifdef CONFIG_SMP_CALL
|
|
||||||
up_enable_irq(GIC_SMP_CPUCALL);
|
up_enable_irq(GIC_SMP_CPUCALL);
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -987,7 +982,21 @@ void arm64_gic_secondary_init(void)
|
|||||||
arm64_gic_init();
|
arm64_gic_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
# ifdef CONFIG_SMP_CALL
|
# ifdef CONFIG_SMP
|
||||||
|
/***************************************************************************
|
||||||
|
* Name: up_send_smp_call
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Send smp call to target cpu.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* cpuset - The set of CPUs to receive the SGI.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None.
|
||||||
|
*
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
void up_send_smp_call(cpu_set_t cpuset)
|
void up_send_smp_call(cpu_set_t cpuset)
|
||||||
{
|
{
|
||||||
up_trigger_irq(GIC_SMP_CPUCALL, cpuset);
|
up_trigger_irq(GIC_SMP_CPUCALL, cpuset);
|
||||||
|
|||||||
@@ -229,6 +229,8 @@ int riscv_pause_handler(int irq, void *c, void *arg)
|
|||||||
{
|
{
|
||||||
int cpu = this_cpu();
|
int cpu = this_cpu();
|
||||||
|
|
||||||
|
nxsched_smp_call_handler(irq, c, arg);
|
||||||
|
|
||||||
/* Clear IPI (Inter-Processor-Interrupt) */
|
/* Clear IPI (Inter-Processor-Interrupt) */
|
||||||
|
|
||||||
riscv_ipi_clear(cpu);
|
riscv_ipi_clear(cpu);
|
||||||
@@ -259,6 +261,31 @@ int riscv_pause_handler(int irq, void *c, void *arg)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: up_send_smp_call
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Send smp call to target cpu.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* cpuset - The set of CPUs to receive the SGI.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void up_send_smp_call(cpu_set_t cpuset)
|
||||||
|
{
|
||||||
|
int cpu;
|
||||||
|
|
||||||
|
for (; cpuset != 0; cpuset &= ~(1 << cpu))
|
||||||
|
{
|
||||||
|
cpu = ffs(cpuset) - 1;
|
||||||
|
riscv_ipi_send(cpu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: up_cpu_pause
|
* Name: up_cpu_pause
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -141,6 +141,7 @@ void up_irqinitialize(void)
|
|||||||
/* Register the pause handler */
|
/* Register the pause handler */
|
||||||
|
|
||||||
sim_init_ipi(SIGUSR1);
|
sim_init_ipi(SIGUSR1);
|
||||||
|
sim_init_func_call_ipi(SIGUSR2);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -263,3 +263,15 @@ void host_send_ipi(int cpu)
|
|||||||
{
|
{
|
||||||
pthread_kill(g_cpu_thread[cpu], SIGUSR1);
|
pthread_kill(g_cpu_thread[cpu], SIGUSR1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: host_send_func_call_ipi(int cpu)
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void host_send_func_call_ipi(int cpu)
|
||||||
|
{
|
||||||
|
pthread_kill(g_cpu_thread[cpu], SIGUSR2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -251,6 +251,7 @@ void sim_sigdeliver(void);
|
|||||||
void host_cpu0_start(void);
|
void host_cpu0_start(void);
|
||||||
int host_cpu_start(int cpu, void *stack, size_t size);
|
int host_cpu_start(int cpu, void *stack, size_t size);
|
||||||
void host_send_ipi(int cpu);
|
void host_send_ipi(int cpu);
|
||||||
|
void host_send_func_call_ipi(int cpu);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* sim_smpsignal.c **********************************************************/
|
/* sim_smpsignal.c **********************************************************/
|
||||||
@@ -258,6 +259,7 @@ void host_send_ipi(int cpu);
|
|||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
void host_cpu_started(void);
|
void host_cpu_started(void);
|
||||||
int sim_init_ipi(int irq);
|
int sim_init_ipi(int irq);
|
||||||
|
int sim_init_func_call_ipi(int irq);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* sim_oneshot.c ************************************************************/
|
/* sim_oneshot.c ************************************************************/
|
||||||
|
|||||||
@@ -447,3 +447,44 @@ int up_cpu_resume(int cpu)
|
|||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: sim_init_func_call_ipi
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Attach the CPU function call request interrupt to the NuttX logic.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* irq - the SIGUSR2 interrupt number
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* On success returns OK (0), otherwise a negative value.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int sim_init_func_call_ipi(int irq)
|
||||||
|
{
|
||||||
|
up_enable_irq(irq);
|
||||||
|
return irq_attach(irq, nxsched_smp_call_handler, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: up_send_smp_call
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Notify the cpuset cpus handler function calls.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void up_send_smp_call(cpu_set_t cpuset)
|
||||||
|
{
|
||||||
|
int cpu;
|
||||||
|
|
||||||
|
for (; cpuset != 0; cpuset &= ~(1 << cpu))
|
||||||
|
{
|
||||||
|
cpu = ffs(cpuset) - 1;
|
||||||
|
host_send_func_call_ipi(cpu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -228,6 +228,8 @@ int s698pm_pause_handler(int irq, void *c, void *arg)
|
|||||||
{
|
{
|
||||||
int cpu = this_cpu();
|
int cpu = this_cpu();
|
||||||
|
|
||||||
|
nxsched_smp_call_handler(irq, c, arg);
|
||||||
|
|
||||||
/* Clear IPI (Inter-Processor-Interrupt) */
|
/* Clear IPI (Inter-Processor-Interrupt) */
|
||||||
|
|
||||||
putreg32(1 << S698PM_IPI_VECTOR, S698PM_IRQREG_ICLEAR);
|
putreg32(1 << S698PM_IPI_VECTOR, S698PM_IRQREG_ICLEAR);
|
||||||
@@ -258,6 +260,62 @@ int s698pm_pause_handler(int irq, void *c, void *arg)
|
|||||||
return OK;
|
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)
|
||||||
|
{
|
||||||
|
uintptr_t regaddr;
|
||||||
|
|
||||||
|
/* Execute Pause IRQ to CPU(cpu) */
|
||||||
|
|
||||||
|
regaddr = (uintptr_t)S698PM_IRQREG_P0_FORCE + (4 * cpu);
|
||||||
|
putreg32(1 << S698PM_IPI_VECTOR, regaddr);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: up_send_smp_call
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Send smp call to target cpu.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* cpuset - The set of CPUs to receive the SGI.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void up_send_smp_call(cpu_set_t cpuset)
|
||||||
|
{
|
||||||
|
int cpu;
|
||||||
|
|
||||||
|
for (; cpuset != 0; cpuset &= ~(1 << cpu))
|
||||||
|
{
|
||||||
|
cpu = ffs(cpuset) - 1;
|
||||||
|
up_cpu_pause_async(cpu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: up_cpu_pause
|
* Name: up_cpu_pause
|
||||||
*
|
*
|
||||||
@@ -280,8 +338,6 @@ int s698pm_pause_handler(int irq, void *c, void *arg)
|
|||||||
|
|
||||||
int up_cpu_pause(int cpu)
|
int up_cpu_pause(int cpu)
|
||||||
{
|
{
|
||||||
uintptr_t regaddr;
|
|
||||||
|
|
||||||
sinfo("cpu=%d\n", cpu);
|
sinfo("cpu=%d\n", cpu);
|
||||||
|
|
||||||
#ifdef CONFIG_SCHED_INSTRUMENTATION
|
#ifdef CONFIG_SCHED_INSTRUMENTATION
|
||||||
@@ -308,8 +364,7 @@ int up_cpu_pause(int cpu)
|
|||||||
|
|
||||||
/* Execute Pause IRQ to CPU(cpu) */
|
/* Execute Pause IRQ to CPU(cpu) */
|
||||||
|
|
||||||
regaddr = (uintptr_t)S698PM_IRQREG_P0_FORCE + (4 * cpu);
|
up_cpu_pause_async(cpu);
|
||||||
putreg32(1 << S698PM_IPI_VECTOR, regaddr);
|
|
||||||
|
|
||||||
/* 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();
|
||||||
|
|||||||
@@ -236,6 +236,8 @@ int up_pause_handler(int irq, void *c, void *arg)
|
|||||||
{
|
{
|
||||||
int cpu = this_cpu();
|
int cpu = this_cpu();
|
||||||
|
|
||||||
|
nxsched_smp_call_handler(irq, c, arg);
|
||||||
|
|
||||||
/* 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.
|
* interrupt by calling up_cpu_paused.
|
||||||
@@ -293,6 +295,25 @@ inline_function int up_cpu_async_pause(int cpu)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: up_send_smp_call
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Send smp call to target cpu.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* cpuset - The set of CPUs to receive the SGI.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void up_send_smp_call(cpu_set_t cpuset)
|
||||||
|
{
|
||||||
|
up_trigger_irq(SMP_IPI_IRQ, cpuset);
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: up_cpu_pause
|
* Name: up_cpu_pause
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -244,6 +244,31 @@ void xtensa_pause_handler(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: up_send_smp_call
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Send smp call to target cpu.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* cpuset - The set of CPUs to receive the SGI.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void up_send_smp_call(cpu_set_t cpuset)
|
||||||
|
{
|
||||||
|
int cpu;
|
||||||
|
|
||||||
|
for (; cpuset != 0; cpuset &= ~(1 << cpu))
|
||||||
|
{
|
||||||
|
cpu = ffs(cpuset) - 1;
|
||||||
|
xtensa_intercpu_interrupt(cpu, CPU_INTCODE_PAUSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: up_cpu_pause
|
* Name: up_cpu_pause
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -83,11 +83,13 @@ static int IRAM_ATTR esp32_fromcpu_interrupt(int fromcpu)
|
|||||||
|
|
||||||
int IRAM_ATTR esp32_fromcpu0_interrupt(int irq, void *context, void *arg)
|
int IRAM_ATTR esp32_fromcpu0_interrupt(int irq, void *context, void *arg)
|
||||||
{
|
{
|
||||||
|
nxsched_smp_call_handler(irq, context, arg);
|
||||||
return esp32_fromcpu_interrupt(0);
|
return esp32_fromcpu_interrupt(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int IRAM_ATTR esp32_fromcpu1_interrupt(int irq, void *context, void *arg)
|
int IRAM_ATTR esp32_fromcpu1_interrupt(int irq, void *context, void *arg)
|
||||||
{
|
{
|
||||||
|
nxsched_smp_call_handler(irq, context, arg);
|
||||||
return esp32_fromcpu_interrupt(1);
|
return esp32_fromcpu_interrupt(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -84,11 +84,13 @@ static int IRAM_ATTR esp32s3_fromcpu_interrupt(int fromcpu)
|
|||||||
|
|
||||||
int IRAM_ATTR esp32s3_fromcpu0_interrupt(int irq, void *context, void *arg)
|
int IRAM_ATTR esp32s3_fromcpu0_interrupt(int irq, void *context, void *arg)
|
||||||
{
|
{
|
||||||
|
nxsched_smp_call_handler(irq, context, arg);
|
||||||
return esp32s3_fromcpu_interrupt(0);
|
return esp32s3_fromcpu_interrupt(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int IRAM_ATTR esp32s3_fromcpu1_interrupt(int irq, void *context, void *arg)
|
int IRAM_ATTR esp32s3_fromcpu1_interrupt(int irq, void *context, void *arg)
|
||||||
{
|
{
|
||||||
|
nxsched_smp_call_handler(irq, context, arg);
|
||||||
return esp32s3_fromcpu_interrupt(1);
|
return esp32s3_fromcpu_interrupt(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1735,7 +1735,7 @@ void up_secure_irq(int irq, bool secure);
|
|||||||
# define up_secure_irq(i, s)
|
# define up_secure_irq(i, s)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SMP_CALL
|
#ifdef CONFIG_SMP
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: up_send_smp_call
|
* Name: up_send_smp_call
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -779,7 +779,7 @@ typedef CODE void (*nxsched_foreach_t)(FAR struct tcb_s *tcb, FAR void *arg);
|
|||||||
|
|
||||||
/* This is the callback type used by nxsched_smp_call() */
|
/* This is the callback type used by nxsched_smp_call() */
|
||||||
|
|
||||||
#ifdef CONFIG_SMP_CALL
|
#ifdef CONFIG_SMP
|
||||||
typedef CODE int (*nxsched_smp_call_t)(FAR void *arg);
|
typedef CODE int (*nxsched_smp_call_t)(FAR void *arg);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1623,7 +1623,7 @@ void nxsched_dumponexit(void);
|
|||||||
# define nxsched_dumponexit()
|
# define nxsched_dumponexit()
|
||||||
#endif /* CONFIG_DUMP_ON_EXIT */
|
#endif /* CONFIG_DUMP_ON_EXIT */
|
||||||
|
|
||||||
#ifdef CONFIG_SMP_CALL
|
#ifdef CONFIG_SMP
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: nxsched_smp_call_handler
|
* Name: nxsched_smp_call_handler
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -389,12 +389,6 @@ config SMP_DEFAULT_CPUSET
|
|||||||
Set the Default CPU bits. The way to use the unset CPU is to call the
|
Set the Default CPU bits. The way to use the unset CPU is to call the
|
||||||
sched_setaffinity function to bind a task to the CPU. bit0 means CPU0.
|
sched_setaffinity function to bind a task to the CPU. bit0 means CPU0.
|
||||||
|
|
||||||
config SMP_CALL
|
|
||||||
bool "Support SMP function call"
|
|
||||||
default n
|
|
||||||
---help---
|
|
||||||
Enable to support SMP function call.
|
|
||||||
|
|
||||||
endif # SMP
|
endif # SMP
|
||||||
|
|
||||||
choice
|
choice
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ if(CONFIG_DUMP_ON_EXIT)
|
|||||||
list(APPEND SRCS sched_dumponexit.c)
|
list(APPEND SRCS sched_dumponexit.c)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CONFIG_SMP_CALL)
|
if(CONFIG_SMP)
|
||||||
list(APPEND SRCS sched_smp.c)
|
list(APPEND SRCS sched_smp.c)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ ifeq ($(CONFIG_DUMP_ON_EXIT),y)
|
|||||||
CSRCS += sched_dumponexit.c
|
CSRCS += sched_dumponexit.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_SMP_CALL),y)
|
ifeq ($(CONFIG_SMP),y)
|
||||||
CSRCS += sched_smp.c
|
CSRCS += sched_smp.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user