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 <cortex_a78.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 "cortex_a78 must be compiled with HW_ASSISTED_COHERENCY enabled"
18#endif
19
20.globl cortex_a78_reset_func
21.globl cortex_a78_core_pwr_dwn
22
23#if WORKAROUND_CVE_2022_23960
24	wa_cve_2022_23960_bhb_vector_table CORTEX_A78_BHB_LOOP_COUNT, cortex_a78
25#endif /* WORKAROUND_CVE_2022_23960 */
26
27/* --------------------------------------------------
28 * Errata Workaround for A78 Erratum 1688305.
29 * This applies to revision r0p0 and r1p0 of A78.
30 * Inputs:
31 * x0: variant[4:7] and revision[0:3] of current cpu.
32 * Shall clobber: x0-x17
33 * --------------------------------------------------
34 */
35func errata_a78_1688305_wa
36	/* Compare x0 against revision r1p0 */
37	mov	x17, x30
38	bl	check_errata_1688305
39	cbz	x0, 1f
40	mrs     x1, CORTEX_A78_ACTLR2_EL1
41	orr	x1, x1, #CORTEX_A78_ACTLR2_EL1_BIT_1
42	msr     CORTEX_A78_ACTLR2_EL1, x1
43	isb
441:
45	ret	x17
46endfunc errata_a78_1688305_wa
47
48func check_errata_1688305
49	/* Applies to r0p0 and r1p0 */
50	mov	x1, #0x10
51	b	cpu_rev_var_ls
52endfunc check_errata_1688305
53
54/* --------------------------------------------------
55 * Errata Workaround for Cortex A78 Errata #1941498.
56 * This applies to revisions r0p0, r1p0, and r1p1.
57 * x0: variant[4:7] and revision[0:3] of current cpu.
58 * Shall clobber: x0-x17
59 * --------------------------------------------------
60 */
61func errata_a78_1941498_wa
62	/* Compare x0 against revision <= r1p1 */
63	mov	x17, x30
64	bl	check_errata_1941498
65	cbz	x0, 1f
66
67	/* Set bit 8 in ECTLR_EL1 */
68	mrs	x1, CORTEX_A78_CPUECTLR_EL1
69	orr	x1, x1, #CORTEX_A78_CPUECTLR_EL1_BIT_8
70	msr	CORTEX_A78_CPUECTLR_EL1, x1
71	isb
721:
73	ret	x17
74endfunc errata_a78_1941498_wa
75
76func check_errata_1941498
77	/* Check for revision <= r1p1, might need to be updated later. */
78	mov	x1, #0x11
79	b	cpu_rev_var_ls
80endfunc check_errata_1941498
81
82/* --------------------------------------------------
83 * Errata Workaround for A78 Erratum 1951500.
84 * This applies to revisions r1p0 and r1p1 of A78.
85 * The issue also exists in r0p0 but there is no fix
86 * in that revision.
87 * Inputs:
88 * x0: variant[4:7] and revision[0:3] of current cpu.
89 * Shall clobber: x0-x17
90 * --------------------------------------------------
91 */
92func errata_a78_1951500_wa
93	/* Compare x0 against revisions r1p0 - r1p1 */
94	mov	x17, x30
95	bl	check_errata_1951500
96	cbz	x0, 1f
97
98	msr	S3_6_c15_c8_0, xzr
99	ldr	x0, =0x10E3900002
100	msr	S3_6_c15_c8_2, x0
101	ldr	x0, =0x10FFF00083
102	msr	S3_6_c15_c8_3, x0
103	ldr	x0, =0x2001003FF
104	msr	S3_6_c15_c8_1, x0
105
106	mov	x0, #1
107	msr	S3_6_c15_c8_0, x0
108	ldr	x0, =0x10E3800082
109	msr	S3_6_c15_c8_2, x0
110	ldr	x0, =0x10FFF00083
111	msr	S3_6_c15_c8_3, x0
112	ldr	x0, =0x2001003FF
113	msr	S3_6_c15_c8_1, x0
114
115	mov	x0, #2
116	msr	S3_6_c15_c8_0, x0
117	ldr	x0, =0x10E3800200
118	msr	S3_6_c15_c8_2, x0
119	ldr	x0, =0x10FFF003E0
120	msr	S3_6_c15_c8_3, x0
121	ldr	x0, =0x2001003FF
122	msr	S3_6_c15_c8_1, x0
123
124	isb
1251:
126	ret	x17
127endfunc errata_a78_1951500_wa
128
129func check_errata_1951500
130	/* Applies to revisions r1p0 and r1p1. */
131	mov	x1, #CPU_REV(1, 0)
132	mov	x2, #CPU_REV(1, 1)
133	b	cpu_rev_var_range
134endfunc check_errata_1951500
135
136/* --------------------------------------------------
137 * Errata Workaround for Cortex A78 Errata #1821534.
138 * This applies to revisions r0p0 and r1p0.
139 * x0: variant[4:7] and revision[0:3] of current cpu.
140 * Shall clobber: x0-x17
141 * --------------------------------------------------
142 */
143func errata_a78_1821534_wa
144	/* Check revision. */
145	mov	x17, x30
146	bl	check_errata_1821534
147	cbz	x0, 1f
148
149	/* Set bit 2 in ACTLR2_EL1 */
150	mrs     x1, CORTEX_A78_ACTLR2_EL1
151	orr	x1, x1, #CORTEX_A78_ACTLR2_EL1_BIT_2
152	msr     CORTEX_A78_ACTLR2_EL1, x1
153	isb
1541:
155	ret	x17
156endfunc errata_a78_1821534_wa
157
158func check_errata_1821534
159	/* Applies to r0p0 and r1p0 */
160	mov	x1, #0x10
161	b	cpu_rev_var_ls
162endfunc check_errata_1821534
163
164/* --------------------------------------------------
165 * Errata Workaround for Cortex A78 Errata 1952683.
166 * This applies to revision r0p0.
167 * x0: variant[4:7] and revision[0:3] of current cpu.
168 * Shall clobber: x0-x17
169 * --------------------------------------------------
170 */
171func errata_a78_1952683_wa
172	/* Check revision. */
173	mov	x17, x30
174	bl	check_errata_1952683
175	cbz	x0, 1f
176
177	ldr	x0,=0x5
178	msr	S3_6_c15_c8_0,x0
179	ldr	x0,=0xEEE10A10
180	msr	S3_6_c15_c8_2,x0
181	ldr	x0,=0xFFEF0FFF
182	msr	S3_6_c15_c8_3,x0
183	ldr	x0,=0x0010F000
184	msr	S3_6_c15_c8_4,x0
185	ldr	x0,=0x0010F000
186	msr	S3_6_c15_c8_5,x0
187	ldr	x0,=0x40000080023ff
188	msr	S3_6_c15_c8_1,x0
189	ldr	x0,=0x6
190	msr	S3_6_c15_c8_0,x0
191	ldr	x0,=0xEE640F34
192	msr	S3_6_c15_c8_2,x0
193	ldr	x0,=0xFFEF0FFF
194	msr	S3_6_c15_c8_3,x0
195	ldr	x0,=0x40000080023ff
196	msr	S3_6_c15_c8_1,x0
197	isb
1981:
199	ret	x17
200endfunc errata_a78_1952683_wa
201
202func check_errata_1952683
203	/* Applies to r0p0 only */
204	mov	x1, #0x00
205	b	cpu_rev_var_ls
206endfunc check_errata_1952683
207
208/* --------------------------------------------------
209 * Errata Workaround for Cortex A78 Errata 2132060.
210 * This applies to revisions r0p0, r1p0, r1p1, and r1p2.
211 * It is still open.
212 * x0: variant[4:7] and revision[0:3] of current cpu.
213 * Shall clobber: x0-x1, x17
214 * --------------------------------------------------
215 */
216func errata_a78_2132060_wa
217	/* Check revision. */
218	mov	x17, x30
219	bl	check_errata_2132060
220	cbz	x0, 1f
221
222	/* Apply the workaround. */
223	mrs	x1, CORTEX_A78_CPUECTLR_EL1
224	mov	x0, #CORTEX_A78_CPUECTLR_EL1_PF_MODE_CNSRV
225	bfi	x1, x0, #CPUECTLR_EL1_PF_MODE_LSB, #CPUECTLR_EL1_PF_MODE_WIDTH
226	msr	CORTEX_A78_CPUECTLR_EL1, x1
2271:
228	ret	x17
229endfunc errata_a78_2132060_wa
230
231func check_errata_2132060
232	/* Applies to r0p0, r0p1, r1p1, and r1p2 */
233	mov	x1, #0x12
234	b	cpu_rev_var_ls
235endfunc check_errata_2132060
236
237/* --------------------------------------------------------------------
238 * Errata Workaround for A78 Erratum 2242635.
239 * This applies to revisions r1p0, r1p1, and r1p2 of the Cortex A78
240 * processor and is still open.
241 * The issue also exists in r0p0 but there is no fix in that revision.
242 * x0: variant[4:7] and revision[0:3] of current cpu.
243 * Shall clobber: x0-x17
244 * --------------------------------------------------------------------
245 */
246func errata_a78_2242635_wa
247	/* Compare x0 against revisions r1p0 - r1p2 */
248	mov	x17, x30
249	bl	check_errata_2242635
250	cbz	x0, 1f
251
252	ldr	x0, =0x5
253	msr	S3_6_c15_c8_0, x0 /* CPUPSELR_EL3 */
254	ldr	x0, =0x10F600E000
255	msr	S3_6_c15_c8_2, x0 /* CPUPOR_EL3 */
256	ldr	x0, =0x10FF80E000
257	msr	S3_6_c15_c8_3, x0 /* CPUPMR_EL3 */
258	ldr	x0, =0x80000000003FF
259	msr	S3_6_c15_c8_1, x0 /* CPUPCR_EL3 */
260
261	isb
2621:
263	ret	x17
264endfunc errata_a78_2242635_wa
265
266func check_errata_2242635
267	/* Applies to revisions r1p0 through r1p2. */
268	mov	x1, #CPU_REV(1, 0)
269	mov	x2, #CPU_REV(1, 2)
270	b	cpu_rev_var_range
271endfunc check_errata_2242635
272
273/* --------------------------------------------------
274 * Errata Workaround for Cortex A78 Errata 2376745.
275 * This applies to revisions r0p0, r1p0, r1p1, and r1p2.
276 * It is still open.
277 * x0: variant[4:7] and revision[0:3] of current cpu.
278 * Shall clobber: x0-x1, x17
279 * --------------------------------------------------
280 */
281func errata_a78_2376745_wa
282	/* Check revision. */
283	mov	x17, x30
284	bl	check_errata_2376745
285	cbz	x0, 1f
286
287	/* Apply the workaround. */
288	mrs	x1, CORTEX_A78_ACTLR2_EL1
289	orr	x1, x1, #BIT(0)
290	msr	CORTEX_A78_ACTLR2_EL1, x1
2911:
292	ret	x17
293endfunc errata_a78_2376745_wa
294
295func check_errata_2376745
296	/* Applies to r0p0, r0p1, r1p1, and r1p2 */
297	mov	x1, #CPU_REV(1, 2)
298	b	cpu_rev_var_ls
299endfunc check_errata_2376745
300
301/* --------------------------------------------------
302 * Errata Workaround for Cortex A78 Errata 2395406.
303 * This applies to revisions r0p0, r1p0, r1p1, and r1p2.
304 * It is still open.
305 * x0: variant[4:7] and revision[0:3] of current cpu.
306 * Shall clobber: x0-x1, x17
307 * --------------------------------------------------
308 */
309func errata_a78_2395406_wa
310	/* Check revision. */
311	mov	x17, x30
312	bl	check_errata_2395406
313	cbz	x0, 1f
314
315	/* Apply the workaround. */
316	mrs	x1, CORTEX_A78_ACTLR2_EL1
317	orr	x1, x1, #BIT(40)
318	msr	CORTEX_A78_ACTLR2_EL1, x1
3191:
320	ret	x17
321endfunc errata_a78_2395406_wa
322
323func check_errata_2395406
324	/* Applies to r0p0, r0p1, r1p1, and r1p2 */
325	mov	x1, #CPU_REV(1, 2)
326	b	cpu_rev_var_ls
327endfunc check_errata_2395406
328
329func check_errata_cve_2022_23960
330#if WORKAROUND_CVE_2022_23960
331	mov	x0, #ERRATA_APPLIES
332#else
333	mov	x0, #ERRATA_MISSING
334#endif
335	ret
336endfunc check_errata_cve_2022_23960
337
338	/* -------------------------------------------------
339	 * The CPU Ops reset function for Cortex-A78
340	 * -------------------------------------------------
341	 */
342func cortex_a78_reset_func
343	mov	x19, x30
344	bl	cpu_get_rev_var
345	mov	x18, x0
346
347#if ERRATA_A78_1688305
348	mov     x0, x18
349	bl	errata_a78_1688305_wa
350#endif
351
352#if ERRATA_A78_1941498
353	mov     x0, x18
354	bl	errata_a78_1941498_wa
355#endif
356
357#if ERRATA_A78_1951500
358	mov	x0, x18
359	bl	errata_a78_1951500_wa
360#endif
361
362#if ERRATA_A78_1821534
363	mov	x0, x18
364	bl	errata_a78_1821534_wa
365#endif
366
367#if ERRATA_A78_1952683
368	mov	x0, x18
369	bl	errata_a78_1952683_wa
370#endif
371
372#if ERRATA_A78_2132060
373	mov	x0, x18
374	bl	errata_a78_2132060_wa
375#endif
376
377#if ERRATA_A78_2242635
378	mov	x0, x18
379	bl	errata_a78_2242635_wa
380#endif
381
382#if ERRATA_A78_2376745
383	mov	x0, x18
384	bl	errata_a78_2376745_wa
385#endif
386
387#if ERRATA_A78_2395406
388	mov	x0, x18
389	bl	errata_a78_2395406_wa
390#endif
391
392#if ENABLE_AMU
393	/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
394	mrs	x0, actlr_el3
395	bic	x0, x0, #CORTEX_A78_ACTLR_TAM_BIT
396	msr	actlr_el3, x0
397
398	/* Make sure accesses from non-secure EL0/EL1 are not trapped to EL2 */
399	mrs	x0, actlr_el2
400	bic	x0, x0, #CORTEX_A78_ACTLR_TAM_BIT
401	msr	actlr_el2, x0
402
403	/* Enable group0 counters */
404	mov	x0, #CORTEX_A78_AMU_GROUP0_MASK
405	msr	CPUAMCNTENSET0_EL0, x0
406
407	/* Enable group1 counters */
408	mov	x0, #CORTEX_A78_AMU_GROUP1_MASK
409	msr	CPUAMCNTENSET1_EL0, x0
410#endif
411
412#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
413	/*
414	 * The Cortex-A78 generic vectors are overridden to apply errata
415	 * mitigation on exception entry from lower ELs.
416	 */
417	adr	x0, wa_cve_vbar_cortex_a78
418	msr	vbar_el3, x0
419#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
420
421	isb
422	ret	x19
423endfunc cortex_a78_reset_func
424
425	/* ---------------------------------------------
426	 * HW will do the cache maintenance while powering down
427	 * ---------------------------------------------
428	 */
429func cortex_a78_core_pwr_dwn
430	/* ---------------------------------------------
431	 * Enable CPU power down bit in power control register
432	 * ---------------------------------------------
433	 */
434	mrs	x0, CORTEX_A78_CPUPWRCTLR_EL1
435	orr	x0, x0, #CORTEX_A78_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT
436	msr	CORTEX_A78_CPUPWRCTLR_EL1, x0
437	isb
438	ret
439endfunc cortex_a78_core_pwr_dwn
440
441	/*
442	 * Errata printing function for cortex_a78. Must follow AAPCS.
443	 */
444#if REPORT_ERRATA
445func cortex_a78_errata_report
446	stp	x8, x30, [sp, #-16]!
447
448	bl	cpu_get_rev_var
449	mov	x8, x0
450
451	/*
452	 * Report all errata. The revision-variant information is passed to
453	 * checking functions of each errata.
454	 */
455	report_errata ERRATA_A78_1688305, cortex_a78, 1688305
456	report_errata ERRATA_A78_1941498, cortex_a78, 1941498
457	report_errata ERRATA_A78_1951500, cortex_a78, 1951500
458	report_errata ERRATA_A78_1821534, cortex_a78, 1821534
459	report_errata ERRATA_A78_1952683, cortex_a78, 1952683
460	report_errata ERRATA_A78_2132060, cortex_a78, 2132060
461	report_errata ERRATA_A78_2242635, cortex_a78, 2242635
462	report_errata ERRATA_A78_2376745, cortex_a78, 2376745
463	report_errata ERRATA_A78_2395406, cortex_a78, 2395406
464	report_errata WORKAROUND_CVE_2022_23960, cortex_a78, cve_2022_23960
465
466	ldp	x8, x30, [sp], #16
467	ret
468endfunc cortex_a78_errata_report
469#endif
470
471	/* ---------------------------------------------
472	 * This function provides cortex_a78 specific
473	 * register information for crash reporting.
474	 * It needs to return with x6 pointing to
475	 * a list of register names in ascii and
476	 * x8 - x15 having values of registers to be
477	 * reported.
478	 * ---------------------------------------------
479	 */
480.section .rodata.cortex_a78_regs, "aS"
481cortex_a78_regs:  /* The ascii list of register names to be reported */
482	.asciz	"cpuectlr_el1", ""
483
484func cortex_a78_cpu_reg_dump
485	adr	x6, cortex_a78_regs
486	mrs	x8, CORTEX_A78_CPUECTLR_EL1
487	ret
488endfunc cortex_a78_cpu_reg_dump
489
490declare_cpu_ops cortex_a78, CORTEX_A78_MIDR, \
491	cortex_a78_reset_func, \
492	cortex_a78_core_pwr_dwn
493