xref: /arm-trusted-firmware/lib/cpus/aarch64/neoverse_n1.S (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu/*
2*91f16700Schasinglulu * Copyright (c) 2017-2023, Arm Limited and Contributors. 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 <cpuamu.h>
10*91f16700Schasinglulu#include <cpu_macros.S>
11*91f16700Schasinglulu#include <neoverse_n1.h>
12*91f16700Schasinglulu#include "wa_cve_2022_23960_bhb_vector.S"
13*91f16700Schasinglulu
14*91f16700Schasinglulu/* Hardware handled coherency */
15*91f16700Schasinglulu#if HW_ASSISTED_COHERENCY == 0
16*91f16700Schasinglulu#error "Neoverse N1 must be compiled with HW_ASSISTED_COHERENCY enabled"
17*91f16700Schasinglulu#endif
18*91f16700Schasinglulu
19*91f16700Schasinglulu/* 64-bit only core */
20*91f16700Schasinglulu#if CTX_INCLUDE_AARCH32_REGS == 1
21*91f16700Schasinglulu#error "Neoverse-N1 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
22*91f16700Schasinglulu#endif
23*91f16700Schasinglulu
24*91f16700Schasinglulu	.global neoverse_n1_errata_ic_trap_handler
25*91f16700Schasinglulu
26*91f16700Schasinglulu#if WORKAROUND_CVE_2022_23960
27*91f16700Schasinglulu	wa_cve_2022_23960_bhb_vector_table NEOVERSE_N1_BHB_LOOP_COUNT, neoverse_n1
28*91f16700Schasinglulu#endif /* WORKAROUND_CVE_2022_23960 */
29*91f16700Schasinglulu
30*91f16700Schasinglulu/*
31*91f16700Schasinglulu * ERRATA_DSU_936184:
32*91f16700Schasinglulu * The errata is defined in dsu_helpers.S and applies to Neoverse N1.
33*91f16700Schasinglulu * Henceforth creating symbolic names to the already existing errata
34*91f16700Schasinglulu * workaround functions to get them registered under the Errata Framework.
35*91f16700Schasinglulu */
36*91f16700Schasinglulu.equ check_erratum_neoverse_n1_936184, check_errata_dsu_936184
37*91f16700Schasinglulu.equ erratum_neoverse_n1_936184_wa, errata_dsu_936184_wa
38*91f16700Schasingluluadd_erratum_entry neoverse_n1, ERRATUM(936184), ERRATA_DSU_936184, APPLY_AT_RESET
39*91f16700Schasinglulu
40*91f16700Schasingluluworkaround_reset_start neoverse_n1, ERRATUM(1043202), ERRATA_N1_1043202
41*91f16700Schasinglulu	/* Apply instruction patching sequence */
42*91f16700Schasinglulu	ldr	x0, =0x0
43*91f16700Schasinglulu	msr	CPUPSELR_EL3, x0
44*91f16700Schasinglulu	ldr	x0, =0xF3BF8F2F
45*91f16700Schasinglulu	msr	CPUPOR_EL3, x0
46*91f16700Schasinglulu	ldr	x0, =0xFFFFFFFF
47*91f16700Schasinglulu	msr	CPUPMR_EL3, x0
48*91f16700Schasinglulu	ldr	x0, =0x800200071
49*91f16700Schasinglulu	msr	CPUPCR_EL3, x0
50*91f16700Schasingluluworkaround_reset_end neoverse_n1, ERRATUM(1043202)
51*91f16700Schasinglulu
52*91f16700Schasinglulucheck_erratum_ls neoverse_n1, ERRATUM(1043202), CPU_REV(1, 0)
53*91f16700Schasinglulu
54*91f16700Schasingluluworkaround_reset_start neoverse_n1, ERRATUM(1073348), ERRATA_N1_1073348
55*91f16700Schasinglulu	sysreg_bit_set NEOVERSE_N1_CPUACTLR_EL1, NEOVERSE_N1_CPUACTLR_EL1_BIT_6
56*91f16700Schasingluluworkaround_reset_end neoverse_n1, ERRATUM(1073348)
57*91f16700Schasinglulu
58*91f16700Schasinglulucheck_erratum_ls neoverse_n1, ERRATUM(1073348), CPU_REV(1, 0)
59*91f16700Schasinglulu
60*91f16700Schasingluluworkaround_reset_start neoverse_n1, ERRATUM(1130799), ERRATA_N1_1130799
61*91f16700Schasinglulu	sysreg_bit_set NEOVERSE_N1_CPUACTLR2_EL1, NEOVERSE_N1_CPUACTLR2_EL1_BIT_59
62*91f16700Schasingluluworkaround_reset_end neoverse_n1, ERRATUM(1130799)
63*91f16700Schasinglulu
64*91f16700Schasinglulucheck_erratum_ls neoverse_n1, ERRATUM(1130799), CPU_REV(2, 0)
65*91f16700Schasinglulu
66*91f16700Schasingluluworkaround_reset_start neoverse_n1, ERRATUM(1165347), ERRATA_N1_1165347
67*91f16700Schasinglulu	sysreg_bit_set NEOVERSE_N1_CPUACTLR2_EL1, NEOVERSE_N1_CPUACTLR2_EL1_BIT_0
68*91f16700Schasinglulu	sysreg_bit_set NEOVERSE_N1_CPUACTLR2_EL1, NEOVERSE_N1_CPUACTLR2_EL1_BIT_15
69*91f16700Schasingluluworkaround_reset_end neoverse_n1, ERRATUM(1165347)
70*91f16700Schasinglulu
71*91f16700Schasinglulucheck_erratum_ls neoverse_n1, ERRATUM(1165347), CPU_REV(2, 0)
72*91f16700Schasinglulu
73*91f16700Schasingluluworkaround_reset_start neoverse_n1, ERRATUM(1207823), ERRATA_N1_1207823
74*91f16700Schasinglulu	sysreg_bit_set NEOVERSE_N1_CPUACTLR2_EL1, NEOVERSE_N1_CPUACTLR2_EL1_BIT_11
75*91f16700Schasingluluworkaround_reset_end neoverse_n1, ERRATUM(1207823)
76*91f16700Schasinglulu
77*91f16700Schasinglulucheck_erratum_ls neoverse_n1, ERRATUM(1207823), CPU_REV(2, 0)
78*91f16700Schasinglulu
79*91f16700Schasingluluworkaround_reset_start neoverse_n1, ERRATUM(1220197), ERRATA_N1_1220197
80*91f16700Schasinglulu	sysreg_bit_set NEOVERSE_N1_CPUECTLR_EL1, NEOVERSE_N1_WS_THR_L2_MASK
81*91f16700Schasingluluworkaround_reset_end neoverse_n1, ERRATUM(1220197)
82*91f16700Schasinglulu
83*91f16700Schasinglulucheck_erratum_ls neoverse_n1, ERRATUM(1220197), CPU_REV(2, 0)
84*91f16700Schasinglulu
85*91f16700Schasingluluworkaround_reset_start neoverse_n1, ERRATUM(1257314), ERRATA_N1_1257314
86*91f16700Schasinglulu	sysreg_bit_set NEOVERSE_N1_CPUACTLR3_EL1, NEOVERSE_N1_CPUACTLR3_EL1_BIT_10
87*91f16700Schasingluluworkaround_reset_end neoverse_n1, ERRATUM(1257314)
88*91f16700Schasinglulu
89*91f16700Schasinglulucheck_erratum_ls neoverse_n1, ERRATUM(1257314), CPU_REV(3, 0)
90*91f16700Schasinglulu
91*91f16700Schasingluluworkaround_reset_start neoverse_n1, ERRATUM(1262606), ERRATA_N1_1262606
92*91f16700Schasinglulu	sysreg_bit_set NEOVERSE_N1_CPUACTLR_EL1, NEOVERSE_N1_CPUACTLR_EL1_BIT_13
93*91f16700Schasingluluworkaround_reset_end neoverse_n1, ERRATUM(1262606)
94*91f16700Schasinglulu
95*91f16700Schasinglulucheck_erratum_ls neoverse_n1, ERRATUM(1262606), CPU_REV(3, 0)
96*91f16700Schasinglulu
97*91f16700Schasingluluworkaround_reset_start neoverse_n1, ERRATUM(1262888), ERRATA_N1_1262888
98*91f16700Schasinglulu	sysreg_bit_set NEOVERSE_N1_CPUECTLR_EL1, NEOVERSE_N1_CPUECTLR_EL1_MM_TLBPF_DIS_BIT
99*91f16700Schasingluluworkaround_reset_end neoverse_n1, ERRATUM(1262888)
100*91f16700Schasinglulu
101*91f16700Schasinglulucheck_erratum_ls neoverse_n1, ERRATUM(1262888), CPU_REV(3, 0)
102*91f16700Schasinglulu
103*91f16700Schasingluluworkaround_reset_start neoverse_n1, ERRATUM(1275112), ERRATA_N1_1275112
104*91f16700Schasinglulu	sysreg_bit_set NEOVERSE_N1_CPUACTLR_EL1, NEOVERSE_N1_CPUACTLR_EL1_BIT_13
105*91f16700Schasingluluworkaround_reset_end neoverse_n1, ERRATUM(1275112)
106*91f16700Schasinglulu
107*91f16700Schasinglulucheck_erratum_ls neoverse_n1, ERRATUM(1275112), CPU_REV(3, 0)
108*91f16700Schasinglulu
109*91f16700Schasingluluworkaround_reset_start neoverse_n1, ERRATUM(1315703), ERRATA_N1_1315703
110*91f16700Schasinglulu	sysreg_bit_set NEOVERSE_N1_CPUACTLR2_EL1, NEOVERSE_N1_CPUACTLR2_EL1_BIT_16
111*91f16700Schasingluluworkaround_reset_end neoverse_n1, ERRATUM(1315703)
112*91f16700Schasinglulu
113*91f16700Schasinglulucheck_erratum_ls neoverse_n1, ERRATUM(1315703), CPU_REV(3, 0)
114*91f16700Schasinglulu
115*91f16700Schasingluluworkaround_reset_start neoverse_n1, ERRATUM(1542419), ERRATA_N1_1542419
116*91f16700Schasinglulu	/* Apply instruction patching sequence */
117*91f16700Schasinglulu	ldr	x0, =0x0
118*91f16700Schasinglulu	msr	CPUPSELR_EL3, x0
119*91f16700Schasinglulu	ldr	x0, =0xEE670D35
120*91f16700Schasinglulu	msr	CPUPOR_EL3, x0
121*91f16700Schasinglulu	ldr	x0, =0xFFFF0FFF
122*91f16700Schasinglulu	msr	CPUPMR_EL3, x0
123*91f16700Schasinglulu	ldr	x0, =0x08000020007D
124*91f16700Schasinglulu	msr	CPUPCR_EL3, x0
125*91f16700Schasinglulu	isb
126*91f16700Schasingluluworkaround_reset_end neoverse_n1, ERRATUM(1542419)
127*91f16700Schasinglulu
128*91f16700Schasinglulucheck_erratum_range neoverse_n1, ERRATUM(1542419), CPU_REV(3, 0), CPU_REV(4, 0)
129*91f16700Schasinglulu
130*91f16700Schasingluluworkaround_reset_start neoverse_n1, ERRATUM(1868343), ERRATA_N1_1868343
131*91f16700Schasinglulu	sysreg_bit_set NEOVERSE_N1_CPUACTLR_EL1, NEOVERSE_N1_CPUACTLR_EL1_BIT_13
132*91f16700Schasingluluworkaround_reset_end neoverse_n1, ERRATUM(1868343)
133*91f16700Schasinglulu
134*91f16700Schasinglulucheck_erratum_ls neoverse_n1, ERRATUM(1868343), CPU_REV(4, 0)
135*91f16700Schasinglulu
136*91f16700Schasingluluworkaround_reset_start neoverse_n1, ERRATUM(1946160), ERRATA_N1_1946160
137*91f16700Schasinglulu	mov	x0, #3
138*91f16700Schasinglulu	msr	S3_6_C15_C8_0, x0
139*91f16700Schasinglulu	ldr	x0, =0x10E3900002
140*91f16700Schasinglulu	msr	S3_6_C15_C8_2, x0
141*91f16700Schasinglulu	ldr	x0, =0x10FFF00083
142*91f16700Schasinglulu	msr	S3_6_C15_C8_3, x0
143*91f16700Schasinglulu	ldr	x0, =0x2001003FF
144*91f16700Schasinglulu	msr	S3_6_C15_C8_1, x0
145*91f16700Schasinglulu	mov	x0, #4
146*91f16700Schasinglulu	msr	S3_6_C15_C8_0, x0
147*91f16700Schasinglulu	ldr	x0, =0x10E3800082
148*91f16700Schasinglulu	msr	S3_6_C15_C8_2, x0
149*91f16700Schasinglulu	ldr	x0, =0x10FFF00083
150*91f16700Schasinglulu	msr	S3_6_C15_C8_3, x0
151*91f16700Schasinglulu	ldr	x0, =0x2001003FF
152*91f16700Schasinglulu	msr	S3_6_C15_C8_1, x0
153*91f16700Schasinglulu	mov	x0, #5
154*91f16700Schasinglulu	msr	S3_6_C15_C8_0, x0
155*91f16700Schasinglulu	ldr	x0, =0x10E3800200
156*91f16700Schasinglulu	msr	S3_6_C15_C8_2, x0
157*91f16700Schasinglulu	ldr	x0, =0x10FFF003E0
158*91f16700Schasinglulu	msr	S3_6_C15_C8_3, x0
159*91f16700Schasinglulu	ldr	x0, =0x2001003FF
160*91f16700Schasinglulu	msr	S3_6_C15_C8_1, x0
161*91f16700Schasinglulu	isb
162*91f16700Schasingluluworkaround_reset_end neoverse_n1, ERRATUM(1946160)
163*91f16700Schasinglulu
164*91f16700Schasinglulucheck_erratum_range neoverse_n1, ERRATUM(1946160), CPU_REV(3, 0), CPU_REV(4, 1)
165*91f16700Schasinglulu
166*91f16700Schasingluluworkaround_runtime_start neoverse_n1, ERRATUM(2743102), ERRATA_N1_2743102
167*91f16700Schasinglulu	/* dsb before isb of power down sequence */
168*91f16700Schasinglulu	dsb	sy
169*91f16700Schasingluluworkaround_runtime_end neoverse_n1, ERRATUM(2743102)
170*91f16700Schasinglulu
171*91f16700Schasinglulucheck_erratum_ls neoverse_n1, ERRATUM(2743102), CPU_REV(4, 1)
172*91f16700Schasinglulu
173*91f16700Schasingluluworkaround_reset_start neoverse_n1, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
174*91f16700Schasinglulu#if IMAGE_BL31
175*91f16700Schasinglulu	/*
176*91f16700Schasinglulu	 * The Neoverse-N1 generic vectors are overridden to apply errata
177*91f16700Schasinglulu	 * mitigation on exception entry from lower ELs.
178*91f16700Schasinglulu	 */
179*91f16700Schasinglulu	override_vector_table wa_cve_vbar_neoverse_n1
180*91f16700Schasinglulu#endif /* IMAGE_BL31 */
181*91f16700Schasingluluworkaround_reset_end neoverse_n1, CVE(2022, 23960)
182*91f16700Schasinglulu
183*91f16700Schasinglulucheck_erratum_chosen neoverse_n1, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
184*91f16700Schasinglulu
185*91f16700Schasinglulu/* --------------------------------------------------
186*91f16700Schasinglulu * Disable speculative loads if Neoverse N1 supports
187*91f16700Schasinglulu * SSBS.
188*91f16700Schasinglulu *
189*91f16700Schasinglulu * Shall clobber: x0.
190*91f16700Schasinglulu * --------------------------------------------------
191*91f16700Schasinglulu */
192*91f16700Schasinglulufunc neoverse_n1_disable_speculative_loads
193*91f16700Schasinglulu	/* Check if the PE implements SSBS */
194*91f16700Schasinglulu	mrs	x0, id_aa64pfr1_el1
195*91f16700Schasinglulu	tst	x0, #(ID_AA64PFR1_EL1_SSBS_MASK << ID_AA64PFR1_EL1_SSBS_SHIFT)
196*91f16700Schasinglulu	b.eq	1f
197*91f16700Schasinglulu
198*91f16700Schasinglulu	/* Disable speculative loads */
199*91f16700Schasinglulu	msr	SSBS, xzr
200*91f16700Schasinglulu
201*91f16700Schasinglulu1:
202*91f16700Schasinglulu	ret
203*91f16700Schasingluluendfunc neoverse_n1_disable_speculative_loads
204*91f16700Schasinglulu
205*91f16700Schasinglulucpu_reset_func_start neoverse_n1
206*91f16700Schasinglulu	bl neoverse_n1_disable_speculative_loads
207*91f16700Schasinglulu
208*91f16700Schasinglulu	/* Forces all cacheable atomic instructions to be near */
209*91f16700Schasinglulu	sysreg_bit_set NEOVERSE_N1_CPUACTLR2_EL1, NEOVERSE_N1_CPUACTLR2_EL1_BIT_2
210*91f16700Schasinglulu	isb
211*91f16700Schasinglulu
212*91f16700Schasinglulu#if ENABLE_FEAT_AMU
213*91f16700Schasinglulu	/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
214*91f16700Schasinglulu	sysreg_bit_set actlr_el3, NEOVERSE_N1_ACTLR_AMEN_BIT
215*91f16700Schasinglulu	/* Make sure accesses from EL0/EL1 are not trapped to EL2 */
216*91f16700Schasinglulu	sysreg_bit_set actlr_el2, NEOVERSE_N1_ACTLR_AMEN_BIT
217*91f16700Schasinglulu	/* Enable group0 counters */
218*91f16700Schasinglulu	mov	x0, #NEOVERSE_N1_AMU_GROUP0_MASK
219*91f16700Schasinglulu	msr	CPUAMCNTENSET_EL0, x0
220*91f16700Schasinglulu#endif
221*91f16700Schasinglulu
222*91f16700Schasinglulu#if NEOVERSE_Nx_EXTERNAL_LLC
223*91f16700Schasinglulu	/* Some system may have External LLC, core needs to be made aware */
224*91f16700Schasinglulu	sysreg_bit_set NEOVERSE_N1_CPUECTLR_EL1, NEOVERSE_N1_CPUECTLR_EL1_EXTLLC_BIT
225*91f16700Schasinglulu#endif
226*91f16700Schasinglulucpu_reset_func_end neoverse_n1
227*91f16700Schasinglulu
228*91f16700Schasinglulu	/* ---------------------------------------------
229*91f16700Schasinglulu	 * HW will do the cache maintenance while powering down
230*91f16700Schasinglulu	 * ---------------------------------------------
231*91f16700Schasinglulu	 */
232*91f16700Schasinglulufunc neoverse_n1_core_pwr_dwn
233*91f16700Schasinglulu	/* ---------------------------------------------
234*91f16700Schasinglulu	 * Enable CPU power down bit in power control register
235*91f16700Schasinglulu	 * ---------------------------------------------
236*91f16700Schasinglulu	 */
237*91f16700Schasinglulu	sysreg_bit_set NEOVERSE_N1_CPUPWRCTLR_EL1, NEOVERSE_N1_CORE_PWRDN_EN_MASK
238*91f16700Schasinglulu
239*91f16700Schasinglulu	apply_erratum neoverse_n1, ERRATUM(2743102), ERRATA_N1_2743102
240*91f16700Schasinglulu
241*91f16700Schasinglulu	isb
242*91f16700Schasinglulu	ret
243*91f16700Schasingluluendfunc neoverse_n1_core_pwr_dwn
244*91f16700Schasinglulu
245*91f16700Schasingluluerrata_report_shim neoverse_n1
246*91f16700Schasinglulu
247*91f16700Schasinglulu/*
248*91f16700Schasinglulu * Handle trap of EL0 IC IVAU instructions to EL3 by executing a TLB
249*91f16700Schasinglulu * inner-shareable invalidation to an arbitrary address followed by a DSB.
250*91f16700Schasinglulu *
251*91f16700Schasinglulu * x1: Exception Syndrome
252*91f16700Schasinglulu */
253*91f16700Schasinglulufunc neoverse_n1_errata_ic_trap_handler
254*91f16700Schasinglulu	cmp	x1, #NEOVERSE_N1_EC_IC_TRAP
255*91f16700Schasinglulu	b.ne	1f
256*91f16700Schasinglulu	tlbi	vae3is, xzr
257*91f16700Schasinglulu	dsb	sy
258*91f16700Schasinglulu
259*91f16700Schasinglulu	# Skip the IC instruction itself
260*91f16700Schasinglulu	mrs     x3, elr_el3
261*91f16700Schasinglulu	add     x3, x3, #4
262*91f16700Schasinglulu	msr     elr_el3, x3
263*91f16700Schasinglulu
264*91f16700Schasinglulu	ldp	x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
265*91f16700Schasinglulu	ldp	x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2]
266*91f16700Schasinglulu	ldp	x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4]
267*91f16700Schasinglulu	ldr	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
268*91f16700Schasinglulu
269*91f16700Schasinglulu	/*
270*91f16700Schasinglulu	 * Issue Error Synchronization Barrier to synchronize SErrors before
271*91f16700Schasinglulu	 * exiting EL3. We're running with EAs unmasked, so any synchronized
272*91f16700Schasinglulu	 * errors would be taken immediately; therefore no need to inspect
273*91f16700Schasinglulu	 * DISR_EL1 register.
274*91f16700Schasinglulu	 */
275*91f16700Schasinglulu	esb
276*91f16700Schasinglulu	exception_return
277*91f16700Schasinglulu1:
278*91f16700Schasinglulu	ret
279*91f16700Schasingluluendfunc neoverse_n1_errata_ic_trap_handler
280*91f16700Schasinglulu
281*91f16700Schasinglulu	/* ---------------------------------------------
282*91f16700Schasinglulu	 * This function provides neoverse_n1 specific
283*91f16700Schasinglulu	 * register information for crash reporting.
284*91f16700Schasinglulu	 * It needs to return with x6 pointing to
285*91f16700Schasinglulu	 * a list of register names in ascii and
286*91f16700Schasinglulu	 * x8 - x15 having values of registers to be
287*91f16700Schasinglulu	 * reported.
288*91f16700Schasinglulu	 * ---------------------------------------------
289*91f16700Schasinglulu	 */
290*91f16700Schasinglulu.section .rodata.neoverse_n1_regs, "aS"
291*91f16700Schasingluluneoverse_n1_regs:  /* The ascii list of register names to be reported */
292*91f16700Schasinglulu	.asciz	"cpuectlr_el1", ""
293*91f16700Schasinglulu
294*91f16700Schasinglulufunc neoverse_n1_cpu_reg_dump
295*91f16700Schasinglulu	adr	x6, neoverse_n1_regs
296*91f16700Schasinglulu	mrs	x8, NEOVERSE_N1_CPUECTLR_EL1
297*91f16700Schasinglulu	ret
298*91f16700Schasingluluendfunc neoverse_n1_cpu_reg_dump
299*91f16700Schasinglulu
300*91f16700Schasingluludeclare_cpu_ops_eh neoverse_n1, NEOVERSE_N1_MIDR, \
301*91f16700Schasinglulu	neoverse_n1_reset_func, \
302*91f16700Schasinglulu	neoverse_n1_errata_ic_trap_handler, \
303*91f16700Schasinglulu	neoverse_n1_core_pwr_dwn
304