armv7-a/r: check gic init wait done when using sgi
In SMP mode, qemu/goldfish platform, cpu0 use up_cpu_start() to start others cpus. But in previous patch(mathion ahead), arm_gic_initialize() will wait others cpus start, so deadlocked! Resolve: Move the wait logic when use using sgi Signed-off-by: ligd <liguiding1@xiaomi.com>
This commit is contained in:
parent
4f5b3f3d82
commit
cd88cb1e48
@ -48,7 +48,7 @@
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_SMP) && CONFIG_SMP_NCPUS > 1
|
||||
static volatile bool g_gic_init_done[CONFIG_SMP_NCPUS];
|
||||
static volatile cpu_set_t g_gic_init_done;
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
@ -68,20 +68,22 @@ static volatile bool g_gic_init_done[CONFIG_SMP_NCPUS];
|
||||
#if defined(CONFIG_SMP) && CONFIG_SMP_NCPUS > 1
|
||||
static void arm_gic_init_done(void)
|
||||
{
|
||||
int cpu = up_cpu_index();
|
||||
int i;
|
||||
CPU_SET(up_cpu_index(), &g_gic_init_done);
|
||||
}
|
||||
|
||||
g_gic_init_done[cpu] = true;
|
||||
if (cpu == 0)
|
||||
static void arm_gic_wait_done(cpu_set_t cpuset)
|
||||
{
|
||||
cpu_set_t tmpset;
|
||||
|
||||
do
|
||||
{
|
||||
for (i = 1; i < CONFIG_SMP_NCPUS; i++)
|
||||
{
|
||||
while (!g_gic_init_done[i]);
|
||||
}
|
||||
CPU_AND(&tmpset, &g_gic_init_done, &cpuset);
|
||||
}
|
||||
while (!CPU_EQUAL(&tmpset, &cpuset));
|
||||
}
|
||||
#else
|
||||
#define arm_gic_init_done()
|
||||
#define arm_gic_wait_done(cpuset)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
@ -709,6 +711,39 @@ int arm_gic_irq_trigger(int irq, bool edge)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
void arm_cpu_sgi(int sgi, unsigned int cpuset)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
arm_gic_wait_done(cpuset);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
regval = GIC_ICDSGIR_INTID(sgi) | GIC_ICDSGIR_CPUTARGET(cpuset) |
|
||||
GIC_ICDSGIR_TGTFILTER_LIST;
|
||||
#else
|
||||
regval = GIC_ICDSGIR_INTID(sgi) | GIC_ICDSGIR_CPUTARGET(0) |
|
||||
GIC_ICDSGIR_TGTFILTER_THIS;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ARCH_TRUSTZONE_SECURE)
|
||||
if (sgi >= GIC_IRQ_SGI0 && sgi <= GIC_IRQ_SGI7)
|
||||
#endif
|
||||
{
|
||||
/* Set NSATT be 1: forward the SGI specified in the SGIINTID field to a
|
||||
* specified CPU interfaces only if the SGI is configured as Group 1 on
|
||||
* that interface.
|
||||
* For non-secure context, the configuration of GIC_ICDSGIR_NSATT_GRP1
|
||||
* is not mandatory in the GICv2 specification, but for SMP scenarios,
|
||||
* this value needs to be configured, otherwise issues may occur in the
|
||||
* SMP scenario.
|
||||
*/
|
||||
|
||||
regval |= GIC_ICDSGIR_NSATT_GRP1;
|
||||
}
|
||||
|
||||
putreg32(regval, GIC_ICDSGIR);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/****************************************************************************
|
||||
* Name: up_send_smp_call
|
||||
|
@ -678,36 +678,7 @@ static inline unsigned int arm_gic_nlines(void)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void arm_cpu_sgi(int sgi, unsigned int cpuset)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
regval = GIC_ICDSGIR_INTID(sgi) | GIC_ICDSGIR_CPUTARGET(cpuset) |
|
||||
GIC_ICDSGIR_TGTFILTER_LIST;
|
||||
#else
|
||||
regval = GIC_ICDSGIR_INTID(sgi) | GIC_ICDSGIR_CPUTARGET(0) |
|
||||
GIC_ICDSGIR_TGTFILTER_THIS;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ARCH_TRUSTZONE_SECURE)
|
||||
if (sgi >= GIC_IRQ_SGI0 && sgi <= GIC_IRQ_SGI7)
|
||||
#endif
|
||||
{
|
||||
/* Set NSATT be 1: forward the SGI specified in the SGIINTID field to a
|
||||
* specified CPU interfaces only if the SGI is configured as Group 1 on
|
||||
* that interface.
|
||||
* For non-secure context, the configuration of GIC_ICDSGIR_NSATT_GRP1
|
||||
* is not mandatory in the GICv2 specification, but for SMP scenarios,
|
||||
* this value needs to be configured, otherwise issues may occur in the
|
||||
* SMP scenario.
|
||||
*/
|
||||
|
||||
regval |= GIC_ICDSGIR_NSATT_GRP1;
|
||||
}
|
||||
|
||||
putreg32(regval, GIC_ICDSGIR);
|
||||
}
|
||||
void arm_cpu_sgi(int sgi, unsigned int cpuset);
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
|
Loading…
Reference in New Issue
Block a user