summaryrefslogtreecommitdiff
path: root/services
diff options
context:
space:
mode:
authorAndrew Thoelke <andrew.thoelke@arm.com>2015-09-10 11:39:36 +0100
committerVikram Kanigiri <vikram.kanigiri@arm.com>2015-09-11 16:19:21 +0100
commitee7b35c4e1169ec68df016bfb244a5281440119d (patch)
tree542012cfa197c96d89a42bbd5e5e0b4a33897fe4 /services
parent604d5da6f2aa837326d5eda7735c8dac9a127ccd (diff)
Re-design bakery lock memory allocation and algorithm
This patch unifies the bakery lock api's across coherent and normal memory implementation of locks by using same data type `bakery_lock_t` and similar arguments to functions. A separate section `bakery_lock` has been created and used to allocate memory for bakery locks using `DEFINE_BAKERY_LOCK`. When locks are allocated in normal memory, each lock for a core has to spread across multiple cache lines. By using the total size allocated in a separate cache line for a single core at compile time, the memory for other core locks is allocated at link time by multiplying the single core locks size with (PLATFORM_CORE_COUNT - 1). The normal memory lock algorithm now uses lock address instead of the `id` in the per_cpu_data. For locks allocated in coherent memory, it moves locks from tzfw_coherent_memory to bakery_lock section. The bakery locks are allocated as part of bss or in coherent memory depending on usage of coherent memory. Both these regions are initialised to zero as part of run_time_init before locks are used. Hence, bakery_lock_init() is made an empty function as the lock memory is already initialised to zero. The above design lead to the removal of psci bakery locks from non_cpu_power_pd_node to psci_locks. NOTE: THE BAKERY LOCK API WHEN USE_COHERENT_MEM IS NOT SET HAS CHANGED. THIS IS A BREAKING CHANGE FOR ALL PLATFORM PORTS THAT ALLOCATE BAKERY LOCKS IN NORMAL MEMORY. Change-Id: Ic3751c0066b8032dcbf9d88f1d4dc73d15f61d8b
Diffstat (limited to 'services')
-rw-r--r--services/std_svc/psci/psci_common.c2
-rw-r--r--services/std_svc/psci/psci_private.h25
-rw-r--r--services/std_svc/psci/psci_setup.c6
3 files changed, 9 insertions, 24 deletions
diff --git a/services/std_svc/psci/psci_common.c b/services/std_svc/psci/psci_common.c
index e12df04b..73326952 100644
--- a/services/std_svc/psci/psci_common.c
+++ b/services/std_svc/psci/psci_common.c
@@ -78,6 +78,8 @@ __attribute__ ((section("tzfw_coherent_mem")))
#endif
;
+DEFINE_BAKERY_LOCK(psci_locks[PSCI_NUM_NON_CPU_PWR_DOMAINS]);
+
cpu_pd_node_t psci_cpu_pd_nodes[PLATFORM_CORE_COUNT];
/*******************************************************************************
diff --git a/services/std_svc/psci/psci_private.h b/services/std_svc/psci/psci_private.h
index 9b55d9f3..8c028a73 100644
--- a/services/std_svc/psci/psci_private.h
+++ b/services/std_svc/psci/psci_private.h
@@ -42,23 +42,12 @@
* The following helper macros abstract the interface to the Bakery
* Lock API.
*/
-#if USE_COHERENT_MEM
-#define psci_lock_init(non_cpu_pd_node, idx) \
- bakery_lock_init(&(non_cpu_pd_node)[(idx)].lock)
-#define psci_lock_get(non_cpu_pd_node) \
- bakery_lock_get(&((non_cpu_pd_node)->lock))
-#define psci_lock_release(non_cpu_pd_node) \
- bakery_lock_release(&((non_cpu_pd_node)->lock))
-#else
#define psci_lock_init(non_cpu_pd_node, idx) \
((non_cpu_pd_node)[(idx)].lock_index = (idx))
#define psci_lock_get(non_cpu_pd_node) \
- bakery_lock_get((non_cpu_pd_node)->lock_index, \
- CPU_DATA_PSCI_LOCK_OFFSET)
+ bakery_lock_get(&psci_locks[(non_cpu_pd_node)->lock_index])
#define psci_lock_release(non_cpu_pd_node) \
- bakery_lock_release((non_cpu_pd_node)->lock_index, \
- CPU_DATA_PSCI_LOCK_OFFSET)
-#endif
+ bakery_lock_release(&psci_locks[(non_cpu_pd_node)->lock_index])
/*
* The PSCI capability which are provided by the generic code but does not
@@ -140,12 +129,9 @@ typedef struct non_cpu_pwr_domain_node {
plat_local_state_t local_state;
unsigned char level;
-#if USE_COHERENT_MEM
- bakery_lock_t lock;
-#else
- /* For indexing the bakery_info array in per CPU data */
+
+ /* For indexing the psci_lock array*/
unsigned char lock_index;
-#endif
} non_cpu_pd_node_t;
typedef struct cpu_pwr_domain_node {
@@ -174,6 +160,9 @@ extern non_cpu_pd_node_t psci_non_cpu_pd_nodes[PSCI_NUM_NON_CPU_PWR_DOMAINS];
extern cpu_pd_node_t psci_cpu_pd_nodes[PLATFORM_CORE_COUNT];
extern unsigned int psci_caps;
+/* One bakery lock is required for each non-cpu power domain */
+DECLARE_BAKERY_LOCK(psci_locks[PSCI_NUM_NON_CPU_PWR_DOMAINS]);
+
/*******************************************************************************
* SPD's power management hooks registered with PSCI
******************************************************************************/
diff --git a/services/std_svc/psci/psci_setup.c b/services/std_svc/psci/psci_setup.c
index 94fe630c..7a801873 100644
--- a/services/std_svc/psci/psci_setup.c
+++ b/services/std_svc/psci/psci_setup.c
@@ -181,12 +181,6 @@ static void populate_power_domain_tree(const unsigned char *topology)
/* Validate the sanity of array exported by the platform */
assert(j == PLATFORM_CORE_COUNT);
-
-#if !USE_COHERENT_MEM
- /* Flush the non CPU power domain data to memory */
- flush_dcache_range((uintptr_t) &psci_non_cpu_pd_nodes,
- sizeof(psci_non_cpu_pd_nodes));
-#endif
}
/*******************************************************************************