mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-27 15:24:54 +00:00
Merge pull request #145 from athoelke/at/psci-memory-optimization-v2
PSCI memory optimizations (v2)
This commit is contained in:
commit
41cf7bdfd7
7 changed files with 22 additions and 43 deletions
|
@ -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 @@
|
||||||
#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 @@
|
||||||
#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
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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 @@
|
||||||
*/
|
*/
|
||||||
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 @@
|
||||||
|
|
||||||
#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 {
|
||||||
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 {
|
||||||
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,
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* 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];
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
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,
|
||||||
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)
|
||||||
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 */
|
||||||
|
|
Loading…
Add table
Reference in a new issue