blob: 3049274b0099ed2bba8a3c31baf3996bd9828407 [file] [log] [blame]
Igor Podgainõi4b672102024-09-23 13:06:15 +02001/*
2 * Copyright (c) 2024, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <lib/context_mgmt/context_el2.h>
8
9/**
10 * Internal functions to save groups of EL2 registers.
11 */
12
13static void el2_save_common_registers(el2_common_regs_t *ctx)
14{
15 EL2_SAVE_CTX_REG(ctx, actlr_el2);
16 EL2_SAVE_CTX_REG(ctx, afsr0_el2);
17 EL2_SAVE_CTX_REG(ctx, afsr1_el2);
18 EL2_SAVE_CTX_REG(ctx, amair_el2);
19 EL2_SAVE_CTX_REG(ctx, cnthctl_el2);
20 EL2_SAVE_CTX_REG(ctx, cntvoff_el2);
21 EL2_SAVE_CTX_REG(ctx, cptr_el2);
22 /* Accessing DBGVCR32_EL2 may crash the test, so it is omitted. */
23 EL2_SAVE_CTX_REG(ctx, elr_el2);
24 EL2_SAVE_CTX_REG(ctx, esr_el2);
25 EL2_SAVE_CTX_REG(ctx, far_el2);
26 EL2_SAVE_CTX_REG(ctx, hacr_el2);
27 EL2_SAVE_CTX_REG(ctx, hcr_el2);
28 EL2_SAVE_CTX_REG(ctx, hpfar_el2);
29 EL2_SAVE_CTX_REG(ctx, hstr_el2);
30 EL2_SAVE_CTX_REG(ctx, icc_sre_el2);
31 EL2_SAVE_CTX_REG(ctx, ich_hcr_el2);
32 EL2_SAVE_CTX_REG(ctx, ich_vmcr_el2);
33 EL2_SAVE_CTX_REG(ctx, mair_el2);
34 EL2_SAVE_CTX_REG(ctx, mdcr_el2);
35 EL2_SAVE_CTX_REG(ctx, pmscr_el2);
36 EL2_SAVE_CTX_REG(ctx, sctlr_el2);
37 EL2_SAVE_CTX_REG(ctx, spsr_el2);
38 EL2_SAVE_CTX_SP(ctx);
39 EL2_SAVE_CTX_REG(ctx, tcr_el2);
40 EL2_SAVE_CTX_REG(ctx, tpidr_el2);
41 EL2_SAVE_CTX_REG(ctx, ttbr0_el2);
42 EL2_SAVE_CTX_REG(ctx, vbar_el2);
43 EL2_SAVE_CTX_REG(ctx, vmpidr_el2);
44 EL2_SAVE_CTX_REG(ctx, vpidr_el2);
45 EL2_SAVE_CTX_REG(ctx, vtcr_el2);
46 EL2_SAVE_CTX_REG(ctx, vttbr_el2);
47}
48
49static void el2_save_mte2_registers(el2_mte2_regs_t *ctx)
50{
51 if (get_armv8_5_mte_support() == 2) {
52 EL2_SAVE_CTX_REG(ctx, tfsr_el2);
53 }
54}
55
56static void el2_save_fgt_registers(el2_fgt_regs_t *ctx)
57{
58 if (is_armv8_6_fgt_present()) {
59 EL2_SAVE_CTX_REG(ctx, hdfgrtr_el2);
60 if (is_armv8_4_amuv1_present())
61 EL2_SAVE_CTX_REG(ctx, hafgrtr_el2);
62 EL2_SAVE_CTX_REG(ctx, hdfgwtr_el2);
63 EL2_SAVE_CTX_REG(ctx, hfgitr_el2);
64 EL2_SAVE_CTX_REG(ctx, hfgrtr_el2);
65 EL2_SAVE_CTX_REG(ctx, hfgwtr_el2);
66 }
67}
68
69static void el2_save_fgt2_registers(el2_fgt2_regs_t *ctx)
70{
71 if (is_armv8_9_fgt2_present()) {
72 EL2_SAVE_CTX_REG(ctx, hdfgrtr2_el2);
73 EL2_SAVE_CTX_REG(ctx, hdfgwtr2_el2);
74 EL2_SAVE_CTX_REG(ctx, hfgitr2_el2);
75 EL2_SAVE_CTX_REG(ctx, hfgrtr2_el2);
76 EL2_SAVE_CTX_REG(ctx, hfgwtr2_el2);
77 }
78}
79
80static void el2_save_ecv_registers(el2_ecv_regs_t *ctx)
81{
82 if (get_armv8_6_ecv_support() == ID_AA64MMFR0_EL1_ECV_SELF_SYNCH) {
83 EL2_SAVE_CTX_REG(ctx, cntpoff_el2);
84 }
85}
86
87static void el2_save_vhe_registers(el2_vhe_regs_t *ctx)
88{
89 if (is_armv8_1_vhe_present()) {
90 EL2_SAVE_CTX_REG(ctx, contextidr_el2);
91 EL2_SAVE_CTX_REG(ctx, ttbr1_el2);
92 }
93}
94
95static void el2_save_ras_registers(el2_ras_regs_t *ctx)
96{
97 if (is_feat_ras_present() || is_feat_rasv1p1_present()) {
98 EL2_SAVE_CTX_REG(ctx, vdisr_el2);
99 EL2_SAVE_CTX_REG(ctx, vsesr_el2);
100 }
101}
102
103static void el2_save_neve_registers(el2_neve_regs_t *ctx)
104{
105 if (is_armv8_4_nv2_present()) {
106 EL2_SAVE_CTX_REG(ctx, vncr_el2);
107 }
108}
109
110static void el2_save_trf_registers(el2_trf_regs_t *ctx)
111{
112 if (get_armv8_4_trf_support()) {
113 EL2_SAVE_CTX_REG(ctx, trfcr_el2);
114 }
115}
116
117static void el2_save_csv2_registers(el2_csv2_regs_t *ctx)
118{
119 if (is_feat_csv2_2_present()) {
120 EL2_SAVE_CTX_REG(ctx, scxtnum_el2);
121 }
122}
123
124static void el2_save_hcx_registers(el2_hcx_regs_t *ctx)
125{
126 if (get_feat_hcx_support()) {
127 EL2_SAVE_CTX_REG(ctx, hcrx_el2);
128 }
129}
130
131static void el2_save_tcr2_registers(el2_tcr2_regs_t *ctx)
132{
133 if (is_feat_tcr2_supported()) {
134 EL2_SAVE_CTX_REG(ctx, tcr2_el2);
135 }
136}
137
138static void el2_save_sxpoe_registers(el2_sxpoe_regs_t *ctx)
139{
140 if (is_feat_sxpoe_present()) {
141 EL2_SAVE_CTX_REG(ctx, por_el2);
142 }
143}
144
145static void el2_save_sxpie_registers(el2_sxpie_regs_t *ctx)
146{
147 if (is_feat_sxpie_present()) {
148 EL2_SAVE_CTX_REG(ctx, pire0_el2);
149 EL2_SAVE_CTX_REG(ctx, pir_el2);
150 }
151}
152
153static void el2_save_s2pie_registers(el2_s2pie_regs_t *ctx)
154{
155 if (is_feat_s2pie_present()) {
156 EL2_SAVE_CTX_REG(ctx, s2pir_el2);
157 }
158}
159
160static void el2_save_gcs_registers(el2_gcs_regs_t *ctx)
161{
162 if (is_feat_gcs_present()) {
163 EL2_SAVE_CTX_REG(ctx, gcscr_el2);
164 EL2_SAVE_CTX_REG(ctx, gcspr_el2);
165 }
166}
167
168static void el2_save_mpam_registers(el2_mpam_regs_t *ctx)
169{
170 if (is_feat_mpam_supported()) {
171 EL2_SAVE_CTX_REG(ctx, mpam2_el2);
172 /**
173 * Registers MPAMHCR_EL2, MPAMVPM0_EL2, MPAMVPM1_EL2, MPAMVPM2_EL2,
174 * MPAMVPM3_EL2, MPAMVPM4_EL2, MPAMVPM5_EL2, MPAMVPM6_EL2, MPAMVPM7_EL2
175 * and MPAMVPMV_EL2 are not included, because an exception is raised
176 * upon accessing them.
177 */
178 }
179}
180
181/******************************************************************************/
182
183/**
184 * Internal functions to corrupt/restore groups of EL2 registers.
185 */
186
187static void el2_write_common_registers_with_mask(const el2_common_regs_t *ctx, uint64_t or_mask)
188{
189 EL2_WRITE_MASK_CTX_REG(ctx, actlr_el2, or_mask);
190 EL2_WRITE_MASK_CTX_REG(ctx, afsr0_el2, or_mask);
191 EL2_WRITE_MASK_CTX_REG(ctx, afsr1_el2, or_mask);
192 EL2_WRITE_MASK_CTX_REG(ctx, amair_el2, or_mask);
193 EL2_WRITE_MASK_CTX_REG(ctx, cnthctl_el2, or_mask);
194 EL2_WRITE_MASK_CTX_REG(ctx, cntvoff_el2, or_mask);
195 EL2_WRITE_MASK_CTX_REG(ctx, cptr_el2, or_mask);
196 /* Accessing DBGVCR32_EL2 may crash the test, so it is omitted. */
197 EL2_WRITE_MASK_CTX_REG(ctx, elr_el2, or_mask);
198 EL2_WRITE_MASK_CTX_REG(ctx, esr_el2, or_mask);
199 EL2_WRITE_MASK_CTX_REG(ctx, far_el2, or_mask);
200 EL2_WRITE_MASK_CTX_REG(ctx, hacr_el2, or_mask);
201 EL2_WRITE_MASK_CTX_REG(ctx, hcr_el2, or_mask);
202 EL2_WRITE_MASK_CTX_REG(ctx, hpfar_el2, or_mask);
203 EL2_WRITE_MASK_CTX_REG(ctx, hstr_el2, or_mask);
204 EL2_WRITE_MASK_CTX_REG(ctx, icc_sre_el2, or_mask);
205 EL2_WRITE_MASK_CTX_REG(ctx, ich_hcr_el2, or_mask);
206 /* Unable to restore ICH_VMCR_EL2 to original value after modification, so it is omitted. */
207 EL2_WRITE_MASK_CTX_REG(ctx, mair_el2, or_mask);
208 EL2_WRITE_MASK_CTX_REG(ctx, mdcr_el2, or_mask);
209 EL2_WRITE_MASK_CTX_REG(ctx, pmscr_el2, or_mask);
210 EL2_WRITE_MASK_CTX_REG(ctx, sctlr_el2, (or_mask & ~SCTLR_EL2_EE));
211 EL2_WRITE_MASK_CTX_REG(ctx, spsr_el2, or_mask);
212 /* The stack pointer should not be modified, because the control flow depends on it. */
213 /* Masking TCR_EL2 may crash the test, so it is omitted. */
214 EL2_WRITE_MASK_CTX_REG(ctx, tpidr_el2, or_mask);
215 /* Masking TTBR0_EL2 may crash the test, so it is omitted. */
216 EL2_WRITE_MASK_CTX_REG(ctx, vbar_el2, or_mask);
217 EL2_WRITE_MASK_CTX_REG(ctx, vmpidr_el2, or_mask);
218 EL2_WRITE_MASK_CTX_REG(ctx, vpidr_el2, or_mask);
219 EL2_WRITE_MASK_CTX_REG(ctx, vtcr_el2, or_mask);
220 EL2_WRITE_MASK_CTX_REG(ctx, vttbr_el2, or_mask);
221}
222
223static void el2_write_mte2_registers_with_mask(const el2_mte2_regs_t *ctx, uint64_t or_mask)
224{
225 if (get_armv8_5_mte_support() == 2) {
226 EL2_WRITE_MASK_CTX_REG(ctx, tfsr_el2, or_mask);
227 }
228}
229
230static void el2_write_fgt_registers_with_mask(const el2_fgt_regs_t *ctx, uint64_t or_mask)
231{
232 if (is_armv8_6_fgt_present()) {
233 EL2_WRITE_MASK_CTX_REG(ctx, hdfgrtr_el2, or_mask);
234 if (is_armv8_4_amuv1_present())
235 EL2_WRITE_MASK_CTX_REG(ctx, hafgrtr_el2, or_mask);
236 EL2_WRITE_MASK_CTX_REG(ctx, hdfgwtr_el2, or_mask);
237 EL2_WRITE_MASK_CTX_REG(ctx, hfgitr_el2, or_mask);
238 EL2_WRITE_MASK_CTX_REG(ctx, hfgrtr_el2, or_mask);
239 EL2_WRITE_MASK_CTX_REG(ctx, hfgwtr_el2, or_mask);
240 }
241}
242
243static void el2_write_fgt2_registers_with_mask(const el2_fgt2_regs_t *ctx, uint64_t or_mask)
244{
245 if (is_armv8_9_fgt2_present()) {
246 EL2_WRITE_MASK_CTX_REG(ctx, hdfgrtr2_el2, or_mask);
247 EL2_WRITE_MASK_CTX_REG(ctx, hdfgwtr2_el2, or_mask);
248 EL2_WRITE_MASK_CTX_REG(ctx, hfgitr2_el2, or_mask);
249 EL2_WRITE_MASK_CTX_REG(ctx, hfgrtr2_el2, or_mask);
250 EL2_WRITE_MASK_CTX_REG(ctx, hfgwtr2_el2, or_mask);
251 }
252}
253
254static void el2_write_ecv_registers_with_mask(const el2_ecv_regs_t *ctx, uint64_t or_mask)
255{
256 if (get_armv8_6_ecv_support() == ID_AA64MMFR0_EL1_ECV_SELF_SYNCH) {
257 EL2_WRITE_MASK_CTX_REG(ctx, cntpoff_el2, or_mask);
258 }
259}
260
261static void el2_write_vhe_registers_with_mask(const el2_vhe_regs_t *ctx, uint64_t or_mask)
262{
263 if (is_armv8_1_vhe_present()) {
264 EL2_WRITE_MASK_CTX_REG(ctx, contextidr_el2, or_mask);
265 EL2_WRITE_MASK_CTX_REG(ctx, ttbr1_el2, (or_mask & ~TTBR1_EL2_ASID));
266 }
267}
268
269static void el2_write_ras_registers_with_mask(const el2_ras_regs_t *ctx, uint64_t or_mask)
270{
271 if (is_feat_ras_present() || is_feat_rasv1p1_present()) {
272 EL2_WRITE_MASK_CTX_REG(ctx, vdisr_el2, or_mask);
273 EL2_WRITE_MASK_CTX_REG(ctx, vsesr_el2, or_mask);
274 }
275}
276
277static void el2_write_neve_registers_with_mask(const el2_neve_regs_t *ctx, uint64_t or_mask)
278{
279 if (is_armv8_4_nv2_present()) {
280 EL2_WRITE_MASK_CTX_REG(ctx, vncr_el2, or_mask);
281 }
282}
283
284static void el2_write_trf_registers_with_mask(const el2_trf_regs_t *ctx, uint64_t or_mask)
285{
286 if (get_armv8_4_trf_support()) {
287 EL2_WRITE_MASK_CTX_REG(ctx, trfcr_el2, or_mask);
288 }
289}
290
291static void el2_write_csv2_registers_with_mask(const el2_csv2_regs_t *ctx, uint64_t or_mask)
292{
293 if (is_feat_csv2_2_present()) {
294 EL2_WRITE_MASK_CTX_REG(ctx, scxtnum_el2, or_mask);
295 }
296}
297
298static void el2_write_hcx_registers_with_mask(const el2_hcx_regs_t *ctx, uint64_t or_mask)
299{
300 if (get_feat_hcx_support()) {
301 EL2_WRITE_MASK_CTX_REG(ctx, hcrx_el2, or_mask);
302 }
303}
304
305static void el2_write_tcr2_registers_with_mask(const el2_tcr2_regs_t *ctx, uint64_t or_mask)
306{
307 if (is_feat_tcr2_supported()) {
308 EL2_WRITE_MASK_CTX_REG(ctx, tcr2_el2, (or_mask & ~TCR2_EL2_POE));
309 }
310}
311
312static void el2_write_sxpoe_registers_with_mask(const el2_sxpoe_regs_t *ctx, uint64_t or_mask)
313{
314 if (is_feat_sxpoe_present()) {
315 EL2_WRITE_MASK_CTX_REG(ctx, por_el2, or_mask);
316 }
317}
318
319static void el2_write_sxpie_registers_with_mask(const el2_sxpie_regs_t *ctx, uint64_t or_mask)
320{
321 if (is_feat_sxpie_present()) {
322 EL2_WRITE_MASK_CTX_REG(ctx, pire0_el2, or_mask);
323 EL2_WRITE_MASK_CTX_REG(ctx, pir_el2, or_mask);
324 }
325}
326
327static void el2_write_s2pie_registers_with_mask(const el2_s2pie_regs_t *ctx, uint64_t or_mask)
328{
329 if (is_feat_s2pie_present()) {
330 EL2_WRITE_MASK_CTX_REG(ctx, s2pir_el2, or_mask);
331 }
332}
333
334static void el2_write_gcs_registers_with_mask(const el2_gcs_regs_t *ctx, uint64_t or_mask)
335{
336 if (is_feat_gcs_present()) {
337 EL2_WRITE_MASK_CTX_REG(ctx, gcscr_el2, (or_mask & ~GCSCR_EL2_PCRSEL));
338 EL2_WRITE_MASK_CTX_REG(ctx, gcspr_el2, or_mask);
339 }
340}
341
342/**
343 * Register MPAM2_EL2 is not included, because its contents may change
344 * before context switching occurs.
345 *
346 * Registers MPAMHCR_EL2, MPAMVPM0_EL2, MPAMVPM1_EL2, MPAMVPM2_EL2,
347 * MPAMVPM3_EL2, MPAMVPM4_EL2, MPAMVPM5_EL2, MPAMVPM6_EL2, MPAMVPM7_EL2
348 * and MPAMVPMV_EL2 are not included, because an exception is raised
349 * upon accessing them.
350 */
351
352/******************************************************************************/
353
354/**
355 * Internal functions to dump the saved EL2 register context.
356 */
357
358static void el2_dump_common_register_context(const el2_common_regs_t *ctx)
359{
360 EL2_PRINT_CTX_HEADING("Common registers");
361 EL2_PRINT_CTX_MEMBER(ctx, "ACTLR_EL2", actlr_el2);
362 EL2_PRINT_CTX_MEMBER(ctx, "AFSR0_EL2", afsr0_el2);
363 EL2_PRINT_CTX_MEMBER(ctx, "AFSR1_EL2", afsr1_el2);
364 EL2_PRINT_CTX_MEMBER(ctx, "AMAIR_EL2", amair_el2);
365 EL2_PRINT_CTX_MEMBER(ctx, "CNTHCTL_EL2", cnthctl_el2);
366 EL2_PRINT_CTX_MEMBER(ctx, "CNTVOFF_EL2", cntvoff_el2);
367 EL2_PRINT_CTX_MEMBER(ctx, "CPTR_EL2", cptr_el2);
368 EL2_PRINT_CTX_MEMBER(ctx, "ELR_EL2", elr_el2);
369 EL2_PRINT_CTX_MEMBER(ctx, "ESR_EL2", esr_el2);
370 EL2_PRINT_CTX_MEMBER(ctx, "FAR_EL2", far_el2);
371 EL2_PRINT_CTX_MEMBER(ctx, "HACR_EL2", hacr_el2);
372 EL2_PRINT_CTX_MEMBER(ctx, "HCR_EL2", hcr_el2);
373 EL2_PRINT_CTX_MEMBER(ctx, "HPFAR_EL2", hpfar_el2);
374 EL2_PRINT_CTX_MEMBER(ctx, "HSTR_EL2", hstr_el2);
375 EL2_PRINT_CTX_MEMBER(ctx, "ICC_SRE_EL2", icc_sre_el2);
376 EL2_PRINT_CTX_MEMBER(ctx, "ICH_HCR_EL2", ich_hcr_el2);
377 EL2_PRINT_CTX_MEMBER(ctx, "ICH_VMCR_EL2", ich_vmcr_el2);
378 EL2_PRINT_CTX_MEMBER(ctx, "MAIR_EL2", mair_el2);
379 EL2_PRINT_CTX_MEMBER(ctx, "MDCR_EL2", mdcr_el2);
380 EL2_PRINT_CTX_MEMBER(ctx, "PMSCR_EL2", pmscr_el2);
381 EL2_PRINT_CTX_MEMBER(ctx, "SCTLR_EL2", sctlr_el2);
382 EL2_PRINT_CTX_MEMBER(ctx, "SPSR_EL2", spsr_el2);
383 EL2_PRINT_CTX_MEMBER(ctx, "SP_EL2", sp_el2);
384 EL2_PRINT_CTX_MEMBER(ctx, "TCR_EL2", tcr_el2);
385 EL2_PRINT_CTX_MEMBER(ctx, "TPIDR_EL2", tpidr_el2);
386 EL2_PRINT_CTX_MEMBER(ctx, "TTBR0_EL2", ttbr0_el2);
387 EL2_PRINT_CTX_MEMBER(ctx, "VBAR_EL2", vbar_el2);
388 EL2_PRINT_CTX_MEMBER(ctx, "VMPIDR_EL2", vmpidr_el2);
389 EL2_PRINT_CTX_MEMBER(ctx, "VPIDR_EL2", vpidr_el2);
390 EL2_PRINT_CTX_MEMBER(ctx, "VTCR_EL2", vtcr_el2);
391 EL2_PRINT_CTX_MEMBER(ctx, "VTTBR_EL2", vttbr_el2);
392 INFO("\n");
393}
394
395static void el2_dump_mte2_register_context(const el2_mte2_regs_t *ctx)
396{
397 EL2_PRINT_CTX_HEADING("MTE2 registers");
398 EL2_PRINT_CTX_MEMBER(ctx, "TFSR_EL2", tfsr_el2);
399 INFO("\n");
400}
401
402static void el2_dump_fgt_register_context(const el2_fgt_regs_t *ctx)
403{
404 EL2_PRINT_CTX_HEADING("FGT registers");
405 EL2_PRINT_CTX_MEMBER(ctx, "HDFGRTR_EL2", hdfgrtr_el2);
406 EL2_PRINT_CTX_MEMBER(ctx, "HAFGRTR_EL2", hafgrtr_el2);
407 EL2_PRINT_CTX_MEMBER(ctx, "HDFGWTR_EL2", hdfgwtr_el2);
408 EL2_PRINT_CTX_MEMBER(ctx, "HFGITR_EL2", hfgitr_el2);
409 EL2_PRINT_CTX_MEMBER(ctx, "HFGRTR_EL2", hfgrtr_el2);
410 EL2_PRINT_CTX_MEMBER(ctx, "HFGWTR_EL2", hfgwtr_el2);
411 INFO("\n");
412}
413
414static void el2_dump_fgt2_register_context(const el2_fgt2_regs_t *ctx)
415{
416 EL2_PRINT_CTX_HEADING("FGT2 registers");
417 EL2_PRINT_CTX_MEMBER(ctx, "HDFGRTR2_EL2", hdfgrtr2_el2);
418 EL2_PRINT_CTX_MEMBER(ctx, "HDFGWTR2_EL2", hdfgwtr2_el2);
419 EL2_PRINT_CTX_MEMBER(ctx, "HFGITR2_EL2", hfgitr2_el2);
420 EL2_PRINT_CTX_MEMBER(ctx, "HFGRTR2_EL2", hfgrtr2_el2);
421 EL2_PRINT_CTX_MEMBER(ctx, "HFGWTR2_EL2", hfgwtr2_el2);
422 INFO("\n");
423}
424
425static void el2_dump_ecv_register_context(const el2_ecv_regs_t *ctx)
426{
427 EL2_PRINT_CTX_HEADING("ECV registers");
428 EL2_PRINT_CTX_MEMBER(ctx, "CNTPOFF_EL2", cntpoff_el2);
429 INFO("\n");
430}
431
432static void el2_dump_vhe_register_context(const el2_vhe_regs_t *ctx)
433{
434 EL2_PRINT_CTX_HEADING("VHE registers");
435 EL2_PRINT_CTX_MEMBER(ctx, "CONTEXTIDR_EL2", contextidr_el2);
436 EL2_PRINT_CTX_MEMBER(ctx, "TTBR1_EL2", ttbr1_el2);
437 INFO("\n");
438}
439
440static void el2_dump_ras_register_context(const el2_ras_regs_t *ctx)
441{
442 EL2_PRINT_CTX_HEADING("RAS registers");
443 EL2_PRINT_CTX_MEMBER(ctx, "VDISR_EL2", vdisr_el2);
444 EL2_PRINT_CTX_MEMBER(ctx, "VSESR_EL2", vsesr_el2);
445 INFO("\n");
446}
447
448static void el2_dump_neve_register_context(const el2_neve_regs_t *ctx)
449{
450 EL2_PRINT_CTX_HEADING("NEVE registers");
451 EL2_PRINT_CTX_MEMBER(ctx, "VNCR_EL2", vncr_el2);
452 INFO("\n");
453}
454
455static void el2_dump_trf_register_context(const el2_trf_regs_t *ctx)
456{
457 EL2_PRINT_CTX_HEADING("TRF registers");
458 EL2_PRINT_CTX_MEMBER(ctx, "TRFCR_EL2", trfcr_el2);
459 INFO("\n");
460}
461
462static void el2_dump_csv2_register_context(const el2_csv2_regs_t *ctx)
463{
464 EL2_PRINT_CTX_HEADING("CSV2 registers");
465 EL2_PRINT_CTX_MEMBER(ctx, "SCXTNUM_EL2", scxtnum_el2);
466 INFO("\n");
467}
468
469static void el2_dump_hcx_register_context(const el2_hcx_regs_t *ctx)
470{
471 EL2_PRINT_CTX_HEADING("HCX registers");
472 EL2_PRINT_CTX_MEMBER(ctx, "HCRX_EL2", hcrx_el2);
473 INFO("\n");
474}
475
476static void el2_dump_tcr2_register_context(const el2_tcr2_regs_t *ctx)
477{
478 EL2_PRINT_CTX_HEADING("TCR2 registers");
479 EL2_PRINT_CTX_MEMBER(ctx, "TCR2_EL2", tcr2_el2);
480 INFO("\n");
481}
482
483static void el2_dump_sxpoe_register_context(const el2_sxpoe_regs_t *ctx)
484{
485 EL2_PRINT_CTX_HEADING("SxPOE registers");
486 EL2_PRINT_CTX_MEMBER(ctx, "POR_EL2", por_el2);
487 INFO("\n");
488}
489
490static void el2_dump_sxpie_register_context(const el2_sxpie_regs_t *ctx)
491{
492 EL2_PRINT_CTX_HEADING("SxPIE registers");
493 EL2_PRINT_CTX_MEMBER(ctx, "PIRE0_EL2", pire0_el2);
494 EL2_PRINT_CTX_MEMBER(ctx, "PIR_EL2", pir_el2);
495 INFO("\n");
496}
497
498static void el2_dump_s2pie_register_context(const el2_s2pie_regs_t *ctx)
499{
500 EL2_PRINT_CTX_HEADING("S2PIE registers");
501 EL2_PRINT_CTX_MEMBER(ctx, "S2PIR_EL2", s2pir_el2);
502 INFO("\n");
503}
504
505static void el2_dump_gcs_register_context(const el2_gcs_regs_t *ctx)
506{
507 EL2_PRINT_CTX_HEADING("GCS registers");
508 EL2_PRINT_CTX_MEMBER(ctx, "GCSCR_EL2", gcscr_el2);
509 EL2_PRINT_CTX_MEMBER(ctx, "GCSPR_EL2", gcspr_el2);
510 INFO("\n");
511}
512
513static void el2_dump_mpam_register_context(const el2_mpam_regs_t *ctx)
514{
515 EL2_PRINT_CTX_HEADING("MPAM registers");
516 EL2_PRINT_CTX_MEMBER(ctx, "MPAM2_EL2", mpam2_el2);
517 INFO("\n");
518}
519
520/******************************************************************************/
521
522/**
523 * Public function definitions.
524 */
525
526/**
527 * Read EL2 system registers and save the values into the given context pointer.
528 */
529void el2_save_registers(el2_sysregs_t *ctx)
530{
531 el2_save_common_registers(&ctx->common);
532 el2_save_mte2_registers(&ctx->mte2);
533 el2_save_fgt_registers(&ctx->fgt);
534 el2_save_fgt2_registers(&ctx->fgt2);
535 el2_save_ecv_registers(&ctx->ecv);
536 el2_save_vhe_registers(&ctx->vhe);
537 el2_save_ras_registers(&ctx->ras);
538 el2_save_neve_registers(&ctx->neve);
539 el2_save_trf_registers(&ctx->trf);
540 el2_save_csv2_registers(&ctx->csv2);
541 el2_save_hcx_registers(&ctx->hcx);
542 el2_save_tcr2_registers(&ctx->tcr2);
543 el2_save_sxpoe_registers(&ctx->sxpoe);
544 el2_save_sxpie_registers(&ctx->sxpie);
545 el2_save_s2pie_registers(&ctx->s2pie);
546 el2_save_gcs_registers(&ctx->gcs);
547 el2_save_mpam_registers(&ctx->mpam);
548}
549
550/**
551 * Modify EL2 system registers from a given context pointer
552 * by applying the appropriate OR mask depending on the operation.
553 */
554void el2_modify_registers(const el2_sysregs_t *ctx, const el2_modify_operation_t op)
555{
556 uint64_t or_mask = (op == CORRUPT_REGS) ? REG_CORRUPTION_MASK : 0;
557 el2_write_common_registers_with_mask(&ctx->common, or_mask);
558 el2_write_mte2_registers_with_mask(&ctx->mte2, or_mask);
559 el2_write_fgt_registers_with_mask(&ctx->fgt, or_mask);
560 el2_write_fgt2_registers_with_mask(&ctx->fgt2, or_mask);
561 el2_write_ecv_registers_with_mask(&ctx->ecv, or_mask);
562 el2_write_vhe_registers_with_mask(&ctx->vhe, or_mask);
563 el2_write_ras_registers_with_mask(&ctx->ras, or_mask);
564 el2_write_neve_registers_with_mask(&ctx->neve, or_mask);
565 el2_write_trf_registers_with_mask(&ctx->trf, or_mask);
566 el2_write_csv2_registers_with_mask(&ctx->csv2, or_mask);
567 el2_write_hcx_registers_with_mask(&ctx->hcx, or_mask);
568 el2_write_tcr2_registers_with_mask(&ctx->tcr2, or_mask);
569 el2_write_sxpoe_registers_with_mask(&ctx->sxpoe, or_mask);
570 el2_write_sxpie_registers_with_mask(&ctx->sxpie, or_mask);
571 el2_write_s2pie_registers_with_mask(&ctx->s2pie, or_mask);
572 el2_write_gcs_registers_with_mask(&ctx->gcs, or_mask);
573 /* There is nothing to do in regards to MPAM registers. */
574}
575
576/**
577 * Dump (print out) the EL2 system registers from a given context pointer.
578 */
579void el2_dump_register_context(const char *ctx_name, const el2_sysregs_t *ctx)
580{
581 INFO("%s:\n", ctx_name);
582 el2_dump_common_register_context(&ctx->common);
583 el2_dump_mte2_register_context(&ctx->mte2);
584 el2_dump_fgt_register_context(&ctx->fgt);
585 el2_dump_fgt2_register_context(&ctx->fgt2);
586 el2_dump_ecv_register_context(&ctx->ecv);
587 el2_dump_vhe_register_context(&ctx->vhe);
588 el2_dump_ras_register_context(&ctx->ras);
589 el2_dump_neve_register_context(&ctx->neve);
590 el2_dump_trf_register_context(&ctx->trf);
591 el2_dump_csv2_register_context(&ctx->csv2);
592 el2_dump_hcx_register_context(&ctx->hcx);
593 el2_dump_tcr2_register_context(&ctx->tcr2);
594 el2_dump_sxpoe_register_context(&ctx->sxpoe);
595 el2_dump_sxpie_register_context(&ctx->sxpie);
596 el2_dump_s2pie_register_context(&ctx->s2pie);
597 el2_dump_gcs_register_context(&ctx->gcs);
598 el2_dump_mpam_register_context(&ctx->mpam);
599}