From c15dd77fd415d0287e94070e700427e3af32d8e8 Mon Sep 17 00:00:00 2001 From: hujun5 Date: Wed, 13 Mar 2024 08:23:02 +0800 Subject: [PATCH] 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 --- arch/arm/src/armv7-a/arm_cpupause.c | 2 +- arch/arm/src/armv7-a/arm_cpustart.c | 3 +- arch/arm/src/armv7-a/arm_gicv2.c | 15 +++++++-- arch/arm/src/armv7-a/gic.h | 31 ++++++++++++++----- arch/arm/src/armv7-r/arm_cpupause.c | 2 +- arch/arm/src/armv7-r/arm_cpustart.c | 2 +- arch/arm/src/armv7-r/arm_gicv2.c | 15 +++++++-- arch/arm/src/armv7-r/gic.h | 26 ++++++++++++++++ arch/arm/src/armv8-r/arm_gic.h | 10 ++++++ arch/arm/src/armv8-r/arm_gicv3.c | 15 +++++++-- arch/arm64/src/common/arm64_cpupause.c | 2 +- arch/arm64/src/common/arm64_gic.h | 42 ++++++++++++++++---------- arch/arm64/src/common/arm64_gicv2.c | 36 ++++++++++++++++++++-- arch/arm64/src/common/arm64_gicv3.c | 17 +++++------ 14 files changed, 173 insertions(+), 45 deletions(-) diff --git a/arch/arm/src/armv7-a/arm_cpupause.c b/arch/arm/src/armv7-a/arm_cpupause.c index 4c7b6a71ddb56..eca12e7453db6 100644 --- a/arch/arm/src/armv7-a/arm_cpupause.c +++ b/arch/arm/src/armv7-a/arm_cpupause.c @@ -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(); diff --git a/arch/arm/src/armv7-a/arm_cpustart.c b/arch/arm/src/armv7-a/arm_cpustart.c index a7dd56c7a5220..4abd78cf2a663 100644 --- a/arch/arm/src/armv7-a/arm_cpustart.c +++ b/arch/arm/src/armv7-a/arm_cpustart.c @@ -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; } diff --git a/arch/arm/src/armv7-a/arm_gicv2.c b/arch/arm/src/armv7-a/arm_gicv2.c index 0dbe6be1708b7..1469a5624e952 100644 --- a/arch/arm/src/armv7-a/arm_gicv2.c +++ b/arch/arm/src/armv7-a/arm_gicv2.c @@ -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 */ diff --git a/arch/arm/src/armv7-a/gic.h b/arch/arm/src/armv7-a/gic.h index 2cbeaa8f7ff7e..75d2147cf080a 100644 --- a/arch/arm/src/armv7-a/gic.h +++ b/arch/arm/src/armv7-a/gic.h @@ -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); } diff --git a/arch/arm/src/armv7-r/arm_cpupause.c b/arch/arm/src/armv7-r/arm_cpupause.c index 3e8102d6f5132..afca4086c6ae5 100644 --- a/arch/arm/src/armv7-r/arm_cpupause.c +++ b/arch/arm/src/armv7-r/arm_cpupause.c @@ -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(); diff --git a/arch/arm/src/armv7-r/arm_cpustart.c b/arch/arm/src/armv7-r/arm_cpustart.c index 51e24476a7103..fe93836e5b5de 100644 --- a/arch/arm/src/armv7-r/arm_cpustart.c +++ b/arch/arm/src/armv7-r/arm_cpustart.c @@ -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; } diff --git a/arch/arm/src/armv7-r/arm_gicv2.c b/arch/arm/src/armv7-r/arm_gicv2.c index 46407b67604cf..fb77ad1c923a7 100644 --- a/arch/arm/src/armv7-r/arm_gicv2.c +++ b/arch/arm/src/armv7-r/arm_gicv2.c @@ -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 */ diff --git a/arch/arm/src/armv7-r/gic.h b/arch/arm/src/armv7-r/gic.h index 65378e8b9c8d6..ecee23563df01 100644 --- a/arch/arm/src/armv7-r/gic.h +++ b/arch/arm/src/armv7-r/gic.h @@ -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); } diff --git a/arch/arm/src/armv8-r/arm_gic.h b/arch/arm/src/armv8-r/arm_gic.h index d7ad47474d7af..e43ccff8d0364 100644 --- a/arch/arm/src/armv8-r/arm_gic.h +++ b/arch/arm/src/armv8-r/arm_gic.h @@ -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 ****************************************************************************/ diff --git a/arch/arm/src/armv8-r/arm_gicv3.c b/arch/arm/src/armv8-r/arm_gicv3.c index 1d22ca0b18baf..9514e45c0b629 100644 --- a/arch/arm/src/armv8-r/arm_gicv3.c +++ b/arch/arm/src/armv8-r/arm_gicv3.c @@ -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 diff --git a/arch/arm64/src/common/arm64_cpupause.c b/arch/arm64/src/common/arm64_cpupause.c index 943b56c42181e..7793b56c48bd5 100644 --- a/arch/arm64/src/common/arm64_cpupause.c +++ b/arch/arm64/src/common/arm64_cpupause.c @@ -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 */ diff --git a/arch/arm64/src/common/arm64_gic.h b/arch/arm64/src/common/arm64_gic.h index 374a2d54c50c6..cce6eebf3bd57 100644 --- a/arch/arm64/src/common/arm64_gic.h +++ b/arch/arm64/src/common/arm64_gic.h @@ -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 diff --git a/arch/arm64/src/common/arm64_gicv2.c b/arch/arm64/src/common/arm64_gicv2.c index 0f844540b5f17..6b7a16f767c50 100644 --- a/arch/arm64/src/common/arm64_gicv2.c +++ b/arch/arm64/src/common/arm64_gicv2.c @@ -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 */ diff --git a/arch/arm64/src/common/arm64_gicv3.c b/arch/arm64/src/common/arm64_gicv3.c index eb37d1d684730..24a3220344fef 100644 --- a/arch/arm64/src/common/arm64_gicv3.c +++ b/arch/arm64/src/common/arm64_gicv3.c @@ -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