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