tee: smp support

During the boot phase, when we transition from tee smp to ap smp, we can use a busy waitflag to wait for the completion of the initialization of ap's core0

test:
We can use qemu for testing.
compiling
make distclean -j20; ./tools/configure.sh -l qemu-armv8a:nsh_smp ;make -j20
running
qemu-system-aarch64 -cpu cortex-a53 -smp 4 -nographic -machine virt,virtualization=on,gic-version=3 -net none -chardev stdio,id=con,mux=on -serial chardev:con -mon chardev=con,mode=readline -kernel ./nuttx
Signed-off-by: hujun5 <hujun5@xiaomi.com>
This commit is contained in:
hujun5 2024-03-13 08:23:02 +08:00 committed by Xiang Xiao
parent 600368fbe2
commit 80fdf95790
14 changed files with 173 additions and 45 deletions

View File

@ -313,7 +313,7 @@ int up_cpu_pause(int cpu)
/* Execute SGI2 */
arm_cpu_sgi(GIC_IRQ_SGI2, (1 << cpu));
arm_cpu_sgi(GIC_SMP_CPUPAUSE, (1 << cpu));
/* Wait for the other CPU to unlock g_cpu_paused meaning that
* it is fully paused and ready for up_cpu_resume();

View File

@ -135,7 +135,8 @@ int up_cpu_start(int cpu)
/* Execute SGI1 */
arm_cpu_sgi(GIC_IRQ_SGI1, (1 << cpu));
arm_cpu_sgi(GIC_SMP_CPUSTART, (1 << cpu));
return OK;
}

View File

@ -165,8 +165,13 @@ void arm_gic0_initialize(void)
#ifdef CONFIG_SMP
/* Attach SGI interrupt handlers. This attaches the handler to all CPUs. */
DEBUGVERIFY(irq_attach(GIC_IRQ_SGI1, arm_start_handler, NULL));
DEBUGVERIFY(irq_attach(GIC_IRQ_SGI2, arm_pause_handler, NULL));
DEBUGVERIFY(irq_attach(GIC_SMP_CPUSTART, arm_start_handler, NULL));
DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE, arm_pause_handler, NULL));
# ifdef CONFIG_SMP_CALL
DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
nxsched_smp_call_handler, NULL));
# endif
#endif
arm_gic_dump("Exit arm_gic0_initialize", true, 0);
@ -667,4 +672,10 @@ int arm_gic_irq_trigger(int irq, bool edge)
return -EINVAL;
}
#ifdef CONFIG_SMP_CALL
void up_send_smp_call(cpu_set_t cpuset)
{
up_trigger_irq(GIC_SMP_CPUCALL, cpuset);
}
#endif
#endif /* CONFIG_ARMV7A_HAVE_GICv2 */

View File

@ -615,6 +615,16 @@
#define GIC_IRQ_SPI 32 /* First SPI interrupt ID */
#ifdef CONFIG_ARCH_TRUSTZONE_SECURE
# define GIC_SMP_CPUSTART GIC_IRQ_SGI9
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI10
# define GIC_SMP_CPUCALL GIC_IRQ_SGI11
#else
# define GIC_SMP_CPUSTART GIC_IRQ_SGI1
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI2
# define GIC_SMP_CPUCALL GIC_IRQ_SGI3
#endif
/****************************************************************************
* Inline Functions
****************************************************************************/
@ -680,14 +690,21 @@ static inline void arm_cpu_sgi(int sgi, unsigned int cpuset)
GIC_ICDSGIR_TGTFILTER_THIS;
#endif
#ifndef CONFIG_ARCH_TRUSTZONE_SECURE
/* 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.
*/
regval |= GIC_ICDSGIR_NSATT_GRP1;
#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);
}

View File

@ -313,7 +313,7 @@ int up_cpu_pause(int cpu)
/* Execute SGI2 */
arm_cpu_sgi(GIC_IRQ_SGI2, (1 << cpu));
arm_cpu_sgi(GIC_SMP_CPUPAUSE, (1 << cpu));
/* Wait for the other CPU to unlock g_cpu_paused meaning that
* it is fully paused and ready for up_cpu_resume();

View File

@ -129,7 +129,7 @@ int up_cpu_start(int cpu)
/* Execute SGI1 */
arm_cpu_sgi(GIC_IRQ_SGI1, (1 << cpu));
arm_cpu_sgi(GIC_SMP_CPUSTART, (1 << cpu));
return OK;
}

View File

