• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <arch_features.h>
8 #include <arch_helpers.h>
9 #include <bl32/tsp/tsp_el1_context.h>
10 #include <common/debug.h>
11 
12 #define DUMMY_CTX_VALUE		ULL(0xffffffff)
13 #define DUMMY_CTX_TCR_VALUE	ULL(0xffff0000)
14 #define DUMMY_CTX_TRF_VALUE	ULL(0xf)
15 #define DUMMY_CTX_GCS_VALUE	ULL(0xffff0000)
16 #define DEFAULT_CTX_VALUE	ULL(0x0)
17 
18 /**
19  * -------------------------------------------------------
20  * Private Helper functions required to access and modify
21  * EL1 context registers at S-EL1.
22  * -------------------------------------------------------
23  */
modify_el1_common_regs(uint64_t cm_value)24 static void modify_el1_common_regs(uint64_t cm_value)
25 {
26 	/**
27 	 * NOTE: Few EL1 registers "SCTLR_EL1, SPSR_EL1, ELR_EL1" are
28 	 *       left out consciously as those are important registers for
29 	 *       execution in each world and overwriting them with dummy value
30 	 *       would cause unintended crash while executing the test.
31 	 */
32 	write_tcr_el1(cm_value);
33 	write_cpacr_el1(cm_value);
34 	write_csselr_el1(cm_value);
35 	write_esr_el1(cm_value);
36 	write_ttbr0_el1(cm_value);
37 	write_ttbr1_el1(cm_value);
38 	write_mair_el1(cm_value);
39 	write_amair_el1(cm_value);
40 	write_actlr_el1(cm_value);
41 	write_tpidr_el1(cm_value);
42 	write_tpidr_el0(cm_value);
43 	write_tpidrro_el0(cm_value);
44 	write_par_el1(cm_value);
45 	write_far_el1(cm_value);
46 	write_afsr0_el1(cm_value);
47 	write_afsr1_el1(cm_value);
48 	write_contextidr_el1(cm_value);
49 	write_vbar_el1(cm_value);
50 	write_mdccint_el1(cm_value);
51 	write_mdscr_el1(cm_value);
52 }
53 
modify_el1_mte2_regs(uint64_t mte_value)54 static void modify_el1_mte2_regs(uint64_t mte_value)
55 {
56 	if (is_feat_mte2_supported()) {
57 		write_tfsre0_el1(mte_value);
58 		write_tfsr_el1(mte_value);
59 		write_rgsr_el1(mte_value);
60 		write_gcr_el1(mte_value);
61 	}
62 }
63 
modify_el1_ras_regs(uint64_t ras_value)64 static void modify_el1_ras_regs(uint64_t ras_value)
65 {
66 	if (is_feat_ras_supported()) {
67 		write_disr_el1(ras_value);
68 	}
69 }
70 
modify_el1_s1pie_regs(uint64_t s1pie_value)71 static void modify_el1_s1pie_regs(uint64_t s1pie_value)
72 {
73 	if (is_feat_s1pie_supported()) {
74 		write_pire0_el1(s1pie_value);
75 		write_pir_el1(s1pie_value);
76 	}
77 }
78 
modify_el1_s1poe_regs(uint64_t s1poe_value)79 static void modify_el1_s1poe_regs(uint64_t s1poe_value)
80 {
81 	if (is_feat_s1poe_supported()) {
82 		write_por_el1(s1poe_value);
83 	}
84 }
85 
modify_el1_s2poe_regs(uint64_t s2poe_value)86 static void modify_el1_s2poe_regs(uint64_t s2poe_value)
87 {
88 	if (is_feat_s2poe_supported()) {
89 		write_s2por_el1(s2poe_value);
90 	}
91 }
92 
modify_el1_tcr2_regs(uint64_t tcr_value)93 static void modify_el1_tcr2_regs(uint64_t tcr_value)
94 {
95 	if (is_feat_tcr2_supported()) {
96 		write_tcr2_el1(tcr_value & DUMMY_CTX_TCR_VALUE);
97 	}
98 }
99 
modify_el1_trf_regs(uint64_t trf_value)100 static void modify_el1_trf_regs(uint64_t trf_value)
101 {
102 	if (is_feat_trf_supported()) {
103 		write_trfcr_el1(trf_value & DUMMY_CTX_TRF_VALUE);
104 	}
105 }
106 
modify_el1_gcs_regs(uint64_t gcs_value)107 static void modify_el1_gcs_regs(uint64_t gcs_value)
108 {
109 	if (is_feat_gcs_supported()) {
110 		write_gcscr_el1(gcs_value & DUMMY_CTX_GCS_VALUE);
111 		write_gcscre0_el1(gcs_value & DUMMY_CTX_GCS_VALUE);
112 		write_gcspr_el1(gcs_value & DUMMY_CTX_GCS_VALUE);
113 		write_gcspr_el0(gcs_value & DUMMY_CTX_GCS_VALUE);
114 	}
115 }
116 
117 /**
118  * -----------------------------------------------------
119  * Public API, to modify/restore EL1 ctx registers:
120  * -----------------------------------------------------
121  */
modify_el1_ctx_regs(const bool modify_option)122 void modify_el1_ctx_regs(const bool modify_option)
123 {
124 	uint64_t mask;
125 
126 	if (modify_option == TSP_CORRUPT_EL1_REGS) {
127 		VERBOSE("TSP(S-EL1): Corrupt EL1 Registers with Dummy values\n");
128 		mask = DUMMY_CTX_VALUE;
129 	} else {
130 		VERBOSE("TSP(S-EL1): Restore EL1 Registers with Default values\n");
131 		mask = DEFAULT_CTX_VALUE;
132 	}
133 
134 	modify_el1_common_regs(mask);
135 	modify_el1_mte2_regs(mask);
136 	modify_el1_ras_regs(mask);
137 	modify_el1_s1pie_regs(mask);
138 	modify_el1_s1poe_regs(mask);
139 	modify_el1_s2poe_regs(mask);
140 	modify_el1_tcr2_regs(mask);
141 	modify_el1_trf_regs(mask);
142 	modify_el1_gcs_regs(mask);
143 }
144