1/* 2 * Copyright (c) 2023-2025, 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_runtime_start cortex_a510, ERRATUM(2008766), ERRATA_A510_2008766 28 /* Stash ERRSELR_EL1 in x2 */ 29 mrs x2, ERRSELR_EL1 30 31 /* Select error record 0 and clear ED bit */ 32 msr ERRSELR_EL1, xzr 33 sysreg_bit_clear ERXCTLR_EL1, ERXCTLR_ED_BIT 34 35 /* Select error record 1 and clear ED bit */ 36 mov x0, #1 37 msr ERRSELR_EL1, x0 38 sysreg_bit_clear ERXCTLR_EL1, ERXCTLR_ED_BIT 39 40 /* Select error record 2 and clear ED bit */ 41 mov x0, #2 42 msr ERRSELR_EL1, x0 43 sysreg_bit_clear ERXCTLR_EL1, ERXCTLR_ED_BIT 44 45 /* Restore ERRSELR_EL1 from x2 */ 46 msr ERRSELR_EL1, x2 47workaround_runtime_end cortex_a510, ERRATUM(2008766), NO_ISB 48 49check_erratum_ls cortex_a510, ERRATUM(2008766), CPU_REV(1, 3) 50 51workaround_reset_start cortex_a510, ERRATUM(2041909), ERRATA_A510_2041909 52 /* Apply workaround */ 53 mov x0, xzr 54 msr S3_6_C15_C4_0, x0 55 isb 56 57 mov x0, #0x8500000 58 msr S3_6_C15_C4_2, x0 59 60 mov x0, #0x1F700000 61 movk x0, #0x8, lsl #32 62 msr S3_6_C15_C4_3, x0 63 64 mov x0, #0x3F1 65 movk x0, #0x110, lsl #16 66 msr S3_6_C15_C4_1, x0 67workaround_reset_end cortex_a510, ERRATUM(2041909) 68 69check_erratum_range cortex_a510, ERRATUM(2041909), CPU_REV(0, 2), CPU_REV(0, 2) 70 71workaround_reset_start cortex_a510, ERRATUM(2042739), ERRATA_A510_2042739 72 /* Apply the workaround by disabling ReadPreferUnique. */ 73 sysreg_bitfield_insert CORTEX_A510_CPUECTLR_EL1, CORTEX_A510_CPUECTLR_EL1_READPREFERUNIQUE_DISABLE, \ 74 CORTEX_A510_CPUECTLR_EL1_READPREFERUNIQUE_SHIFT, CORTEX_A510_CPUECTLR_EL1_READPREFERUNIQUE_WIDTH 75workaround_reset_end cortex_a510, ERRATUM(2042739) 76 77check_erratum_ls cortex_a510, ERRATUM(2042739), CPU_REV(0, 2) 78 79workaround_reset_start cortex_a510, ERRATUM(2080326), ERRATA_A510_2080326 80 /* Apply workaround */ 81 mov x0, #1 82 msr S3_6_C15_C4_0, x0 83 isb 84 85 mov x0, #0x0100 86 movk x0, #0x0E08, lsl #16 87 msr S3_6_C15_C4_2, x0 88 89 mov x0, #0x0300 90 movk x0, #0x0F1F, lsl #16 91 movk x0, #0x0008, lsl #32 92 msr S3_6_C15_C4_3, x0 93 94 mov x0, #0x03F1 95 movk x0, #0x00C0, lsl #16 96 msr S3_6_C15_C4_1, x0 97 98 isb 99workaround_reset_end cortex_a510, ERRATUM(2080326) 100 101check_erratum_range cortex_a510, ERRATUM(2080326), CPU_REV(0, 2), CPU_REV(0, 2) 102 103workaround_reset_start cortex_a510, ERRATUM(2169012), ERRATA_A510_2169012 104 sysreg_bitfield_insert CORTEX_A510_CMPXACTLR_EL1, CORTEX_A510_CMPXACTLR_EL1_SNPPREFERUNIQUE_DISABLE, \ 105 CORTEX_A510_CMPXACTLR_EL1_SNPPREFERUNIQUE_SHIFT, CORTEX_A510_CMPXACTLR_EL1_SNPPREFERUNIQUE_WIDTH 106workaround_reset_end cortex_a510, ERRATUM(2169012) 107 108check_erratum_ls cortex_a510, ERRATUM(2169012), CPU_REV(1, 0) 109 110workaround_reset_start cortex_a510, ERRATUM(2172148), ERRATA_A510_2172148 111 /* 112 * Force L2 allocation of transient lines by setting 113 * CPUECTLR_EL1.RSCTL=0b01 and CPUECTLR_EL1.NTCTL=0b01. 114 */ 115 mrs x0, CORTEX_A510_CPUECTLR_EL1 116 mov x1, #1 117 bfi x0, x1, #CORTEX_A510_CPUECTLR_EL1_RSCTL_SHIFT, #2 118 bfi x0, x1, #CORTEX_A510_CPUECTLR_EL1_NTCTL_SHIFT, #2 119 msr CORTEX_A510_CPUECTLR_EL1, x0 120workaround_reset_end cortex_a510, ERRATUM(2172148) 121 122check_erratum_ls cortex_a510, ERRATUM(2172148), CPU_REV(1, 0) 123 124workaround_reset_start cortex_a510, ERRATUM(2218134), ERRATA_A510_2218134 125 sysreg_bit_set CORTEX_A510_CPUACTLR2_EL1, BIT(43) 126workaround_reset_end cortex_a510, ERRATUM(2218134) 127 128check_erratum_range cortex_a510, ERRATUM(2218134), CPU_REV(1, 0), CPU_REV(1, 0) 129 130workaround_reset_start cortex_a510, ERRATUM(2218950), ERRATA_A510_2218950 131 /* Set bit 18 in CPUACTLR_EL1 */ 132 sysreg_bitfield_insert CORTEX_A510_CPUACTLR_EL1, CORTEX_A510_CPUACTLR_EL1_ALIAS_LOADSTORE_DISABLE, \ 133 CORTEX_A510_CPUACTLR_EL1_ALIAS_LOADSTORE_SHIFT, CORTEX_A510_CPUACTLR_EL1_ALIAS_LOADSTORE_WIDTH 134 135 /* Set bit 25 in CMPXACTLR_EL1 */ 136 sysreg_bitfield_insert CORTEX_A510_CMPXACTLR_EL1, CORTEX_A510_CMPXACTLR_EL1_ALIAS_LOADSTORE_DISABLE, \ 137 CORTEX_A510_CMPXACTLR_EL1_ALIAS_LOADSTORE_SHIFT, CORTEX_A510_CMPXACTLR_EL1_ALIAS_LOADSTORE_WIDTH 138 139workaround_reset_end cortex_a510, ERRATUM(2218950) 140 141check_erratum_ls cortex_a510, ERRATUM(2218950), CPU_REV(1, 0) 142 143workaround_reset_start cortex_a510, ERRATUM(2250311), ERRATA_A510_2250311 144 /* Disable MPMM */ 145 mrs x0, CPUMPMMCR_EL3 146 bfm x0, xzr, #0, #0 /* bfc instruction does not work in GCC */ 147 msr CPUMPMMCR_EL3, x0 148workaround_reset_end cortex_a510, ERRATUM(2250311) 149 150check_erratum_ls cortex_a510, ERRATUM(2250311), CPU_REV(1, 0) 151 152workaround_reset_start cortex_a510, ERRATUM(2288014), ERRATA_A510_2288014 153 /* Apply the workaround by setting IMP_CPUACTLR_EL1[18] = 0b1. */ 154 sysreg_bitfield_insert CORTEX_A510_CPUACTLR_EL1, CORTEX_A510_CPUACTLR_EL1_DATA_CORRUPT_DISABLE, \ 155 CORTEX_A510_CPUACTLR_EL1_DATA_CORRUPT_SHIFT, CORTEX_A510_CPUACTLR_EL1_DATA_CORRUPT_WIDTH 156workaround_reset_end cortex_a510, ERRATUM(2288014) 157 158check_erratum_ls cortex_a510, ERRATUM(2288014), CPU_REV(1, 0) 159 160workaround_reset_start cortex_a510, ERRATUM(2313941), ERRATA_DSU_2313941 161 errata_dsu_2313941_wa_impl 162workaround_reset_end cortex_a510, ERRATUM(2313941) 163 164check_erratum_custom_start cortex_a510, ERRATUM(2313941) 165 check_errata_dsu_2313941_impl 166 ret 167check_erratum_custom_end cortex_a510, ERRATUM(2313941) 168 169workaround_reset_start cortex_a510, ERRATUM(2347730), ERRATA_A510_2347730 170 /* 171 * Set CPUACTLR_EL1[17] to 1'b1, which disables 172 * specific microarchitectural clock gating 173 * behaviour. 174 */ 175 sysreg_bit_set CORTEX_A510_CPUACTLR_EL1, CORTEX_A510_CPUACTLR_EL1_BIT_17 176workaround_reset_end cortex_a510, ERRATUM(2347730) 177 178check_erratum_ls cortex_a510, ERRATUM(2347730), CPU_REV(1, 1) 179 180workaround_reset_start cortex_a510, ERRATUM(2371937), ERRATA_A510_2371937 181 /* 182 * Cacheable atomic operations can be forced 183 * to be executed near by setting 184 * IMP_CPUECTLR_EL1.ATOM=0b010. ATOM is found 185 * in [40:38] of CPUECTLR_EL1. 186 */ 187 sysreg_bitfield_insert CORTEX_A510_CPUECTLR_EL1, CORTEX_A510_CPUECTLR_EL1_ATOM_EXECALLINSTRNEAR, \ 188 CORTEX_A510_CPUECTLR_EL1_ATOM_SHIFT, CORTEX_A510_CPUECTLR_EL1_ATOM_WIDTH 189workaround_reset_end cortex_a510, ERRATUM(2371937) 190 191check_erratum_ls cortex_a510, ERRATUM(2371937), CPU_REV(1, 1) 192 193workaround_reset_start cortex_a510, ERRATUM(2420992), ERRATA_A510_2420992 194 sysreg_bit_set CORTEX_A510_CPUACTLR3_EL1, BIT(3) 195workaround_reset_end cortex_a510, ERRATUM(2420992) 196 197check_erratum_range cortex_a510, ERRATUM(2420992), CPU_REV(1, 0), CPU_REV(1, 1) 198 199workaround_reset_start cortex_a510, ERRATUM(2666669), ERRATA_A510_2666669 200 sysreg_bit_set CORTEX_A510_CPUACTLR_EL1, CORTEX_A510_CPUACTLR_EL1_BIT_38 201workaround_reset_end cortex_a510, ERRATUM(2666669) 202 203check_erratum_ls cortex_a510, ERRATUM(2666669), CPU_REV(1, 1) 204 205.global erratum_cortex_a510_2684597_wa 206workaround_runtime_start cortex_a510, ERRATUM(2684597), ERRATA_A510_2684597, CORTEX_A510_MIDR 207 /* 208 * Many assemblers do not yet understand the "tsb csync" mnemonic, 209 * so use the equivalent hint instruction. 210 */ 211 hint #18 /* tsb csync */ 212workaround_runtime_end cortex_a510, ERRATUM(2684597) 213 214check_erratum_ls cortex_a510, ERRATUM(2684597), CPU_REV(1, 2) 215 216.global check_erratum_cortex_a510_2971420 217add_erratum_entry cortex_a510, ERRATUM(2971420), ERRATA_A510_2971420 218check_erratum_range cortex_a510, ERRATUM(2971420), CPU_REV(0, 1), CPU_REV(1, 3) 219 220workaround_reset_start cortex_a510, ERRATUM(3672349), ERRATA_A510_3672349 221 /* 222 * Disable retention control for WFI and WFE by clearing both RET_CTRL 223 * fields in CPUPWRCTLR_EL1. 224 */ 225 sysreg_bit_clear CORTEX_A510_CPUPWRCTLR_EL1, \ 226 (CORTEX_A510_CPUPWRCTLR_EL1_WFE_RET_CTRL_BITS | \ 227 CORTEX_A510_CPUPWRCTLR_EL1_WFI_RET_CTRL_BITS) 228workaround_reset_end cortex_a510, ERRATUM(3672349) 229 230check_erratum_ls cortex_a510, ERRATUM(3672349), CPU_REV(1, 3) 231 232workaround_reset_start cortex_a510, ERRATUM(3704847), ERRATA_A510_3704847 233 sysreg_bit_set CORTEX_A510_CPUACTLR_EL1, BIT(9) 234workaround_reset_end cortex_a510, ERRATUM(3704847) 235 236check_erratum_ls cortex_a510, ERRATUM(3704847), CPU_REV(1, 3) 237 238 /* ---------------------------------------------------- 239 * HW will do the cache maintenance while powering down 240 * ---------------------------------------------------- 241 */ 242func cortex_a510_core_pwr_dwn 243 apply_erratum cortex_a510, ERRATUM(2008766), ERRATA_A510_2008766 244 apply_erratum cortex_a510, ERRATUM(2684597), ERRATA_A510_2684597, NO_GET_CPU_REV 245 /* --------------------------------------------------- 246 * Enable CPU power down bit in power control register 247 * --------------------------------------------------- 248 */ 249 sysreg_bit_set CORTEX_A510_CPUPWRCTLR_EL1, CORTEX_A510_CPUPWRCTLR_EL1_CORE_PWRDN_BIT 250 isb 251 ret 252endfunc cortex_a510_core_pwr_dwn 253 254cpu_reset_func_start cortex_a510 255 /* Disable speculative loads */ 256 msr SSBS, xzr 257 /* skip enabling MPMM if this erratum is present */ 258#if ERRATA_A510_2250311 259 /* the cpu_rev_var is kept in x14 */ 260 mov x14, x0 261 bl check_erratum_cortex_a510_2250311 262 cbz x0, skip_mpmm 263#endif 264 enable_mpmm 265skip_mpmm: 266cpu_reset_func_end cortex_a510 267 268 /* --------------------------------------------- 269 * This function provides Cortex-A510 specific 270 * register information for crash reporting. 271 * It needs to return with x6 pointing to 272 * a list of register names in ascii and 273 * x8 - x15 having values of registers to be 274 * reported. 275 * --------------------------------------------- 276 */ 277.section .rodata.cortex_a510_regs, "aS" 278cortex_a510_regs: /* The ascii list of register names to be reported */ 279 .asciz "cpuectlr_el1", "" 280 281func cortex_a510_cpu_reg_dump 282 adr x6, cortex_a510_regs 283 mrs x8, CORTEX_A510_CPUECTLR_EL1 284 ret 285endfunc cortex_a510_cpu_reg_dump 286 287declare_cpu_ops cortex_a510, CORTEX_A510_MIDR, \ 288 cortex_a510_reset_func, \ 289 cortex_a510_core_pwr_dwn 290