xref: /rk3399_ARM-atf/lib/cpus/aarch64/cortex_a57.S (revision 06f3c7058c42a9f1a9f7df75ea2de71a000855e8)
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/* Erratum entry and check function for SMCCC_ARCH_WORKAROUND_3 */
69add_erratum_entry cortex_a57, ERRATUM(ARCH_WORKAROUND_3), WORKAROUND_CVE_2022_23960
70
71check_erratum_chosen cortex_a57, ERRATUM(ARCH_WORKAROUND_3), WORKAROUND_CVE_2022_23960
72
73/*
74 * Disable the over-read from the LDNP/STNP instruction. The SDEN doesn't
75 * provide and erratum number, so assign it an obvious 99999
76 */
77workaround_reset_start cortex_a57, ERRATUM(99999), A57_DISABLE_NON_TEMPORAL_HINT
78	sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_DIS_OVERREAD
79workaround_reset_end cortex_a57, ERRATUM(99999)
80
81check_erratum_ls cortex_a57, ERRATUM(99999), CPU_REV(1, 2)
82
83workaround_reset_start cortex_a57, ERRATUM(806969), ERRATA_A57_806969
84	sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_NO_ALLOC_WBWA
85workaround_reset_end cortex_a57, ERRATUM(806969)
86
87check_erratum_ls cortex_a57, ERRATUM(806969), CPU_REV(0, 0)
88
89/* erratum always worked around, but report it correctly */
90check_erratum_ls cortex_a57, ERRATUM(813419), CPU_REV(0, 0)
91add_erratum_entry cortex_a57, ERRATUM(813419), ERRATUM_ALWAYS_CHOSEN
92
93workaround_reset_start cortex_a57, ERRATUM(813420), ERRATA_A57_813420
94	sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_DCC_AS_DCCI
95workaround_reset_end cortex_a57, ERRATUM(813420)
96
97check_erratum_ls cortex_a57, ERRATUM(813420), CPU_REV(0, 0)
98
99workaround_reset_start cortex_a57, ERRATUM(814670), ERRATA_A57_814670
100	sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_DIS_DMB_NULLIFICATION
101workaround_reset_end cortex_a57, ERRATUM(814670)
102
103check_erratum_ls cortex_a57, ERRATUM(814670), CPU_REV(0, 0)
104
105workaround_runtime_start cortex_a57, ERRATUM(817169), ERRATA_A57_817169
106	/* Invalidate any TLB address */
107	mov	x0, #0
108	tlbi	vae3, x0
109workaround_runtime_end cortex_a57, ERRATUM(817169), NO_ISB
110
111check_erratum_ls cortex_a57, ERRATUM(817169), CPU_REV(0, 1)
112
113workaround_reset_start cortex_a57, ERRATUM(826974), ERRATA_A57_826974
114	sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_DIS_LOAD_PASS_DMB
115workaround_reset_end cortex_a57, ERRATUM(826974)
116
117check_erratum_ls cortex_a57, ERRATUM(826974), CPU_REV(1, 1)
118
119workaround_reset_start cortex_a57, ERRATUM(826977), ERRATA_A57_826977
120	sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_GRE_NGRE_AS_NGNRE
121workaround_reset_end cortex_a57, ERRATUM(826977)
122
123check_erratum_ls cortex_a57, ERRATUM(826977), CPU_REV(1, 1)
124
125workaround_reset_start cortex_a57, ERRATUM(828024), ERRATA_A57_828024
126	mrs	x1, CORTEX_A57_CPUACTLR_EL1
127	/*
128	 * Setting the relevant bits in CPUACTLR_EL1 has to be done in 2
129	 * instructions here because the resulting bitmask doesn't fit in a
130	 * 16-bit value so it cannot be encoded in a single instruction.
131	 */
132	orr	x1, x1, #CORTEX_A57_CPUACTLR_EL1_NO_ALLOC_WBWA
133	orr	x1, x1, #(CORTEX_A57_CPUACTLR_EL1_DIS_L1_STREAMING | \
134			  CORTEX_A57_CPUACTLR_EL1_DIS_STREAMING)
135	msr	CORTEX_A57_CPUACTLR_EL1, x1
136workaround_reset_end cortex_a57, ERRATUM(828024)
137
138check_erratum_ls cortex_a57, ERRATUM(828024), CPU_REV(1, 1)
139
140workaround_reset_start cortex_a57, ERRATUM(829520), ERRATA_A57_829520
141	sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_DIS_INDIRECT_PREDICTOR
142workaround_reset_end cortex_a57, ERRATUM(829520)
143
144check_erratum_ls cortex_a57, ERRATUM(829520), CPU_REV(1, 2)
145
146workaround_reset_start cortex_a57, ERRATUM(833471), ERRATA_A57_833471
147	sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_FORCE_FPSCR_FLUSH
148workaround_reset_end cortex_a57, ERRATUM(833471)
149
150check_erratum_ls cortex_a57, ERRATUM(833471), CPU_REV(1, 2)
151
152workaround_reset_start cortex_a57, ERRATUM(859972), ERRATA_A57_859972
153	sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_DIS_INSTR_PREFETCH
154workaround_reset_end cortex_a57, ERRATUM(859972)
155
156check_erratum_ls cortex_a57, ERRATUM(859972), CPU_REV(1, 3)
157
158check_erratum_chosen cortex_a57, ERRATUM(1319537), ERRATA_A57_1319537
159/* erratum has no workaround in the cpu. Generic code must take care */
160add_erratum_entry cortex_a57, ERRATUM(1319537), ERRATA_A57_1319537
161
162workaround_reset_start cortex_a57, CVE(2017, 5715), WORKAROUND_CVE_2017_5715
163#if IMAGE_BL31
164	override_vector_table wa_cve_2017_5715_mmu_vbar
165#endif
166workaround_reset_end cortex_a57, CVE(2017, 5715)
167
168check_erratum_chosen cortex_a57, CVE(2017, 5715), WORKAROUND_CVE_2017_5715
169
170workaround_reset_start cortex_a57, CVE(2018, 3639), WORKAROUND_CVE_2018_3639
171	sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_DIS_LOAD_PASS_STORE
172	isb
173	dsb	sy
174workaround_reset_end cortex_a57, CVE(2018, 3639)
175
176check_erratum_chosen cortex_a57, CVE(2018, 3639), WORKAROUND_CVE_2018_3639
177
178workaround_reset_start cortex_a57, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
179#if IMAGE_BL31
180	override_vector_table wa_cve_2017_5715_mmu_vbar
181#endif
182workaround_reset_end cortex_a57, CVE(2022, 23960)
183
184check_erratum_chosen cortex_a57, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
185
186cpu_reset_func_start cortex_a57
187#if A57_ENABLE_NONCACHEABLE_LOAD_FWD
188	/* Enable higher performance non-cacheable load forwarding */
189	sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_EN_NC_LOAD_FWD
190#endif
191	/* Enable the SMP bit. */
192	sysreg_bit_set CORTEX_A57_ECTLR_EL1, CORTEX_A57_ECTLR_SMP_BIT
193cpu_reset_func_end cortex_a57
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 cortex_a57, CORTEX_A57_MIDR, \
311	cortex_a57_reset_func, \
312	cortex_a57_core_pwr_dwn, \
313	cortex_a57_cluster_pwr_dwn
314