diff --git a/docs/porting-guide.md b/docs/porting-guide.md index 3ba6715..fd60097 100644 --- a/docs/porting-guide.md +++ b/docs/porting-guide.md @@ -181,6 +181,17 @@ 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 @@ 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 18b7eae..8188f45 100644 --- a/include/plat/common/platform.h +++ b/include/plat/common/platform.h @@ -177,7 +177,6 @@ * 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 49f7daf..11ca107 100644 --- a/plat/fvp/fvp_topology.c +++ b/plat/fvp/fvp_topology.c @@ -177,15 +177,6 @@ } /******************************************************************************* - * 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 * and rely on the PWRC.PSYSR to flag absent cpus when their status is queried. diff --git a/plat/fvp/include/platform_def.h b/plat/fvp/include/platform_def.h index 7cc9e90..6713c5c 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 be1fb27..9eb3053 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 70439e8..9a5944c 100644 --- a/plat/juno/juno_private.h +++ b/plat/juno/juno_private.h @@ -157,7 +157,6 @@ /* 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 39d4dab..c22edda 100644 --- a/plat/juno/plat_topology.c +++ b/plat/juno/plat_topology.c @@ -48,11 +48,6 @@ 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 a31643e..7ab607d 100644 --- a/services/std_svc/psci/psci_common.c +++ b/services/std_svc/psci/psci_common.c @@ -62,6 +62,13 @@ 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 * affinity level which is marked as physically powered off. @@ -150,30 +157,16 @@ /* * 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 @@ 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 d8a0009..fcd3b55 100644 --- a/services/std_svc/psci/psci_main.c +++ b/services/std_svc/psci/psci_main.c @@ -78,7 +78,7 @@ * 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 @@ /* 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_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 @@ 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 5484665..62a0efc 100644 --- a/services/std_svc/psci/psci_private.h +++ b/services/std_svc/psci/psci_private.h @@ -113,7 +113,6 @@ * 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 02a8786..5ff24d5 100644 --- a/services/std_svc/psci/psci_setup.c +++ b/services/std_svc/psci/psci_setup.c @@ -107,7 +107,7 @@ { 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 @@ 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); /*