summaryrefslogtreecommitdiff
path: root/lib/cpus/aarch64/c1_premium.S
blob: 4444574d1af52361b9f68da2f2be1b6cef4f19d3 (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
/*
 * Copyright (c) 2024-2026, Arm Limited. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 *
 * TRM: https://developer.arm.com/documentation/109416/latest
 * SDEN: https://developer.arm.com/documentation/111078/latest
 */

#include <arch.h>
#include <asm_macros.S>
#include <c1_premium.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-Premium must be compiled with HW_ASSISTED_COHERENCY enabled"
#endif

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

cpu_reset_prologue c1_premium

workaround_runtime_start c1_premium, ERRATUM(3324333), ERRATA_C1PREMIUM_3324333
	speculation_barrier
workaround_runtime_end c1_premium, ERRATUM(3324333)

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

workaround_reset_start c1_premium, ERRATUM(3502731), ERRATA_C1PREMIUM_3502731
	sysreg_bit_set C1_PREMIUM_IMP_CPUACTLR4_EL1, BIT(23)
workaround_reset_end c1_premium, ERRATUM(3502731)

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

workaround_reset_start c1_premium, ERRATUM(3684152), ERRATA_C1PREMIUM_3684152
	sysreg_bitfield_insert C1_PREMIUM_IMP_CPUACTLR_EL1, C1_PREMIUM_IMP_CPUACTLR_EL1_LOAD_BIT, \
	C1_PREMIUM_IMP_CPUACTLR_EL1_LOAD_SHIFT, C1_PREMIUM_IMP_CPUACTLR_EL1_LOAD_WIDTH
workaround_reset_end c1_premium, ERRATUM(3684152)

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

workaround_reset_start c1_premium, ERRATUM(3705939), ERRATA_C1PREMIUM_3705939
	sysreg_bit_set C1_PREMIUM_IMP_CPUACTLR_EL1, BIT(48)
workaround_reset_end c1_premium, ERRATUM(3705939)

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

workaround_reset_start c1_premium, ERRATUM(3815514), ERRATA_C1PREMIUM_3815514
	sysreg_bit_set C1_PREMIUM_IMP_CPUACTLR5_EL1, BIT(13)
workaround_reset_end c1_premium, ERRATUM(3815514)

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

workaround_reset_start c1_premium, ERRATUM(3865171), ERRATA_C1PREMIUM_3865171
	sysreg_bit_set C1_PREMIUM_IMP_CPUACTLR2_EL1, BIT(22)
workaround_reset_end c1_premium, ERRATUM(3865171)

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

workaround_reset_start c1_premium, ERRATUM(3926381), ERRATA_C1PREMIUM_3926381
	/* Convert WFx to NOP */
	ldr x0,=0x0
	msr C1_PREMIUM_IMP_CPUPSELR_EL3, x0
	ldr x0,=0xD503205f
	msr C1_PREMIUM_IMP_CPUPOR_EL3, x0
	ldr x0,=0xFFFFFFDF
	msr C1_PREMIUM_IMP_CPUPMR_EL3, x0
	ldr x0,=0x1000002043ff
	msr C1_PREMIUM_IMP_CPUPCR_EL3, x0

	/* Convert WFxT to NOP */
	ldr x0,=0x1
	msr C1_PREMIUM_IMP_CPUPSELR_EL3, x0
	ldr x0,=0xD5031000
	msr C1_PREMIUM_IMP_CPUPOR_EL3, x0
	ldr x0,=0xFFFFFFC0
	msr C1_PREMIUM_IMP_CPUPMR_EL3, x0
	ldr x0,=0x1000002043ff
	msr C1_PREMIUM_IMP_CPUPCR_EL3, x0
	isb
workaround_reset_end c1_premium, ERRATUM(3926381)

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

workaround_reset_start c1_premium, ERRATUM(4102704), ERRATA_C1PREMIUM_4102704
	sysreg_bit_set C1_PREMIUM_IMP_CPUACTLR4_EL1, BIT(23)
workaround_reset_end c1_premium, ERRATUM(4102704)

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

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

check_erratum_ls c1_premium, 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_premium, 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_premium, CVE(2025, 647)

check_erratum_chosen c1_premium, CVE(2025, 647), WORKAROUND_CVE_2025_0647

#if WORKAROUND_CVE_2025_0647
func c1_premium_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_premium_impl_defined_el3_handler
#endif

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

cpu_reset_func_start c1_premium
	/* Disable speculative loads */
	msr	SSBS, xzr
	apply_erratum c1_premium, ERRATUM(3324333), ERRATA_C1PREMIUM_3324333
	enable_mpmm
cpu_reset_func_end c1_premium

func c1_premium_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_premium_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_PREMIUM_IMP_CPUPWRCTLR_EL1, \
		C1_PREMIUM_IMP_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT
	isb
c1_premium_skip_pwr_dwn:
	signal_pabandon_handled
	ret
endfunc c1_premium_core_pwr_dwn

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

func c1_premium_cpu_reg_dump
	adr 	x6, c1_premium_regs
	mrs	x8, C1_PREMIUM_IMP_CPUECTLR_EL1
	ret
endfunc c1_premium_cpu_reg_dump

#if WORKAROUND_CVE_2025_0647 && defined(IMAGE_BL31)
declare_cpu_ops_eh c1_premium, C1_PREMIUM_MIDR, \
	c1_premium_reset_func, \
	c1_premium_impl_defined_el3_handler, \
	c1_premium_core_pwr_dwn
#else
declare_cpu_ops c1_premium, C1_PREMIUM_MIDR, \
	c1_premium_reset_func, \
	c1_premium_core_pwr_dwn
#endif