summaryrefslogtreecommitdiff
path: root/lib/cpus/aarch64/c1_ultra.S
blob: 2a1beea1edfd336ecd92265f79b6ca0fc15769a5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
/*
 * Copyright (c) 2023-2026, Arm Limited. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 *
 * TRM: https://support.arm.com/documentation/108014/latest
 * SDEN: https://support.arm.com/documentation/111077/latest
 */

#include <arch.h>
#include <asm_macros.S>
#include <c1_ultra.h>
#include <common/bl_common.h>
#include <cpu_macros.S>
#include <wa_cve_2025_0647_cpprctx.h>

#include <plat_macros.S>

/* Hardware handled coherency */
#if HW_ASSISTED_COHERENCY == 0
#error "Arm C1-Ultra must be compiled with HW_ASSISTED_COHERENCY enabled"
#endif

/* 64-bit only core */
#if CTX_INCLUDE_AARCH32_REGS == 1
#error "Arm C1-Ultra supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
#endif

cpu_reset_prologue c1_ultra

workaround_runtime_start c1_ultra, ERRATUM(3324333), ERRATA_C1ULTRA_3324333
	speculation_barrier
workaround_runtime_end c1_ultra, ERRATUM(3324333)

check_erratum_ls c1_ultra, ERRATUM(3324333), CPU_REV(0, 0)

workaround_reset_start c1_ultra, ERRATUM(3502731), ERRATA_C1ULTRA_3502731
	sysreg_bit_set C1_ULTRA_IMP_CPUACTLR4_EL1, BIT(23)
workaround_reset_end c1_ultra, ERRATUM(3502731)

check_erratum_ls c1_ultra, ERRATUM(3502731), CPU_REV(0, 0)

.global check_erratum_c1_ultra_3658374
add_erratum_entry c1_ultra, ERRATUM(3658374), ERRATA_C1ULTRA_3658374
check_erratum_ls c1_ultra, ERRATUM(3658374), CPU_REV(1, 0)

/* Erratum avoided by the generic implementation in lib/xlat_tables_v2. */
add_erratum_entry c1_ultra, ERRATUM(3683289), ERRATUM_ALWAYS_CHOSEN
check_erratum_ls c1_ultra, ERRATUM(3683289), CPU_REV(1, 0)

workaround_reset_start c1_ultra, ERRATUM(3684152), ERRATA_C1ULTRA_3684152
	sysreg_bitfield_insert C1_ULTRA_IMP_CPUACTLR_EL1, C1_ULTRA_IMP_CPUACTLR_EL1_LOAD_BIT, \
	C1_ULTRA_IMP_CPUACTLR_EL1_LOAD_SHIFT, C1_ULTRA_IMP_CPUACTLR_EL1_LOAD_WIDTH
workaround_reset_end c1_ultra, ERRATUM(3684152)

check_erratum_ls c1_ultra, ERRATUM(3684152), CPU_REV(0, 0)

workaround_reset_start c1_ultra, ERRATUM(3705939), ERRATA_C1ULTRA_3705939
	sysreg_bit_set C1_ULTRA_IMP_CPUACTLR_EL1, BIT(48)
workaround_reset_end c1_ultra, ERRATUM(3705939)

check_erratum_ls c1_ultra, ERRATUM(3705939), CPU_REV(1, 0)

workaround_reset_start c1_ultra, ERRATUM(3815514), ERRATA_C1ULTRA_3815514
	sysreg_bit_set C1_ULTRA_IMP_CPUACTLR5_EL1, BIT(13)
workaround_reset_end c1_ultra, ERRATUM(3815514)

check_erratum_ls c1_ultra, ERRATUM(3815514), CPU_REV(1, 0)

workaround_reset_start c1_ultra, ERRATUM(3865171), ERRATA_C1ULTRA_3865171
	sysreg_bit_set C1_ULTRA_IMP_CPUACTLR2_EL1, BIT(22)
workaround_reset_end c1_ultra, ERRATUM(3865171)

check_erratum_ls c1_ultra, ERRATUM(3865171), CPU_REV(1, 0)

workaround_reset_start c1_ultra, ERRATUM(3926381), ERRATA_C1ULTRA_3926381
	/* Convert WFx to NOP */
	ldr x0,=0x0
	msr C1_ULTRA_IMP_CPUPSELR_EL3, x0
	ldr x0,=0xD503205f
	msr C1_ULTRA_IMP_CPUPOR_EL3, x0
	ldr x0,=0xFFFFFFDF
	msr C1_ULTRA_IMP_CPUPMR_EL3, x0
	ldr x0,=0x1000002043ff
	msr C1_ULTRA_IMP_CPUPCR_EL3, x0
	/* Convert WFxT to NOP */
	ldr x0,=0x1
	msr C1_ULTRA_IMP_CPUPSELR_EL3, x0
	ldr x0,=0xD5031000
	msr C1_ULTRA_IMP_CPUPOR_EL3, x0
	ldr x0,=0xFFFFFFC0
	msr C1_ULTRA_IMP_CPUPMR_EL3, x0
	ldr x0,=0x1000002043ff
	msr C1_ULTRA_IMP_CPUPCR_EL3, x0
	isb
workaround_reset_end c1_ultra, ERRATUM(3926381)

