xref: /arm-trusted-firmware/lib/cpus/aarch64/cortex_a78.S (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu/*
2*91f16700Schasinglulu * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
3*91f16700Schasinglulu *
4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu */
6*91f16700Schasinglulu
7*91f16700Schasinglulu#include <arch.h>
8*91f16700Schasinglulu#include <asm_macros.S>
9*91f16700Schasinglulu#include <common/bl_common.h>
10*91f16700Schasinglulu#include <cortex_a78.h>
11*91f16700Schasinglulu#include <cpu_macros.S>
12*91f16700Schasinglulu#include <plat_macros.S>
13*91f16700Schasinglulu#include "wa_cve_2022_23960_bhb_vector.S"
14*91f16700Schasinglulu
15*91f16700Schasinglulu/* Hardware handled coherency */
16*91f16700Schasinglulu#if HW_ASSISTED_COHERENCY == 0
17*91f16700Schasinglulu#error "cortex_a78 must be compiled with HW_ASSISTED_COHERENCY enabled"
18*91f16700Schasinglulu#endif
19*91f16700Schasinglulu
20*91f16700Schasinglulu.globl cortex_a78_reset_func
21*91f16700Schasinglulu.globl cortex_a78_core_pwr_dwn
22*91f16700Schasinglulu
23*91f16700Schasinglulu#if WORKAROUND_CVE_2022_23960
24*91f16700Schasinglulu	wa_cve_2022_23960_bhb_vector_table CORTEX_A78_BHB_LOOP_COUNT, cortex_a78
25*91f16700Schasinglulu#endif /* WORKAROUND_CVE_2022_23960 */
26*91f16700Schasinglulu
27*91f16700Schasingluluworkaround_reset_start cortex_a78, ERRATUM(1688305), ERRATA_A78_1688305
28*91f16700Schasinglulu	sysreg_bit_set CORTEX_A78_ACTLR2_EL1, CORTEX_A78_ACTLR2_EL1_BIT_1
29*91f16700Schasingluluworkaround_reset_end cortex_a78, ERRATUM(1688305)
30*91f16700Schasinglulu
31*91f16700Schasinglulucheck_erratum_ls cortex_a78, ERRATUM(1688305), CPU_REV(1, 0)
32*91f16700Schasinglulu
33*91f16700Schasingluluworkaround_reset_start cortex_a78, ERRATUM(1821534), ERRATA_A78_1821534
34*91f16700Schasinglulu	sysreg_bit_set CORTEX_A78_ACTLR2_EL1, CORTEX_A78_ACTLR2_EL1_BIT_2
35*91f16700Schasingluluworkaround_reset_end cortex_a78, ERRATUM(1821534)
36*91f16700Schasinglulu
37*91f16700Schasinglulucheck_erratum_ls cortex_a78, ERRATUM(1821534), CPU_REV(1, 0)
38*91f16700Schasinglulu
39*91f16700Schasingluluworkaround_reset_start cortex_a78, ERRATUM(1941498), ERRATA_A78_1941498
40*91f16700Schasinglulu	sysreg_bit_set CORTEX_A78_CPUECTLR_EL1, CORTEX_A78_CPUECTLR_EL1_BIT_8
41*91f16700Schasingluluworkaround_reset_end cortex_a78, ERRATUM(1941498)
42*91f16700Schasinglulu
43*91f16700Schasinglulucheck_erratum_ls cortex_a78, ERRATUM(1941498), CPU_REV(1, 1)
44*91f16700Schasinglulu
45*91f16700Schasingluluworkaround_reset_start cortex_a78, ERRATUM(1951500), ERRATA_A78_1951500
46*91f16700Schasinglulu	msr	S3_6_c15_c8_0, xzr
47*91f16700Schasinglulu	ldr	x0, =0x10E3900002
48*91f16700Schasinglulu	msr	S3_6_c15_c8_2, x0
49*91f16700Schasinglulu	ldr	x0, =0x10FFF00083
50*91f16700Schasinglulu	msr	S3_6_c15_c8_3, x0
51*91f16700Schasinglulu	ldr	x0, =0x2001003FF
52*91f16700Schasinglulu	msr	S3_6_c15_c8_1, x0
53*91f16700Schasinglulu
54*91f16700Schasinglulu	mov	x0, #1
55*91f16700Schasinglulu	msr	S3_6_c15_c8_0, x0
56*91f16700Schasinglulu	ldr	x0, =0x10E3800082
57*91f16700Schasinglulu	msr	S3_6_c15_c8_2, x0
58*91f16700Schasinglulu	ldr	x0, =0x10FFF00083
59*91f16700Schasinglulu	msr	S3_6_c15_c8_3, x0
60*91f16700Schasinglulu	ldr	x0, =0x2001003FF
61*91f16700Schasinglulu	msr	S3_6_c15_c8_1, x0
62*91f16700Schasinglulu
63*91f16700Schasinglulu	mov	x0, #2
64*91f16700Schasinglulu	msr	S3_6_c15_c8_0, x0
65*91f16700Schasinglulu	ldr	x0, =0x10E3800200
66*91f16700Schasinglulu	msr	S3_6_c15_c8_2, x0
67*91f16700Schasinglulu	ldr	x0, =0x10FFF003E0
68*91f16700Schasinglulu	msr	S3_6_c15_c8_3, x0
69*91f16700Schasinglulu	ldr	x0, =0x2001003FF
70*91f16700Schasinglulu	msr	S3_6_c15_c8_1, x0
71*91f16700Schasingluluworkaround_reset_end cortex_a78, ERRATUM(1951500)
72*91f16700Schasinglulu
73*91f16700Schasinglulucheck_erratum_range cortex_a78, ERRATUM(1951500), CPU_REV(1, 0), CPU_REV(1, 1)
74*91f16700Schasinglulu
75*91f16700Schasingluluworkaround_reset_start cortex_a78, ERRATUM(1952683), ERRATA_A78_1952683
76*91f16700Schasinglulu	ldr	x0,=0x5
77*91f16700Schasinglulu	msr	S3_6_c15_c8_0,x0
78*91f16700Schasinglulu	ldr	x0,=0xEEE10A10
79*91f16700Schasinglulu	msr	S3_6_c15_c8_2,x0
80*91f16700Schasinglulu	ldr	x0,=0xFFEF0FFF
81*91f16700Schasinglulu	msr	S3_6_c15_c8_3,x0
82*91f16700Schasinglulu	ldr	x0,=0x0010F000
83*91f16700Schasinglulu	msr	S3_6_c15_c8_4,x0
84*91f16700Schasinglulu	ldr	x0,=0x0010F000
85*91f16700Schasinglulu	msr	S3_6_c15_c8_5,x0
86*91f16700Schasinglulu	ldr	x0,=0x40000080023ff
87*91f16700Schasinglulu	msr	S3_6_c15_c8_1,x0
88*91f16700Schasinglulu	ldr	x0,=0x6
89*91f16700Schasinglulu	msr	S3_6_c15_c8_0,x0
90*91f16700Schasinglulu	ldr	x0,=0xEE640F34
91*91f16700Schasinglulu	msr	S3_6_c15_c8_2,x0
92*91f16700Schasinglulu	ldr	x0,=0xFFEF0FFF
93*91f16700Schasinglulu	msr	S3_6_c15_c8_3,x0
94*91f16700Schasinglulu	ldr	x0,=0x40000080023ff
95*91f16700Schasinglulu	msr	S3_6_c15_c8_1,x0
96*91f16700Schasingluluworkaround_reset_end cortex_a78, ERRATUM(1952683)
97*91f16700Schasinglulu
98*91f16700Schasinglulucheck_erratum_ls cortex_a78, ERRATUM(1952683), CPU_REV(0, 0)
99*91f16700Schasinglulu
100*91f16700Schasingluluworkaround_reset_start cortex_a78, ERRATUM(2132060), ERRATA_A78_2132060
101*91f16700Schasinglulu	/* Apply the workaround. */
102*91f16700Schasinglulu	mrs	x1, CORTEX_A78_CPUECTLR_EL1
103*91f16700Schasinglulu	mov	x0, #CORTEX_A78_CPUECTLR_EL1_PF_MODE_CNSRV
104*91f16700Schasinglulu	bfi	x1, x0, #CPUECTLR_EL1_PF_MODE_LSB, #CPUECTLR_EL1_PF_MODE_WIDTH
105*91f16700Schasinglulu	msr	CORTEX_A78_CPUECTLR_EL1, x1
106*91f16700Schasingluluworkaround_reset_end cortex_a78, ERRATUM(2132060)
107*91f16700Schasinglulu
108*91f16700Schasinglulucheck_erratum_ls cortex_a78, ERRATUM(2132060), CPU_REV(1, 2)
109*91f16700Schasinglulu
110*91f16700Schasingluluworkaround_reset_start cortex_a78, ERRATUM(2242635), ERRATA_A78_2242635
111*91f16700Schasinglulu	ldr	x0, =0x5
112*91f16700Schasinglulu	msr	S3_6_c15_c8_0, x0 /* CPUPSELR_EL3 */
113*91f16700Schasinglulu	ldr	x0, =0x10F600E000
114*91f16700Schasinglulu	msr	S3_6_c15_c8_2, x0 /* CPUPOR_EL3 */
115*91f16700Schasinglulu	ldr	x0, =0x10FF80E000
116*91f16700Schasinglulu	msr	S3_6_c15_c8_3, x0 /* CPUPMR_EL3 */
117*91f16700Schasinglulu	ldr	x0, =0x80000000003FF
118*91f16700Schasinglulu	msr	S3_6_c15_c8_1, x0 /* CPUPCR_EL3 */
119*91f16700Schasingluluworkaround_reset_end cortex_a78, ERRATUM(2242635)
120*91f16700Schasinglulu
121*91f16700Schasinglulucheck_erratum_range cortex_a78, ERRATUM(2242635), CPU_REV(1, 0), CPU_REV(1, 2)
122*91f16700Schasinglulu
123*91f16700Schasingluluworkaround_reset_start cortex_a78, ERRATUM(2376745), ERRATA_A78_2376745
124*91f16700Schasinglulu	sysreg_bit_set CORTEX_A78_ACTLR2_EL1, BIT(0)
125*91f16700Schasingluluworkaround_reset_end cortex_a78, ERRATUM(2376745)
126*91f16700Schasinglulu
127*91f16700Schasinglulucheck_erratum_ls cortex_a78, ERRATUM(2376745), CPU_REV(1, 2)
128*91f16700Schasinglulu
129*91f16700Schasingluluworkaround_reset_start cortex_a78, ERRATUM(2395406), ERRATA_A78_2395406
130*91f16700Schasinglulu	sysreg_bit_set CORTEX_A78_ACTLR2_EL1, BIT(40)
131*91f16700Schasingluluworkaround_reset_end cortex_a78, ERRATUM(2395406)
132*91f16700Schasinglulu
133*91f16700Schasinglulucheck_erratum_ls cortex_a78, ERRATUM(2395406), CPU_REV(1, 2)
134*91f16700Schasinglulu
135*91f16700Schasingluluworkaround_reset_start cortex_a78, ERRATUM(2742426), ERRATA_A78_2742426
136*91f16700Schasinglulu	/* Apply the workaround */
137*91f16700Schasinglulu	mrs	x1, CORTEX_A78_ACTLR5_EL1
138*91f16700Schasinglulu	bic	x1, x1, #BIT(56)
139*91f16700Schasinglulu	orr	x1, x1, #BIT(55)
140*91f16700Schasinglulu	msr	CORTEX_A78_ACTLR5_EL1, x1
141*91f16700Schasingluluworkaround_reset_end cortex_a78, ERRATUM(2742426)
142*91f16700Schasinglulu
143*91f16700Schasinglulucheck_erratum_ls cortex_a78, ERRATUM(2742426), CPU_REV(1, 2)
144*91f16700Schasinglulu
145*91f16700Schasingluluworkaround_runtime_start cortex_a78, ERRATUM(2772019), ERRATA_A78_2772019
146*91f16700Schasinglulu	/* dsb before isb of power down sequence */
147*91f16700Schasinglulu	dsb	sy
148*91f16700Schasingluluworkaround_runtime_end cortex_a78, ERRATUM(2772019)
149*91f16700Schasinglulu
150*91f16700Schasinglulucheck_erratum_ls cortex_a78, ERRATUM(2772019), CPU_REV(1, 2)
151*91f16700Schasinglulu
152*91f16700Schasingluluworkaround_reset_start cortex_a78, ERRATUM(2779479), ERRATA_A78_2779479
153*91f16700Schasinglulu	sysreg_bit_set CORTEX_A78_ACTLR3_EL1, BIT(47)
154*91f16700Schasingluluworkaround_reset_end cortex_a78, ERRATUM(2779479)
155*91f16700Schasinglulu
156*91f16700Schasinglulucheck_erratum_ls cortex_a78, ERRATUM(2779479), CPU_REV(1, 2)
157*91f16700Schasinglulu
158*91f16700Schasingluluworkaround_reset_start cortex_a78, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
159*91f16700Schasinglulu#if IMAGE_BL31
160*91f16700Schasinglulu	/*
161*91f16700Schasinglulu	 * The Cortex-X1 generic vectors are overridden to apply errata
162*91f16700Schasinglulu	 * mitigation on exception entry from lower ELs.
163*91f16700Schasinglulu	 */
164*91f16700Schasinglulu	override_vector_table wa_cve_vbar_cortex_a78
165*91f16700Schasinglulu#endif /* IMAGE_BL31 */
166*91f16700Schasingluluworkaround_reset_end cortex_a78, CVE(2022, 23960)
167*91f16700Schasinglulu
168*91f16700Schasinglulucheck_erratum_chosen cortex_a78, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
169*91f16700Schasinglulu
170*91f16700Schasinglulucpu_reset_func_start cortex_a78
171*91f16700Schasinglulu#if ENABLE_FEAT_AMU
172*91f16700Schasinglulu	/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
173*91f16700Schasinglulu	sysreg_bit_clear actlr_el3, CORTEX_A78_ACTLR_TAM_BIT
174*91f16700Schasinglulu
175*91f16700Schasinglulu	/* Make sure accesses from non-secure EL0/EL1 are not trapped to EL2 */
176*91f16700Schasinglulu	sysreg_bit_clear actlr_el2, CORTEX_A78_ACTLR_TAM_BIT
177*91f16700Schasinglulu
178*91f16700Schasinglulu	/* Enable group0 counters */
179*91f16700Schasinglulu	mov	x0, #CORTEX_A78_AMU_GROUP0_MASK
180*91f16700Schasinglulu	msr	CPUAMCNTENSET0_EL0, x0
181*91f16700Schasinglulu
182*91f16700Schasinglulu	/* Enable group1 counters */
183*91f16700Schasinglulu	mov	x0, #CORTEX_A78_AMU_GROUP1_MASK
184*91f16700Schasinglulu	msr	CPUAMCNTENSET1_EL0, x0
185*91f16700Schasinglulu#endif
186*91f16700Schasinglulucpu_reset_func_end cortex_a78
187*91f16700Schasinglulu
188*91f16700Schasinglulu	/* ---------------------------------------------
189*91f16700Schasinglulu	 * HW will do the cache maintenance while powering down
190*91f16700Schasinglulu	 * ---------------------------------------------
191*91f16700Schasinglulu	 */
192*91f16700Schasinglulufunc cortex_a78_core_pwr_dwn
193*91f16700Schasinglulu	sysreg_bit_set CORTEX_A78_CPUPWRCTLR_EL1, CORTEX_A78_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT
194*91f16700Schasinglulu
195*91f16700Schasinglulu	apply_erratum cortex_a78, ERRATUM(2772019), ERRATA_A78_2772019
196*91f16700Schasinglulu
197*91f16700Schasinglulu	isb
198*91f16700Schasinglulu	ret
199*91f16700Schasingluluendfunc cortex_a78_core_pwr_dwn
200*91f16700Schasinglulu
201*91f16700Schasingluluerrata_report_shim cortex_a78
202*91f16700Schasinglulu
203*91f16700Schasinglulu	/* ---------------------------------------------
204*91f16700Schasinglulu	 * This function provides cortex_a78 specific
205*91f16700Schasinglulu	 * register information for crash reporting.
206*91f16700Schasinglulu	 * It needs to return with x6 pointing to
207*91f16700Schasinglulu	 * a list of register names in ascii and
208*91f16700Schasinglulu	 * x8 - x15 having values of registers to be
209*91f16700Schasinglulu	 * reported.
210*91f16700Schasinglulu	 * ---------------------------------------------
211*91f16700Schasinglulu	 */
212*91f16700Schasinglulu.section .rodata.cortex_a78_regs, "aS"
213*91f16700Schasinglulucortex_a78_regs:  /* The ascii list of register names to be reported */
214*91f16700Schasinglulu	.asciz	"cpuectlr_el1", ""
215*91f16700Schasinglulu
216*91f16700Schasinglulufunc cortex_a78_cpu_reg_dump
217*91f16700Schasinglulu	adr	x6, cortex_a78_regs
218*91f16700Schasinglulu	mrs	x8, CORTEX_A78_CPUECTLR_EL1
219*91f16700Schasinglulu	ret
220*91f16700Schasingluluendfunc cortex_a78_cpu_reg_dump
221*91f16700Schasinglulu
222*91f16700Schasingluludeclare_cpu_ops cortex_a78, CORTEX_A78_MIDR, \
223*91f16700Schasinglulu	cortex_a78_reset_func, \
224*91f16700Schasinglulu	cortex_a78_core_pwr_dwn
225