1/* 2 * Copyright (c) 2014-2025, Arm Limited and Contributors. All rights reserved. 3 * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. 4 * 5 * SPDX-License-Identifier: BSD-3-Clause 6 */ 7#include <arch.h> 8#include <asm_macros.S> 9#include <assert_macros.S> 10#include <common/bl_common.h> 11#include <common/debug.h> 12#include <cortex_a57.h> 13#include <cpu_macros.S> 14#include <plat_macros.S> 15 16cpu_reset_prologue cortex_a57 17 18 /* --------------------------------------------- 19 * Disable L1 data cache and unified L2 cache 20 * --------------------------------------------- 21 */ 22func cortex_a57_disable_dcache 23 sysreg_bit_clear sctlr_el3, SCTLR_C_BIT 24 isb 25 ret 26endfunc cortex_a57_disable_dcache 27 28 /* --------------------------------------------- 29 * Disable all types of L2 prefetches. 30 * --------------------------------------------- 31 */ 32func cortex_a57_disable_l2_prefetch 33 mrs x0, CORTEX_A57_ECTLR_EL1 34 orr x0, x0, #CORTEX_A57_ECTLR_DIS_TWD_ACC_PFTCH_BIT 35 mov x1, #CORTEX_A57_ECTLR_L2_IPFTCH_DIST_MASK 36 orr x1, x1, #CORTEX_A57_ECTLR_L2_DPFTCH_DIST_MASK 37 bic x0, x0, x1 38 msr CORTEX_A57_ECTLR_EL1, x0 39 isb 40 dsb ish 41 ret 42endfunc cortex_a57_disable_l2_prefetch 43 44 /* --------------------------------------------- 45 * Disable intra-cluster coherency 46 * --------------------------------------------- 47 */ 48func cortex_a57_disable_smp 49 sysreg_bit_clear CORTEX_A57_ECTLR_EL1, CORTEX_A57_ECTLR_SMP_BIT 50 ret 51endfunc cortex_a57_disable_smp 52 53 /* --------------------------------------------- 54 * Disable debug interfaces 55 * --------------------------------------------- 56 */ 57func cortex_a57_disable_ext_debug 58 mov x0, #1 59 msr osdlr_el1, x0 60 isb 61 62 apply_erratum cortex_a57, ERRATUM(817169), ERRATA_A57_817169, NO_GET_CPU_REV 63 64 dsb sy 65 ret 66endfunc cortex_a57_disable_ext_debug 67 68/* Erratum entry and check function for SMCCC_ARCH_WORKAROUND_3 */ 69add_erratum_entry cortex_a57, ERRATUM(ARCH_WORKAROUND_3), WORKAROUND_CVE_2022_23960 70 71check_erratum_chosen cortex_a57, ERRATUM(ARCH_WORKAROUND_3), WORKAROUND_CVE_2022_23960 72 73/* 74 * Disable the over-read from the LDNP/STNP instruction. The SDEN doesn't 75 * provide and erratum number, so assign it an obvious 99999 76 */ 77workaround_reset_start cortex_a57, ERRATUM(99999), A57_DISABLE_NON_TEMPORAL_HINT 78 sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_DIS_OVERREAD 79workaround_reset_end cortex_a57, ERRATUM(99999) 80 81check_erratum_ls cortex_a57, ERRATUM(99999), CPU_REV(1, 2) 82 83workaround_reset_start cortex_a57, ERRATUM(806969), ERRATA_A57_806969 84 sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_NO_ALLOC_WBWA 85workaround_reset_end cortex_a57, ERRATUM(806969) 86 87check_erratum_ls cortex_a57, ERRATUM(806969), CPU_REV(0, 0) 88 89/* erratum always worked around, but report it correctly */ 90check_erratum_ls cortex_a57, ERRATUM(813419), CPU_REV(0, 0) 91add_erratum_entry cortex_a57, ERRATUM(813419), ERRATUM_ALWAYS_CHOSEN 92 93workaround_reset_start cortex_a57, ERRATUM(813420), ERRATA_A57_813420 94 sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_DCC_AS_DCCI 95workaround_reset_end cortex_a57, ERRATUM(813420) 96 97check_erratum_ls cortex_a57, ERRATUM(813420), CPU_REV(0, 0) 98 99workaround_reset_start cortex_a57, ERRATUM(814670), ERRATA_A57_814670 100 sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_DIS_DMB_NULLIFICATION 101workaround_reset_end cortex_a57, ERRATUM(814670) 102 103check_erratum_ls cortex_a57, ERRATUM(814670), CPU_REV(0, 0) 104 105workaround_runtime_start cortex_a57, ERRATUM(817169), ERRATA_A57_817169 106 /* Invalidate any TLB address */ 107 mov x0, #0 108 tlbi vae3, x0 109workaround_runtime_end cortex_a57, ERRATUM(817169), NO_ISB 110 111check_erratum_ls cortex_a57, ERRATUM(817169), CPU_REV(0, 1) 112 113workaround_reset_start cortex_a57, ERRATUM(826974), ERRATA_A57_826974 114 sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_DIS_LOAD_PASS_DMB 115workaround_reset_end cortex_a57, ERRATUM(826974) 116 117check_erratum_ls cortex_a57, ERRATUM(826974), CPU_REV(1, 1) 118 119workaround_reset_start cortex_a57, ERRATUM(826977), ERRATA_A57_826977 120 sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_GRE_NGRE_AS_NGNRE 121workaround_reset_end cortex_a57, ERRATUM(826977) 122 123check_erratum_ls cortex_a57, ERRATUM(826977), CPU_REV(1, 1) 124 125workaround_reset_start cortex_a57, ERRATUM(828024), ERRATA_A57_828024 126 mrs x1, CORTEX_A57_CPUACTLR_EL1 127 /* 128 * Setting the relevant bits in CPUACTLR_EL1 has to be done in 2 129 * instructions here because the resulting bitmask doesn't fit in a 130 * 16-bit value so it cannot be encoded in a single instruction. 131 */ 132 orr x1, x1, #CORTEX_A57_CPUACTLR_EL1_NO_ALLOC_WBWA 133 orr x1, x1, #(CORTEX_A57_CPUACTLR_EL1_DIS_L1_STREAMING | \ 134 CORTEX_A57_CPUACTLR_EL1_DIS_STREAMING) 135 msr CORTEX_A57_CPUACTLR_EL1, x1 136workaround_reset_end cortex_a57, ERRATUM(828024) 137 138check_erratum_ls cortex_a57, ERRATUM(828024), CPU_REV(1, 1) 139 140workaround_reset_start cortex_a57, ERRATUM(829520), ERRATA_A57_829520 141 sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_DIS_INDIRECT_PREDICTOR 142workaround_reset_end cortex_a57, ERRATUM(829520) 143 144check_erratum_ls cortex_a57, ERRATUM(829520), CPU_REV(1, 2) 145 146workaround_reset_start cortex_a57, ERRATUM(833471), ERRATA_A57_833471 147 sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_FORCE_FPSCR_FLUSH 148workaround_reset_end cortex_a57, ERRATUM(833471) 149 150check_erratum_ls cortex_a57, ERRATUM(833471), CPU_REV(1, 2) 151 152workaround_reset_start cortex_a57, ERRATUM(859972), ERRATA_A57_859972 153 sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_DIS_INSTR_PREFETCH 154workaround_reset_end cortex_a57, ERRATUM(859972) 155 156check_erratum_ls cortex_a57, ERRATUM(859972), CPU_REV(1, 3) 157 158check_erratum_chosen cortex_a57, ERRATUM(1319537), ERRATA_A57_1319537 159/* erratum has no workaround in the cpu. Generic code must take care */ 160add_erratum_entry cortex_a57, ERRATUM(1319537), ERRATA_A57_1319537 161 162workaround_reset_start cortex_a57, CVE(2017, 5715), WORKAROUND_CVE_2017_5715 163#if IMAGE_BL31 164 override_vector_table wa_cve_2017_5715_mmu_vbar 165#endif 166workaround_reset_end cortex_a57, CVE(2017, 5715) 167 168check_erratum_chosen cortex_a57, CVE(2017, 5715), WORKAROUND_CVE_2017_5715 169 170workaround_reset_start cortex_a57, CVE(2018, 3639), WORKAROUND_CVE_2018_3639 171 sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_DIS_LOAD_PASS_STORE 172 isb 173 dsb sy 174workaround_reset_end cortex_a57, CVE(2018, 3639) 175 176check_erratum_chosen cortex_a57, CVE(2018, 3639), WORKAROUND_CVE_2018_3639 177 178workaround_reset_start cortex_a57, CVE(2022, 23960), WORKAROUND_CVE_2022_23960 179#if IMAGE_BL31 180 override_vector_table wa_cve_2017_5715_mmu_vbar 181#endif 182workaround_reset_end cortex_a57, CVE(2022, 23960) 183 184check_erratum_chosen cortex_a57, CVE(2022, 23960), WORKAROUND_CVE_2022_23960 185 186cpu_reset_func_start cortex_a57 187#if A57_ENABLE_NONCACHEABLE_LOAD_FWD 188 /* Enable higher performance non-cacheable load forwarding */ 189 sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_EN_NC_LOAD_FWD 190#endif 191 /* Enable the SMP bit. */ 192 sysreg_bit_set CORTEX_A57_ECTLR_EL1, CORTEX_A57_ECTLR_SMP_BIT 193cpu_reset_func_end cortex_a57 194 195 /* ---------------------------------------------------- 196 * The CPU Ops core power down function for Cortex-A57. 197 * ---------------------------------------------------- 198 */ 199func cortex_a57_core_pwr_dwn 200 mov x18, x30 201 202 /* --------------------------------------------- 203 * Turn off caches. 204 * --------------------------------------------- 205 */ 206 bl cortex_a57_disable_dcache 207 208 /* --------------------------------------------- 209 * Disable the L2 prefetches. 210 * --------------------------------------------- 211 */ 212 bl cortex_a57_disable_l2_prefetch 213 214 /* --------------------------------------------- 215 * Flush L1 caches. 216 * --------------------------------------------- 217 */ 218 mov x0, #DCCISW 219 bl dcsw_op_level1 220 221 /* --------------------------------------------- 222 * Come out of intra cluster coherency 223 * --------------------------------------------- 224 */ 225 bl cortex_a57_disable_smp 226 227 /* --------------------------------------------- 228 * Force the debug interfaces to be quiescent 229 * --------------------------------------------- 230 */ 231 mov x30, x18 232 b cortex_a57_disable_ext_debug 233endfunc cortex_a57_core_pwr_dwn 234 235 /* ------------------------------------------------------- 236 * The CPU Ops cluster power down function for Cortex-A57. 237 * ------------------------------------------------------- 238 */ 239func cortex_a57_cluster_pwr_dwn 240 mov x18, x30 241 242 /* --------------------------------------------- 243 * Turn off caches. 244 * --------------------------------------------- 245 */ 246 bl cortex_a57_disable_dcache 247 248 /* --------------------------------------------- 249 * Disable the L2 prefetches. 250 * --------------------------------------------- 251 */ 252 bl cortex_a57_disable_l2_prefetch 253 254#if !SKIP_A57_L1_FLUSH_PWR_DWN 255 /* ------------------------------------------------- 256 * Flush the L1 caches. 257 * ------------------------------------------------- 258 */ 259 mov x0, #DCCISW 260 bl dcsw_op_level1 261#endif 262 /* --------------------------------------------- 263 * Disable the optional ACP. 264 * --------------------------------------------- 265 */ 266 bl plat_disable_acp 267 268 /* ------------------------------------------------- 269 * Flush the L2 caches. 270 * ------------------------------------------------- 271 */ 272 mov x0, #DCCISW 273 bl dcsw_op_level2 274 275 /* --------------------------------------------- 276 * Come out of intra cluster coherency 277 * --------------------------------------------- 278 */ 279 bl cortex_a57_disable_smp 280 281 /* --------------------------------------------- 282 * Force the debug interfaces to be quiescent 283 * --------------------------------------------- 284 */ 285 mov x30, x18 286 b cortex_a57_disable_ext_debug 287endfunc cortex_a57_cluster_pwr_dwn 288 289 /* --------------------------------------------- 290 * This function provides cortex_a57 specific 291 * register information for crash reporting. 292 * It needs to return with x6 pointing to 293 * a list of register names in ascii and 294 * x8 - x15 having values of registers to be 295 * reported. 296 * --------------------------------------------- 297 */ 298.section .rodata.cortex_a57_regs, "aS" 299cortex_a57_regs: /* The ascii list of register names to be reported */ 300 .asciz "cpuectlr_el1", "cpumerrsr_el1", "l2merrsr_el1", "" 301 302func cortex_a57_cpu_reg_dump 303 adr x6, cortex_a57_regs 304 mrs x8, CORTEX_A57_ECTLR_EL1 305 mrs x9, CORTEX_A57_MERRSR_EL1 306 mrs x10, CORTEX_A57_L2MERRSR_EL1 307 ret 308endfunc cortex_a57_cpu_reg_dump 309 310declare_cpu_ops cortex_a57, CORTEX_A57_MIDR, \ 311 cortex_a57_reset_func, \ 312 cortex_a57_core_pwr_dwn, \ 313 cortex_a57_cluster_pwr_dwn 314