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://developer.arm.com/documentation/108014/latest
* SDEN: https://developer.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
|