From 8c32bc26e7bc58f028c1b31dd226610d3d388237 Mon Sep 17 00:00:00 2001 From: Soby Mathew Date: Thu, 12 Feb 2015 14:45:02 +0000 Subject: [PATCH] Export maximum affinity using PLATFORM_MAX_AFFLVL macro This patch removes the plat_get_max_afflvl() platform API and instead replaces it with a platform macro PLATFORM_MAX_AFFLVL. This is done because the maximum affinity level for a platform is a static value and it is more efficient for it to be defined as a platform macro. NOTE: PLATFORM PORTS NEED TO BE UPDATED ON MERGE OF THIS COMMIT Fixes ARM-Software/tf-issues#265 Change-Id: I31d89b30c2ccda30d28271154d869060d50df7bf --- docs/porting-guide.md | 30 ++++++++++------------------ include/plat/common/platform.h | 1 - plat/fvp/fvp_topology.c | 9 --------- plat/fvp/include/platform_def.h | 1 + plat/juno/include/platform_def.h | 1 + plat/juno/juno_private.h | 1 - plat/juno/plat_topology.c | 5 ----- services/std_svc/psci/psci_common.c | 27 ++++++++++--------------- services/std_svc/psci/psci_main.c | 8 ++++---- services/std_svc/psci/psci_private.h | 1 - services/std_svc/psci/psci_setup.c | 4 ++-- 11 files changed, 29 insertions(+), 59 deletions(-) diff --git a/docs/porting-guide.md b/docs/porting-guide.md index 3ba6715d2..fd6009779 100644 --- a/docs/porting-guide.md +++ b/docs/porting-guide.md @@ -181,6 +181,17 @@ file is found in [plat/fvp/include/platform_def.h]. Defines the total number of nodes in the affinity heirarchy at all affinity levels used by the platform. +* **#define : PLATFORM_MAX_AFFLVL** + + Defines the maximum affinity level that the power management operations + should apply to. ARMv8-A has support for 4 affinity levels. It is likely + that hardware will implement fewer affinity levels. This macro allows the + PSCI implementation to consider only those affinity levels in the system + that the platform implements. For example, the Base AEM FVP implements two + clusters with a configurable number of CPUs. It reports the maximum + affinity level as 1, resulting in PSCI power control up to the cluster + level. + * **#define : BL1_RO_BASE** Defines the base address in secure ROM where BL1 originally lives. Must be @@ -1131,25 +1142,6 @@ is missing but needs to be accounted for to reach this single CPU in the topology tree. Hence it is marked as `PSCI_AFF_ABSENT`. -### Function : plat_get_max_afflvl() [mandatory] - - Argument : void - Return : int - -This function may execute with the MMU and data caches enabled if the platform -port does the necessary initializations in `bl31_plat_arch_setup()`. It is only -called by the primary CPU. - -This function is called by the PSCI implementation both during cold and warm -boot, to determine the maximum affinity level that the power management -operations should apply to. ARMv8-A has support for 4 affinity levels. It is -likely that hardware will implement fewer affinity levels. This function allows -the PSCI implementation to consider only those affinity levels in the system -that the platform implements. For example, the Base AEM FVP implements two -clusters with a configurable number of CPUs. It reports the maximum affinity -level as 1, resulting in PSCI power control up to the cluster level. - - ### Function : platform_setup_pm() [mandatory] Argument : const plat_pm_ops ** diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h index 18b7eae22..8188f456d 100644 --- a/include/plat/common/platform.h +++ b/include/plat/common/platform.h @@ -177,7 +177,6 @@ struct entry_point_info *bl31_plat_get_next_image_ep_info(uint32_t type); * Mandatory PSCI functions (BL3-1) ******************************************************************************/ int platform_setup_pm(const struct plat_pm_ops **); -int plat_get_max_afflvl(void); unsigned int plat_get_aff_count(unsigned int, unsigned long); unsigned int plat_get_aff_state(unsigned int, unsigned long); diff --git a/plat/fvp/fvp_topology.c b/plat/fvp/fvp_topology.c index 49f7daf4c..11ca107b6 100644 --- a/plat/fvp/fvp_topology.c +++ b/plat/fvp/fvp_topology.c @@ -176,15 +176,6 @@ unsigned int plat_get_aff_state(unsigned int aff_lvl, return aff_state; } -/******************************************************************************* - * Handy optimization to prevent the psci implementation from traversing through - * affinity levels which are not present while detecting the platform topology. - ******************************************************************************/ -int plat_get_max_afflvl(void) -{ - return MPIDR_AFFLVL1; -} - /******************************************************************************* * This function populates the FVP specific topology information depending upon * the FVP flavour its running on. We construct all the mpidrs we can handle diff --git a/plat/fvp/include/platform_def.h b/plat/fvp/include/platform_def.h index 326ba9d98..fcecc56a9 100644 --- a/plat/fvp/include/platform_def.h +++ b/plat/fvp/include/platform_def.h @@ -105,6 +105,7 @@ #define PLATFORM_MAX_CPUS_PER_CLUSTER 4 #define PLATFORM_NUM_AFFS (PLATFORM_CLUSTER_COUNT + \ PLATFORM_CORE_COUNT) +#define PLATFORM_MAX_AFFLVL MPIDR_AFFLVL1 #define MAX_IO_DEVICES 3 #define MAX_IO_HANDLES 4 diff --git a/plat/juno/include/platform_def.h b/plat/juno/include/platform_def.h index 1071d1205..f7d79cc82 100644 --- a/plat/juno/include/platform_def.h +++ b/plat/juno/include/platform_def.h @@ -92,6 +92,7 @@ #define PLATFORM_CORE_COUNT 6 #define PLATFORM_NUM_AFFS (PLATFORM_CLUSTER_COUNT + \ PLATFORM_CORE_COUNT) +#define PLATFORM_MAX_AFFLVL MPIDR_AFFLVL1 #define MAX_IO_DEVICES 3 #define MAX_IO_HANDLES 4 diff --git a/plat/juno/juno_private.h b/plat/juno/juno_private.h index 70439e8b5..9a5944cad 100644 --- a/plat/juno/juno_private.h +++ b/plat/juno/juno_private.h @@ -157,7 +157,6 @@ void plat_gic_init(void); /* Declarations for plat_topology.c */ int plat_setup_topology(void); -int plat_get_max_afflvl(void); unsigned int plat_get_aff_count(unsigned int aff_lvl, unsigned long mpidr); unsigned int plat_get_aff_state(unsigned int aff_lvl, unsigned long mpidr); diff --git a/plat/juno/plat_topology.c b/plat/juno/plat_topology.c index 39d4dabc6..c22edda2d 100644 --- a/plat/juno/plat_topology.c +++ b/plat/juno/plat_topology.c @@ -48,11 +48,6 @@ unsigned int plat_get_aff_state(unsigned int aff_lvl, unsigned long mpidr) return aff_lvl <= MPIDR_AFFLVL1 ? PSCI_AFF_PRESENT : PSCI_AFF_ABSENT; } -int plat_get_max_afflvl() -{ - return MPIDR_AFFLVL1; -} - int plat_setup_topology() { /* Juno todo: Make topology configurable via SCC */ diff --git a/services/std_svc/psci/psci_common.c b/services/std_svc/psci/psci_common.c index a31643e4f..7ab607dba 100644 --- a/services/std_svc/psci/psci_common.c +++ b/services/std_svc/psci/psci_common.c @@ -61,6 +61,13 @@ __attribute__ ((section("tzfw_coherent_mem"))) ******************************************************************************/ const plat_pm_ops_t *psci_plat_pm_ops; +/******************************************************************************* + * Check that the maximum affinity level supported by the platform makes sense + * ****************************************************************************/ +CASSERT(PLATFORM_MAX_AFFLVL <= MPIDR_MAX_AFFLVL && \ + PLATFORM_MAX_AFFLVL >= MPIDR_AFFLVL0, \ + assert_platform_max_afflvl_check); + /******************************************************************************* * This function is passed an array of pointers to affinity level nodes in the * topology tree for an mpidr. It iterates through the nodes to find the highest @@ -150,29 +157,15 @@ int get_power_on_target_afflvl() /* * Assume that this cpu was suspended and retrieve its target affinity * level. If it is invalid then it could only have been turned off - * earlier. get_max_afflvl() will return the highest affinity level a + * earlier. PLATFORM_MAX_AFFLVL will be the highest affinity level a * cpu can be turned off to. */ afflvl = psci_get_suspend_afflvl(); if (afflvl == PSCI_INVALID_DATA) - afflvl = get_max_afflvl(); + afflvl = PLATFORM_MAX_AFFLVL; return afflvl; } -/******************************************************************************* - * Simple routine to retrieve the maximum affinity level supported by the - * platform and check that it makes sense. - ******************************************************************************/ -int get_max_afflvl(void) -{ - int aff_lvl; - - aff_lvl = plat_get_max_afflvl(); - assert(aff_lvl <= MPIDR_MAX_AFFLVL && aff_lvl >= MPIDR_AFFLVL0); - - return aff_lvl; -} - /******************************************************************************* * Simple routine to set the id of an affinity instance at a given level in the * mpidr. @@ -204,7 +197,7 @@ unsigned long mpidr_set_aff_inst(unsigned long mpidr, int psci_check_afflvl_range(int start_afflvl, int end_afflvl) { /* Sanity check the parameters passed */ - if (end_afflvl > get_max_afflvl()) + if (end_afflvl > PLATFORM_MAX_AFFLVL) return PSCI_E_INVALID_PARAMS; if (start_afflvl < MPIDR_AFFLVL0) diff --git a/services/std_svc/psci/psci_main.c b/services/std_svc/psci/psci_main.c index d8a00097b..fcd3b5526 100644 --- a/services/std_svc/psci/psci_main.c +++ b/services/std_svc/psci/psci_main.c @@ -78,7 +78,7 @@ int psci_cpu_on(unsigned long target_cpu, * levels need to be turned on */ start_afflvl = MPIDR_AFFLVL0; - end_afflvl = get_max_afflvl(); + end_afflvl = PLATFORM_MAX_AFFLVL; rc = psci_afflvl_on(target_cpu, &ep, start_afflvl, @@ -106,7 +106,7 @@ int psci_cpu_suspend(unsigned int power_state, /* Sanity check the requested state */ target_afflvl = psci_get_pstate_afflvl(power_state); - if (target_afflvl > get_max_afflvl()) + if (target_afflvl > PLATFORM_MAX_AFFLVL) return PSCI_E_INVALID_PARAMS; /* Validate the power_state using platform pm_ops */ @@ -170,7 +170,7 @@ int psci_cpu_suspend(unsigned int power_state, int psci_cpu_off(void) { int rc; - int target_afflvl = get_max_afflvl(); + int target_afflvl = PLATFORM_MAX_AFFLVL; /* * Traverse from the highest to the lowest affinity level. When the @@ -196,7 +196,7 @@ int psci_affinity_info(unsigned long target_affinity, unsigned int aff_state; aff_map_node_t *node; - if (lowest_affinity_level > get_max_afflvl()) + if (lowest_affinity_level > PLATFORM_MAX_AFFLVL) return rc; node = psci_get_aff_map_node(target_affinity, lowest_affinity_level); diff --git a/services/std_svc/psci/psci_private.h b/services/std_svc/psci/psci_private.h index 548466569..62a0efc86 100644 --- a/services/std_svc/psci/psci_private.h +++ b/services/std_svc/psci/psci_private.h @@ -113,7 +113,6 @@ extern const spd_pm_ops_t *psci_spd_pm; * Function prototypes ******************************************************************************/ /* Private exported functions from psci_common.c */ -int get_max_afflvl(void); unsigned short psci_get_state(aff_map_node_t *node); unsigned short psci_get_phys_state(aff_map_node_t *node); void psci_set_state(aff_map_node_t *node, unsigned short state); diff --git a/services/std_svc/psci/psci_setup.c b/services/std_svc/psci/psci_setup.c index 02a878651..5ff24d5bc 100644 --- a/services/std_svc/psci/psci_setup.c +++ b/services/std_svc/psci/psci_setup.c @@ -107,7 +107,7 @@ aff_map_node_t *psci_get_aff_map_node(unsigned long mpidr, int aff_lvl) { int rc; - if (aff_lvl > get_max_afflvl()) + if (aff_lvl > PLATFORM_MAX_AFFLVL) return NULL; /* Right shift the mpidr to the required affinity level */ @@ -320,7 +320,7 @@ int32_t psci_setup(void) psci_plat_pm_ops = NULL; /* Find out the maximum affinity level that the platform implements */ - max_afflvl = get_max_afflvl(); + max_afflvl = PLATFORM_MAX_AFFLVL; assert(max_afflvl <= MPIDR_MAX_AFFLVL); /*