diff options
author | danh-arm <dan.handley@arm.com> | 2014-06-23 18:04:29 +0100 |
---|---|---|
committer | danh-arm <dan.handley@arm.com> | 2014-06-23 18:04:29 +0100 |
commit | 41cf7bdfd7114ee437d165974367a483636df76d (patch) | |
tree | d3c246819aec7ff01ec1cd83ebd658c86d3ef623 | |
parent | 47fe640c97603b313994bb0d37a48d01e53213eb (diff) | |
parent | 6c0b45d1ceb13cb409f8d62d712d6f0c44feab6c (diff) |
Merge pull request #145 from athoelke/at/psci-memory-optimization-v2
PSCI memory optimizations (v2)
-rw-r--r-- | docs/porting-guide.md | 5 | ||||
-rw-r--r-- | include/bl31/services/psci.h | 3 | ||||
-rw-r--r-- | plat/fvp/include/platform_def.h | 2 | ||||
-rw-r--r-- | services/std_svc/psci/psci_afflvl_suspend.c | 15 | ||||
-rw-r--r-- | services/std_svc/psci/psci_common.c | 7 | ||||
-rw-r--r-- | services/std_svc/psci/psci_private.h | 19 | ||||
-rw-r--r-- | services/std_svc/psci/psci_setup.c | 14 |
7 files changed, 22 insertions, 43 deletions
diff --git a/docs/porting-guide.md b/docs/porting-guide.md index d970190..f854af9 100644 --- a/docs/porting-guide.md +++ b/docs/porting-guide.md @@ -150,6 +150,11 @@ file is found in [plat/fvp/include/platform_def.h]. Defines the maximum number of CPUs that can be implemented within a cluster on the platform. +* **#define : PLATFORM_NUM_AFFS** + + Defines the total number of nodes in the affinity heirarchy at all affinity + levels used by the platform. + * **#define : PRIMARY_CPU** Defines the `MPIDR` of the primary CPU on the platform. This value is used diff --git a/include/bl31/services/psci.h b/include/bl31/services/psci.h index 887c4ce..77f406d 100644 --- a/include/bl31/services/psci.h +++ b/include/bl31/services/psci.h @@ -128,9 +128,6 @@ #define psci_validate_power_state(pstate) (pstate & PSTATE_VALID_MASK) -/* Number of affinity instances whose state this psci imp. can track */ -#define PSCI_NUM_AFFS 32ull - #ifndef __ASSEMBLY__ #include <stdint.h> diff --git a/plat/fvp/include/platform_def.h b/plat/fvp/include/platform_def.h index c8aaee6..fe4d73b 100644 --- a/plat/fvp/include/platform_def.h +++ b/plat/fvp/include/platform_def.h @@ -75,6 +75,8 @@ #define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER1_CORE_COUNT + \ PLATFORM_CLUSTER0_CORE_COUNT) #define PLATFORM_MAX_CPUS_PER_CLUSTER 4 +#define PLATFORM_NUM_AFFS (PLATFORM_CLUSTER_COUNT + \ + PLATFORM_CORE_COUNT) #define PRIMARY_CPU 0x0 #define MAX_IO_DEVICES 3 #define MAX_IO_HANDLES 4 diff --git a/services/std_svc/psci/psci_afflvl_suspend.c b/services/std_svc/psci/psci_afflvl_suspend.c index f43dced..ea90389 100644 --- a/services/std_svc/psci/psci_afflvl_suspend.c +++ b/services/std_svc/psci/psci_afflvl_suspend.c @@ -57,16 +57,11 @@ void psci_set_suspend_power_state(aff_map_node_t *node, unsigned int power_state assert(node->mpidr == (read_mpidr() & MPIDR_AFFINITY_MASK)); assert(node->level == MPIDR_AFFLVL0); - /* Save PSCI power state parameter for the core in suspend context */ - psci_suspend_context[node->data].power_state = power_state; - /* - * Flush the suspend data to PoC since it will be accessed while - * returning back from suspend with the caches turned off + * Save PSCI power state parameter for the core in suspend context. + * The node is in always-coherent RAM so it does not need to be flushed */ - flush_dcache_range( - (unsigned long)&psci_suspend_context[node->data], - sizeof(suspend_context_t)); + node->power_state = power_state; } /******************************************************************************* @@ -97,7 +92,7 @@ int psci_get_aff_map_node_suspend_afflvl(aff_map_node_t *node) assert(node->level == MPIDR_AFFLVL0); - power_state = psci_suspend_context[node->data].power_state; + power_state = node->power_state; return ((power_state == PSCI_INVALID_DATA) ? power_state : psci_get_pstate_afflvl(power_state)); } @@ -117,7 +112,7 @@ int psci_get_suspend_stateid(unsigned long mpidr) assert(node); assert(node->level == MPIDR_AFFLVL0); - power_state = psci_suspend_context[node->data].power_state; + power_state = node->power_state; return ((power_state == PSCI_INVALID_DATA) ? power_state : psci_get_pstate_id(power_state)); } diff --git a/services/std_svc/psci/psci_common.c b/services/std_svc/psci/psci_common.c index d69c5f5..87be843 100644 --- a/services/std_svc/psci/psci_common.c +++ b/services/std_svc/psci/psci_common.c @@ -46,13 +46,6 @@ const spd_pm_ops_t *psci_spd_pm; /******************************************************************************* - * Arrays that contains information needs to resume a cpu's execution when woken - * out of suspend or off states. Each cpu is allocated a single entry in each - * array during startup. - ******************************************************************************/ -suspend_context_t psci_suspend_context[PSCI_NUM_AFFS]; - -/******************************************************************************* * Grand array that holds the platform's topology information for state * management of affinity instances. Each node (aff_map_node) in the array * corresponds to an affinity instance e.g. cluster, cpu within an mpidr diff --git a/services/std_svc/psci/psci_private.h b/services/std_svc/psci/psci_private.h index 970ad21..f534087 100644 --- a/services/std_svc/psci/psci_private.h +++ b/services/std_svc/psci/psci_private.h @@ -33,8 +33,16 @@ #include <arch.h> #include <bakery_lock.h> +#include <platform_def.h> /* for PLATFORM_NUM_AFFS */ #include <psci.h> +/* Number of affinity instances whose state this psci imp. can track */ +#ifdef PLATFORM_NUM_AFFS +#define PSCI_NUM_AFFS PLATFORM_NUM_AFFS +#else +#define PSCI_NUM_AFFS (2 * PLATFORM_CORE_COUNT) +#endif + /******************************************************************************* * The following two data structures hold the topology tree which in turn tracks * the state of the all the affinity instances supported by the platform. @@ -44,7 +52,7 @@ typedef struct aff_map_node { unsigned short ref_count; unsigned char state; unsigned char level; - unsigned int data; + unsigned int power_state; bakery_lock_t lock; } aff_map_node_t; @@ -53,14 +61,6 @@ typedef struct aff_limits_node { int max; } aff_limits_node_t; -/******************************************************************************* - * This data structure holds secure world context that needs to be preserved - * across cpu_suspend calls which enter the power down state. - ******************************************************************************/ -typedef struct suspend_context { - unsigned int power_state; -} __aligned(CACHE_WRITEBACK_GRANULE) suspend_context_t; - typedef aff_map_node_t (*mpidr_aff_map_nodes_t[MPIDR_MAX_AFFLVL]); typedef unsigned int (*afflvl_power_on_finisher_t)(unsigned long, aff_map_node_t *); @@ -68,7 +68,6 @@ typedef unsigned int (*afflvl_power_on_finisher_t)(unsigned long, /******************************************************************************* * Data prototypes ******************************************************************************/ -extern suspend_context_t psci_suspend_context[PSCI_NUM_AFFS]; extern const plat_pm_ops_t *psci_plat_pm_ops; extern aff_map_node_t psci_aff_map[PSCI_NUM_AFFS]; diff --git a/services/std_svc/psci/psci_setup.c b/services/std_svc/psci/psci_setup.c index af82150..68f19a0 100644 --- a/services/std_svc/psci/psci_setup.c +++ b/services/std_svc/psci/psci_setup.c @@ -58,12 +58,6 @@ static cpu_context_t psci_ns_context[PLATFORM_CORE_COUNT]; static aff_limits_node_t psci_aff_limits[MPIDR_MAX_AFFLVL + 1]; /******************************************************************************* - * 'psci_ns_einfo_idx' keeps track of the next free index in the - * 'psci_suspend_context' arrays. - ******************************************************************************/ -static unsigned int psci_ns_einfo_idx; - -/******************************************************************************* * Routines for retrieving the node corresponding to an affinity level instance * in the mpidr. The first one uses binary search to find the node corresponding * to the mpidr (key) at a particular affinity level. The second routine decides @@ -195,13 +189,8 @@ static void psci_init_aff_map_node(unsigned long mpidr, if (state & PSCI_AFF_PRESENT) psci_set_state(&psci_aff_map[idx], PSCI_STATE_OFF); - /* Ensure that we have not overflowed the psci_ns_einfo array */ - assert(psci_ns_einfo_idx < PSCI_NUM_AFFS); - - psci_aff_map[idx].data = psci_ns_einfo_idx; /* Invalidate the suspend context for the node */ - psci_suspend_context[psci_ns_einfo_idx].power_state = PSCI_INVALID_DATA; - psci_ns_einfo_idx++; + psci_aff_map[idx].power_state = PSCI_INVALID_DATA; /* * Associate a non-secure context with this affinity @@ -301,7 +290,6 @@ int32_t psci_setup(void) int afflvl, affmap_idx, max_afflvl; aff_map_node_t *node; - psci_ns_einfo_idx = 0; psci_plat_pm_ops = NULL; /* Find out the maximum affinity level that the platform implements */ |