aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Thoelke <andrew.thoelke@arm.com>2014-06-20 00:38:03 +0100
committerAndrew Thoelke <andrew.thoelke@arm.com>2014-06-23 14:56:12 +0100
commit13ac44a5c7336657ba7518ea31c66f7e7dd7eea8 (patch)
treeb20935b3c3dee3ee537197504c45f40b5bef1e52
parent167a935733a6e3e412b8ed6a60034d0d84895f2e (diff)
downloadarm-trusted-firmware-13ac44a5c7336657ba7518ea31c66f7e7dd7eea8.tar.gz
Eliminate psci_suspend_context array
psci_suspend_context is an array of cache-line aligned structures containing the single power_state integer per cpu. This array is the only structure indexed by the aff_map_node.data integer. This patch saves 2KB of BL3-1 memory by placing the CPU power_state value directly in the aff_map_node structure. As a result, this value is now never cached and the cache clean when writing the value is no longer required. Fixes ARM-software/tf-issues#195 Change-Id: Ib4c70c8f79eed295ea541e7827977a588a19ef9b
-rw-r--r--services/std_svc/psci/psci_afflvl_suspend.c15
-rw-r--r--services/std_svc/psci/psci_common.c7
-rw-r--r--services/std_svc/psci/psci_private.h11
-rw-r--r--services/std_svc/psci/psci_setup.c14
4 files changed, 7 insertions, 40 deletions
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..08a4a34 100644
--- a/services/std_svc/psci/psci_private.h
+++ b/services/std_svc/psci/psci_private.h
@@ -44,7 +44,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 +53,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 +60,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 */