check_erratum_range c1_ultra, ERRATUM(3926381), CPU_REV(1, 0), CPU_REV(1, 0)

/* Erratum avoided by the generic MDCR_EL3 initialization. */
add_erratum_entry c1_ultra, ERRATUM(4015814), ERRATUM_ALWAYS_CHOSEN
check_erratum_ls c1_ultra, ERRATUM(4015814), CPU_REV(1, 0)

workaround_reset_start c1_ultra, ERRATUM(4102704), ERRATA_C1ULTRA_4102704
	sysreg_bit_set C1_ULTRA_IMP_CPUACTLR4_EL1, BIT(23)
workaround_reset_end c1_ultra, ERRATUM(4102704)

check_erratum_ls c1_ultra, ERRATUM(4102704), CPU_REV(1, 0)

	/* -------------------------------------------------------------
	 * CVE-2024-7881 is mitigated for C1-Ultra using erratum 3651221
	 * workaround by disabling the affected prefetcher setting
	 * CPUACTLR6_EL1[41].
	 * -------------------------------------------------------------
	 */
workaround_reset_start c1_ultra, CVE(2024, 7881), WORKAROUND_CVE_2024_7881
	sysreg_bit_set C1_ULTRA_IMP_CPUACTLR6_EL1, BIT(41)
workaround_reset_end c1_ultra, CVE(2024, 7881)

check_erratum_ls c1_ultra, CVE(2024, 7881), CPU_REV(0, 0)

	/*
	 * Instruction patch sequence to trap 'cpp rctx' instructions to EL3.
	 * Enables mitigation for CVE-2025-0647.
	 */
workaround_reset_start c1_ultra, CVE(2025, 647), WORKAROUND_CVE_2025_0647
#ifdef IMAGE_BL31
	mov	x0, #WA_PATCH_SLOT(3)
	bl	wa_cve_2025_0647_instruction_patch
#endif /* IMAGE_BL31 */
workaround_reset_end c1_ultra, CVE(2025, 647)

check_erratum_chosen c1_ultra, CVE(2025, 647), WORKAROUND_CVE_2025_0647

#if WORKAROUND_CVE_2025_0647
func c1_ultra_impl_defined_el3_handler
	mov	x0, #WA_LS_RCG_EN

	/* See if this call came from trap handler. */
	cmp	x1, #EC_IMP_DEF_EL3
	bne	wa_cve_2025_0647_do_cpp_wa
	orr	x0, x0, #WA_IS_TRAP_HANDLER
	b	wa_cve_2025_0647_do_cpp_wa
endfunc c1_ultra_impl_defined_el3_handler
#endif

add_erratum_entry c1_ultra, CVE(2025, 10263), WORKAROUND_CVE_2025_10263
check_erratum_chosen c1_ultra, CVE(2025, 10263), WORKAROUND_CVE_2025_10263

cpu_reset_func_start c1_ultra
	/* ----------------------------------------------------
	 * Disable speculative loads
	 * ----------------------------------------------------
	 */
	msr	SSBS, xzr
	apply_erratum c1_ultra, ERRATUM(3324333), ERRATA_C1ULTRA_3324333
	/* model bug: not cleared on reset */
	sysreg_bit_clear C1_ULTRA_IMP_CPUPWRCTLR_EL1, \
		C1_ULTRA_IMP_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT
	enable_mpmm
cpu_reset_func_end c1_ultra

func c1_ultra_core_pwr_dwn
	/*
	 * When software running at lower ELs requests power down without first
	 * disabling SME, the CME connected to it will reject its power down
	 * request. Skip setting the PWRDN_EN bit, downgrading the powerdown
	 * request to a simple WFI wait, to get a minimal amount of power saving
	 * rather than an instant pabandon.
	 */
	mrs	x0, SVCR
	cbnz	x0, c1_ultra_skip_pwr_dwn

	/* ---------------------------------------------------
	 * Flip CPU power down bit in power control register.
	 * It will be set on powerdown and cleared on wakeup
	 * ---------------------------------------------------
	 */
	sysreg_bit_toggle C1_ULTRA_IMP_CPUPWRCTLR_EL1, \
		C1_ULTRA_IMP_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT
	isb
c1_ultra_skip_pwr_dwn:
	signal_pabandon_handled
	ret
endfunc c1_ultra_core_pwr_dwn

.section .rodata.c1_ultra_regs, "aS"
c1_ultra_regs: /* The ASCII list of register names to be reported */
	.asciz	"cpuectlr_el1", ""

func c1_ultra_cpu_reg_dump
	adr 	x6, c1_ultra_regs
	mrs	x8, C1_ULTRA_IMP_CPUECTLR_EL1
	ret
endfunc c1_ultra_cpu_reg_dump

#if WORKAROUND_CVE_2025_0647 && defined(IMAGE_BL31)
declare_cpu_ops_eh c1_ultra, C1_ULTRA_MIDR, \
	c1_ultra_reset_func, \
	c1_ultra_impl_defined_el3_handler, \
	c1_ultra_core_pwr_dwn
#else
declare_cpu_ops c1_ultra, C1_ULTRA_MIDR, \
	c1_ultra_reset_func, \
	c1_ultra_core_pwr_dwn
#endif