@ -159,8 +159,13 @@ void arm_gic0_initialize(void)
#ifdef CONFIG_SMP
/* Attach SGI interrupt handlers. This attaches the handler to all CPUs. */
DEBUGVERIFY(irq_attach(GIC_IRQ_SGI1, arm_start_handler, NULL));
DEBUGVERIFY(irq_attach(GIC_IRQ_SGI2, arm_pause_handler, NULL));
DEBUGVERIFY(irq_attach(GIC_SMP_CPUSTART, arm_start_handler, NULL));
DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE, arm_pause_handler, NULL));
# ifdef CONFIG_SMP_CALL
DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
nxsched_smp_call_handler, NULL));
# endif
#endif
arm_gic_dump("Exit arm_gic0_initialize", true, 0);
@ -657,4 +662,10 @@ int arm_gic_irq_trigger(int irq, bool edge)
return -EINVAL;
}
# ifdef CONFIG_SMP_CALL
void up_send_smp_call(cpu_set_t cpuset)
{
up_trigger_irq(GIC_SMP_CPUCALL, cpuset);
}
# endif
#endif /* CONFIG_ARMV7R_HAVE_GICv2 */

View File

@ -606,6 +606,16 @@
#define GIC_IRQ_SPI 32 /* First SPI interrupt ID */
#ifdef CONFIG_ARCH_TRUSTZONE_SECURE
# define GIC_SMP_CPUSTART GIC_IRQ_SGI9
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI10
# define GIC_SMP_CPUCALL GIC_IRQ_SGI11
#else
# define GIC_SMP_CPUSTART GIC_IRQ_SGI1
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI2
# define GIC_SMP_CPUCALL GIC_IRQ_SGI3
#endif
/****************************************************************************
* Inline Functions
****************************************************************************/
@ -671,6 +681,22 @@ static inline void arm_cpu_sgi(int sgi, unsigned int cpuset)
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);
}

View File

@ -309,6 +309,16 @@
(((_aff1) & SGIR_AFF_MASK) << SGIR_AFF1_SHIFT) | \
((_tgt) & SGIR_TGT_MASK))
#ifdef CONFIG_ARCH_TRUSTZONE_SECURE
# define GIC_SMP_CPUSTART GIC_IRQ_SGI9
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI10
# define GIC_SMP_CPUCALL GIC_IRQ_SGI11
#else
# define GIC_SMP_CPUSTART GIC_IRQ_SGI1
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI2
# define GIC_SMP_CPUCALL GIC_IRQ_SGI3
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/

View File

@ -560,7 +560,12 @@ static void gicv3_dist_init(void)
#ifdef CONFIG_SMP
/* Attach SGI interrupt handlers. This attaches the handler to all CPUs. */
DEBUGVERIFY(irq_attach(GIC_IRQ_SGI2, arm64_pause_handler, NULL));
DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE, arm64_pause_handler, NULL));
# ifdef CONFIG_SMP_CALL
DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
nxsched_smp_call_handler, NULL));
# endif
#endif
}
@ -800,7 +805,7 @@ static void arm_gic_init(void)
gicv3_cpuif_init();
#ifdef CONFIG_SMP
up_enable_irq(GIC_IRQ_SGI2);
up_enable_irq(GIC_SMP_CPUPAUSE);
#endif
}
@ -828,4 +833,10 @@ void arm_gic_secondary_init(void)
arm_gic_init();
}
# ifdef CONFIG_SMP_CALL
void up_send_smp_call(cpu_set_t cpuset)
{
up_trigger_irq(GIC_SMP_CPUCALL, cpuset);
}
# endif
#endif

View File

