summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/cpus/aarch64/aem_generic.S38
-rw-r--r--lib/psci/psci_common.c22
2 files changed, 44 insertions, 16 deletions
diff --git a/lib/cpus/aarch64/aem_generic.S b/lib/cpus/aarch64/aem_generic.S
index 51b5ce91..6291e43e 100644
--- a/lib/cpus/aarch64/aem_generic.S
+++ b/lib/cpus/aarch64/aem_generic.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -18,15 +18,43 @@ func aem_generic_core_pwr_dwn
msr sctlr_el3, x1
isb
+ /* ---------------------------------------------
+ * AEM model supports L3 caches in which case L2
+ * will be private per core caches and flush
+ * from L1 to L2 is not sufficient.
+ * ---------------------------------------------
+ */
+ mrs x1, clidr_el1
+
+ /* ---------------------------------------------
+ * Check if L3 cache is implemented.
+ * ---------------------------------------------
+ */
+ tst x1, ((1 << CLIDR_FIELD_WIDTH) - 1) << CTYPE_SHIFT(3)
+
+ /* ---------------------------------------------
+ * There is no L3 cache, flush L1 to L2 only.
+ * ---------------------------------------------
+ */
mov x0, #DCCISW
+ b.eq dcsw_op_level1
+
+ mov x18, x30
/* ---------------------------------------------
- * Flush L1 cache to PoU.
+ * Flush L1 cache to L2.
* ---------------------------------------------
*/
- b dcsw_op_louis
-endfunc aem_generic_core_pwr_dwn
+ bl dcsw_op_level1
+ mov x30, x18
+ /* ---------------------------------------------
+ * Flush L2 cache to L3.
+ * ---------------------------------------------
+ */
+ mov x0, #DCCISW
+ b dcsw_op_level2
+endfunc aem_generic_core_pwr_dwn
func aem_generic_cluster_pwr_dwn
/* ---------------------------------------------
@@ -39,7 +67,7 @@ func aem_generic_cluster_pwr_dwn
isb
/* ---------------------------------------------
- * Flush L1 and L2 caches to PoC.
+ * Flush all caches to PoC.
* ---------------------------------------------
*/
mov x0, #DCCISW
diff --git a/lib/psci/psci_common.c b/lib/psci/psci_common.c
index 5d24356c..022c8775 100644
--- a/lib/psci/psci_common.c
+++ b/lib/psci/psci_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -198,21 +198,17 @@ static unsigned int get_power_on_target_pwrlvl(void)
/******************************************************************************
* Helper function to update the requested local power state array. This array
* does not store the requested state for the CPU power level. Hence an
- * assertion is added to prevent us from accessing the wrong index.
+ * assertion is added to prevent us from accessing the CPU power level.
*****************************************************************************/
static void psci_set_req_local_pwr_state(unsigned int pwrlvl,
unsigned int cpu_idx,
plat_local_state_t req_pwr_state)
{
- /*
- * This should never happen, we have this here to avoid
- * "array subscript is above array bounds" errors in GCC.
- */
assert(pwrlvl > PSCI_CPU_PWR_LVL);
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Warray-bounds"
- psci_req_local_pwr_states[pwrlvl - 1U][cpu_idx] = req_pwr_state;
-#pragma GCC diagnostic pop
+ if ((pwrlvl > PSCI_CPU_PWR_LVL) && (pwrlvl <= PLAT_MAX_PWR_LVL) &&
+ (cpu_idx < PLATFORM_CORE_COUNT)) {
+ psci_req_local_pwr_states[pwrlvl - 1U][cpu_idx] = req_pwr_state;
+ }
}
/******************************************************************************
@@ -245,7 +241,11 @@ static plat_local_state_t *psci_get_req_local_pwr_states(unsigned int pwrlvl,
{
assert(pwrlvl > PSCI_CPU_PWR_LVL);
- return &psci_req_local_pwr_states[pwrlvl - 1U][cpu_idx];
+ if ((pwrlvl > PSCI_CPU_PWR_LVL) && (pwrlvl <= PLAT_MAX_PWR_LVL) &&
+ (cpu_idx < PLATFORM_CORE_COUNT)) {
+ return &psci_req_local_pwr_states[pwrlvl - 1U][cpu_idx];
+ } else
+ return NULL;
}
/*