xref: /rk3399_ARM-atf/lib/cpus/aarch64/cortex_a78.S (revision 034a2e3ef8a9e8e58f7cb7fab6db4ee60b2f9c29)
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 <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
329/* ----------------------------------------------------
330 * Errata Workaround for Cortex-A78 Errata 2772019
331 * This applies to revisions <= r1p2 and is still open.
332 * x0: variant[4:7] and revision[0:3] of current cpu.
333 * Shall clobber: x0-x17
334 * ----------------------------------------------------
335 */
336func errata_a78_2772019_wa
337	mov	x17, x30
338	bl	check_errata_2772019
339	cbz	x0, 1f
340
341
342	/* dsb before isb of power down sequence */
343	dsb	sy
3441:
345	ret	x17
346endfunc errata_a78_2772019_wa
347
348func check_errata_2772019
349	/* Applies to all revisions <= r1p2 */
350	mov	x1, #0x12
351	b	cpu_rev_var_ls
352endfunc check_errata_2772019
353
354/* ----------------------------------------------------
355 * Errata Workaround for Cortex A78 Errata 2779479.
356 * This applies to revisions r0p0, r1p0, r1p1, and r1p2.
357 * It is still open.
358 * x0: variant[4:7] and revision[0:3] of current cpu.
359 * Shall clobber: x0-x1, x17
360 * ----------------------------------------------------
361 */
362func errata_a78_2779479_wa
363	/* Check revision. */
364	mov	x17, x30
365	bl	check_errata_2779479
366	cbz	x0, 1f
367
368	/* Apply the workaround */
369	mrs	x1, CORTEX_A78_ACTLR3_EL1
370	orr	x1, x1, #BIT(47)
371	msr	CORTEX_A78_ACTLR3_EL1, x1
372
3731:
374	ret	x17
375endfunc errata_a78_2779479_wa
376
377func check_errata_2779479
378	/* Applies to r0p0, r1p0, r1p1, r1p2 */
379	mov	x1, #CPU_REV(1, 2)
380	b	cpu_rev_var_ls
381endfunc check_errata_2779479
382
383func check_errata_cve_2022_23960
384#if WORKAROUND_CVE_2022_23960
385	mov	x0, #ERRATA_APPLIES
386#else
387	mov	x0, #ERRATA_MISSING
388#endif
389	ret
390endfunc check_errata_cve_2022_23960
391
392	/* -------------------------------------------------
393	 * The CPU Ops reset function for Cortex-A78
394	 * -------------------------------------------------
395	 */
396func cortex_a78_reset_func
397	mov	x19, x30
398	bl	cpu_get_rev_var
399	mov	x18, x0
400
401#if ERRATA_A78_1688305
402	mov     x0, x18
403	bl	errata_a78_1688305_wa
404#endif
405
406#if ERRATA_A78_1941498
407	mov     x0, x18
408	bl	errata_a78_1941498_wa
409#endif
410
411#if ERRATA_A78_1951500
412	mov	x0, x18
413	bl	errata_a78_1951500_wa
414#endif
415
416#if ERRATA_A78_1821534
417	mov	x0, x18
418	bl	errata_a78_1821534_wa
419#endif
420
421#if ERRATA_A78_1952683
422	mov	x0, x18
423	bl	errata_a78_1952683_wa
424#endif
425
426#if ERRATA_A78_2132060
427	mov	x0, x18
428	bl	errata_a78_2132060_wa
429#endif
430
431#if ERRATA_A78_2242635
432	mov	x0, x18
433	bl	errata_a78_2242635_wa
434#endif
435
436#if ERRATA_A78_2376745
437	mov	x0, x18
438	bl	errata_a78_2376745_wa
439#endif
440
441#if ERRATA_A78_2395406
442	mov	x0, x18
443	bl	errata_a78_2395406_wa
444#endif
445
446#if ERRATA_A78_2779479
447	mov	x0, x18
448	bl	errata_a78_2779479_wa
449#endif
450
451#if ENABLE_AMU
452	/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
453	mrs	x0, actlr_el3
454	bic	x0, x0, #CORTEX_A78_ACTLR_TAM_BIT
455	msr	actlr_el3, x0
456
457	/* Make sure accesses from non-secure EL0/EL1 are not trapped to EL2 */
458	mrs	x0, actlr_el2
459	bic	x0, x0, #CORTEX_A78_ACTLR_TAM_BIT
460	msr	actlr_el2, x0
461
462	/* Enable group0 counters */
463	mov	x0, #CORTEX_A78_AMU_GROUP0_MASK
464	msr	CPUAMCNTENSET0_EL0, x0
465
466	/* Enable group1 counters */
467	mov	x0, #CORTEX_A78_AMU_GROUP1_MASK
468	msr	CPUAMCNTENSET1_EL0, x0
469#endif
470
471#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
472	/*
473	 * The Cortex-A78 generic vectors are overridden to apply errata
474	 * mitigation on exception entry from lower ELs.
475	 */
476	adr	x0, wa_cve_vbar_cortex_a78
477	msr	vbar_el3, x0
478#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
479
480	isb
481	ret	x19
482endfunc cortex_a78_reset_func
483
484	/* ---------------------------------------------
485	 * HW will do the cache maintenance while powering down
486	 * ---------------------------------------------
487	 */
488func cortex_a78_core_pwr_dwn
489	/* ---------------------------------------------
490	 * Enable CPU power down bit in power control register
491	 * ---------------------------------------------
492	 */
493	mrs	x0, CORTEX_A78_CPUPWRCTLR_EL1
494	orr	x0, x0, #CORTEX_A78_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT
495	msr	CORTEX_A78_CPUPWRCTLR_EL1, x0
496#if ERRATA_A78_2772019
497	mov	x15, x30
498	bl	cpu_get_rev_var
499	bl	errata_a78_2772019_wa
500	mov	x30, x15
501#endif /* ERRATA_A78_2772019 */
502	isb
503	ret
504endfunc cortex_a78_core_pwr_dwn
505
506	/*
507	 * Errata printing function for cortex_a78. Must follow AAPCS.
508	 */
509#if REPORT_ERRATA
510func cortex_a78_errata_report
511	stp	x8, x30, [sp, #-16]!
512
513	bl	cpu_get_rev_var
514	mov	x8, x0
515
516	/*
517	 * Report all errata. The revision-variant information is passed to
518	 * checking functions of each errata.
519	 */
520	report_errata ERRATA_A78_1688305, cortex_a78, 1688305
521	report_errata ERRATA_A78_1941498, cortex_a78, 1941498
522	report_errata ERRATA_A78_1951500, cortex_a78, 1951500
523	report_errata ERRATA_A78_1821534, cortex_a78, 1821534
524	report_errata ERRATA_A78_1952683, cortex_a78, 1952683
525	report_errata ERRATA_A78_2132060, cortex_a78, 2132060
526	report_errata ERRATA_A78_2242635, cortex_a78, 2242635
527	report_errata ERRATA_A78_2376745, cortex_a78, 2376745
528	report_errata ERRATA_A78_2395406, cortex_a78, 2395406
529	report_errata ERRATA_A78_2772019, cortex_a78, 2772019
530	report_errata ERRATA_A78_2779479, cortex_a78, 2779479
531	report_errata WORKAROUND_CVE_2022_23960, cortex_a78, cve_2022_23960
532
533	ldp	x8, x30, [sp], #16
534	ret
535endfunc cortex_a78_errata_report
536#endif
537
538	/* ---------------------------------------------
539	 * This function provides cortex_a78 specific
540	 * register information for crash reporting.
541	 * It needs to return with x6 pointing to
542	 * a list of register names in ascii and
543	 * x8 - x15 having values of registers to be
544	 * reported.
545	 * ---------------------------------------------
546	 */
547.section .rodata.cortex_a78_regs, "aS"
548cortex_a78_regs:  /* The ascii list of register names to be reported */
549	.asciz	"cpuectlr_el1", ""
550
551func cortex_a78_cpu_reg_dump
552	adr	x6, cortex_a78_regs
553	mrs	x8, CORTEX_A78_CPUECTLR_EL1
554	ret
555endfunc cortex_a78_cpu_reg_dump
556
557declare_cpu_ops cortex_a78, CORTEX_A78_MIDR, \
558	cortex_a78_reset_func, \
559	cortex_a78_core_pwr_dwn
560