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(2218950), ERRATA_A510_2218950 125 /* Set bit 18 in CPUACTLR_EL1 */ 126 sysreg_bitfield_insert CORTEX_A510_CPUACTLR_EL1, CORTEX_A510_CPUACTLR_EL1_ALIAS_LOADSTORE_DISABLE, \ 127 CORTEX_A510_CPUACTLR_EL1_ALIAS_LOADSTORE_SHIFT, CORTEX_A510_CPUACTLR_EL1_ALIAS_LOADSTORE_WIDTH 128 129 /* Set bit 25 in CMPXACTLR_EL1 */ 130 sysreg_bitfield_insert CORTEX_A510_CMPXACTLR_EL1, CORTEX_A510_CMPXACTLR_EL1_ALIAS_LOADSTORE_DISABLE, \ 131 CORTEX_A510_CMPXACTLR_EL1_ALIAS_LOADSTORE_SHIFT, CORTEX_A510_CMPXACTLR_EL1_ALIAS_LOADSTORE_WIDTH 132 133workaround_reset_end cortex_a510, ERRATUM(2218950) 134 135check_erratum_ls cortex_a510, ERRATUM(2218950), CPU_REV(1, 0) 136 137workaround_reset_start cortex_a510, ERRATUM(2250311), ERRATA_A510_2250311 138 /* Disable MPMM */ 139 mrs x0, CPUMPMMCR_EL3 140 bfm x0, xzr, #0, #0 /* bfc instruction does not work in GCC */ 141 msr CPUMPMMCR_EL3, x0 142workaround_reset_end cortex_a510, ERRATUM(2250311) 143 144check_erratum_ls cortex_a510, ERRATUM(2250311), CPU_REV(1, 0) 145 146workaround_reset_start cortex_a510, ERRATUM(2288014), ERRATA_A510_2288014 147 /* Apply the workaround by setting IMP_CPUACTLR_EL1[18] = 0b1. */ 148 sysreg_bitfield_insert CORTEX_A510_CPUACTLR_EL1, CORTEX_A510_CPUACTLR_EL1_DATA_CORRUPT_DISABLE, \ 149 CORTEX_A510_CPUACTLR_EL1_DATA_CORRUPT_SHIFT, CORTEX_A510_CPUACTLR_EL1_DATA_CORRUPT_WIDTH 150workaround_reset_end cortex_a510, ERRATUM(2288014) 151 152check_erratum_ls cortex_a510, ERRATUM(2288014), CPU_REV(1, 0) 153 154workaround_reset_start cortex_a510, ERRATUM(2313941), ERRATA_DSU_2313941 155 errata_dsu_2313941_wa_impl 156workaround_reset_end cortex_a510, ERRATUM(2313941) 157 158check_erratum_custom_start cortex_a510, ERRATUM(2313941) 159 check_errata_dsu_2313941_impl 160 ret 161check_erratum_custom_end cortex_a510, ERRATUM(2313941) 162 163workaround_reset_start cortex_a510, ERRATUM(2347730), ERRATA_A510_2347730 164 /* 165 * Set CPUACTLR_EL1[17] to 1'b1, which disables 166 * specific microarchitectural clock gating 167 * behaviour. 168 */ 169 sysreg_bit_set CORTEX_A510_CPUACTLR_EL1, CORTEX_A510_CPUACTLR_EL1_BIT_17 170workaround_reset_end cortex_a510, ERRATUM(2347730) 171 172check_erratum_ls cortex_a510, ERRATUM(2347730), CPU_REV(1, 1) 173 174workaround_reset_start cortex_a510, ERRATUM(2371937), ERRATA_A510_2371937 175 /* 176 * Cacheable atomic operations can be forced 177 * to be executed near by setting 178 * IMP_CPUECTLR_EL1.ATOM=0b010. ATOM is found 179 * in [40:38] of CPUECTLR_EL1. 180 */ 181 sysreg_bitfield_insert CORTEX_A510_CPUECTLR_EL1, CORTEX_A510_CPUECTLR_EL1_ATOM_EXECALLINSTRNEAR, \ 182 CORTEX_A510_CPUECTLR_EL1_ATOM_SHIFT, CORTEX_A510_CPUECTLR_EL1_ATOM_WIDTH 183workaround_reset_end cortex_a510, ERRATUM(2371937) 184 185check_erratum_ls cortex_a510, ERRATUM(2371937), CPU_REV(1, 1) 186 187workaround_reset_start cortex_a510, ERRATUM(2666669), ERRATA_A510_2666669 188 sysreg_bit_set CORTEX_A510_CPUACTLR_EL1, CORTEX_A510_CPUACTLR_EL1_BIT_38 189workaround_reset_end cortex_a510, ERRATUM(2666669) 190 191check_erratum_ls cortex_a510, ERRATUM(2666669), CPU_REV(1, 1) 192 193.global erratum_cortex_a510_2684597_wa 194workaround_runtime_start cortex_a510, ERRATUM(2684597), ERRATA_A510_2684597, CORTEX_A510_MIDR 195 /* 196 * Many assemblers do not yet understand the "tsb csync" mnemonic, 197 * so use the equivalent hint instruction. 198 */ 199 hint #18 /* tsb csync */ 200workaround_runtime_end cortex_a510, ERRATUM(2684597) 201 202check_erratum_ls cortex_a510, ERRATUM(2684597), CPU_REV(1, 2) 203 204.global check_erratum_cortex_a510_2971420 205add_erratum_entry cortex_a510, ERRATUM(2971420), ERRATA_A510_2971420 206check_erratum_range cortex_a510, ERRATUM(2971420), CPU_REV(0, 1), CPU_REV(1, 3) 207 208 /* ---------------------------------------------------- 209 * HW will do the cache maintenance while powering down 210 * ---------------------------------------------------- 211 */ 212func cortex_a510_core_pwr_dwn 213 apply_erratum cortex_a510, ERRATUM(2008766), ERRATA_A510_2008766 214 apply_erratum cortex_a510, ERRATUM(2684597), ERRATA_A510_2684597, NO_GET_CPU_REV 215 /* --------------------------------------------------- 216 * Enable CPU power down bit in power control register 217 * --------------------------------------------------- 218 */ 219 sysreg_bit_set CORTEX_A510_CPUPWRCTLR_EL1, CORTEX_A510_CPUPWRCTLR_EL1_CORE_PWRDN_BIT 220 isb 221 ret 222endfunc cortex_a510_core_pwr_dwn 223 224cpu_reset_func_start cortex_a510 225 /* Disable speculative loads */ 226 msr SSBS, xzr 227 /* skip enabling MPMM if this erratum is present */ 228#if ERRATA_A510_2250311 229 /* the cpu_rev_var is kept in x14 */ 230 mov x14, x0 231 bl check_erratum_cortex_a510_2250311 232 cbz x0, skip_mpmm 233#endif 234 enable_mpmm 235skip_mpmm: 236cpu_reset_func_end cortex_a510 237 238 /* --------------------------------------------- 239 * This function provides Cortex-A510 specific 240 * register information for crash reporting. 241 * It needs to return with x6 pointing to 242 * a list of register names in ascii and 243 * x8 - x15 having values of registers to be 244 * reported. 245 * --------------------------------------------- 246 */ 247.section .rodata.cortex_a510_regs, "aS" 248cortex_a510_regs: /* The ascii list of register names to be reported */ 249 .asciz "cpuectlr_el1", "" 250 251func cortex_a510_cpu_reg_dump 252 adr x6, cortex_a510_regs 253 mrs x8, CORTEX_A510_CPUECTLR_EL1 254 ret 255endfunc cortex_a510_cpu_reg_dump 256 257declare_cpu_ops cortex_a510, CORTEX_A510_MIDR, \ 258 cortex_a510_reset_func, \ 259 cortex_a510_core_pwr_dwn 260