Tegra: assembly version of the 'plat_core_pos_by_mpidr' handler

The 'plat_core_pos_by_mpidr' handler gets called very early during boot
and the compiler generated code overwrites the caller's registers.

This patch converts the 'plat_core_pos_by_mpidr' handler into an assembly
function and uses registers x0-x3, to fix this anomaly.

Change-Id: I8d974e007a0bad039defaf77b11a180d899ead3c
Signed-off-by: Varun Wadekar <vwadekar@nvidia.com>
diff --git a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S
index b6622c7..5f01416 100644
--- a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S
+++ b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S
@@ -39,6 +39,7 @@
 	.globl	plat_crash_console_init
 	.globl	plat_crash_console_putc
 	.globl	plat_crash_console_flush
+	.weak	plat_core_pos_by_mpidr
 	.globl	tegra_secure_entrypoint
 	.globl	plat_reset_handler
 
@@ -270,6 +271,42 @@
 	ret
 endfunc plat_reset_handler
 
+	/* ------------------------------------------------------
+	 * int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
+	 *
+	 * This function implements a part of the critical
+	 * interface between the psci generic layer and the
+	 * platform that allows the former to query the platform
+	 * to convert an MPIDR to a unique linear index. An error
+	 * code (-1) is returned in case the MPIDR is invalid.
+	 *
+	 * Clobbers: x0-x3
+	 * ------------------------------------------------------
+	 */
+func plat_core_pos_by_mpidr
+	lsr	x1, x0, #MPIDR_AFF0_SHIFT
+	and	x1, x1, #MPIDR_AFFLVL_MASK /* core id */
+	lsr	x2, x0, #MPIDR_AFF1_SHIFT
+	and	x2, x2, #MPIDR_AFFLVL_MASK /* cluster id */
+
+	/* core_id >= PLATFORM_MAX_CPUS_PER_CLUSTER */
+	mov	x0, #-1
+	cmp	x1, #(PLATFORM_MAX_CPUS_PER_CLUSTER - 1)
+	b.gt	1f
+
+	/* cluster_id >= PLATFORM_CLUSTER_COUNT */
+	cmp	x2, #(PLATFORM_CLUSTER_COUNT - 1)
+	b.gt	1f
+
+	/* CorePos = CoreId + (ClusterId * cpus per cluster) */
+	mov	x3, #PLATFORM_MAX_CPUS_PER_CLUSTER
+	mul	x3, x3, x2
+	add	x0, x1, x3
+
+1:
+	ret
+endfunc plat_core_pos_by_mpidr
+
 	/* ----------------------------------------
 	 * Secure entrypoint function for CPU boot
 	 * ----------------------------------------