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