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
 	 * ----------------------------------------
diff --git a/plat/nvidia/tegra/common/tegra_common.mk b/plat/nvidia/tegra/common/tegra_common.mk
index 50c9592..66d037f 100644
--- a/plat/nvidia/tegra/common/tegra_common.mk
+++ b/plat/nvidia/tegra/common/tegra_common.mk
@@ -32,5 +32,4 @@
 				${COMMON_DIR}/tegra_io_storage.c		\
 				${COMMON_DIR}/tegra_platform.c			\
 				${COMMON_DIR}/tegra_pm.c			\
-				${COMMON_DIR}/tegra_sip_calls.c			\
-				${COMMON_DIR}/tegra_topology.c
+				${COMMON_DIR}/tegra_sip_calls.c
diff --git a/plat/nvidia/tegra/common/tegra_topology.c b/plat/nvidia/tegra/common/tegra_topology.c
deleted file mode 100644
index 205b051..0000000
--- a/plat/nvidia/tegra/common/tegra_topology.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <platform_def.h>
-
-#include <arch.h>
-#include <lib/psci/psci.h>
-#include <plat/common/platform.h>
-
-#pragma weak plat_core_pos_by_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.
- ******************************************************************************/
-int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
-{
-	u_register_t cluster_id, cpu_id;
-	int32_t result;
-
-	cluster_id = (mpidr >> (u_register_t)MPIDR_AFF1_SHIFT) &
-		     (u_register_t)MPIDR_AFFLVL_MASK;
-	cpu_id = (mpidr >> (u_register_t)MPIDR_AFF0_SHIFT) &
-		 (u_register_t)MPIDR_AFFLVL_MASK;
-
-	/* CorePos = CoreId + (ClusterId * cpus per cluster) */
-	result = (int32_t)cpu_id + ((int32_t)cluster_id *
-		 PLATFORM_MAX_CPUS_PER_CLUSTER);
-
-	if (cluster_id >= (u_register_t)PLATFORM_CLUSTER_COUNT) {
-		result = PSCI_E_NOT_PRESENT;
-	}
-
-	/*
-	 * Validate cpu_id by checking whether it represents a CPU in
-	 * one of the two clusters present on the platform.
-	 */
-	if (cpu_id >= (u_register_t)PLATFORM_MAX_CPUS_PER_CLUSTER) {
-		result = PSCI_E_NOT_PRESENT;
-	}
-
-	return result;
-}