diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/cpus/aarch64/aem_generic.S | 38 | ||||
-rw-r--r-- | lib/psci/psci_common.c | 22 |
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; } /* |