diff --git a/docs/user-guide.md b/docs/user-guide.md index 7fd765815dd8f12efc7b07f42869ceef08f802c7..0db622b80469e8dfb059c211a91be00bfcd966bc 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 4c8435607b1a60081db94caa3394afb4772e205c..f6c090f49f1241018c52d3268e0eb146e3d3f904 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 8d7e83b5796049666a284f0496b2727a98090100..e9eebaa09d09c59f71d9ccc61a41e5438580b41a 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 41b872af5988a16f575968be02a911aadd312a49..dbca280cb2b9b9f9d0a2372aca02346cc1c632df 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 a212eda74c88bc0d26e0428a78532e5560d56c18..741aad645b21aac7c09f115629024805d6e8ddaa 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 9c82cbfa2a719fb48387557e1f9ca63e4689978d..b912643e6e910292d3c54212067906d089e4dbfb 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 c82c21a8c2f6d3378fb290ca39b26b0229599485..aad2e2ef522cf1142ede1bb1f381c4a8965d2836 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 deac0fffdd7a1c03c9594c1cf75bfc52eb92b066..e1e0af67b553680b4a94e6f21e002dec33f4ba72 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 f4e225996d1aa8912e798cfad9b51d1dd52d5d56..f27bbb22e78a5a83e358065d1f5cb96c9cd28d9f 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 0000000000000000000000000000000000000000..ee4ec4419f162ae75b3c290d8eb0ff2d7e4b5f3f --- /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 3ffc7e7737b0635397a9c44bc32b1e9cc12e52f1..1876821b1bddbfd24d34900ad187546bb22b2a93 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 2ef964e8beae4b9bb84150a93503dd3e7244b86b..4e8060786be28563c3031ed7845f7f678b354f56 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 cb0bb9c9c3367eb38d219656bca6b1eeabafec87..4430b139991cdbe1bbf20d540ca1705a5c32cf2c 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 @@ 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 03f81e615bbb2dabc67d1b104229f9bfb8150702..d5f0275a8e04389f802ea8f6698ec15cd3ea3eee 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