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