From af8462cb06f9860542b63d6070418d431abb67fb Mon Sep 17 00:00:00 2001
From: Lukas Hanel <lukas.hanel@trustonic.com>
Date: Mon, 7 Jun 2021 18:14:40 +0200
Subject: [PATCH 1/2] feat(spmd): pass linear id to secondary cores boot

Our TEE, Kinibi, is used to receives the core linear ID in the x3
register of booting secondary cores.
This patch is necessary to bring up secondary cores with Kinibi as an
SPMC in SEL1.

In Kinibi, the TEE is mostly platform-independent and all platform-
specifics like topology is concentrated in ATF of our customers.
That is why we don't have the MPIDR - linear ID mapping in Kinibi.
We need the correct linear ID to program the GICv2 target register,
for example in power management case.
It is not needed on GICv3 and GICv4, because GICv3/v4 use a fixed
mapping from MPIDR to ICDIPTR/GICD_ITARGETSRn register.

For debug and power management purpose, we also want a unified view to
linear_id between Linux and the TEE.
E.g. to disable a core, to see what cores are printing a trace /
an event.

In the past, Kinibi had several other designs, but the complexity was
getting out of control:
* Platform-specific assembler macros in the kernel.
* A per-core SMC from Linux to tell the linear ID after the boot.
* With DynamiQ, it seems SIPs were playing with MPIDR register values,
  reusing them between cores and changing them during boot.

Change-Id: I66c7fd52a9458ac82e0b1824eaedab0b22ea59c0
Signed-off-by: Lukas Hanel <lukas.hanel@trustonic.com>
---
 services/std_svc/spmd/spmd_pm.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/services/std_svc/spmd/spmd_pm.c b/services/std_svc/spmd/spmd_pm.c
index 1983ac30c..44e19042a 100644
--- a/services/std_svc/spmd/spmd_pm.c
+++ b/services/std_svc/spmd/spmd_pm.c
@@ -100,6 +100,13 @@ static void spmd_cpu_on_finish_handler(u_register_t unused)
 
 	cm_setup_context(&ctx->cpu_ctx, spmc_ep_info);
 
+	/*
+	 * Pass linear id of secondary cores in x3 to SPMC.
+	 * SPMC can use this to index into a per-core boot stack array, etc.
+	 * That way SPMC reuses the platform-specific MPIDR topology of TF-A.
+	 */
+	write_ctx_reg(get_gpregs_ctx(&ctx->cpu_ctx), CTX_GPREG_X3, linear_id);
+
 	/* Mark CPU as initiating ON operation */
 	ctx->state = SPMC_STATE_ON_PENDING;
 
-- 
2.17.1

