FVP: Add support for multi-threaded CPUs
ARM CPUs with multi-threading implementation has more than one
Processing Element in a single physical CPU. Such an implementation will
reflect the following changes in the MPIDR register:
- The MT bit set;
- Affinity levels pertaining to cluster and CPUs occupy one level
higher than in a single-threaded implementation, and the lowest
affinity level pertains to hardware threads. MPIDR affinity level
fields essentially appear shifted to left than otherwise.
The FVP port henceforth assumes that both properties above to be
concomitant on a given FVP platform.
To accommodate for varied MPIDR formats at run time, this patch
re-implements the FVP platform-specific functions that translates MPIDR
values to a linear indices, along with required validation. The same
treatment is applied for GICv3 MPIDR hashing function as well.
An FVP-specific build option FVP_MAX_PE_PER_CPU is introduced which
specifies the maximum number of threads implemented per CPU. For
backwards compatibility, its value defaults to 1.
Change-Id: I729b00d3e121d16ce9a03de4f9db36dfac580e3f
Signed-off-by: Jeenu Viswambharan <jeenu.viswambharan@arm.com>
diff --git a/plat/arm/board/fvp/fvp_topology.c b/plat/arm/board/fvp/fvp_topology.c
index 055b985..848aaf8 100644
--- a/plat/arm/board/fvp/fvp_topology.c
+++ b/plat/arm/board/fvp/fvp_topology.c
@@ -1,10 +1,11 @@
/*
- * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
+#include <arm_config.h>
#include <cassert.h>
#include <plat_arm.h>
#include <platform_def.h>
@@ -55,11 +56,18 @@
******************************************************************************/
int plat_core_pos_by_mpidr(u_register_t mpidr)
{
- if (arm_check_mpidr(mpidr) == -1)
- return -1;
-
if (fvp_pwrc_read_psysr(mpidr) == PSYSR_INVALID)
return -1;
+ /*
+ * Core position calculation for FVP platform depends on the MT bit in
+ * MPIDR. This function cannot assume that the supplied MPIDR has the MT
+ * bit set even if the implementation has. For example, PSCI clients
+ * might supply MPIDR values without the MT bit set. Therefore, we
+ * inject the current PE's MT bit so as to get the calculation correct.
+ * This of course assumes that none or all CPUs on the platform has MT
+ * bit set.
+ */
+ mpidr |= (read_mpidr_el1() & MPIDR_MT_MASK);
return plat_arm_calc_core_pos(mpidr);
}