Merge pull request #531 from soby-mathew/sm/multicluster_fvp
Allow multi cluster topology definitions for ARM platforms
diff --git a/docs/user-guide.md b/docs/user-guide.md
index 767fc42..70e1abc 100644
--- a/docs/user-guide.md
+++ b/docs/user-guide.md
@@ -505,6 +505,11 @@
Trusted Firmware must be compiled with GICv2 only driver using
`FVP_USE_GIC_DRIVER=FVP_GICV2` build option.
+* `FVP_CLUSTER_COUNT` : Configures the cluster count to be used to
+ build the topology tree within Trusted Firmware. By default the
+ Trusted Firmware is configured for dual cluster topology and this option
+ can be used to override the default value.
+
### Creating a Firmware Image Package
FIPs are automatically created as part of the build instructions described in
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index 8d75363..dab7545 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -44,7 +44,6 @@
/* Special value used to verify platform parameters from BL2 to BL31 */
#define ARM_BL31_PLAT_PARAM_VAL 0x0f1e2d3c4b5a6978ULL
-#define ARM_CLUSTER_COUNT 2
#define ARM_SYSTEM_COUNT 1
#define ARM_CACHE_WRITEBACK_SHIFT 6
@@ -214,10 +213,6 @@
*/
#define PLAT_MAX_OFF_STATE ARM_LOCAL_STATE_OFF
-
-#define PLATFORM_CORE_COUNT (PLAT_ARM_CLUSTER0_CORE_COUNT + \
- PLAT_ARM_CLUSTER1_CORE_COUNT)
-
/*
* Some data must be aligned on the biggest cache line size in the platform.
* This is known only to the platform as it might have a combination of
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index 8d7e83b..e9eebaa 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -179,6 +179,7 @@
/*
* Mandatory functions required in ARM standard platforms
*/
+unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr);
void plat_arm_gic_driver_init(void);
void plat_arm_gic_init(void);
void plat_arm_gic_cpuif_enable(void);
diff --git a/plat/arm/board/fvp/fvp_def.h b/plat/arm/board/fvp/fvp_def.h
index 41b872a..dbca280 100644
--- a/plat/arm/board/fvp/fvp_def.h
+++ b/plat/arm/board/fvp/fvp_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -33,7 +33,9 @@
#include <arm_def.h>
-
+#ifndef FVP_CLUSTER_COUNT
+#define FVP_CLUSTER_COUNT 2
+#endif
#define FVP_MAX_CPUS_PER_CLUSTER 4
#define FVP_PRIMARY_CPU 0x0
diff --git a/plat/arm/board/fvp/fvp_topology.c b/plat/arm/board/fvp/fvp_topology.c
index a212eda..741aad6 100644
--- a/plat/arm/board/fvp/fvp_topology.c
+++ b/plat/arm/board/fvp/fvp_topology.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -29,27 +29,47 @@
*/
#include <arch.h>
+#include <cassert.h>
#include <plat_arm.h>
#include <platform_def.h>
#include "drivers/pwrc/fvp_pwrc.h"
-/*
- * The FVP power domain tree does not have a single system level power domain
- * i.e. a single root node. The first entry in the power domain descriptor
- * specifies the number of power domains at the highest power level. For the FVP
- * this is 2 i.e. the number of cluster power domains.
- */
-#define FVP_PWR_DOMAINS_AT_MAX_PWR_LVL ARM_CLUSTER_COUNT
-
/* The FVP power domain tree descriptor */
-const unsigned char arm_power_domain_tree_desc[] = {
- /* No of root nodes */
- FVP_PWR_DOMAINS_AT_MAX_PWR_LVL,
- /* No of children for the first node */
- PLAT_ARM_CLUSTER0_CORE_COUNT,
- /* No of children for the second node */
- PLAT_ARM_CLUSTER1_CORE_COUNT
-};
+unsigned char fvp_power_domain_tree_desc[FVP_CLUSTER_COUNT + 1];
+
+
+CASSERT(FVP_CLUSTER_COUNT && FVP_CLUSTER_COUNT <= 256, assert_invalid_fvp_cluster_count);
+
+/*******************************************************************************
+ * This function dynamically constructs the topology according to
+ * FVP_CLUSTER_COUNT and returns it.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+ int i;
+
+ /*
+ * The FVP power domain tree does not have a single system level power domain
+ * i.e. a single root node. The first entry in the power domain descriptor
+ * specifies the number of power domains at the highest power level. For the FVP
+ * this is the number of cluster power domains.
+ */
+ fvp_power_domain_tree_desc[0] = FVP_CLUSTER_COUNT;
+
+ for (i = 0; i < FVP_CLUSTER_COUNT; i++)
+ fvp_power_domain_tree_desc[i + 1] = FVP_MAX_CPUS_PER_CLUSTER;
+
+ return fvp_power_domain_tree_desc;
+}
+
+/*******************************************************************************
+ * This function returns the core count within the cluster corresponding to
+ * `mpidr`.
+ ******************************************************************************/
+unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr)
+{
+ return FVP_MAX_CPUS_PER_CLUSTER;
+}
/*******************************************************************************
* This function implements a part of the critical interface between the psci
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index c5e3095..a8267de 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -39,9 +39,10 @@
#include "../fvp_def.h"
/* Required platform porting definitions */
-#define PLAT_NUM_PWR_DOMAINS (ARM_CLUSTER_COUNT + \
+#define PLAT_NUM_PWR_DOMAINS (FVP_CLUSTER_COUNT + \
PLATFORM_CORE_COUNT)
#define PLAT_MAX_PWR_LVL ARM_PWR_LVL1
+#define PLATFORM_CORE_COUNT (FVP_CLUSTER_COUNT * FVP_MAX_CPUS_PER_CLUSTER)
/*
* Other platform porting definitions are provided by included headers
@@ -50,8 +51,7 @@
/*
* Required ARM standard platform porting definitions
*/
-#define PLAT_ARM_CLUSTER0_CORE_COUNT 4
-#define PLAT_ARM_CLUSTER1_CORE_COUNT 4
+#define PLAT_ARM_CLUSTER_COUNT FVP_CLUSTER_COUNT
#define PLAT_ARM_TRUSTED_ROM_BASE 0x00000000
#define PLAT_ARM_TRUSTED_ROM_SIZE 0x04000000 /* 64 MB */
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index c82c21a..aad2e2e 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -34,6 +34,11 @@
# The FVP platform depends on this macro to build with correct GIC driver.
$(eval $(call add_define,FVP_USE_GIC_DRIVER))
+# If FVP_CLUSTER_COUNT has been defined, pass it into the build system.
+ifdef FVP_CLUSTER_COUNT
+$(eval $(call add_define,FVP_CLUSTER_COUNT))
+endif
+
# Choose the GIC sources depending upon the how the FVP will be invoked
ifeq (${FVP_USE_GIC_DRIVER}, FVP_GICV3)
FVP_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \
diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h
index deac0ff..e1e0af6 100644
--- a/plat/arm/board/juno/include/platform_def.h
+++ b/plat/arm/board/juno/include/platform_def.h
@@ -41,11 +41,15 @@
#include <v2m_def.h>
#include "../juno_def.h"
+/* Required platform porting definitions */
/* Juno supports system power domain */
#define PLAT_MAX_PWR_LVL ARM_PWR_LVL2
#define PLAT_NUM_PWR_DOMAINS (ARM_SYSTEM_COUNT + \
- ARM_CLUSTER_COUNT + \
+ JUNO_CLUSTER_COUNT + \
PLATFORM_CORE_COUNT)
+#define PLATFORM_CORE_COUNT (JUNO_CLUSTER0_CORE_COUNT + \
+ JUNO_CLUSTER1_CORE_COUNT)
+
/*
* Other platform porting definitions are provided by included headers
*/
@@ -53,8 +57,7 @@
/*
* Required ARM standard platform porting definitions
*/
-#define PLAT_ARM_CLUSTER0_CORE_COUNT 2
-#define PLAT_ARM_CLUSTER1_CORE_COUNT 4
+#define PLAT_ARM_CLUSTER_COUNT JUNO_CLUSTER_COUNT
/* Use the bypass address */
#define PLAT_ARM_TRUSTED_ROM_BASE V2M_FLASH0_BASE + BL1_ROM_BYPASS_OFFSET
diff --git a/plat/arm/board/juno/juno_def.h b/plat/arm/board/juno/juno_def.h
index f4e2259..f27bbb2 100644
--- a/plat/arm/board/juno/juno_def.h
+++ b/plat/arm/board/juno/juno_def.h
@@ -53,6 +53,13 @@
#define JUNO_SSC_VER_PART_NUM 0x030
/*******************************************************************************
+ * Juno topology related constants
+ ******************************************************************************/
+#define JUNO_CLUSTER_COUNT 2
+#define JUNO_CLUSTER0_CORE_COUNT 2
+#define JUNO_CLUSTER1_CORE_COUNT 4
+
+/*******************************************************************************
* TZC-400 related constants
******************************************************************************/
#define TZC400_NSAID_CCI400 0 /* Note: Same as default NSAID!! */
diff --git a/plat/arm/board/juno/juno_topology.c b/plat/arm/board/juno/juno_topology.c
new file mode 100644
index 0000000..ee4ec44
--- /dev/null
+++ b/plat/arm/board/juno/juno_topology.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arm_def.h>
+#include <plat_arm.h>
+#include "juno_def.h"
+
+/*
+ * On Juno, the system power level is the highest power level.
+ * The first entry in the power domain descriptor specifies the
+ * number of system power domains i.e. 1.
+ */
+#define JUNO_PWR_DOMAINS_AT_MAX_PWR_LVL ARM_SYSTEM_COUNT
+
+/*
+ * The Juno power domain tree descriptor. The cluster power domains
+ * are arranged so that when the PSCI generic code creates the power
+ * domain tree, the indices of the CPU power domain nodes it allocates
+ * match the linear indices returned by plat_core_pos_by_mpidr()
+ * i.e. CLUSTER1 CPUs are allocated indices from 0 to 3 and the higher
+ * indices for CLUSTER0 CPUs.
+ */
+const unsigned char juno_power_domain_tree_desc[] = {
+ /* No of root nodes */
+ JUNO_PWR_DOMAINS_AT_MAX_PWR_LVL,
+ /* No of children for the root node */
+ JUNO_CLUSTER_COUNT,
+ /* No of children for the first cluster node */
+ JUNO_CLUSTER1_CORE_COUNT,
+ /* No of children for the second cluster node */
+ JUNO_CLUSTER0_CORE_COUNT
+};
+
+/*******************************************************************************
+ * This function returns the Juno topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+ return juno_power_domain_tree_desc;
+}
+
+/*******************************************************************************
+ * This function returns the core count within the cluster corresponding to
+ * `mpidr`.
+ ******************************************************************************/
+unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr)
+{
+ return (((mpidr) & 0x100) ? JUNO_CLUSTER1_CORE_COUNT :\
+ JUNO_CLUSTER0_CORE_COUNT);
+}
diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk
index 3ffc7e7..1876821 100644
--- a/plat/arm/board/juno/platform.mk
+++ b/plat/arm/board/juno/platform.mk
@@ -62,6 +62,7 @@
lib/cpus/aarch64/cortex_a57.S \
lib/cpus/aarch64/cortex_a72.S \
plat/arm/board/juno/juno_pm.c \
+ plat/arm/board/juno/juno_topology.c \
${JUNO_GIC_SOURCES} \
${JUNO_INTERCONNECT_SOURCES} \
${JUNO_SECURITY_SOURCES}
diff --git a/plat/arm/board/juno/tsp/tsp-juno.mk b/plat/arm/board/juno/tsp/tsp-juno.mk
index 2ef964e..4e80607 100644
--- a/plat/arm/board/juno/tsp/tsp-juno.mk
+++ b/plat/arm/board/juno/tsp/tsp-juno.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
@@ -28,7 +28,8 @@
# POSSIBILITY OF SUCH DAMAGE.
#
-BL32_SOURCES += plat/arm/css/common/css_topology.c \
+BL32_SOURCES += plat/arm/board/juno/juno_topology.c \
+ plat/arm/css/common/css_topology.c \
${JUNO_GIC_SOURCES}
include plat/arm/common/tsp/arm_tsp.mk
diff --git a/plat/arm/common/arm_topology.c b/plat/arm/common/arm_topology.c
index cb0bb9c..4430b13 100644
--- a/plat/arm/common/arm_topology.c
+++ b/plat/arm/common/arm_topology.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -29,26 +29,9 @@
*/
#include <arch.h>
-#include <psci.h>
#include <plat_arm.h>
#include <platform_def.h>
-#define get_arm_cluster_core_count(mpidr)\
- (((mpidr) & 0x100) ? PLAT_ARM_CLUSTER1_CORE_COUNT :\
- PLAT_ARM_CLUSTER0_CORE_COUNT)
-
-/* The power domain tree descriptor which need to be exported by ARM platforms */
-extern const unsigned char arm_power_domain_tree_desc[];
-
-
-/*******************************************************************************
- * This function returns the ARM default topology tree information.
- ******************************************************************************/
-const unsigned char *plat_get_power_domain_tree_desc(void)
-{
- return arm_power_domain_tree_desc;
-}
-
/*******************************************************************************
* This function validates an MPIDR by checking whether it falls within the
* acceptable bounds. An error code (-1) is returned if an incorrect mpidr
@@ -66,12 +49,12 @@
cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
- if (cluster_id >= ARM_CLUSTER_COUNT)
+ if (cluster_id >= PLAT_ARM_CLUSTER_COUNT)
return -1;
/* Validate cpu_id by checking whether it represents a CPU in
one of the two clusters present on the platform. */
- if (cpu_id >= get_arm_cluster_core_count(mpidr))
+ if (cpu_id >= plat_arm_get_cluster_core_count(mpidr))
return -1;
return 0;
diff --git a/plat/arm/css/common/css_topology.c b/plat/arm/css/common/css_topology.c
index 03f81e6..d5f0275 100644
--- a/plat/arm/css/common/css_topology.c
+++ b/plat/arm/css/common/css_topology.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -30,33 +30,6 @@
#include <plat_arm.h>
-/*
- * On ARM CSS platforms, by default, the system power level is treated as the
- * highest. The first entry in the power domain descriptor specifies the
- * number of system power domains i.e. 1.
- */
-#define CSS_PWR_DOMAINS_AT_MAX_PWR_LVL ARM_SYSTEM_COUNT
-
-/*
- * The CSS power domain tree descriptor for dual cluster CSS platforms.
- * The cluster power domains are arranged so that when the PSCI generic
- * code creates the power domain tree, the indices of the CPU power
- * domain nodes it allocates match the linear indices returned by
- * plat_core_pos_by_mpidr() i.e. CLUSTER1 CPUs are allocated indices
- * from 0 to 3 and the higher indices for CLUSTER0 CPUs.
- */
-const unsigned char arm_power_domain_tree_desc[] = {
- /* No of root nodes */
- CSS_PWR_DOMAINS_AT_MAX_PWR_LVL,
- /* No of children for the root node */
- ARM_CLUSTER_COUNT,
- /* No of children for the first cluster node */
- PLAT_ARM_CLUSTER1_CORE_COUNT,
- /* No of children for the second cluster node */
- PLAT_ARM_CLUSTER0_CORE_COUNT
-};
-
-
/******************************************************************************
* 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