arch: arm64: Fix coherence issue of SMP boot code

The current SMP boot code doesn't consider that the cores can boot at
the same time. Possibly, more than one core can boot into primary core
boot sequence. Fix it by using the atomic operation to make sure only
one core act as the primary core.

Correspondingly, sgi_raise_ipi should transfer CPU id to mpidr.

Signed-off-by: Jaxson Han <jaxson.han@arm.com>
diff --git a/arch/arm64/core/reset.S b/arch/arm64/core/reset.S
index 9499753..6c12f0d 100644
--- a/arch/arm64/core/reset.S
+++ b/arch/arm64/core/reset.S
@@ -109,9 +109,18 @@
 
 	ldr	x0, =arm64_cpu_boot_params
 	get_cpu_id x1
-	ldr	x2, [x0, #BOOT_PARAM_MPID_OFFSET]
+
+	/*
+	 * If the cores start up at the same time, we should atomically load and
+	 * store the mpid into arm64_cpu_boot_params.
+	 */
+	ldaxr	x2, [x0, #BOOT_PARAM_MPID_OFFSET]
 	cmp	x2, #-1
-	beq	primary_core
+	bne	1f
+	/* try to store x1 (mpid) */
+	stlxr	w3, x1, [x0]
+	/* If succeed, go to primary_core */
+	cbz	w3, primary_core
 
 	/* loop until our turn comes */
 1:	dmb	ld
@@ -125,8 +134,6 @@
 	b	2f
 
 primary_core:
-	/* advertise ourself */
-	str	x1, [x0, #BOOT_PARAM_MPID_OFFSET]
 #endif
 	/* load primary stack and entry point */
 	ldr	x24, =(z_interrupt_stacks + CONFIG_ISR_STACK_SIZE)
diff --git a/arch/arm64/core/smp.c b/arch/arm64/core/smp.c
index e23a8ad..ea84914 100644
--- a/arch/arm64/core/smp.c
+++ b/arch/arm64/core/smp.c
@@ -213,9 +213,9 @@
 
 void z_arm64_flush_fpu_ipi(unsigned int cpu)
 {
-	const uint64_t mpidr = GET_MPIDR();
+	const uint64_t mpidr = cpu_node_list[cpu];
 
-	gic_raise_sgi(SGI_FPU_IPI, mpidr, (1 << cpu));
+	gic_raise_sgi(SGI_FPU_IPI, mpidr, 1 << MPIDR_TO_CORE(mpidr));
 }
 #endif