xref: /rk3399_ARM-atf/lib/cpus/aarch64/cortex_a78_ae.S (revision 92e870843e9bd654fd1041d66f284c19ca9c0d4f)
1/*
2 * Copyright (c) 2019-2022, ARM Limited. All rights reserved.
3 * Copyright (c) 2021-2022, NVIDIA Corporation. All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8#include <arch.h>
9#include <asm_macros.S>
10#include <common/bl_common.h>
11#include <cortex_a78_ae.h>
12#include <cpu_macros.S>
13#include <plat_macros.S>
14#include "wa_cve_2022_23960_bhb_vector.S"
15
16/* Hardware handled coherency */
17#if HW_ASSISTED_COHERENCY == 0
18#error "cortex_a78_ae must be compiled with HW_ASSISTED_COHERENCY enabled"
19#endif
20
21#if WORKAROUND_CVE_2022_23960
22	wa_cve_2022_23960_bhb_vector_table CORTEX_A78_AE_BHB_LOOP_COUNT, cortex_a78_ae
23#endif /* WORKAROUND_CVE_2022_23960 */
24
25/* --------------------------------------------------
26 * Errata Workaround for A78 AE Erratum 1941500.
27 * This applies to revisions r0p0 and r0p1 of A78 AE.
28 * Inputs:
29 * x0: variant[4:7] and revision[0:3] of current cpu.
30 * Shall clobber: x0-x17
31 * --------------------------------------------------
32 */
33func errata_a78_ae_1941500_wa
34	/* Compare x0 against revisions r0p0 - r0p1 */
35	mov	x17, x30
36	bl	check_errata_1941500
37	cbz	x0, 1f
38
39	/* Set bit 8 in ECTLR_EL1 */
40	mrs	x0, CORTEX_A78_AE_CPUECTLR_EL1
41	bic	x0, x0, #CORTEX_A78_AE_CPUECTLR_EL1_BIT_8
42	msr	CORTEX_A78_AE_CPUECTLR_EL1, x0
43	isb
441:
45	ret	x17
46endfunc errata_a78_ae_1941500_wa
47
48func check_errata_1941500
49	/* Applies to revisions r0p0 and r0p1. */
50	mov	x1, #CPU_REV(0, 0)
51	mov	x2, #CPU_REV(0, 1)
52	b	cpu_rev_var_range
53endfunc check_errata_1941500
54
55/* --------------------------------------------------
56 * Errata Workaround for A78 AE Erratum 1951502.
57 * This applies to revisions r0p0 and r0p1 of A78 AE.
58 * Inputs:
59 * x0: variant[4:7] and revision[0:3] of current cpu.
60 * Shall clobber: x0-x17
61 * --------------------------------------------------
62 */
63func errata_a78_ae_1951502_wa
64	/* Compare x0 against revisions r0p0 - r0p1 */
65	mov	x17, x30
66	bl	check_errata_1951502
67	cbz	x0, 1f
68
69	msr	S3_6_c15_c8_0, xzr
70	ldr	x0, =0x10E3900002
71	msr	S3_6_c15_c8_2, x0
72	ldr	x0, =0x10FFF00083
73	msr	S3_6_c15_c8_3, x0
74	ldr	x0, =0x2001003FF
75	msr	S3_6_c15_c8_1, x0
76
77	mov	x0, #1
78	msr	S3_6_c15_c8_0, x0
79	ldr	x0, =0x10E3800082
80	msr	S3_6_c15_c8_2, x0
81	ldr	x0, =0x10FFF00083
82	msr	S3_6_c15_c8_3, x0
83	ldr	x0, =0x2001003FF
84	msr	S3_6_c15_c8_1, x0
85
86	mov	x0, #2
87	msr	S3_6_c15_c8_0, x0
88	ldr	x0, =0x10E3800200
89	msr	S3_6_c15_c8_2, x0
90	ldr	x0, =0x10FFF003E0
91	msr	S3_6_c15_c8_3, x0
92	ldr	x0, =0x2001003FF
93	msr	S3_6_c15_c8_1, x0
94
95	isb
961:
97	ret	x17
98endfunc errata_a78_ae_1951502_wa
99
100func check_errata_1951502
101	/* Applies to revisions r0p0 and r0p1. */
102	mov	x1, #CPU_REV(0, 0)
103	mov	x2, #CPU_REV(0, 1)
104	b	cpu_rev_var_range
105endfunc check_errata_1951502
106
107/* --------------------------------------------------
108 * Errata Workaround for A78 AE Erratum 2376748.
109 * This applies to revisions r0p0 and r0p1 of A78 AE.
110 * Inputs:
111 * x0: variant[4:7] and revision[0:3] of current cpu.
112 * Shall clobber: x0-x17
113 * --------------------------------------------------
114 */
115func errata_a78_ae_2376748_wa
116	/* Compare x0 against revisions r0p0 - r0p1 */
117	mov	x17, x30
118	bl	check_errata_2376748
119	cbz	x0, 1f
120
121	/* -------------------------------------------------------
122	 * Set CPUACTLR2_EL1[0] to 1 to force PLDW/PFRM ST to
123	 * behave like PLD/PRFM LD and not cause invalidations to
124	 * other PE caches. There might be a small performance
125	 * degradation to this workaround for certain workloads
126	 * that share data.
127	 * -------------------------------------------------------
128	 */
129	mrs	x0, CORTEX_A78_AE_ACTLR2_EL1
130	orr	x0, x0, #CORTEX_A78_AE_ACTLR2_EL1_BIT_0
131	msr	CORTEX_A78_AE_ACTLR2_EL1, x0
132	isb
1331:
134	ret	x17
135endfunc errata_a78_ae_2376748_wa
136
137func check_errata_2376748
138	/* Applies to revisions r0p0 and r0p1. */
139	mov	x1, #CPU_REV(0, 0)
140	mov	x2, #CPU_REV(0, 1)
141	b	cpu_rev_var_range
142endfunc check_errata_2376748
143
144func check_errata_cve_2022_23960
145#if WORKAROUND_CVE_2022_23960
146	mov	x0, #ERRATA_APPLIES
147#else
148	mov	x0, #ERRATA_MISSING
149#endif
150	ret
151endfunc check_errata_cve_2022_23960
152
153	/* -------------------------------------------------
154	 * The CPU Ops reset function for Cortex-A78-AE
155	 * -------------------------------------------------
156	 */
157func cortex_a78_ae_reset_func
158	mov	x19, x30
159	bl	cpu_get_rev_var
160	mov	x18, x0
161
162#if ERRATA_A78_AE_1941500
163	mov	x0, x18
164	bl	errata_a78_ae_1941500_wa
165#endif
166
167#if ERRATA_A78_AE_1951502
168	mov	x0, x18
169	bl	errata_a78_ae_1951502_wa
170#endif
171
172#if ERRATA_A78_AE_2376748
173	mov	x0, x18
174	bl	errata_a78_ae_2376748_wa
175#endif
176
177#if ENABLE_AMU
178	/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
179	mrs	x0, actlr_el3
180	bic	x0, x0, #CORTEX_A78_ACTLR_TAM_BIT
181	msr	actlr_el3, x0
182
183	/* Make sure accesses from non-secure EL0/EL1 are not trapped to EL2 */
184	mrs	x0, actlr_el2
185	bic	x0, x0, #CORTEX_A78_ACTLR_TAM_BIT
186	msr	actlr_el2, x0
187
188	/* Enable group0 counters */
189	mov	x0, #CORTEX_A78_AMU_GROUP0_MASK
190	msr	CPUAMCNTENSET0_EL0, x0
191
192	/* Enable group1 counters */
193	mov	x0, #CORTEX_A78_AMU_GROUP1_MASK
194	msr	CPUAMCNTENSET1_EL0, x0
195#endif
196
197#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
198	/*
199	 * The Cortex-A78AE generic vectors are overridden to apply errata
200	 * mitigation on exception entry from lower ELs.
201	 */
202	adr	x0, wa_cve_vbar_cortex_a78_ae
203	msr	vbar_el3, x0
204#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
205
206	isb
207	ret	x19
208endfunc cortex_a78_ae_reset_func
209
210	/* -------------------------------------------------------
211	 * HW will do the cache maintenance while powering down
212	 * -------------------------------------------------------
213	 */
214func cortex_a78_ae_core_pwr_dwn
215	/* -------------------------------------------------------
216	 * Enable CPU power down bit in power control register
217	 * -------------------------------------------------------
218	 */
219	mrs	x0, CORTEX_A78_CPUPWRCTLR_EL1
220	orr	x0, x0, #CORTEX_A78_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT
221	msr	CORTEX_A78_CPUPWRCTLR_EL1, x0
222	isb
223	ret
224endfunc cortex_a78_ae_core_pwr_dwn
225
226	/*
227	 * Errata printing function for cortex_a78_ae. Must follow AAPCS.
228	 */
229#if REPORT_ERRATA
230func cortex_a78_ae_errata_report
231	stp	x8, x30, [sp, #-16]!
232
233	bl	cpu_get_rev_var
234	mov	x8, x0
235
236	/*
237	 * Report all errata. The revision-variant information is passed to
238	 * checking functions of each errata.
239	 */
240	report_errata ERRATA_A78_AE_1941500, cortex_a78_ae, 1941500
241	report_errata ERRATA_A78_AE_1951502, cortex_a78_ae, 1951502
242	report_errata ERRATA_A78_AE_2376748, cortex_a78_ae, 2376748
243	report_errata WORKAROUND_CVE_2022_23960, cortex_a78_ae, cve_2022_23960
244
245	ldp	x8, x30, [sp], #16
246	ret
247endfunc cortex_a78_ae_errata_report
248#endif
249
250	/* -------------------------------------------------------
251	 * This function provides cortex_a78_ae specific
252	 * register information for crash reporting.
253	 * It needs to return with x6 pointing to
254	 * a list of register names in ascii and
255	 * x8 - x15 having values of registers to be
256	 * reported.
257	 * -------------------------------------------------------
258	 */
259.section .rodata.cortex_a78_ae_regs, "aS"
260cortex_a78_ae_regs:  /* The ascii list of register names to be reported */
261	.asciz	"cpuectlr_el1", ""
262
263func cortex_a78_ae_cpu_reg_dump
264	adr	x6, cortex_a78_ae_regs
265	mrs	x8, CORTEX_A78_CPUECTLR_EL1
266	ret
267endfunc cortex_a78_ae_cpu_reg_dump
268
269declare_cpu_ops cortex_a78_ae, CORTEX_A78_AE_MIDR, \
270	cortex_a78_ae_reset_func, \
271	cortex_a78_ae_core_pwr_dwn
272