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