TFTF: Add support for FVP platforms with SMT capabilities
This patch adds support for Simultaneously MultiThreaded (SMT)
cores on FVP models. Number of threads per CPU is passed in
FVP_MAX_PE_PER_CPU build parameter which can be set either to
1 or 2. This option defaults to 1.
Signed-off-by: Alexei Fedorov <Alexei.Fedorov@arm.com>
Change-Id: Ib0e2afe429e8f24b8a74ad6ee98750ed1ac121fb
diff --git a/docs/user-guide.rst b/docs/user-guide.rst
index 2e6f7ba..d6e1ae5 100644
--- a/docs/user-guide.rst
+++ b/docs/user-guide.rst
@@ -430,6 +430,12 @@
platform makefile is free to override this value if Firmware Update is
supported on this platform.
+Arm FVP platform specific build options
+'''''''''''''''''''''''''''''''''''''''
+
+- ``FVP_MAX_PE_PER_CPU``: Sets the maximum number of PEs implemented on any CPU
+ in the system. It can take either 1 or 2 values. This option defaults to 1.
+
Checking source code style
--------------------------
diff --git a/el3_payload/Makefile b/el3_payload/Makefile
index 984f60d..188731c 100644
--- a/el3_payload/Makefile
+++ b/el3_payload/Makefile
@@ -1,9 +1,25 @@
#
-# Copyright (c) 2018, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2019, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
+# Default number of threads per CPU on FVP
+FVP_MAX_PE_PER_CPU := 1
+
+# Check the PE per core count
+ifneq ($(FVP_MAX_PE_PER_CPU),$(filter $(FVP_MAX_PE_PER_CPU),1 2))
+$(error "Incorrect FVP_MAX_PE_PER_CPU specified for FVP port")
+endif
+
+# Convenience function for adding build definitions
+# $(eval $(call add_define,BAR_DEFINES,FOO)) will have:
+# -DFOO if $(FOO) is empty; -DFOO=$(FOO) otherwise
+# inside the BAR_DEFINES variable.
+define add_define
+$(1) += -D$(2)$(if $(value $(2)),=$(value $(2)),)
+endef
+
CC := ${CROSS_COMPILE}gcc
AS := ${CROSS_COMPILE}as
LD := ${CROSS_COMPILE}ld
@@ -27,6 +43,9 @@
include plat/${PLAT}/platform.mk
+# Pass FVP_MAX_PE_PER_CPU to the build system
+$(eval $(call add_define,ASFLAGS,FVP_MAX_PE_PER_CPU))
+
all: ${BIN}
${PLAT_BUILD_DIR}:
diff --git a/el3_payload/plat/fvp/platform.h b/el3_payload/plat/fvp/platform.h
index 809ae7e..657b9db 100644
--- a/el3_payload/plat/fvp/platform.h
+++ b/el3_payload/plat/fvp/platform.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -15,7 +15,5 @@
#define UART_BASE 0x1c090000
#define FVP_MAX_CPUS_PER_CLUSTER 4
-/* Currently multi-threaded CPUs only have a single thread */
-#define FVP_MAX_PE_PER_CPU 1
#endif /* __PLATFORM_H__ */
diff --git a/include/lib/tftf_lib.h b/include/lib/tftf_lib.h
index 3f60fec..091497a 100644
--- a/include/lib/tftf_lib.h
+++ b/include/lib/tftf_lib.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -195,7 +195,12 @@
unsigned int tftf_is_rebooted(void);
static inline unsigned int make_mpid(unsigned int clusterid,
+#if FVP_MAX_PE_PER_CPU > 1
+ unsigned int coreid,
+ unsigned int threadid)
+#else
unsigned int coreid)
+#endif
{
/*
* If MT bit is set then need to shift the affinities and also set the
@@ -203,11 +208,14 @@
*/
if ((read_mpidr_el1() & MPIDR_MT_MASK) != 0)
return MPIDR_MT_MASK |
- ((clusterid & MPIDR_AFFLVL_MASK) << MPIDR_AFF2_SHIFT) |
- ((coreid & MPIDR_AFFLVL_MASK) << MPIDR_AFF1_SHIFT);
+#if FVP_MAX_PE_PER_CPU > 1
+ ((threadid & MPIDR_AFFLVL_MASK) << MPIDR_AFF0_SHIFT) |
+#endif
+ ((coreid & MPIDR_AFFLVL_MASK) << MPIDR_AFF1_SHIFT) |
+ ((clusterid & MPIDR_AFFLVL_MASK) << MPIDR_AFF2_SHIFT);
else
- return ((clusterid & MPIDR_AFFLVL_MASK) << MPIDR_AFF1_SHIFT) |
- ((coreid & MPIDR_AFFLVL_MASK) << MPIDR_AFF0_SHIFT);
+ return ((coreid & MPIDR_AFFLVL_MASK) << MPIDR_AFF0_SHIFT) |
+ ((clusterid & MPIDR_AFFLVL_MASK) << MPIDR_AFF1_SHIFT);
}
diff --git a/plat/arm/fvp/fvp_def.h b/plat/arm/fvp/fvp_def.h
index abaa387..3f01678 100644
--- a/plat/arm/fvp/fvp_def.h
+++ b/plat/arm/fvp/fvp_def.h
@@ -19,8 +19,6 @@
#define FVP_MAX_CPUS_PER_CLUSTER 8
/* Currently the highest cluster count on the FVP is 4 (Quad cluster) */
#define FVP_CLUSTER_COUNT 4
-/* Currently multi-threaded CPUs only have a single thread */
-#define FVP_MAX_PE_PER_CPU 1
/*******************************************************************************
* FVP memory map related constants
diff --git a/plat/arm/fvp/fvp_topology.c b/plat/arm/fvp/fvp_topology.c
index 751a1b8..dddd25b 100644
--- a/plat/arm/fvp/fvp_topology.c
+++ b/plat/arm/fvp/fvp_topology.c
@@ -17,46 +17,40 @@
#define PSYSR_OFF 0x10
#define PSYSR_INVALID 0xffffffff
+#if FVP_MAX_PE_PER_CPU == 2
+/* SMT: 2 threads per CPU */
+#define CPU_DEF(cluster, cpu) \
+ { cluster, cpu, 0 }, \
+ { cluster, cpu, 1 }
+
+#else
+#define CPU_DEF(cluster, cpu) \
+ { cluster, cpu }
+#endif
+
+/* 8 CPUs per cluster */
+#define CLUSTER_DEF(cluster) \
+ CPU_DEF(cluster, 0), \
+ CPU_DEF(cluster, 1), \
+ CPU_DEF(cluster, 2), \
+ CPU_DEF(cluster, 3), \
+ CPU_DEF(cluster, 4), \
+ CPU_DEF(cluster, 5), \
+ CPU_DEF(cluster, 6), \
+ CPU_DEF(cluster, 7)
+
static const struct {
unsigned int cluster_id;
unsigned int cpu_id;
+#if FVP_MAX_PE_PER_CPU > 1
+ unsigned int thread_id;
+#endif
} fvp_base_aemv8a_aemv8a_cores[] = {
- /* Cluster 0 */
- { 0, 0 },
- { 0, 1 },
- { 0, 2 },
- { 0, 3 },
- { 0, 4 },
- { 0, 5 },
- { 0, 6 },
- { 0, 7 },
- /* Cluster 1 */
- { 1, 0 },
- { 1, 1 },
- { 1, 2 },
- { 1, 3 },
- { 1, 4 },
- { 1, 5 },
- { 1, 6 },
- { 1, 7 },
- /* Cluster 2 */
- { 2, 0 },
- { 2, 1 },
- { 2, 2 },
- { 2, 3 },
- { 2, 4 },
- { 2, 5 },
- { 2, 6 },
- { 2, 7 },
- /* Cluster 3 */
- { 3, 0 },
- { 3, 1 },
- { 3, 2 },
- { 3, 3 },
- { 3, 4 },
- { 3, 5 },
- { 3, 6 },
- { 3, 7 },
+ /* Clusters 0...3 */
+ CLUSTER_DEF(0),
+ CLUSTER_DEF(1),
+ CLUSTER_DEF(2),
+ CLUSTER_DEF(3)
};
/*
@@ -105,7 +99,12 @@
mpid = make_mpid(
fvp_base_aemv8a_aemv8a_cores[core_pos].cluster_id,
+#if FVP_MAX_PE_PER_CPU > 1
+ fvp_base_aemv8a_aemv8a_cores[core_pos].cpu_id,
+ fvp_base_aemv8a_aemv8a_cores[core_pos].thread_id);
+#else
fvp_base_aemv8a_aemv8a_cores[core_pos].cpu_id);
+#endif
if (fvp_pwrc_read_psysr(mpid) != PSYSR_INVALID)
return mpid;
diff --git a/plat/arm/fvp/platform.mk b/plat/arm/fvp/platform.mk
index c014d6d..27874e2 100644
--- a/plat/arm/fvp/platform.mk
+++ b/plat/arm/fvp/platform.mk
@@ -4,6 +4,19 @@
# SPDX-License-Identifier: BSD-3-Clause
#
+# Default number of threads per CPU on FVP
+FVP_MAX_PE_PER_CPU := 1
+
+# Check the PE per core count
+ifneq ($(FVP_MAX_PE_PER_CPU),$(filter $(FVP_MAX_PE_PER_CPU),1 2))
+$(error "Incorrect FVP_MAX_PE_PER_CPU specified for FVP port")
+endif
+
+# Pass FVP_MAX_PE_PER_CPU to the build system
+$(eval $(call add_define,TFTF_DEFINES,FVP_MAX_PE_PER_CPU))
+$(eval $(call add_define,NS_BL1U_DEFINES,FVP_MAX_PE_PER_CPU))
+$(eval $(call add_define,NS_BL2U_DEFINES,FVP_MAX_PE_PER_CPU))
+
PLAT_INCLUDES := -Iplat/arm/fvp/include/
PLAT_SOURCES := drivers/arm/gic/arm_gic_v2v3.c \
diff --git a/spm/cactus/cactus.mk b/spm/cactus/cactus.mk
index d964ab1..4acc715 100644
--- a/spm/cactus/cactus.mk
+++ b/spm/cactus/cactus.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2018, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2019, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -53,6 +53,7 @@
CACTUS_DEFINES :=
$(eval $(call add_define,CACTUS_DEFINES,DEBUG))
+$(eval $(call add_define,CACTUS_DEFINES,FVP_MAX_PE_PER_CPU))
$(eval $(call add_define,CACTUS_DEFINES,ENABLE_ASSERTIONS))
$(eval $(call add_define,CACTUS_DEFINES,LOG_LEVEL))
$(eval $(call add_define,CACTUS_DEFINES,PLAT_${PLAT}))
diff --git a/tftf/tests/runtime_services/standard_service/psci/api_tests/affinity_info/test_psci_affinity_info.c b/tftf/tests/runtime_services/standard_service/psci/api_tests/affinity_info/test_psci_affinity_info.c
index 9afd910..cc4ad19 100644
--- a/tftf/tests/runtime_services/standard_service/psci/api_tests/affinity_info/test_psci_affinity_info.c
+++ b/tftf/tests/runtime_services/standard_service/psci/api_tests/affinity_info/test_psci_affinity_info.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -214,7 +214,11 @@
* CPU on the platform. The PSCI implementation should ignore the
* affinity 0 field.
*/
+#if FVP_MAX_PE_PER_CPU > 1
+ target_mpid = make_mpid(cluster_id, 0, 0xE1);
+#else
target_mpid = make_mpid(cluster_id, 0xE1);
+#endif
aff_info = tftf_psci_affinity_info(target_mpid, MPIDR_AFFLVL1);
return get_test_result(expected_values, aff_info);
}