1/*
2 * Copyright (c) 2019-2022, 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
29	/* --------------------------------------------------
30	 * Errata Workaround for Neoverse V1 Errata #1618635.
31	 * This applies to revision r0p0 and is fixed in
32	 * r1p0.
33	 * x0: variant[4:7] and revision[0:3] of current cpu.
34	 * Shall clobber: x0, x17
35	 * --------------------------------------------------
36	 */
37func errata_neoverse_v1_1618635_wa
38	/* Check workaround compatibility. */
39	mov	x17, x30
40	bl	check_errata_1618635
41	cbz	x0, 1f
42
43	/* Inserts a DMB SY before and after MRS PAR_EL1 */
44	ldr	x0, =0x0
45	msr	NEOVERSE_V1_CPUPSELR_EL3, x0
46	ldr	x0, = 0xEE070F14
47	msr	NEOVERSE_V1_CPUPOR_EL3, x0
48	ldr	x0, = 0xFFFF0FFF
49	msr	NEOVERSE_V1_CPUPMR_EL3, x0
50	ldr	x0, =0x4005027FF
51	msr	NEOVERSE_V1_CPUPCR_EL3, x0
52
53	/* Inserts a DMB SY before STREX imm offset */
54	ldr	x0, =0x1
55	msr	NEOVERSE_V1_CPUPSELR_EL3, x0
56	ldr	x0, =0x00e8400000
57	msr	NEOVERSE_V1_CPUPOR_EL3, x0
58	ldr	x0, =0x00fff00000
59	msr	NEOVERSE_V1_CPUPMR_EL3, x0
60	ldr	x0, = 0x4001027FF
61	msr	NEOVERSE_V1_CPUPCR_EL3, x0
62
63	/* Inserts a DMB SY before STREX[BHD}/STLEX* */
64	ldr	x0, =0x2
65	msr	NEOVERSE_V1_CPUPSELR_EL3, x0
66	ldr	x0, =0x00e8c00040
67	msr	NEOVERSE_V1_CPUPOR_EL3, x0
68	ldr	x0, =0x00fff00040
69	msr	NEOVERSE_V1_CPUPMR_EL3, x0
70	ldr	x0, = 0x4001027FF
71	msr	NEOVERSE_V1_CPUPCR_EL3, x0
72
73	/* Inserts a DMB SY after STREX imm offset */
74	ldr	x0, =0x3
75	msr	NEOVERSE_V1_CPUPSELR_EL3, x0
76	ldr	x0, =0x00e8400000
77	msr	NEOVERSE_V1_CPUPOR_EL3, x0
78	ldr	x0, =0x00fff00000
79	msr	NEOVERSE_V1_CPUPMR_EL3, x0
80	ldr	x0, = 0x4004027FF
81	msr	NEOVERSE_V1_CPUPCR_EL3, x0
82
83	/* Inserts a DMB SY after STREX[BHD}/STLEX* */
84	ldr	x0, =0x4
85	msr	NEOVERSE_V1_CPUPSELR_EL3, x0
86	ldr	x0, =0x00e8c00040
87	msr	NEOVERSE_V1_CPUPOR_EL3, x0
88	ldr	x0, =0x00fff00040
89	msr	NEOVERSE_V1_CPUPMR_EL3, x0
90	ldr	x0, = 0x4004027FF
91	msr	NEOVERSE_V1_CPUPCR_EL3, x0
92
93	/* Synchronize to enable patches */
94	isb
951:
96	ret x17
97endfunc errata_neoverse_v1_1618635_wa
98
99func check_errata_1618635
100	/* Applies to revision r0p0. */
101	mov	x1, #0x00
102	b	cpu_rev_var_ls
103endfunc check_errata_1618635
104
105	/* --------------------------------------------------
106	 * Errata Workaround for Neoverse V1 Errata #1774420.
107	 * This applies to revisions r0p0 and r1p0, fixed in r1p1.
108	 * x0: variant[4:7] and revision[0:3] of current cpu.
109	 * Shall clobber: x0-x17
110	 * --------------------------------------------------
111	 */
112func errata_neoverse_v1_1774420_wa
113	/* Check workaround compatibility. */
114	mov	x17, x30
115	bl	check_errata_1774420
116	cbz	x0, 1f
117
118	/* Set bit 53 in CPUECTLR_EL1 */
119	mrs     x1, NEOVERSE_V1_CPUECTLR_EL1
120	orr	x1, x1, #NEOVERSE_V1_CPUECTLR_EL1_BIT_53
121	msr     NEOVERSE_V1_CPUECTLR_EL1, x1
122	isb
1231:
124	ret	x17
125endfunc errata_neoverse_v1_1774420_wa
126
127func check_errata_1774420
128	/* Applies to r0p0 and r1p0. */
129	mov	x1, #0x10
130	b	cpu_rev_var_ls
131endfunc check_errata_1774420
132
133	/* --------------------------------------------------
134	 * Errata Workaround for Neoverse V1 Errata #1791573.
135	 * This applies to revisions r0p0 and r1p0, fixed in r1p1.
136	 * x0: variant[4:7] and revision[0:3] of current cpu.
137	 * Shall clobber: x0-x17
138	 * --------------------------------------------------
139	 */
140func errata_neoverse_v1_1791573_wa
141	/* Check workaround compatibility. */
142	mov	x17, x30
143	bl	check_errata_1791573
144	cbz	x0, 1f
145
146	/* Set bit 2 in ACTLR2_EL1 */
147	mrs	x1, NEOVERSE_V1_ACTLR2_EL1
148	orr	x1, x1, #NEOVERSE_V1_ACTLR2_EL1_BIT_2
149	msr	NEOVERSE_V1_ACTLR2_EL1, x1
150	isb
1511:
152	ret	x17
153endfunc errata_neoverse_v1_1791573_wa
154
155func check_errata_1791573
156	/* Applies to r0p0 and r1p0. */
157	mov	x1, #0x10
158	b	cpu_rev_var_ls
159endfunc check_errata_1791573
160
161	/* --------------------------------------------------
162	 * Errata Workaround for Neoverse V1 Errata #1852267.
163	 * This applies to revisions r0p0 and r1p0, fixed in r1p1.
164	 * x0: variant[4:7] and revision[0:3] of current cpu.
165	 * Shall clobber: x0-x17
166	 * --------------------------------------------------
167	 */
168func errata_neoverse_v1_1852267_wa
169	/* Check workaround compatibility. */
170	mov	x17, x30
171	bl	check_errata_1852267
172	cbz	x0, 1f
173
174	/* Set bit 28 in ACTLR2_EL1 */
175	mrs	x1, NEOVERSE_V1_ACTLR2_EL1
176	orr	x1, x1, #NEOVERSE_V1_ACTLR2_EL1_BIT_28
177	msr	NEOVERSE_V1_ACTLR2_EL1, x1
178	isb
1791:
180	ret	x17
181endfunc errata_neoverse_v1_1852267_wa
182
183func check_errata_1852267
184	/* Applies to r0p0 and r1p0. */
185	mov	x1, #0x10
186	b	cpu_rev_var_ls
187endfunc check_errata_1852267
188
189	/* --------------------------------------------------
190	 * Errata Workaround for Neoverse V1 Errata #1925756.
191	 * This applies to revisions <= r1p1.
192	 * x0: variant[4:7] and revision[0:3] of current cpu.
193	 * Shall clobber: x0-x17
194	 * --------------------------------------------------
195	 */
196func errata_neoverse_v1_1925756_wa
197	/* Check workaround compatibility. */
198	mov	x17, x30
199	bl	check_errata_1925756
200	cbz	x0, 1f
201
202	/* Set bit 8 in CPUECTLR_EL1 */
203	mrs	x1, NEOVERSE_V1_CPUECTLR_EL1
204	orr	x1, x1, #NEOVERSE_V1_CPUECTLR_EL1_BIT_8
205	msr	NEOVERSE_V1_CPUECTLR_EL1, x1
206	isb
2071:
208	ret	x17
209endfunc errata_neoverse_v1_1925756_wa
210
211func check_errata_1925756
212	/* Applies to <= r1p1. */
213	mov	x1, #0x11
214	b	cpu_rev_var_ls
215endfunc check_errata_1925756
216
217	/* --------------------------------------------------
218	 * Errata Workaround for Neoverse V1 Erratum #1940577
219	 * This applies to revisions r1p0 - r1p1 and is open.
220	 * It also exists in r0p0 but there is no fix in that
221	 * revision.
222	 * Inputs:
223	 * x0: variant[4:7] and revision[0:3] of current cpu.
224	 * Shall clobber: x0-x17
225	 * --------------------------------------------------
226	 */
227func errata_neoverse_v1_1940577_wa
228	/* Compare x0 against revisions r1p0 - r1p1 */
229	mov	x17, x30
230	bl	check_errata_1940577
231	cbz	x0, 1f
232
233	mov	x0, #0
234	msr	S3_6_C15_C8_0, x0
235	ldr	x0, =0x10E3900002
236	msr	S3_6_C15_C8_2, x0
237	ldr	x0, =0x10FFF00083
238	msr	S3_6_C15_C8_3, x0
239	ldr	x0, =0x2001003FF
240	msr	S3_6_C15_C8_1, x0
241
242	mov	x0, #1
243	msr	S3_6_C15_C8_0, x0
244	ldr	x0, =0x10E3800082
245	msr	S3_6_C15_C8_2, x0
246	ldr	x0, =0x10FFF00083
247	msr	S3_6_C15_C8_3, x0
248	ldr	x0, =0x2001003FF
249	msr	S3_6_C15_C8_1, x0
250
251	mov	x0, #2
252	msr	S3_6_C15_C8_0, x0
253	ldr	x0, =0x10E3800200
254	msr	S3_6_C15_C8_2, x0
255	ldr	x0, =0x10FFF003E0
256	msr	S3_6_C15_C8_3, x0
257	ldr	x0, =0x2001003FF
258	msr	S3_6_C15_C8_1, x0
259
260	isb
2611:
262	ret	x17
263endfunc errata_neoverse_v1_1940577_wa
264
265func check_errata_1940577
266	/* Applies to revisions r1p0 - r1p1. */
267	mov	x1, #0x10
268	mov	x2, #0x11
269	b	cpu_rev_var_range
270endfunc check_errata_1940577
271
272	/* --------------------------------------------------
273	 * Errata Workaround for Neoverse V1 Errata #1966096
274	 * This applies to revisions r1p0 - r1p1 and is open.
275	 * It also exists in r0p0 but there is no workaround
276	 * for that revision.
277	 * x0: variant[4:7] and revision[0:3] of current cpu.
278	 * Shall clobber: x0-x17
279	 * --------------------------------------------------
280	 */
281func errata_neoverse_v1_1966096_wa
282	/* Check workaround compatibility. */
283	mov	x17, x30
284	bl	check_errata_1966096
285	cbz	x0, 1f
286
287	/* Apply the workaround. */
288	mov	x0, #0x3
289	msr	S3_6_C15_C8_0, x0
290	ldr	x0, =0xEE010F12
291	msr	S3_6_C15_C8_2, x0
292	ldr	x0, =0xFFFF0FFF
293	msr	S3_6_C15_C8_3, x0
294	ldr	x0, =0x80000000003FF
295	msr	S3_6_C15_C8_1, x0
296	isb
297
2981:
299	ret	x17
300endfunc errata_neoverse_v1_1966096_wa
301
302func check_errata_1966096
303	mov	x1, #0x10
304	mov	x2, #0x11
305	b	cpu_rev_var_range
306endfunc check_errata_1966096
307
308	/* --------------------------------------------------
309	 * Errata Workaround for Neoverse V1 Errata #2139242.
310	 * This applies to revisions r0p0, r1p0, and r1p1, it
311	 * is still open.
312	 * x0: variant[4:7] and revision[0:3] of current cpu.
313	 * Shall clobber: x0-x17
314	 * --------------------------------------------------
315	 */
316func errata_neoverse_v1_2139242_wa
317	/* Check workaround compatibility. */
318	mov	x17, x30
319	bl	check_errata_2139242
320	cbz	x0, 1f
321
322	/* Apply the workaround. */
323	mov	x0, #0x3
324	msr	S3_6_C15_C8_0, x0
325	ldr	x0, =0xEE720F14
326	msr	S3_6_C15_C8_2, x0
327	ldr	x0, =0xFFFF0FDF
328	msr	S3_6_C15_C8_3, x0
329	ldr	x0, =0x40000005003FF
330	msr	S3_6_C15_C8_1, x0
331	isb
332
3331:
334	ret	x17
335endfunc errata_neoverse_v1_2139242_wa
336
337func check_errata_2139242
338	/* Applies to r0p0, r1p0, r1p1 */
339	mov	x1, #0x11
340	b	cpu_rev_var_ls
341endfunc check_errata_2139242
342
343	/* --------------------------------------------------
344	 * Errata Workaround for Neoverse V1 Errata #2108267.
345	 * This applies to revisions r0p0, r1p0, and r1p1, it
346	 * is still open.
347	 * x0: variant[4:7] and revision[0:3] of current cpu.
348	 * Shall clobber: x0-x1, x17
349	 * --------------------------------------------------
350	 */
351func errata_neoverse_v1_2108267_wa
352	/* Check workaround compatibility. */
353	mov	x17, x30
354	bl	check_errata_2108267
355	cbz	x0, 1f
356
357	/* Apply the workaround. */
358	mrs	x1, NEOVERSE_V1_CPUECTLR_EL1
359	mov	x0, #NEOVERSE_V1_CPUECTLR_EL1_PF_MODE_CNSRV
360	bfi	x1, x0, #CPUECTLR_EL1_PF_MODE_LSB, #CPUECTLR_EL1_PF_MODE_WIDTH
361	msr	NEOVERSE_V1_CPUECTLR_EL1, x1
3621:
363	ret	x17
364endfunc errata_neoverse_v1_2108267_wa
365
366func check_errata_2108267
367	/* Applies to r0p0, r1p0, r1p1 */
368	mov	x1, #0x11
369	b	cpu_rev_var_ls
370endfunc check_errata_2108267
371
372	/* --------------------------------------------------
373	 * Errata Workaround for Neoverse V1 Errata #2216392.
374	 * This applies to revisions r1p0 and r1p1 and is
375	 * still open.
376	 * This issue is also present in r0p0 but there is no
377	 * workaround in that revision.
378	 * x0: variant[4:7] and revision[0:3] of current cpu.
379	 * Shall clobber: x0-x17
380	 * --------------------------------------------------
381	 */
382func errata_neoverse_v1_2216392_wa
383	/* Check workaround compatibility. */
384	mov	x17, x30
385	bl	check_errata_2216392
386	cbz	x0, 1f
387
388	ldr	x0, =0x5
389	msr	S3_6_c15_c8_0, x0 /* CPUPSELR_EL3 */
390	ldr	x0, =0x10F600E000
391	msr	S3_6_c15_c8_2, x0 /* CPUPOR_EL3 */
392	ldr	x0, =0x10FF80E000
393	msr	S3_6_c15_c8_3, x0 /* CPUPMR_EL3 */
394	ldr	x0, =0x80000000003FF
395	msr	S3_6_c15_c8_1, x0 /* CPUPCR_EL3 */
396
397	isb
3981:
399	ret	x17
400endfunc errata_neoverse_v1_2216392_wa
401
402func check_errata_2216392
403	/* Applies to revisions r1p0 and r1p1. */
404	mov	x1, #CPU_REV(1, 0)
405	mov	x2, #CPU_REV(1, 1)
406	b	cpu_rev_var_range
407endfunc check_errata_2216392
408
409	/* -----------------------------------------------------------------
410	 * Errata Workaround for Neoverse V1 Errata #2294912.
411	 * This applies to revisions r0p0, r1p0, and r1p1 and is still open.
412	 * x0: variant[4:7] and revision[0:3] of current cpu.
413	 * Shall clobber: x0-x17
414	 * -----------------------------------------------------------------
415	 */
416func errata_neoverse_v1_2294912_wa
417	/* Check workaround compatibility. */
418	mov	x17, x30
419	bl	check_errata_2294912
420	cbz	x0, 1f
421
422	/* Set bit 0 in ACTLR2_EL1 */
423	mrs     x1, NEOVERSE_V1_ACTLR2_EL1
424	orr	x1, x1, #NEOVERSE_V1_ACTLR2_EL1_BIT_0
425	msr     NEOVERSE_V1_ACTLR2_EL1, x1
426	isb
4271:
428	ret	x17
429endfunc errata_neoverse_v1_2294912_wa
430
431func check_errata_2294912
432	/* Applies to r0p0, r1p0, and r1p1 right now */
433	mov	x1, #0x11
434	b	cpu_rev_var_ls
435endfunc check_errata_2294912
436
437	/* ---------------------------------------------------
438	 * Errata Workaround for Neoverse V1 Errata #2372203.
439	 * This applies to revisions <= r1p1 and is still open.
440	 * x0: variant[4:7] and revision[0:3] of current cpu.
441	 * Shall clobber: x0-x17
442	 * ----------------------------------------------------
443	 */
444func errata_neoverse_v1_2372203_wa
445	/* Check workaround compatibility. */
446	mov	x17, x30
447	bl	check_errata_2372203
448	cbz	x0, 1f
449
450	/* Set bit 40 in ACTLR2_EL1 */
451	mrs	x1, NEOVERSE_V1_ACTLR2_EL1
452	orr	x1, x1, #NEOVERSE_V1_ACTLR2_EL1_BIT_40
453	msr	NEOVERSE_V1_ACTLR2_EL1, x1
454	isb
4551:
456	ret	x17
457endfunc errata_neoverse_v1_2372203_wa
458
459func check_errata_2372203
460	/* Applies to <= r1p1. */
461	mov	x1, #0x11
462	b	cpu_rev_var_ls
463endfunc check_errata_2372203
464
465func check_errata_cve_2022_23960
466#if WORKAROUND_CVE_2022_23960
467	mov	x0, #ERRATA_APPLIES
468#else
469	mov	x0, #ERRATA_MISSING
470#endif
471	ret
472endfunc check_errata_cve_2022_23960
473
474	/* ---------------------------------------------
475	 * HW will do the cache maintenance while powering down
476	 * ---------------------------------------------
477	 */
478func neoverse_v1_core_pwr_dwn
479	/* ---------------------------------------------
480	 * Enable CPU power down bit in power control register
481	 * ---------------------------------------------
482	 */
483	mrs	x0, NEOVERSE_V1_CPUPWRCTLR_EL1
484	orr	x0, x0, #NEOVERSE_V1_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
485	msr	NEOVERSE_V1_CPUPWRCTLR_EL1, x0
486	isb
487	ret
488endfunc neoverse_v1_core_pwr_dwn
489
490	/*
491	 * Errata printing function for Neoverse V1. Must follow AAPCS.
492	 */
493#if REPORT_ERRATA
494func neoverse_v1_errata_report
495	stp	x8, x30, [sp, #-16]!
496
497	bl	cpu_get_rev_var
498	mov	x8, x0
499
500	/*
501	 * Report all errata. The revision-variant information is passed to
502	 * checking functions of each errata.
503	 */
504	report_errata ERRATA_V1_1618635, neoverse_v1, 1618635
505	report_errata ERRATA_V1_1774420, neoverse_v1, 1774420
506	report_errata ERRATA_V1_1791573, neoverse_v1, 1791573
507	report_errata ERRATA_V1_1852267, neoverse_v1, 1852267
508	report_errata ERRATA_V1_1925756, neoverse_v1, 1925756
509	report_errata ERRATA_V1_1940577, neoverse_v1, 1940577
510	report_errata ERRATA_V1_1966096, neoverse_v1, 1966096
511	report_errata ERRATA_V1_2108267, neoverse_v1, 2108267
512	report_errata ERRATA_V1_2139242, neoverse_v1, 2139242
513	report_errata ERRATA_V1_2216392, neoverse_v1, 2216392
514	report_errata ERRATA_V1_2294912, neoverse_v1, 2294912
515	report_errata ERRATA_V1_2372203, neoverse_v1, 2372203
516	report_errata WORKAROUND_CVE_2022_23960, neoverse_v1, cve_2022_23960
517
518	ldp	x8, x30, [sp], #16
519	ret
520endfunc neoverse_v1_errata_report
521#endif
522
523func neoverse_v1_reset_func
524	mov	x19, x30
525
526	/* Disable speculative loads */
527	msr	SSBS, xzr
528	isb
529
530	/* Get the CPU revision and stash it in x18. */
531	bl	cpu_get_rev_var
532	mov	x18, x0
533
534#if ERRATA_V1_1618635
535	mov x0, x18
536	bl errata_neoverse_v1_1618635_wa
537#endif
538
539#if ERRATA_V1_1774420
540	mov	x0, x18
541	bl	errata_neoverse_v1_1774420_wa
542#endif
543
544#if ERRATA_V1_1791573
545	mov	x0, x18
546	bl	errata_neoverse_v1_1791573_wa
547#endif
548
549#if ERRATA_V1_1852267
550	mov	x0, x18
551	bl	errata_neoverse_v1_1852267_wa
552#endif
553
554#if ERRATA_V1_1925756
555	mov	x0, x18
556	bl	errata_neoverse_v1_1925756_wa
557#endif
558
559#if ERRATA_V1_1940577
560	mov	x0, x18
561	bl	errata_neoverse_v1_1940577_wa
562#endif
563
564#if ERRATA_V1_1966096
565	mov	x0, x18
566	bl	errata_neoverse_v1_1966096_wa
567#endif
568
569#if ERRATA_V1_2139242
570	mov	x0, x18
571	bl	errata_neoverse_v1_2139242_wa
572#endif
573
574#if ERRATA_V1_2108267
575	mov	x0, x18
576	bl	errata_neoverse_v1_2108267_wa
577#endif
578
579#if ERRATA_V1_2216392
580	mov	x0, x18
581	bl	errata_neoverse_v1_2216392_wa
582#endif
583
584#if ERRATA_V1_2294912
585	mov	x0, x18
586	bl	errata_neoverse_v1_2294912_wa
587#endif
588
589#if ERRATA_V1_2372203
590	mov	x0, x18
591	bl	errata_neoverse_v1_2372203_wa
592#endif
593
594#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
595	/*
596	 * The Neoverse-V1 generic vectors are overridden to apply errata
597         * mitigation on exception entry from lower ELs.
598	 */
599	adr	x0, wa_cve_vbar_neoverse_v1
600	msr	vbar_el3, x0
601#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
602
603	isb
604	ret	x19
605endfunc neoverse_v1_reset_func
606
607	/* ---------------------------------------------
608	 * This function provides Neoverse-V1 specific
609	 * register information for crash reporting.
610	 * It needs to return with x6 pointing to
611	 * a list of register names in ascii and
612	 * x8 - x15 having values of registers to be
613	 * reported.
614	 * ---------------------------------------------
615	 */
616.section .rodata.neoverse_v1_regs, "aS"
617neoverse_v1_regs:  /* The ascii list of register names to be reported */
618	.asciz	"cpuectlr_el1", ""
619
620func neoverse_v1_cpu_reg_dump
621	adr	x6, neoverse_v1_regs
622	mrs	x8, NEOVERSE_V1_CPUECTLR_EL1
623	ret
624endfunc neoverse_v1_cpu_reg_dump
625
626declare_cpu_ops neoverse_v1, NEOVERSE_V1_MIDR, \
627	neoverse_v1_reset_func, \
628	neoverse_v1_core_pwr_dwn
629