diff --git a/arch/arm/src/armv7-a/arm_gicv2.c b/arch/arm/src/armv7-a/arm_gicv2.c index d970f86877..82d486f653 100644 --- a/arch/arm/src/armv7-a/arm_gicv2.c +++ b/arch/arm/src/armv7-a/arm_gicv2.c @@ -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 diff --git a/arch/arm/src/armv7-a/gic.h b/arch/arm/src/armv7-a/gic.h index 75d2147cf0..29359e12dd 100644 --- a/arch/arm/src/armv7-a/gic.h +++ b/arch/arm/src/armv7-a/gic.h @@ -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