xref: /rk3399_ARM-atf/lib/cpus/aarch64/neoverse_v1.S (revision 7f798aaa3ea7bed86876fbbc18ce0097814964ff)
1/*
2 * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <arch.h>
8#include <asm_macros.S>
9#include <common/bl_common.h>
10#include <neoverse_v1.h>
11#include <cpu_macros.S>
12#include <plat_macros.S>
13#include "wa_cve_2022_23960_bhb_vector.S"
14
15/* Hardware handled coherency */
16#if HW_ASSISTED_COHERENCY == 0
17#error "Neoverse V1 must be compiled with HW_ASSISTED_COHERENCY enabled"
18#endif
19
20/* 64-bit only core */
21#if CTX_INCLUDE_AARCH32_REGS == 1
22#error "Neoverse-V1 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
23#endif
24
25#if WORKAROUND_CVE_2022_23960
26	wa_cve_2022_23960_bhb_vector_table NEOVERSE_V1_BHB_LOOP_COUNT, neoverse_v1
27#endif /* WORKAROUND_CVE_2022_23960 */
28
29workaround_reset_start neoverse_v1, ERRATUM(1618635), ERRATA_V1_1618635
30	/* Inserts a DMB SY before and after MRS PAR_EL1 */
31	ldr	x0, =0x0
32	msr	NEOVERSE_V1_CPUPSELR_EL3, x0
33	ldr	x0, = 0xEE070F14
34	msr	NEOVERSE_V1_CPUPOR_EL3, x0
35	ldr	x0, = 0xFFFF0FFF
36	msr	NEOVERSE_V1_CPUPMR_EL3, x0
37	ldr	x0, =0x4005027FF
38	msr	NEOVERSE_V1_CPUPCR_EL3, x0
39
40	/* Inserts a DMB SY before STREX imm offset */
41	ldr	x0, =0x1
42	msr	NEOVERSE_V1_CPUPSELR_EL3, x0
43	ldr	x0, =0x00e8400000
44	msr	NEOVERSE_V1_CPUPOR_EL3, x0
45	ldr	x0, =0x00fff00000
46	msr	NEOVERSE_V1_CPUPMR_EL3, x0
47	ldr	x0, = 0x4001027FF
48	msr	NEOVERSE_V1_CPUPCR_EL3, x0
49
50	/* Inserts a DMB SY before STREX[BHD}/STLEX* */
51	ldr	x0, =0x2
52	msr	NEOVERSE_V1_CPUPSELR_EL3, x0
53	ldr	x0, =0x00e8c00040
54	msr	NEOVERSE_V1_CPUPOR_EL3, x0
55	ldr	x0, =0x00fff00040
56	msr	NEOVERSE_V1_CPUPMR_EL3, x0
57	ldr	x0, = 0x4001027FF
58	msr	NEOVERSE_V1_CPUPCR_EL3, x0
59
60	/* Inserts a DMB SY after STREX imm offset */
61	ldr	x0, =0x3
62	msr	NEOVERSE_V1_CPUPSELR_EL3, x0
63	ldr	x0, =0x00e8400000
64	msr	NEOVERSE_V1_CPUPOR_EL3, x0
65	ldr	x0, =0x00fff00000
66	msr	NEOVERSE_V1_CPUPMR_EL3, x0
67	ldr	x0, = 0x4004027FF
68	msr	NEOVERSE_V1_CPUPCR_EL3, x0
69
70	/* Inserts a DMB SY after STREX[BHD}/STLEX* */
71	ldr	x0, =0x4
72	msr	NEOVERSE_V1_CPUPSELR_EL3, x0
73	ldr	x0, =0x00e8c00040
74	msr	NEOVERSE_V1_CPUPOR_EL3, x0
75	ldr	x0, =0x00fff00040
76	msr	NEOVERSE_V1_CPUPMR_EL3, x0
77	ldr	x0, = 0x4004027FF
78	msr	NEOVERSE_V1_CPUPCR_EL3, x0
79
80workaround_reset_end neoverse_v1, ERRATUM(1618635)
81
82check_erratum_ls neoverse_v1, ERRATUM(1618635), CPU_REV(0, 0)
83
84workaround_reset_start neoverse_v1, ERRATUM(1774420), ERRATA_V1_1774420
85	/* Set bit 53 in CPUECTLR_EL1 */
86	mrs     x1, NEOVERSE_V1_CPUECTLR_EL1
87	orr	x1, x1, #NEOVERSE_V1_CPUECTLR_EL1_BIT_53
88	msr     NEOVERSE_V1_CPUECTLR_EL1, x1
89workaround_reset_end neoverse_v1, ERRATUM(1774420)
90
91check_erratum_ls neoverse_v1, ERRATUM(1774420), CPU_REV(1, 0)
92
93workaround_reset_start neoverse_v1, ERRATUM(1791573), ERRATA_V1_1791573
94	/* Set bit 2 in ACTLR2_EL1 */
95	mrs	x1, NEOVERSE_V1_ACTLR2_EL1
96	orr	x1, x1, #NEOVERSE_V1_ACTLR2_EL1_BIT_2
97	msr	NEOVERSE_V1_ACTLR2_EL1, x1
98workaround_reset_end neoverse_v1, ERRATUM(1791573)
99
100check_erratum_ls neoverse_v1, ERRATUM(1791573), CPU_REV(1, 0)
101
102workaround_reset_start neoverse_v1, ERRATUM(1852267), ERRATA_V1_1852267
103	/* Set bit 28 in ACTLR2_EL1 */
104	mrs	x1, NEOVERSE_V1_ACTLR2_EL1
105	orr	x1, x1, #NEOVERSE_V1_ACTLR2_EL1_BIT_28
106	msr	NEOVERSE_V1_ACTLR2_EL1, x1
107workaround_reset_end neoverse_v1, ERRATUM(1852267)
108
109check_erratum_ls neoverse_v1, ERRATUM(1852267), CPU_REV(1, 0)
110
111workaround_reset_start neoverse_v1, ERRATUM(1925756), ERRATA_V1_1925756
112	/* Set bit 8 in CPUECTLR_EL1 */
113	mrs	x1, NEOVERSE_V1_CPUECTLR_EL1
114	orr	x1, x1, #NEOVERSE_V1_CPUECTLR_EL1_BIT_8
115	msr	NEOVERSE_V1_CPUECTLR_EL1, x1
116workaround_reset_end neoverse_v1, ERRATUM(1925756)
117
118check_erratum_ls neoverse_v1, ERRATUM(1925756), CPU_REV(1, 1)
119
120workaround_reset_start neoverse_v1, ERRATUM(1940577), ERRATA_V1_1940577
121	mov	x0, #0
122	msr	S3_6_C15_C8_0, x0
123	ldr	x0, =0x10E3900002
124	msr	S3_6_C15_C8_2, x0
125	ldr	x0, =0x10FFF00083
126	msr	S3_6_C15_C8_3, x0
127	ldr	x0, =0x2001003FF
128	msr	S3_6_C15_C8_1, x0
129
130	mov	x0, #1
131	msr	S3_6_C15_C8_0, x0
132	ldr	x0, =0x10E3800082
133	msr	S3_6_C15_C8_2, x0
134	ldr	x0, =0x10FFF00083
135	msr	S3_6_C15_C8_3, x0
136	ldr	x0, =0x2001003FF
137	msr	S3_6_C15_C8_1, x0
138
139	mov	x0, #2
140	msr	S3_6_C15_C8_0, x0
141	ldr	x0, =0x10E3800200
142	msr	S3_6_C15_C8_2, x0
143	ldr	x0, =0x10FFF003E0
144	msr	S3_6_C15_C8_3, x0
145	ldr	x0, =0x2001003FF
146	msr	S3_6_C15_C8_1, x0
147
148workaround_reset_end neoverse_v1, ERRATUM(1940577)
149
150check_erratum_range neoverse_v1, ERRATUM(1940577), CPU_REV(1, 0), CPU_REV(1, 1)
151
152workaround_reset_start neoverse_v1, ERRATUM(1966096), ERRATA_V1_1966096
153	mov	x0, #0x3
154	msr	S3_6_C15_C8_0, x0
155	ldr	x0, =0xEE010F12
156	msr	S3_6_C15_C8_2, x0
157	ldr	x0, =0xFFFF0FFF
158	msr	S3_6_C15_C8_3, x0
159	ldr	x0, =0x80000000003FF
160	msr	S3_6_C15_C8_1, x0
161workaround_reset_end neoverse_v1, ERRATUM(1966096)
162
163check_erratum_range neoverse_v1, ERRATUM(1966096), CPU_REV(1, 0), CPU_REV(1, 1)
164
165workaround_reset_start neoverse_v1, ERRATUM(2108267), ERRATA_V1_2108267
166	mrs	x1, NEOVERSE_V1_CPUECTLR_EL1
167	mov	x0, #NEOVERSE_V1_CPUECTLR_EL1_PF_MODE_CNSRV
168	bfi	x1, x0, #CPUECTLR_EL1_PF_MODE_LSB, #CPUECTLR_EL1_PF_MODE_WIDTH
169	msr	NEOVERSE_V1_CPUECTLR_EL1, x1
170workaround_reset_end neoverse_v1, ERRATUM(2108267)
171
172check_erratum_ls neoverse_v1, ERRATUM(2108267), CPU_REV(1, 1)
173
174workaround_reset_start neoverse_v1, ERRATUM(2139242), ERRATA_V1_2139242
175	mov	x0, #0x3
176	msr	S3_6_C15_C8_0, x0
177	ldr	x0, =0xEE720F14
178	msr	S3_6_C15_C8_2, x0
179	ldr	x0, =0xFFFF0FDF
180	msr	S3_6_C15_C8_3, x0
181	ldr	x0, =0x40000005003FF
182	msr	S3_6_C15_C8_1, x0
183workaround_reset_end neoverse_v1, ERRATUM(2139242)
184
185check_erratum_ls neoverse_v1, ERRATUM(2139242), CPU_REV(1, 1)
186
187workaround_reset_start neoverse_v1, ERRATUM(2216392), ERRATA_V1_2216392
188	ldr	x0, =0x5
189	msr	S3_6_c15_c8_0, x0 /* CPUPSELR_EL3 */
190	ldr	x0, =0x10F600E000
191	msr	S3_6_c15_c8_2, x0 /* CPUPOR_EL3 */
192	ldr	x0, =0x10FF80E000
193	msr	S3_6_c15_c8_3, x0 /* CPUPMR_EL3 */
194	ldr	x0, =0x80000000003FF
195	msr	S3_6_c15_c8_1, x0 /* CPUPCR_EL3 */
196workaround_reset_end neoverse_v1, ERRATUM(2216392)
197
198check_erratum_range neoverse_v1, ERRATUM(2216392), CPU_REV(1, 0), CPU_REV(1, 1)
199
200workaround_reset_start neoverse_v1, ERRATUM(2294912), ERRATA_V1_2294912
201	/* Set bit 0 in ACTLR2_EL1 */
202	mrs     x1, NEOVERSE_V1_ACTLR2_EL1
203	orr	x1, x1, #NEOVERSE_V1_ACTLR2_EL1_BIT_0
204	msr     NEOVERSE_V1_ACTLR2_EL1, x1
205workaround_reset_end neoverse_v1, ERRATUM(2294912)
206
207check_erratum_ls neoverse_v1, ERRATUM(2294912), CPU_REV(1, 1)
208
209workaround_reset_start neoverse_v1, ERRATUM(2372203), ERRATA_V1_2372203
210	/* Set bit 40 in ACTLR2_EL1 */
211	mrs	x1, NEOVERSE_V1_ACTLR2_EL1
212	orr	x1, x1, #NEOVERSE_V1_ACTLR2_EL1_BIT_40
213	msr	NEOVERSE_V1_ACTLR2_EL1, x1
214workaround_reset_end neoverse_v1, ERRATUM(2372203)
215
216check_erratum_ls neoverse_v1, ERRATUM(2372203), CPU_REV(1, 1)
217
218workaround_runtime_start neoverse_v1, ERRATUM(2743093), ERRATA_V1_2743093
219	/* dsb before isb of power down sequence */
220	dsb	sy
221workaround_runtime_end neoverse_v1, ERRATUM(2743093)
222
223check_erratum_ls neoverse_v1, ERRATUM(2743093), CPU_REV(1, 2)
224
225workaround_reset_start neoverse_v1, ERRATUM(2743233), ERRATA_V1_2743233
226	mrs	x1, NEOVERSE_V1_ACTLR5_EL1
227	bic	x1, x1, #BIT(56)
228	orr	x1, x1, #BIT(55)
229	msr	NEOVERSE_V1_ACTLR5_EL1, x1
230workaround_reset_end neoverse_v1, ERRATUM(2743233)
231
232check_erratum_ls neoverse_v1, ERRATUM(2743233), CPU_REV(1, 2)
233
234workaround_reset_start neoverse_v1, ERRATUM(2779461), ERRATA_V1_2779461
235	mrs	x1, NEOVERSE_V1_ACTLR3_EL1
236	orr	x1, x1, #BIT(47)
237	msr	NEOVERSE_V1_ACTLR3_EL1, x1
238workaround_reset_end neoverse_v1, ERRATUM(2779461)
239
240check_erratum_ls neoverse_v1, ERRATUM(2779461), CPU_REV(1, 2)
241
242
243workaround_reset_start neoverse_v1, CVE(2022,23960), WORKAROUND_CVE_2022_23960
244#if IMAGE_BL31
245	/*
246	 * The Neoverse-V1 generic vectors are overridden to apply errata
247         * mitigation on exception entry from lower ELs.
248	 */
249	adr	x0, wa_cve_vbar_neoverse_v1
250	msr	vbar_el3, x0
251#endif /* IMAGE_BL31 */
252workaround_reset_end neoverse_v1, CVE(2022,23960)
253
254check_erratum_chosen neoverse_v1, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
255
256	/* ---------------------------------------------
257	 * HW will do the cache maintenance while powering down
258	 * ---------------------------------------------
259	 */
260func neoverse_v1_core_pwr_dwn
261	/* ---------------------------------------------
262	 * Enable CPU power down bit in power control register
263	 * ---------------------------------------------
264	 */
265	mrs	x0, NEOVERSE_V1_CPUPWRCTLR_EL1
266	orr	x0, x0, #NEOVERSE_V1_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
267	msr	NEOVERSE_V1_CPUPWRCTLR_EL1, x0
268#if ERRATA_V1_2743093
269	mov	x15, x30
270	bl	cpu_get_rev_var
271	bl	erratum_neoverse_v1_2743093_wa
272	mov	x30, x15
273#endif /* ERRATA_V1_2743093 */
274	isb
275	ret
276endfunc neoverse_v1_core_pwr_dwn
277
278errata_report_shim neoverse_v1
279
280cpu_reset_func_start neoverse_v1
281	/* Disable speculative loads */
282	msr	SSBS, xzr
283cpu_reset_func_end neoverse_v1
284
285	/* ---------------------------------------------
286	 * This function provides Neoverse-V1 specific
287	 * register information for crash reporting.
288	 * It needs to return with x6 pointing to
289	 * a list of register names in ascii and
290	 * x8 - x15 having values of registers to be
291	 * reported.
292	 * ---------------------------------------------
293	 */
294.section .rodata.neoverse_v1_regs, "aS"
295neoverse_v1_regs:  /* The ascii list of register names to be reported */
296	.asciz	"cpuectlr_el1", ""
297
298func neoverse_v1_cpu_reg_dump
299	adr	x6, neoverse_v1_regs
300	mrs	x8, NEOVERSE_V1_CPUECTLR_EL1
301	ret
302endfunc neoverse_v1_cpu_reg_dump
303
304declare_cpu_ops neoverse_v1, NEOVERSE_V1_MIDR, \
305	neoverse_v1_reset_func, \
306	neoverse_v1_core_pwr_dwn
307