Commit 41cf7bdf authored by danh-arm's avatar danh-arm
Browse files

Merge pull request #145 from athoelke/at/psci-memory-optimization-v2

PSCI memory optimizations (v2)
parents 47fe640c 6c0b45d1
...@@ -150,6 +150,11 @@ file is found in [plat/fvp/include/platform_def.h]. ...@@ -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 Defines the maximum number of CPUs that can be implemented within a cluster
on the platform. 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** * **#define : PRIMARY_CPU**
Defines the `MPIDR` of the primary CPU on the platform. This value is used Defines the `MPIDR` of the primary CPU on the platform. This value is used
......
...@@ -128,9 +128,6 @@ ...@@ -128,9 +128,6 @@
#define psci_validate_power_state(pstate) (pstate & PSTATE_VALID_MASK) #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__ #ifndef __ASSEMBLY__
#include <stdint.h> #include <stdint.h>
......
...@@ -75,6 +75,8 @@ ...@@ -75,6 +75,8 @@
#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER1_CORE_COUNT + \ #define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER1_CORE_COUNT + \
PLATFORM_CLUSTER0_CORE_COUNT) PLATFORM_CLUSTER0_CORE_COUNT)
#define PLATFORM_MAX_CPUS_PER_CLUSTER 4 #define PLATFORM_MAX_CPUS_PER_CLUSTER 4
#define PLATFORM_NUM_AFFS (PLATFORM_CLUSTER_COUNT + \
PLATFORM_CORE_COUNT)
#define PRIMARY_CPU 0x0 #define PRIMARY_CPU 0x0
#define MAX_IO_DEVICES 3 #define MAX_IO_DEVICES 3
#define MAX_IO_HANDLES 4 #define MAX_IO_HANDLES 4
......
...@@ -57,16 +57,11 @@ void psci_set_suspend_power_state(aff_map_node_t *node, unsigned int power_state ...@@ -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->mpidr == (read_mpidr() & MPIDR_AFFINITY_MASK));
assert(node->level == MPIDR_AFFLVL0); 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 * Save PSCI power state parameter for the core in suspend context.
* returning back from suspend with the caches turned off * The node is in always-coherent RAM so it does not need to be flushed
*/ */
flush_dcache_range( node->power_state = power_state;
(unsigned long)&psci_suspend_context[node->data],
sizeof(suspend_context_t));
} }
/******************************************************************************* /*******************************************************************************
...@@ -97,7 +92,7 @@ int psci_get_aff_map_node_suspend_afflvl(aff_map_node_t *node) ...@@ -97,7 +92,7 @@ int psci_get_aff_map_node_suspend_afflvl(aff_map_node_t *node)
assert(node->level == MPIDR_AFFLVL0); 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) ? return ((power_state == PSCI_INVALID_DATA) ?
power_state : psci_get_pstate_afflvl(power_state)); power_state : psci_get_pstate_afflvl(power_state));
} }
...@@ -117,7 +112,7 @@ int psci_get_suspend_stateid(unsigned long mpidr) ...@@ -117,7 +112,7 @@ int psci_get_suspend_stateid(unsigned long mpidr)
assert(node); assert(node);
assert(node->level == MPIDR_AFFLVL0); 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) ? return ((power_state == PSCI_INVALID_DATA) ?
power_state : psci_get_pstate_id(power_state)); power_state : psci_get_pstate_id(power_state));
} }
......
...@@ -45,13 +45,6 @@ ...@@ -45,13 +45,6 @@
*/ */
const spd_pm_ops_t *psci_spd_pm; 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 * Grand array that holds the platform's topology information for state
* management of affinity instances. Each node (aff_map_node) in the array * management of affinity instances. Each node (aff_map_node) in the array
......
...@@ -33,8 +33,16 @@ ...@@ -33,8 +33,16 @@
#include <arch.h> #include <arch.h>
#include <bakery_lock.h> #include <bakery_lock.h>
#include <platform_def.h> /* for PLATFORM_NUM_AFFS */
#include <psci.h> #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 following two data structures hold the topology tree which in turn tracks
* the state of the all the affinity instances supported by the platform. * the state of the all the affinity instances supported by the platform.
...@@ -44,7 +52,7 @@ typedef struct aff_map_node { ...@@ -44,7 +52,7 @@ typedef struct aff_map_node {
unsigned short ref_count; unsigned short ref_count;
unsigned char state; unsigned char state;
unsigned char level; unsigned char level;
unsigned int data; unsigned int power_state;
bakery_lock_t lock; bakery_lock_t lock;
} aff_map_node_t; } aff_map_node_t;
...@@ -53,14 +61,6 @@ typedef struct aff_limits_node { ...@@ -53,14 +61,6 @@ typedef struct aff_limits_node {
int max; int max;
} aff_limits_node_t; } 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 aff_map_node_t (*mpidr_aff_map_nodes_t[MPIDR_MAX_AFFLVL]);
typedef unsigned int (*afflvl_power_on_finisher_t)(unsigned long, typedef unsigned int (*afflvl_power_on_finisher_t)(unsigned long,
aff_map_node_t *); aff_map_node_t *);
...@@ -68,7 +68,6 @@ typedef unsigned int (*afflvl_power_on_finisher_t)(unsigned long, ...@@ -68,7 +68,6 @@ typedef unsigned int (*afflvl_power_on_finisher_t)(unsigned long,
/******************************************************************************* /*******************************************************************************
* Data prototypes * Data prototypes
******************************************************************************/ ******************************************************************************/
extern suspend_context_t psci_suspend_context[PSCI_NUM_AFFS];
extern const plat_pm_ops_t *psci_plat_pm_ops; extern const plat_pm_ops_t *psci_plat_pm_ops;
extern aff_map_node_t psci_aff_map[PSCI_NUM_AFFS]; extern aff_map_node_t psci_aff_map[PSCI_NUM_AFFS];
......
...@@ -57,12 +57,6 @@ static cpu_context_t psci_ns_context[PLATFORM_CORE_COUNT]; ...@@ -57,12 +57,6 @@ static cpu_context_t psci_ns_context[PLATFORM_CORE_COUNT];
******************************************************************************/ ******************************************************************************/
static aff_limits_node_t psci_aff_limits[MPIDR_MAX_AFFLVL + 1]; 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 * 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 * in the mpidr. The first one uses binary search to find the node corresponding
...@@ -195,13 +189,8 @@ static void psci_init_aff_map_node(unsigned long mpidr, ...@@ -195,13 +189,8 @@ static void psci_init_aff_map_node(unsigned long mpidr,
if (state & PSCI_AFF_PRESENT) if (state & PSCI_AFF_PRESENT)
psci_set_state(&psci_aff_map[idx], PSCI_STATE_OFF); 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 */ /* Invalidate the suspend context for the node */
psci_suspend_context[psci_ns_einfo_idx].power_state = PSCI_INVALID_DATA; psci_aff_map[idx].power_state = PSCI_INVALID_DATA;
psci_ns_einfo_idx++;
/* /*
* Associate a non-secure context with this affinity * Associate a non-secure context with this affinity
...@@ -301,7 +290,6 @@ int32_t psci_setup(void) ...@@ -301,7 +290,6 @@ int32_t psci_setup(void)
int afflvl, affmap_idx, max_afflvl; int afflvl, affmap_idx, max_afflvl;
aff_map_node_t *node; aff_map_node_t *node;
psci_ns_einfo_idx = 0;
psci_plat_pm_ops = NULL; psci_plat_pm_ops = NULL;
/* Find out the maximum affinity level that the platform implements */ /* Find out the maximum affinity level that the platform implements */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment