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/* 69 * Disable the over-read from the LDNP/STNP instruction. The SDEN doesn't 70 * provide and erratum number, so assign it an obvious 1 71 */ 72workaround_reset_start cortex_a57, ERRATUM(1), A57_DISABLE_NON_TEMPORAL_HINT 73 sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_DIS_OVERREAD 74workaround_reset_end cortex_a57, ERRATUM(1) 75 76check_erratum_ls cortex_a57, ERRATUM(1), CPU_REV(1, 2) 77 78workaround_reset_start cortex_a57, ERRATUM(806969), ERRATA_A57_806969 79 sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_NO_ALLOC_WBWA 80workaround_reset_end cortex_a57, ERRATUM(806969) 81 82check_erratum_ls cortex_a57, ERRATUM(806969), CPU_REV(0, 0) 83 84/* erratum always worked around, but report it correctly */ 85check_erratum_ls cortex_a57, ERRATUM(813419), CPU_REV(0, 0) 86add_erratum_entry cortex_a57, ERRATUM(813419), ERRATUM_ALWAYS_CHOSEN 87 88workaround_reset_start cortex_a57, ERRATUM(813420), ERRATA_A57_813420 89 sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_DCC_AS_DCCI 90workaround_reset_end cortex_a57, ERRATUM(813420) 91 92check_erratum_ls cortex_a57, ERRATUM(813420), CPU_REV(0, 0) 93 94workaround_reset_start cortex_a57, ERRATUM(814670), ERRATA_A57_814670 95 sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_DIS_DMB_NULLIFICATION 96workaround_reset_end cortex_a57, ERRATUM(814670) 97 98check_erratum_ls cortex_a57, ERRATUM(814670), CPU_REV(0, 0) 99 100workaround_runtime_start cortex_a57, ERRATUM(817169), ERRATA_A57_817169 101 /* Invalidate any TLB address */ 102 mov x0, #0 103 tlbi vae3, x0 104workaround_runtime_end cortex_a57, ERRATUM(817169), NO_ISB 105 106check_erratum_ls cortex_a57, ERRATUM(817169), CPU_REV(0, 1) 107 108workaround_reset_start cortex_a57, ERRATUM(826974), ERRATA_A57_826974 109 sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_DIS_LOAD_PASS_DMB 110workaround_reset_end cortex_a57, ERRATUM(826974) 111 112check_erratum_ls cortex_a57, ERRATUM(826974), CPU_REV(1, 1) 113 114workaround_reset_start cortex_a57, ERRATUM(826977), ERRATA_A57_826977 115 sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_GRE_NGRE_AS_NGNRE 116workaround_reset_end cortex_a57, ERRATUM(826977) 117 118check_erratum_ls cortex_a57, ERRATUM(826977), CPU_REV(1, 1) 119 120workaround_reset_start cortex_a57, ERRATUM(828024), ERRATA_A57_828024 121 mrs x1, CORTEX_A57_CPUACTLR_EL1 122 /* 123 * Setting the relevant bits in CPUACTLR_EL1 has to be done in 2 124 * instructions here because the resulting bitmask doesn't fit in a 125 * 16-bit value so it cannot be encoded in a single instruction. 126 */ 127 orr x1, x1, #CORTEX_A57_CPUACTLR_EL1_NO_ALLOC_WBWA 128 orr x1, x1, #(CORTEX_A57_CPUACTLR_EL1_DIS_L1_STREAMING | \ 129 CORTEX_A57_CPUACTLR_EL1_DIS_STREAMING) 130 msr CORTEX_A57_CPUACTLR_EL1, x1 131workaround_reset_end cortex_a57, ERRATUM(828024) 132 133check_erratum_ls cortex_a57, ERRATUM(828024), CPU_REV(1, 1) 134 135workaround_reset_start cortex_a57, ERRATUM(829520), ERRATA_A57_829520 136 sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_DIS_INDIRECT_PREDICTOR 137workaround_reset_end cortex_a57, ERRATUM(829520) 138 139check_erratum_ls cortex_a57, ERRATUM(829520), CPU_REV(1, 2) 140 141workaround_reset_start cortex_a57, ERRATUM(833471), ERRATA_A57_833471 142 sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_FORCE_FPSCR_FLUSH 143workaround_reset_end cortex_a57, ERRATUM(833471) 144 145check_erratum_ls cortex_a57, ERRATUM(833471), CPU_REV(1, 2) 146 147workaround_reset_start cortex_a57, ERRATUM(859972), ERRATA_A57_859972 148 sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_DIS_INSTR_PREFETCH 149workaround_reset_end cortex_a57, ERRATUM(859972) 150 151check_erratum_ls cortex_a57, ERRATUM(859972), CPU_REV(1, 3) 152 153check_erratum_chosen cortex_a57, ERRATUM(1319537), ERRATA_A57_1319537 154/* erratum has no workaround in the cpu. Generic code must take care */ 155add_erratum_entry cortex_a57, ERRATUM(1319537), ERRATA_A57_1319537 156 157workaround_reset_start cortex_a57, CVE(2017, 5715), WORKAROUND_CVE_2017_5715 158#if IMAGE_BL31 159 override_vector_table wa_cve_2017_5715_mmu_vbar 160#endif 161workaround_reset_end cortex_a57, CVE(2017, 5715) 162 163check_erratum_chosen cortex_a57, CVE(2017, 5715), WORKAROUND_CVE_2017_5715 164 165workaround_reset_start cortex_a57, CVE(2018, 3639), WORKAROUND_CVE_2018_3639 166 sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_DIS_LOAD_PASS_STORE 167 isb 168 dsb sy 169workaround_reset_end cortex_a57, CVE(2018, 3639) 170 171check_erratum_chosen cortex_a57, CVE(2018, 3639), WORKAROUND_CVE_2018_3639 172 173workaround_reset_start cortex_a57, CVE(2022, 23960), WORKAROUND_CVE_2022_23960 174#if IMAGE_BL31 175 override_vector_table wa_cve_2017_5715_mmu_vbar 176#endif 177workaround_reset_end cortex_a57, CVE(2022, 23960) 178 179check_erratum_chosen cortex_a57, CVE(2022, 23960), WORKAROUND_CVE_2022_23960 180 181cpu_reset_func_start cortex_a57 182#if A57_ENABLE_NONCACHEABLE_LOAD_FWD 183 /* Enable higher performance non-cacheable load forwarding */ 184 sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_EN_NC_LOAD_FWD 185#endif 186 /* Enable the SMP bit. */ 187 sysreg_bit_set CORTEX_A57_ECTLR_EL1, CORTEX_A57_ECTLR_SMP_BIT 188cpu_reset_func_end cortex_a57 189 190func check_smccc_arch_workaround_3 191 mov x0, #ERRATA_APPLIES 192 ret 193endfunc check_smccc_arch_workaround_3 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_wa cortex_a57, CORTEX_A57_MIDR, \ 311 cortex_a57_reset_func, \ 312 check_erratum_cortex_a57_5715, \ 313 CPU_NO_EXTRA2_FUNC, \ 314 check_smccc_arch_workaround_3, \ 315 cortex_a57_core_pwr_dwn, \ 316 cortex_a57_cluster_pwr_dwn 317