diff --git a/docs/user-guide.md b/docs/user-guide.md index 7fd765815..0db622b80 100644 --- a/docs/user-guide.md +++ b/docs/user-guide.md @@ -486,6 +486,11 @@ map is explained in the [Firmware Design]. 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 4c8435607..f6c090f49 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 @@ -218,10 +217,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 8d7e83b57..e9eebaa09 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -179,6 +179,7 @@ int arm_io_is_toc_valid(void); /* * 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 41b872af5..dbca280cb 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 - +#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 a212eda74..741aad645 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 +#include #include #include #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 9c82cbfa2..b912643e6 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 c82c21a8c..aad2e2ef5 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -34,6 +34,11 @@ FVP_USE_GIC_DRIVER := FVP_GICV3_LEGACY # 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 deac0fffd..e1e0af67b 100644 --- a/plat/arm/board/juno/include/platform_def.h +++ b/plat/arm/board/juno/include/platform_def.h @@ -41,11 +41,15 @@ #include #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 f4e225996..f27bbb22e 100644 --- a/plat/arm/board/juno/juno_def.h +++ b/plat/arm/board/juno/juno_def.h @@ -52,6 +52,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 ******************************************************************************/ diff --git a/plat/arm/board/juno/juno_topology.c b/plat/arm/board/juno/juno_topology.c new file mode 100644 index 000000000..ee4ec4419 --- /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 +#include +#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 3ffc7e773..1876821b1 100644 --- a/plat/arm/board/juno/platform.mk +++ b/plat/arm/board/juno/platform.mk @@ -62,6 +62,7 @@ BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \ 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 2ef964e8b..4e8060786 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 cb0bb9c9c..4430b1399 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 -#include #include #include -#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 @@ int arm_check_mpidr(u_register_t mpidr) 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 03f81e615..d5f0275a8 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 -/* - * 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