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