diff --git a/plat/arm/board/fvp/fvp_topology.c b/plat/arm/board/fvp/fvp_topology.c index 24e79b4d4..80cfbd5ce 100644 --- a/plat/arm/board/fvp/fvp_topology.c +++ b/plat/arm/board/fvp/fvp_topology.c @@ -1,18 +1,21 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ -#include +#include #include #include +#include #include #include #include #include +#include + /* The FVP power domain tree descriptor */ static unsigned char fvp_power_domain_tree_desc[FVP_CLUSTER_COUNT + 2]; @@ -21,24 +24,47 @@ CASSERT(((FVP_CLUSTER_COUNT > 0) && (FVP_CLUSTER_COUNT <= 256)), assert_invalid_fvp_cluster_count); /******************************************************************************* - * This function dynamically constructs the topology according to - * FVP_CLUSTER_COUNT and returns it. + * This function dynamically constructs the topology according to cpu-map node + * in HW_CONFIG dtb and returns it. ******************************************************************************/ const unsigned char *plat_get_power_domain_tree_desc(void) { - int i; + unsigned int i; + uint32_t cluster_count, cpus_per_cluster; + + /* + * fconf APIs are not supported for RESET_TO_SP_MIN, RESET_TO_BL31 and + * BL2_AT_EL3 systems. + */ +#if RESET_TO_SP_MIN || RESET_TO_BL31 || BL2_AT_EL3 + cluster_count = FVP_CLUSTER_COUNT; + cpus_per_cluster = FVP_MAX_CPUS_PER_CLUSTER * FVP_MAX_PE_PER_CPU; +#else + cluster_count = FCONF_GET_PROPERTY(hw_config, topology, plat_cluster_count); + cpus_per_cluster = FCONF_GET_PROPERTY(hw_config, topology, cluster_cpu_count); + /* Several FVP Models use the same blanket dts. Ex: FVP_Base_Cortex-A65x4 + * and FVP_Base_Cortex-A65AEx8 both use same dts but have different number of + * CPUs in the cluster, as reflected by build flags FVP_MAX_CPUS_PER_CLUSTER. + * Take the minimum of two to ensure PSCI functions do not exceed the size of + * the PSCI data structures allocated at build time. + */ + cpus_per_cluster = MIN(cpus_per_cluster, + (uint32_t)(FVP_MAX_CPUS_PER_CLUSTER * FVP_MAX_PE_PER_CPU)); + +#endif + + assert(cluster_count > 0U); + assert(cpus_per_cluster > 0U); /* * The highest level is the system level. The next level is constituted * by clusters and then cores in clusters. */ fvp_power_domain_tree_desc[0] = 1; - fvp_power_domain_tree_desc[1] = FVP_CLUSTER_COUNT; - - for (i = 0; i < FVP_CLUSTER_COUNT; i++) - fvp_power_domain_tree_desc[i + 2] = - FVP_MAX_CPUS_PER_CLUSTER * FVP_MAX_PE_PER_CPU; + fvp_power_domain_tree_desc[1] = (unsigned char)cluster_count; + for (i = 0; i < cluster_count; i++) + fvp_power_domain_tree_desc[i + 2] = (unsigned char)cpus_per_cluster; return fvp_power_domain_tree_desc; }