@ -318,7 +318,7 @@ int up_cpu_pause(int cpu)
/* Execute SGI2 */
ret = arm64_gic_raise_sgi(GIC_IRQ_SGI2, (1 << cpu));
ret = arm64_gic_raise_sgi(GIC_SMP_CPUPAUSE, (1 << cpu));
if (ret < 0)
{
/* What happened? Unlock the g_cpu_wait spinlock */

View File

@ -263,22 +263,32 @@
#define IRQ_DEFAULT_PRIORITY 0xa0
#define GIC_IRQ_SGI0 0
#define GIC_IRQ_SGI1 1
#define GIC_IRQ_SGI2 2
#define GIC_IRQ_SGI3 3
#define GIC_IRQ_SGI4 4
#define GIC_IRQ_SGI5 5
#define GIC_IRQ_SGI6 6
#define GIC_IRQ_SGI7 7
#define GIC_IRQ_SGI8 8
#define GIC_IRQ_SGI9 9
#define GIC_IRQ_SGI10 10
#define GIC_IRQ_SGI11 11
#define GIC_IRQ_SGI12 12
#define GIC_IRQ_SGI13 13
#define GIC_IRQ_SGI14 14
#define GIC_IRQ_SGI15 15
#define GIC_IRQ_SGI0 0
#define GIC_IRQ_SGI1 1
#define GIC_IRQ_SGI2 2
#define GIC_IRQ_SGI3 3
#define GIC_IRQ_SGI4 4
#define GIC_IRQ_SGI5 5
#define GIC_IRQ_SGI6 6
#define GIC_IRQ_SGI7 7
#define GIC_IRQ_SGI8 8
#define GIC_IRQ_SGI9 9
#define GIC_IRQ_SGI10 10
#define GIC_IRQ_SGI11 11
#define GIC_IRQ_SGI12 12
#define GIC_IRQ_SGI13 13
#define GIC_IRQ_SGI14 14
#define GIC_IRQ_SGI15 15
#ifdef CONFIG_ARCH_TRUSTZONE_SECURE
# define GIC_SMP_CPUSTART GIC_IRQ_SGI9
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI10
# define GIC_SMP_CPUCALL GIC_IRQ_SGI11
#else
# define GIC_SMP_CPUSTART GIC_IRQ_SGI1
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI2
# define GIC_SMP_CPUCALL GIC_IRQ_SGI3
#endif
/****************************************************************************
* Public Function Prototypes

View File

@ -543,7 +543,11 @@
#define GIC_ICDSGIR_INTID_MASK (0x3ff << GIC_ICDSGIR_INTID_SHIFT)
# define GIC_ICDSGIR_INTID(n) ((uint32_t)(n) << GIC_ICDSGIR_INTID_SHIFT)
/* Bits 10-14: Reserved */
#define GIC_ICDSGIR_NSATT (1 << 15)
#define GIC_ICDSGIR_NSATT_SHIFT (15)
#define GIC_ICDSGIR_NSATT_MASK (1 << GIC_ICDSGIR_NSATT_SHIFT)
# define GIC_ICDSGIR_NSATT_GRP0 (0 << GIC_ICDSGIR_NSATT_SHIFT)
# define GIC_ICDSGIR_NSATT_GRP1 (1 << GIC_ICDSGIR_NSATT_SHIFT)
#define GIC_ICDSGIR_CPUTARGET_SHIFT (16) /* Bits 16-23: CPU target */
#define GIC_ICDSGIR_CPUTARGET_MASK (0xff << GIC_ICDSGIR_CPUTARGET_SHIFT)
# define GIC_ICDSGIR_CPUTARGET(n) ((uint32_t)(n) << GIC_ICDSGIR_CPUTARGET_SHIFT)
@ -735,6 +739,22 @@ static inline void arm_cpu_sgi(int sgi, unsigned int cpuset)
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);
}
@ -890,7 +910,12 @@ static void arm_gic0_initialize(void)
#ifdef CONFIG_SMP
/* Attach SGI interrupt handlers. This attaches the handler to all CPUs. */
DEBUGVERIFY(irq_attach(GIC_IRQ_SGI2, arm64_pause_handler, NULL));
DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE, arm64_pause_handler, NULL));
# ifdef CONFIG_SMP_CALL
DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
nxsched_smp_call_handler, NULL));
# endif
#endif
}
@ -1461,6 +1486,13 @@ int arm64_gic_raise_sgi(unsigned int sgi, uint16_t cpuset)
arm_cpu_sgi(sgi, cpuset);
return 0;
}
# ifdef CONFIG_SMP_CALL
void up_send_smp_call(cpu_set_t cpuset)
{
up_trigger_irq(GIC_SMP_CPUCALL, cpuset);
}
# endif
#endif /* CONFIG_SMP */
#endif /* CONFIG_ARM64_GIC_VERSION == 2 */

View File

@ -69,8 +69,6 @@
# define IGROUPR_SGI_VAL 0xFFFFFFFFU
#endif
#define SMP_FUNC_CALL_IPI GIC_IRQ_SGI3
#define PENDING_GRP1NS_INTID 1021
#define SPURIOUS_INT 1023
@ -657,9 +655,10 @@ static void gicv3_dist_init(void)
#ifdef CONFIG_SMP
/* Attach SGI interrupt handlers. This attaches the handler to all CPUs. */
DEBUGVERIFY(irq_attach(GIC_IRQ_SGI2, arm64_pause_handler, NULL));
DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE, arm64_pause_handler, NULL));
# ifdef CONFIG_SMP_CALL
DEBUGVERIFY(irq_attach(SMP_FUNC_CALL_IPI,
DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
nxsched_smp_call_handler, NULL));
# endif
#endif
@ -957,9 +956,9 @@ static void arm64_gic_init(void)
gicv3_cpuif_init();
#ifdef CONFIG_SMP
up_enable_irq(GIC_IRQ_SGI2);
up_enable_irq(GIC_SMP_CPUPAUSE);
# ifdef CONFIG_SMP_CALL
up_enable_irq(SMP_FUNC_CALL_IPI);
up_enable_irq(GIC_SMP_CPUCALL);
# endif
#endif
}
@ -987,11 +986,11 @@ void arm64_gic_secondary_init(void)
{
arm64_gic_init();
}
#endif
#ifdef CONFIG_SMP_CALL
# ifdef CONFIG_SMP_CALL
void up_send_smp_call(cpu_set_t cpuset)
{
up_trigger_irq(SMP_FUNC_CALL_IPI, cpuset);
up_trigger_irq(GIC_SMP_CPUCALL, cpuset);
}
# endif
#endif