1/* 2 * Copyright (c) 2023-2026, Arm Limited. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7#include <arch.h> 8#include <asm_macros.S> 9#include <common/bl_common.h> 10#include <cortex_a510.h> 11#include <cpu_macros.S> 12#include <dsu_macros.S> 13#include <plat_macros.S> 14 15/* Hardware handled coherency */ 16#if HW_ASSISTED_COHERENCY == 0 17#error "Cortex-A510 must be compiled with HW_ASSISTED_COHERENCY enabled" 18#endif 19 20/* 64-bit only core */ 21#if CTX_INCLUDE_AARCH32_REGS == 1 22#error "Cortex-A510 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0" 23#endif 24 25cpu_reset_prologue cortex_a510 26 27workaround_reset_start cortex_a510, ERRATUM(1910738), ERRATA_A510_1910738 28 is_feat_mte_present_asm x1 29 cmp x1, #1 /* if the value is 0b01, BROADCASTMTE is low */ 30 beq 1f 31 sysreg_bit_set CORTEX_A510_CPUECTLR_EL1, BIT(19) 32 sysreg_bit_set CORTEX_A510_CPUACTLR_EL1, BIT(4) 33 sysreg_bit_set CORTEX_A510_CPUACTLR_EL1, BIT(26) 341: 35workaround_reset_end cortex_a510, ERRATUM(1910738) 36 37check_erratum_ls cortex_a510, ERRATUM(1910738), CPU_REV(0, 0) 38 39workaround_reset_start cortex_a510, ERRATUM(1937669), ERRATA_A510_1937669 40 is_feat_mte_present_asm x1 41 cmp x1, #1 /* if the value is 0b01, BROADCASTMTE is low */ 42 beq 1f 43 sysreg_bit_set CORTEX_A510_CPUACTLR_EL1, BIT(10) 441: 45workaround_reset_end cortex_a510, ERRATUM(1937669) 46 47check_erratum_ls cortex_a510, ERRATUM(1937669), CPU_REV(0, 0) 48 49workaround_reset_start cortex_a510, ERRATUM(1942494), ERRATA_A510_1942494 50 sysreg_bit_set CORTEX_A510_CPUACTLR_EL1, BIT(15) 51workaround_reset_end cortex_a510, ERRATUM(1942494) 52 53check_erratum_ls cortex_a510, ERRATUM(1942494), CPU_REV(0, 0) 54 55workaround_reset_start cortex_a510, ERRATUM(1952872), ERRATA_A510_1952872 56 sysreg_bit_set CORTEX_A510_CPUACTLR_EL1, BIT(18) 57workaround_reset_end cortex_a510, ERRATUM(1952872) 58 59check_erratum_ls cortex_a510, ERRATUM(1952872), CPU_REV(0, 0) 60 61workaround_reset_start cortex_a510, ERRATUM(1966377), ERRATA_A510_1966377 62 sysreg_bit_set CORTEX_A510_CPUACTLR2_EL1, BIT(29) 63workaround_reset_end cortex_a510, ERRATUM(1966377) 64 65check_erratum_ls cortex_a510, ERRATUM(1966377), CPU_REV(0, 0) 66 67workaround_reset_start cortex_a510, ERRATUM(1975068), ERRATA_A510_1975068 68 sysreg_bitfield_insert CORTEX_A510_CMPXECTLR_EL1, \ 69 CORTEX_A510_CMPXECTLR_EL1_FPDFTH_BIT, \ 70 CORTEX_A510_CMPXECTLR_EL1_FPDFTH_SHIFT, \ 71 CORTEX_A510_CMPXECTLR_EL1_FPDFTH_WIDTH 72workaround_reset_end cortex_a510, ERRATUM(1975068) 73 74check_erratum_ls cortex_a510, ERRATUM(1975068), CPU_REV(0, 0) 75 76workaround_reset_start cortex_a510, ERRATUM(1976290), ERRATA_A510_1976290 77 is_feat_mte_present_asm x1 78 cmp x1, #1 /* if the value is 0b01, BROADCASTMTE is low */ 79 beq 1f 80 sysreg_bit_set CORTEX_A510_CPUACTLR_EL1, BIT(4) 811: 82workaround_reset_end cortex_a510, ERRATUM(1976290) 83 84check_erratum_ls cortex_a510, ERRATUM(1976290), CPU_REV(0, 0) 85 86workaround_reset_start cortex_a510, ERRATUM(2002389), ERRATA_A510_2002389 87 sysreg_bit_set CORTEX_A510_CPUACTLR_EL1, BIT(3) 88workaround_reset_end cortex_a510, ERRATUM(2002389) 89 90check_erratum_ls cortex_a510, ERRATUM(2002389), CPU_REV(0, 1) 91 92workaround_runtime_start cortex_a510, ERRATUM(2008766), ERRATA_A510_2008766 93 /* Stash ERRSELR_EL1 in x2 */ 94 mrs x2, ERRSELR_EL1 95 96 /* Select error record 0 and clear ED bit */ 97 msr ERRSELR_EL1, xzr 98 sysreg_bit_clear ERXCTLR_EL1, ERXCTLR_ED_BIT 99 100 /* Select error record 1 and clear ED bit */ 101 mov x0, #1 102 msr ERRSELR_EL1, x0 103 sysreg_bit_clear ERXCTLR_EL1, ERXCTLR_ED_BIT 104 105 /* Select error record 2 and clear ED bit */ 106 mov x0, #2 107 msr ERRSELR_EL1, x0 108 sysreg_bit_clear ERXCTLR_EL1, ERXCTLR_ED_BIT 109 110 /* Restore ERRSELR_EL1 from x2 */ 111 msr ERRSELR_EL1, x2 112workaround_runtime_end cortex_a510, ERRATUM(2008766), NO_ISB 113 114check_erratum_ls cortex_a510, ERRATUM(2008766), CPU_REV(1, 3) 115 116workaround_reset_start cortex_a510, ERRATUM(2027318), ERRATA_A510_2027318 117 sysreg_bit_set CORTEX_A510_CMPXACTLR_EL1, BIT(11) 118workaround_reset_end cortex_a510, ERRATUM(2027318) 119 120check_erratum_ls cortex_a510, ERRATUM(2027318), CPU_REV(0, 1) 121 122workaround_reset_start cortex_a510, ERRATUM(2028010), ERRATA_A510_2028010 123 sysreg_bit_set CORTEX_A510_CPUACTLR_EL1, BIT(38) 124workaround_reset_end cortex_a510, ERRATUM(2028010) 125 126check_erratum_ls cortex_a510, ERRATUM(2028010), CPU_REV(0, 1) 127 128workaround_reset_start cortex_a510, ERRATUM(2041909), ERRATA_A510_2041909 129 /* Apply workaround */ 130 mov x0, xzr 131 msr S3_6_C15_C4_0, x0 132 isb 133 134 mov x0, #0x8500000 135 msr S3_6_C15_C4_2, x0 136 137 mov x0, #0x1F700000 138 movk x0, #0x8, lsl #32 139 msr S3_6_C15_C4_3, x0 140 141 mov x0, #0x3F1 142 movk x0, #0x110, lsl #16 143 msr S3_6_C15_C4_1, x0 144workaround_reset_end cortex_a510, ERRATUM(2041909) 145 146check_erratum_range cortex_a510, ERRATUM(2041909), CPU_REV(0, 2), CPU_REV(0, 2) 147 148workaround_reset_start cortex_a510, ERRATUM(2042739), ERRATA_A510_2042739 149 /* Apply the workaround by disabling ReadPreferUnique. */ 150 sysreg_bitfield_insert CORTEX_A510_CPUECTLR_EL1, CORTEX_A510_CPUECTLR_EL1_READPREFERUNIQUE_DISABLE, \ 151 CORTEX_A510_CPUECTLR_EL1_READPREFERUNIQUE_SHIFT, CORTEX_A510_CPUECTLR_EL1_READPREFERUNIQUE_WIDTH 152workaround_reset_end cortex_a510, ERRATUM(2042739) 153 154check_erratum_ls cortex_a510, ERRATUM(2042739), CPU_REV(0, 2) 155 156workaround_reset_start cortex_a510, ERRATUM(2080326), ERRATA_A510_2080326 157 /* Apply workaround */ 158 mov x0, #1 159 msr S3_6_C15_C4_0, x0 160 isb 161 162 mov x0, #0x0100 163 movk x0, #0x0E08, lsl #16 164 msr S3_6_C15_C4_2, x0 165 166 mov x0, #0x0300 167 movk x0, #0x0F1F, lsl #16 168 movk x0, #0x0008, lsl #32 169 msr S3_6_C15_C4_3, x0 170 171 mov x0, #0x03F1 172 movk x0, #0x00C0, lsl #16 173 msr S3_6_C15_C4_1, x0 174 175 isb 176workaround_reset_end cortex_a510, ERRATUM(2080326) 177 178check_erratum_range cortex_a510, ERRATUM(2080326), CPU_REV(0, 2), CPU_REV(0, 2) 179 180workaround_reset_start cortex_a510, ERRATUM(2169012), ERRATA_A510_2169012 181 sysreg_bitfield_insert CORTEX_A510_CMPXACTLR_EL1, CORTEX_A510_CMPXACTLR_EL1_SNPPREFERUNIQUE_DISABLE, \ 182 CORTEX_A510_CMPXACTLR_EL1_SNPPREFERUNIQUE_SHIFT, CORTEX_A510_CMPXACTLR_EL1_SNPPREFERUNIQUE_WIDTH 183workaround_reset_end cortex_a510, ERRATUM(2169012) 184 185check_erratum_ls cortex_a510, ERRATUM(2169012), CPU_REV(1, 0) 186 187workaround_reset_start cortex_a510, ERRATUM(2172148), ERRATA_A510_2172148 188 /* 189 * Force L2 allocation of transient lines by setting 190 * CPUECTLR_EL1.RSCTL=0b01 and CPUECTLR_EL1.NTCTL=0b01. 191 */ 192 mrs x0, CORTEX_A510_CPUECTLR_EL1 193 mov x1, #1 194 bfi x0, x1, #CORTEX_A510_CPUECTLR_EL1_RSCTL_SHIFT, #2 195 bfi x0, x1, #CORTEX_A510_CPUECTLR_EL1_NTCTL_SHIFT, #2 196 msr CORTEX_A510_CPUECTLR_EL1, x0 197workaround_reset_end cortex_a510, ERRATUM(2172148) 198 199check_erratum_ls cortex_a510, ERRATUM(2172148), CPU_REV(1, 0) 200 201workaround_reset_start cortex_a510, ERRATUM(2218134), ERRATA_A510_2218134 202 sysreg_bit_set CORTEX_A510_CPUACTLR2_EL1, BIT(43) 203workaround_reset_end cortex_a510, ERRATUM(2218134) 204 205check_erratum_range cortex_a510, ERRATUM(2218134), CPU_REV(1, 0), CPU_REV(1, 0) 206 207workaround_reset_start cortex_a510, ERRATUM(2218950), ERRATA_A510_2218950 208 /* Set bit 18 in CPUACTLR_EL1 */ 209 sysreg_bitfield_insert CORTEX_A510_CPUACTLR_EL1, CORTEX_A510_CPUACTLR_EL1_ALIAS_LOADSTORE_DISABLE, \ 210 CORTEX_A510_CPUACTLR_EL1_ALIAS_LOADSTORE_SHIFT, CORTEX_A510_CPUACTLR_EL1_ALIAS_LOADSTORE_WIDTH 211 212 /* Set bit 25 in CMPXACTLR_EL1 */ 213 sysreg_bitfield_insert CORTEX_A510_CMPXACTLR_EL1, CORTEX_A510_CMPXACTLR_EL1_ALIAS_LOADSTORE_DISABLE, \ 214 CORTEX_A510_CMPXACTLR_EL1_ALIAS_LOADSTORE_SHIFT, CORTEX_A510_CMPXACTLR_EL1_ALIAS_LOADSTORE_WIDTH 215 216workaround_reset_end cortex_a510, ERRATUM(2218950) 217 218check_erratum_ls cortex_a510, ERRATUM(2218950), CPU_REV(1, 0) 219 220workaround_reset_start cortex_a510, ERRATUM(2250311), ERRATA_A510_2250311 221 /* Disable MPMM */ 222 mrs x0, CPUMPMMCR_EL3 223 bfm x0, xzr, #0, #0 /* bfc instruction does not work in GCC */ 224 msr CPUMPMMCR_EL3, x0 225workaround_reset_end cortex_a510, ERRATUM(2250311) 226 227check_erratum_ls cortex_a510, ERRATUM(2250311), CPU_REV(1, 0) 228 229workaround_reset_start cortex_a510, ERRATUM(2288014), ERRATA_A510_2288014 230 /* Apply the workaround by setting IMP_CPUACTLR_EL1[18] = 0b1. */ 231 sysreg_bitfield_insert CORTEX_A510_CPUACTLR_EL1, CORTEX_A510_CPUACTLR_EL1_DATA_CORRUPT_DISABLE, \ 232 CORTEX_A510_CPUACTLR_EL1_DATA_CORRUPT_SHIFT, CORTEX_A510_CPUACTLR_EL1_DATA_CORRUPT_WIDTH 233workaround_reset_end cortex_a510, ERRATUM(2288014) 234 235check_erratum_ls cortex_a510, ERRATUM(2288014), CPU_REV(1, 0) 236 237workaround_reset_start cortex_a510, ERRATUM(2313941), ERRATA_DSU_2313941 238 errata_dsu_2313941_wa_impl 239workaround_reset_end cortex_a510, ERRATUM(2313941) 240 241check_erratum_custom_start cortex_a510, ERRATUM(2313941) 242 check_errata_dsu_2313941_impl 243 ret 244check_erratum_custom_end cortex_a510, ERRATUM(2313941) 245 246workaround_reset_start cortex_a510, ERRATUM(2347730), ERRATA_A510_2347730 247 /* 248 * Set CPUACTLR_EL1[17] to 1'b1, which disables 249 * specific microarchitectural clock gating 250 * behaviour. 251 */ 252 sysreg_bit_set CORTEX_A510_CPUACTLR_EL1, CORTEX_A510_CPUACTLR_EL1_BIT_17 253workaround_reset_end cortex_a510, ERRATUM(2347730) 254 255check_erratum_ls cortex_a510, ERRATUM(2347730), CPU_REV(1, 1) 256 257workaround_reset_start cortex_a510, ERRATUM(2371937), ERRATA_A510_2371937 258 /* 259 * Cacheable atomic operations can be forced 260 * to be executed near by setting 261 * IMP_CPUECTLR_EL1.ATOM=0b010. ATOM is found 262 * in [40:38] of CPUECTLR_EL1. 263 */ 264 sysreg_bitfield_insert CORTEX_A510_CPUECTLR_EL1, CORTEX_A510_CPUECTLR_EL1_ATOM_EXECALLINSTRNEAR, \ 265 CORTEX_A510_CPUECTLR_EL1_ATOM_SHIFT, CORTEX_A510_CPUECTLR_EL1_ATOM_WIDTH 266workaround_reset_end cortex_a510, ERRATUM(2371937) 267 268check_erratum_ls cortex_a510, ERRATUM(2371937), CPU_REV(1, 1) 269 270workaround_reset_start cortex_a510, ERRATUM(2420992), ERRATA_A510_2420992 271 sysreg_bit_set CORTEX_A510_CPUACTLR3_EL1, BIT(3) 272workaround_reset_end cortex_a510, ERRATUM(2420992) 273 274check_erratum_range cortex_a510, ERRATUM(2420992), CPU_REV(1, 0), CPU_REV(1, 1) 275 276workaround_reset_start cortex_a510, ERRATUM(2666669), ERRATA_A510_2666669 277 sysreg_bit_set CORTEX_A510_CPUACTLR_EL1, CORTEX_A510_CPUACTLR_EL1_BIT_38 278workaround_reset_end cortex_a510, ERRATUM(2666669) 279 280check_erratum_ls cortex_a510, ERRATUM(2666669), CPU_REV(1, 1) 281 282.global erratum_cortex_a510_2684597_wa 283workaround_runtime_start cortex_a510, ERRATUM(2684597), ERRATA_A510_2684597, CORTEX_A510_MIDR 284 /* 285 * Many assemblers do not yet understand the "tsb csync" mnemonic, 286 * so use the equivalent hint instruction. 287 */ 288 hint #18 /* tsb csync */ 289workaround_runtime_end cortex_a510, ERRATUM(2684597) 290 291check_erratum_ls cortex_a510, ERRATUM(2684597), CPU_REV(1, 2) 292 293.global check_erratum_cortex_a510_2971420 294add_erratum_entry cortex_a510, ERRATUM(2971420), ERRATA_A510_2971420 295check_erratum_range cortex_a510, ERRATUM(2971420), CPU_REV(0, 1), CPU_REV(1, 3) 296 297workaround_reset_start cortex_a510, ERRATUM(3672349), ERRATA_A510_3672349 298 /* 299 * Disable retention control for WFI and WFE by clearing both RET_CTRL 300 * fields in CPUPWRCTLR_EL1. 301 */ 302 sysreg_bit_clear CORTEX_A510_CPUPWRCTLR_EL1, \ 303 (CORTEX_A510_CPUPWRCTLR_EL1_WFE_RET_CTRL_BITS | \ 304 CORTEX_A510_CPUPWRCTLR_EL1_WFI_RET_CTRL_BITS) 305workaround_reset_end cortex_a510, ERRATUM(3672349) 306 307check_erratum_ls cortex_a510, ERRATUM(3672349), CPU_REV(1, 3) 308 309workaround_reset_start cortex_a510, ERRATUM(3704847), ERRATA_A510_3704847 310 sysreg_bit_set CORTEX_A510_CPUACTLR_EL1, BIT(9) 311workaround_reset_end cortex_a510, ERRATUM(3704847) 312 313check_erratum_ls cortex_a510, ERRATUM(3704847), CPU_REV(1, 3) 314 315 /* ---------------------------------------------------- 316 * HW will do the cache maintenance while powering down 317 * ---------------------------------------------------- 318 */ 319func cortex_a510_core_pwr_dwn 320 apply_erratum cortex_a510, ERRATUM(2008766), ERRATA_A510_2008766 321 apply_erratum cortex_a510, ERRATUM(2684597), ERRATA_A510_2684597, NO_GET_CPU_REV 322 /* --------------------------------------------------- 323 * Enable CPU power down bit in power control register 324 * --------------------------------------------------- 325 */ 326 sysreg_bit_set CORTEX_A510_CPUPWRCTLR_EL1, CORTEX_A510_CPUPWRCTLR_EL1_CORE_PWRDN_BIT 327 isb 328 ret 329endfunc cortex_a510_core_pwr_dwn 330 331cpu_reset_func_start cortex_a510 332 /* Disable speculative loads */ 333 msr SSBS, xzr 334 /* skip enabling MPMM if this erratum is present */ 335#if ERRATA_A510_2250311 336 /* the cpu_rev_var is kept in x14 */ 337 mov x14, x0 338 bl check_erratum_cortex_a510_2250311 339 cbz x0, skip_mpmm 340#endif 341 enable_mpmm 342skip_mpmm: 343cpu_reset_func_end cortex_a510 344 345 /* --------------------------------------------- 346 * This function provides Cortex-A510 specific 347 * register information for crash reporting. 348 * It needs to return with x6 pointing to 349 * a list of register names in ascii and 350 * x8 - x15 having values of registers to be 351 * reported. 352 * --------------------------------------------- 353 */ 354.section .rodata.cortex_a510_regs, "aS" 355cortex_a510_regs: /* The ascii list of register names to be reported */ 356 .asciz "cpuectlr_el1", "" 357 358func cortex_a510_cpu_reg_dump 359 adr x6, cortex_a510_regs 360 mrs x8, CORTEX_A510_CPUECTLR_EL1 361 ret 362endfunc cortex_a510_cpu_reg_dump 363 364declare_cpu_ops cortex_a510, CORTEX_A510_MIDR, \ 365 cortex_a510_reset_func, \ 366 cortex_a510_core_pwr_dwn 367