blob: 50b78c8c74aa53cf5d513335e3c3912b081ca33d [file] [log] [blame]
nabkah01002e5692022-10-10 12:36:46 +01001/*
AlexeiFedorovc398c8f2025-01-16 14:35:48 +00002 * Copyright (c) 2022-2025, Arm Limited. All rights reserved.
nabkah01002e5692022-10-10 12:36:46 +01003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8#include <stdio.h>
9
Shruti Gupta9d0cfe82023-04-17 10:57:26 +010010#include <arch_features.h>
nabkah01002e5692022-10-10 12:36:46 +010011#include <debug.h>
Shruti Gupta369955a2023-04-19 18:05:56 +010012#include <fpu.h>
nabkah01002e5692022-10-10 12:36:46 +010013#include <host_realm_helper.h>
14#include <host_shared_data.h>
Shruti Gupta9d0cfe82023-04-17 10:57:26 +010015#include <pauth.h>
nabkah01002e5692022-10-10 12:36:46 +010016#include "realm_def.h"
Shruti Gupta91105082024-11-27 05:29:55 +000017#include <realm_helpers.h>
18#include <realm_psi.h>
nabkah01002e5692022-10-10 12:36:46 +010019#include <realm_rsi.h>
AlexeiFedorov2f30f102023-03-13 19:37:46 +000020#include <realm_tests.h>
Javier Almansa Sobrino7c78f7b2024-10-25 11:44:32 +010021#include <serror.h>
Shruti Guptab027f572024-01-02 22:00:29 +000022#include <sync.h>
nabkah01002e5692022-10-10 12:36:46 +010023#include <tftf_lib.h>
24
Arunachalam Ganapathy7e514f62023-08-30 13:27:36 +010025static fpu_state_t rl_fpu_state_write;
26static fpu_state_t rl_fpu_state_read;
Shruti Gupta158208e2024-11-27 10:12:41 +000027static rsi_plane_run run __aligned(PAGE_SIZE);
Javier Almansa Sobrino7c78f7b2024-10-25 11:44:32 +010028
nabkah01002e5692022-10-10 12:36:46 +010029/*
AlexeiFedorov2f30f102023-03-13 19:37:46 +000030 * This function reads sleep time in ms from shared buffer and spins PE
31 * in a loop for that time period.
nabkah01002e5692022-10-10 12:36:46 +010032 */
33static void realm_sleep_cmd(void)
34{
Shruti Gupta52b5f022023-10-12 22:02:29 +010035 uint64_t sleep = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX);
nabkah01002e5692022-10-10 12:36:46 +010036
Shruti Guptaa276b202023-12-18 10:07:43 +000037 realm_printf("going to sleep for %llums\n", sleep);
nabkah01002e5692022-10-10 12:36:46 +010038 waitms(sleep);
39}
40
Shruti Gupta6bb95102023-10-02 13:21:37 +010041static void realm_loop_cmd(void)
42{
43 while (true) {
44 waitms(500);
45 }
46}
47
Shruti Gupta158208e2024-11-27 10:12:41 +000048static bool test_realm_enter_plane_n(void)
49{
50 u_register_t base, plane_index, perm_index, flags = 0U;
Shruti Gupta41434682024-12-05 14:57:48 +000051 bool ret1;
Shruti Gupta158208e2024-11-27 10:12:41 +000052
53 plane_index = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX);
54 base = realm_shared_data_get_my_host_val(HOST_ARG2_INDEX);
55 perm_index = plane_index + 1U;
56
Shruti Gupta41434682024-12-05 14:57:48 +000057 ret1 = plane_common_init(plane_index, perm_index, base, &run);
58 if (!ret1) {
59 return ret1;
60 }
61
Shruti Gupta158208e2024-11-27 10:12:41 +000062 realm_printf("Entering plane %ld, ep=0x%lx run=0x%lx\n", plane_index, base, &run);
63 return realm_plane_enter(plane_index, perm_index, base, flags, &run);
64}
65
Shruti Gupta41434682024-12-05 14:57:48 +000066static bool test_realm_enter_plane_n_reg_rw(void)
67{
68 u_register_t base, plane_index, perm_index, flags = 0U;
69 u_register_t reg1, reg2, reg3, reg4, ret;
70 bool ret1;
71
72 if (realm_is_plane0()) {
73 plane_index = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX);
74 base = realm_shared_data_get_my_host_val(HOST_ARG2_INDEX);
75 perm_index = plane_index + 1U;
76
77 ret1 = plane_common_init(plane_index, perm_index, base, &run);
78 if (!ret1) {
79 return ret1;
80 }
81
82 realm_printf("Entering plane %ld, ep=0x%lx run=0x%lx\n", plane_index, base, &run);
83 ret = realm_plane_enter(plane_index, perm_index, base, flags, &run);
84 if (ret) {
85 /* get return value from plane1 */
86 reg1 = realm_shared_data_get_plane_n_val(plane_index,
87 REC_IDX(read_mpidr_el1()), HOST_ARG1_INDEX);
88
89 reg2 = realm_shared_data_get_plane_n_val(plane_index,
90 REC_IDX(read_mpidr_el1()), HOST_ARG2_INDEX);
91
92 realm_printf("P0 read 0x%lx 0x%lx\n", reg1, reg2);
93
94 /* read pauth register for plane1 */
95 ret = rsi_plane_reg_read(plane_index, SYSREG_ID_apiakeylo_el1, &reg3);
96 if ((ret != RSI_SUCCESS) || (reg1 != reg3)) {
97 realm_printf("pauth register mismatch 0x%lx 0x%lx\n", reg1, reg3);
98 return false;
99 }
100
101 /* read sctlr register for plane1 */
102 ret = rsi_plane_reg_read(plane_index, SYSREG_ID_sctlr_el1, &reg4);
103 if ((ret != RSI_SUCCESS) || (reg2 != reg4)) {
104 realm_printf("sctlr register mismatch 0x%lx 0x%lx\n", reg2, reg4);
105 return false;
106 }
107
108 /* write pauth register and verify it is same after exiting plane n */
109 ret = rsi_plane_reg_write(plane_index, SYSREG_ID_apibkeylo_el1, 0xABCD);
110 if (ret != RSI_SUCCESS) {
111 realm_printf("pauth register write failed\n");
112 return false;
113 }
114
115 /* enter plane n */
116 ret = realm_plane_enter(plane_index, perm_index, base, flags, &run);
117 if (ret) {
118 /* read pauth register for plane1 */
119 ret = rsi_plane_reg_read(plane_index, SYSREG_ID_apibkeylo_el1,
120 &reg3);
121
122 if ((ret != RSI_SUCCESS) || (reg3 != 0xABCD)) {
123 realm_printf("reg mismatch after write 0x%lx\n", reg3);
124 return false;
125 }
126 }
127
128 /* read sysreg not supported by rmm, expect error */
129 ret = rsi_plane_reg_read(plane_index, SYSREG_ID_mpamidr_el1, &reg3);
130 if (ret == RSI_SUCCESS) {
131 realm_printf("reg read should have failed\n");
132 return false;
133 }
134 return true;
135 }
136 return false;
137 } else {
138 realm_printf("PN set 0x%lx 0x%lx\n", read_apiakeylo_el1(), read_sctlr_el1());
139
140 /* return pauth and sctlr back to p0 */
141 realm_shared_data_set_my_realm_val(HOST_ARG1_INDEX, read_apiakeylo_el1());
142 realm_shared_data_set_my_realm_val(HOST_ARG2_INDEX, read_sctlr_el1());
143 return true;
144 }
145}
146
Shruti Gupta78effaa2025-02-07 10:30:15 +0000147static bool test_realm_s2poe_undef_abort(void)
148{
149 realm_reset_undef_abort_count();
150
151 /* Install exception handler to catch undefined abort */
152 register_custom_sync_exception_handler(realm_sync_exception_handler);
153 write_s2por_el1(0UL);
154 unregister_custom_sync_exception_handler();
155
156 return (realm_get_undef_abort_count() != 0UL);
157}
158
nabkah01002e5692022-10-10 12:36:46 +0100159/*
160 * This function requests RSI/ABI version from RMM.
161 */
Shruti Gupta40de8ec2023-10-12 21:45:12 +0100162static bool realm_get_rsi_version(void)
nabkah01002e5692022-10-10 12:36:46 +0100163{
Shruti Gupta40de8ec2023-10-12 21:45:12 +0100164 u_register_t version = 0U;
nabkah01002e5692022-10-10 12:36:46 +0100165
Shruti Gupta40de8ec2023-10-12 21:45:12 +0100166 version = rsi_get_version(RSI_ABI_VERSION_VAL);
nabkah01002e5692022-10-10 12:36:46 +0100167 if (version == (u_register_t)SMC_UNKNOWN) {
Shruti Gupta40de8ec2023-10-12 21:45:12 +0100168 realm_printf("SMC_RSI_ABI_VERSION failed\n");
169 return false;
nabkah01002e5692022-10-10 12:36:46 +0100170 }
171
Shruti Gupta40de8ec2023-10-12 21:45:12 +0100172 realm_printf("RSI ABI version %u.%u (expected: %u.%u)\n",
nabkah01002e5692022-10-10 12:36:46 +0100173 RSI_ABI_VERSION_GET_MAJOR(version),
174 RSI_ABI_VERSION_GET_MINOR(version),
Shruti Gupta40de8ec2023-10-12 21:45:12 +0100175 RSI_ABI_VERSION_GET_MAJOR(RSI_ABI_VERSION_VAL),
176 RSI_ABI_VERSION_GET_MINOR(RSI_ABI_VERSION_VAL));
177 return true;
nabkah01002e5692022-10-10 12:36:46 +0100178}
179
Shruti Guptabb772192023-10-09 16:08:28 +0100180bool test_realm_set_ripas(void)
181{
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100182 u_register_t ret, base, new_base, top, new_top;
AlexeiFedorov08a5f162025-05-09 17:29:13 +0100183 rsi_response_type response;
Shruti Guptabb772192023-10-09 16:08:28 +0100184 rsi_ripas_type ripas;
185
186 base = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX);
187 top = realm_shared_data_get_my_host_val(HOST_ARG2_INDEX);
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100188 realm_printf("base=0x%lx top=0x%lx\n", base, top);
189 ret = rsi_ipa_state_get(base, top, &new_top, &ripas);
Shruti Guptabb772192023-10-09 16:08:28 +0100190 if (ripas != RSI_EMPTY) {
191 return false;
192 }
193
194 ret = rsi_ipa_state_set(base, top, RSI_RAM,
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100195 RSI_NO_CHANGE_DESTROYED, &new_base, &response);
196 if ((ret != RSI_SUCCESS) || (response != RSI_ACCEPT)) {
Shruti Guptabb772192023-10-09 16:08:28 +0100197 return false;
198 }
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100199
Shruti Guptabb772192023-10-09 16:08:28 +0100200 while (new_base < top) {
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100201 realm_printf("new_base=0x%lx top=0x%lx\n", new_base, top);
Shruti Guptabb772192023-10-09 16:08:28 +0100202 ret = rsi_ipa_state_set(new_base, top, RSI_RAM,
203 RSI_NO_CHANGE_DESTROYED, &new_base, &response);
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100204 if ((ret != RSI_SUCCESS) || (response != RSI_ACCEPT)) {
Shruti Guptabb772192023-10-09 16:08:28 +0100205 realm_printf("rsi_ipa_state_set failed\n");
206 return false;
207 }
208 }
209
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100210 /* Verify that RIAS has changed for range base-top */
211 ret = rsi_ipa_state_get(base, top, &new_top, &ripas);
212 if ((ret != RSI_SUCCESS) || (ripas != RSI_RAM) || (new_top != top)) {
213 realm_printf("rsi_ipa_state_get failed base=0x%lx top=0x%lx",
214 "new_top=0x%lx ripas=%u ret=0x%lx\n",
215 base, top, ripas);
216 return false;
Shruti Guptabb772192023-10-09 16:08:28 +0100217 }
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100218
Shruti Guptabb772192023-10-09 16:08:28 +0100219 return true;
220}
221
Shruti Guptafef86212023-10-17 12:15:38 +0100222bool test_realm_reject_set_ripas(void)
223{
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100224 u_register_t ret, base, top, new_base, new_top;
AlexeiFedorov08a5f162025-05-09 17:29:13 +0100225 rsi_response_type response;
Shruti Guptafef86212023-10-17 12:15:38 +0100226 rsi_ripas_type ripas;
227
228 base = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX);
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100229 top = base + PAGE_SIZE;
230 ret = rsi_ipa_state_get(base, top, &new_top, &ripas);
231 if ((ret != RSI_SUCCESS) || (ripas != RSI_EMPTY)) {
232 realm_printf("Wrong initial ripas=%u\n", ripas);
Shruti Guptafef86212023-10-17 12:15:38 +0100233 return false;
234 }
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100235 ret = rsi_ipa_state_set(base, top, RSI_RAM,
236 RSI_NO_CHANGE_DESTROYED, &new_base, &response);
237 if ((ret == RSI_SUCCESS) && (response == RSI_REJECT)) {
238 realm_printf("rsi_ipa_state_set passed response=%u\n", response);
239 ret = rsi_ipa_state_get(base, top, &new_top, &ripas);
240 if ((ret == RSI_SUCCESS) && (ripas == RSI_EMPTY) &&
241 (new_top == top)) {
Shruti Guptafef86212023-10-17 12:15:38 +0100242 return true;
243 } else {
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100244 realm_printf("rsi_ipa_state_get failed top=0x%lx",
245 "new_top=0x%lx ripas=%u ret=0x%lx\n",
AlexeiFedorov20cf8512025-05-20 14:37:22 +0100246 top, new_top, ripas, ret);
Shruti Guptafef86212023-10-17 12:15:38 +0100247 return false;
248 }
249 }
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100250 realm_printf("rsi_ipa_state_set failed ret=0x%lx response=%u\n",
251 ret, response);
Shruti Guptafef86212023-10-17 12:15:38 +0100252 return false;
253}
254
Shruti Gupta2a5abad2024-01-17 13:48:44 +0000255bool test_realm_dit_check_cmd(void)
256{
257 if (is_armv8_4_dit_present()) {
258 write_dit(DIT_BIT);
259 realm_printf("Testing DIT=0x%lx\n", read_dit());
260 /* Test if DIT is preserved after HOST_CALL */
261 if (read_dit() == DIT_BIT) {
262 return true;
263 }
264 }
265 return false;
266}
267
Shruti Gupta55d5db82025-03-03 12:56:04 +0000268static bool test_plane_exception_cmd(void)
269{
270 u_register_t base, plane_index, perm_index, flags = 0U;
271 bool ret1;
272
273 plane_index = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX);
274 base = realm_shared_data_get_my_host_val(HOST_ARG2_INDEX);
275 perm_index = plane_index + 1U;
276
277 ret1 = plane_common_init(plane_index, perm_index, base, &run);
278 if (!ret1) {
279 return ret1;
280 }
281
282 realm_printf("Entering plane %ld, ep=0x%lx run=0x%lx\n", plane_index, base, &run);
283 ret1 = realm_plane_enter(plane_index, perm_index, base, flags, &run);
284
285 realm_printf("Plane exit reason=0x%lx\n", run.exit.exit_reason);
286
287 /*
288 * @TODO- P0 can inject SEA back to PN,
289 * if capability is added in future.
290 */
291 if (ret1 && (run.exit.exit_reason == RSI_EXIT_SYNC)) {
292 u_register_t far, esr, elr;
293
294 far = run.exit.far;
295 esr = run.exit.esr;
296 elr = run.exit.elr;
297
298 /* Return ESR FAR to Host */
299 realm_shared_data_set_my_realm_val(HOST_ARG2_INDEX, esr);
300 realm_shared_data_set_my_realm_val(HOST_ARG3_INDEX, far);
301 realm_printf("Plane exit FAR=0x%lx ESR=0x%lx ELR=0x%lx\n",
302 far, esr, elr);
303 rsi_exit_to_host(HOST_CALL_EXIT_SUCCESS_CMD);
304 }
305 return false;
306}
307
Shruti Guptae68494e2023-11-06 11:04:57 +0000308static bool test_realm_instr_fetch_cmd(void)
309{
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100310 u_register_t base, new_top;
Shruti Guptae68494e2023-11-06 11:04:57 +0000311 void (*func_ptr)(void);
312 rsi_ripas_type ripas;
313
Shruti Gupta7d3b9992025-02-25 15:39:55 +0000314 base = realm_shared_data_get_my_host_val(HOST_ARG3_INDEX);
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100315 rsi_ipa_state_get(base, base + PAGE_SIZE, &new_top, &ripas);
316 realm_printf("Initial ripas=%u\n", ripas);
317 /* Causes instruction abort */
Shruti Gupta55d5db82025-03-03 12:56:04 +0000318 realm_printf("Generate Instruction Abort base=0x%lx\n", base);
Shruti Guptae68494e2023-11-06 11:04:57 +0000319 func_ptr = (void (*)(void))base;
320 func_ptr();
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100321 /* Should not return */
Shruti Guptae68494e2023-11-06 11:04:57 +0000322 return false;
323}
324
325static bool test_realm_data_access_cmd(void)
326{
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100327 u_register_t base, new_top;
Shruti Guptae68494e2023-11-06 11:04:57 +0000328 rsi_ripas_type ripas;
Shruti Gupta7d3b9992025-02-25 15:39:55 +0000329 base = realm_shared_data_get_my_host_val(HOST_ARG3_INDEX);
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100330 rsi_ipa_state_get(base, base + PAGE_SIZE, &new_top, &ripas);
331 realm_printf("Initial ripas=%u\n", ripas);
332 /* Causes data abort */
Shruti Gupta55d5db82025-03-03 12:56:04 +0000333 realm_printf("Generate Data Abort base=0x%lx\n", base);
Shruti Guptae68494e2023-11-06 11:04:57 +0000334 *((volatile uint64_t *)base);
Javier Almansa Sobrino7c78f7b2024-10-25 11:44:32 +0100335
Shruti Guptae68494e2023-11-06 11:04:57 +0000336 return false;
337}
338
Javier Almansa Sobrinoa1fe7382025-04-25 20:45:17 +0100339static bool test_realm_plane_n_inst_fetch(void)
340{
341 u_register_t esr, far, test_ipa;
342
343 bool ret = test_realm_enter_plane_n();
344
345 if (!ret) {
346 ERROR("Failed to enter Plane N\n");
347 return false;
348 }
349
350 esr = run.exit.esr;
351 far = run.exit.far;
352 test_ipa = realm_shared_data_get_my_host_val(HOST_ARG2_INDEX);
353
354 if ((EC_BITS(esr) != EC_IABORT_LOWER_EL) || (far != test_ipa)) {
355 ERROR("Plane N: incorrect ESR=0x%lx FAR=0x%lx\n", esr, far);
356 return false;
357 }
358
359 return true;
360}
361
Shruti Guptab027f572024-01-02 22:00:29 +0000362static bool realm_exception_handler(void)
363{
Shruti Gupta91105082024-11-27 05:29:55 +0000364 u_register_t base, far, esr, elr;
Shruti Guptab027f572024-01-02 22:00:29 +0000365
Shruti Gupta7d3b9992025-02-25 15:39:55 +0000366 base = realm_shared_data_get_my_host_val(HOST_ARG3_INDEX);
Shruti Guptab027f572024-01-02 22:00:29 +0000367 far = read_far_el1();
368 esr = read_esr_el1();
Shruti Gupta91105082024-11-27 05:29:55 +0000369 elr = read_elr_el1();
Shruti Guptab027f572024-01-02 22:00:29 +0000370
371 if (far == base) {
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100372 /* Return ESR to Host */
Shruti Guptab027f572024-01-02 22:00:29 +0000373 realm_shared_data_set_my_realm_val(HOST_ARG2_INDEX, esr);
Javier Almansa Sobrinoa1fe7382025-04-25 20:45:17 +0100374 if (realm_is_plane0()) {
375 rsi_exit_to_host(HOST_CALL_EXIT_SUCCESS_CMD);
376 } else {
377 realm_shared_data_set_my_realm_val(HOST_ARG3_INDEX, far);
378 psi_exit_to_plane0(PSI_CALL_EXIT_SUCCESS_CMD,
379 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL);
380 }
Shruti Guptab027f572024-01-02 22:00:29 +0000381 }
Javier Almansa Sobrinoa1fe7382025-04-25 20:45:17 +0100382
Shruti Gupta91105082024-11-27 05:29:55 +0000383 realm_printf("Realm Abort fail incorrect FAR=0x%lx ESR=0x%lx ELR=0x%lx\n",
384 far, esr, elr);
Javier Almansa Sobrinoa1fe7382025-04-25 20:45:17 +0100385
386 if (realm_is_plane0()) {
387 rsi_exit_to_host(HOST_CALL_EXIT_FAILED_CMD);
388 } else {
389 psi_exit_to_plane0(PSI_CALL_EXIT_FAILED_CMD,
390 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL);
391 }
Shruti Guptab027f572024-01-02 22:00:29 +0000392
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100393 /* Should not return */
Shruti Guptab027f572024-01-02 22:00:29 +0000394 return false;
395}
396
Manish V Badarkhe46d02282024-11-18 16:58:37 +0000397static bool realm_serror_handler_doublefault(bool *incr_elr_elx)
Javier Almansa Sobrino7c78f7b2024-10-25 11:44:32 +0100398{
Manish V Badarkhe46d02282024-11-18 16:58:37 +0000399 *incr_elr_elx = false;
400
Javier Almansa Sobrino7c78f7b2024-10-25 11:44:32 +0100401 if ((read_sctlr2_el1() & SCTLR2_EASE_BIT) != 0UL) {
402 /* The serror exception should have been routed here */
Manish V Badarkhe46d02282024-11-18 16:58:37 +0000403 *incr_elr_elx = true;
404
Javier Almansa Sobrino7c78f7b2024-10-25 11:44:32 +0100405 return true;
406 }
407
408 rsi_exit_to_host(HOST_CALL_EXIT_FAILED_CMD);
409
410 /* Should have never get here */
411 return false;
412}
413
414static bool realm_sync_handler_doublefault(void)
415{
416 if ((read_sctlr2_el1() & SCTLR2_EASE_BIT) == 0UL) {
417 /* The sync exception should have been routed here */
418 return true;
419 }
420
421 rsi_exit_to_host(HOST_CALL_EXIT_FAILED_CMD);
422
423 /* Should have never get here */
424 return false;
425}
426
427static void test_realm_feat_doublefault2(void)
428{
429 u_register_t ease_bit = realm_shared_data_get_my_host_val(HOST_ARG2_INDEX);
430
431 unregister_custom_sync_exception_handler();
432 register_custom_sync_exception_handler(realm_sync_handler_doublefault);
433 register_custom_serror_handler(realm_serror_handler_doublefault);
434
435 if (ease_bit != 0UL) {
436 write_sctlr2_el1(read_sctlr2_el1() | SCTLR2_EASE_BIT);
437 } else {
438 write_sctlr2_el1(read_sctlr2_el1() & ~SCTLR2_EASE_BIT);
439 }
440
441 (void)test_realm_data_access_cmd();
442}
443
Javier Almansa Sobrino8307c332025-06-12 10:30:46 +0100444static bool test_realm_feat_tcr2(void)
445{
446 /*
447 * TCR2_EL1.PIE (bit 1) and TCR2_EL1.E0POE (bit 2) only make
448 * effect when using stage 1 translation, which is not used by
449 * this test, hence it is safe to write to them.
450 */
451 u_register_t tcr2_el1_val = (1UL << 1U);
452
453 if (is_feat_tcr2_supported()) {
454 for (unsigned int i = 0U; i < 2U; i++) {
455 write_tcr2_el1(tcr2_el1_val);
456 realm_printf("Testing TCR2_EL1 = 0x%lx\n", read_tcr2_el1());
457
458 /* Test if TCR2_EL1 is preserved after HOST_CALL */
459 if (read_tcr2_el1() != tcr2_el1_val) {
460 return false;
461 }
462
463 tcr2_el1_val <<= 1U;
464 }
465
466 return true;
467 }
468
469 /* Fall back in case FEAT_TCR2 is not implemented */
470 realm_reset_undef_abort_count();
471
472 /* Install exception handler to catch undefined abort */
473 register_custom_sync_exception_handler(realm_sync_exception_handler);
474 write_tcr2_el1(tcr2_el1_val);
475 unregister_custom_sync_exception_handler();
476
477 return (realm_get_undef_abort_count() != 0UL);
478}
479
nabkah01002e5692022-10-10 12:36:46 +0100480/*
481 * This is the entry function for Realm payload, it first requests the shared buffer
482 * IPA address from Host using HOST_CALL/RSI, it reads the command to be executed,
483 * performs the request, and returns to Host with the execution state SUCCESS/FAILED
484 *
485 * Host in NS world requests Realm to execute certain operations using command
486 * depending on the test case the Host wants to perform.
487 */
488void realm_payload_main(void)
489{
nabkah01002e5692022-10-10 12:36:46 +0100490 bool test_succeed = false;
491
Shruti Guptab027f572024-01-02 22:00:29 +0000492 register_custom_sync_exception_handler(realm_exception_handler);
Javier Almansa Sobrino7c78f7b2024-10-25 11:44:32 +0100493
494 /* No serror handler registered by default */
495 unregister_custom_serror_handler();
496
Shruti Gupta69cae792024-11-27 04:30:00 +0000497 realm_set_shared_structure(realm_get_ns_buffer());
Javier Almansa Sobrino7c78f7b2024-10-25 11:44:32 +0100498
Shruti Gupta550e3e82023-08-16 13:20:11 +0100499 if (realm_get_my_shared_structure() != NULL) {
500 uint8_t cmd = realm_shared_data_get_my_realm_cmd();
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000501
nabkah01002e5692022-10-10 12:36:46 +0100502 switch (cmd) {
503 case REALM_SLEEP_CMD:
504 realm_sleep_cmd();
505 test_succeed = true;
506 break;
Shruti Gupta6bb95102023-10-02 13:21:37 +0100507 case REALM_LOOP_CMD:
508 realm_loop_cmd();
509 test_succeed = true;
510 break;
Shruti Gupta158208e2024-11-27 10:12:41 +0000511 case REALM_ENTER_PLANE_N_CMD:
512 test_succeed = test_realm_enter_plane_n();
513 break;
Shruti Gupta41434682024-12-05 14:57:48 +0000514 case REALM_PLANE_N_REG_RW_CMD:
515 test_succeed = test_realm_enter_plane_n_reg_rw();
516 break;
Shruti Gupta78effaa2025-02-07 10:30:15 +0000517 case REALM_S2POE_ACCESS:
518 test_succeed = test_realm_s2poe_undef_abort();
519 break;
Javier Almansa Sobrino82cd82e2025-01-17 17:37:42 +0000520 case REALM_MPAM_ACCESS:
521 test_succeed = test_realm_mpam_undef_abort();
522 break;
523 case REALM_MPAM_PRESENT:
524 /* FEAT_MPAM must be hidden to the Realm */
525 test_succeed = !is_feat_mpam_supported();
526 break;
Shruti Gupta24597d12023-10-02 10:40:19 +0100527 case REALM_MULTIPLE_REC_PSCI_DENIED_CMD:
528 test_succeed = test_realm_multiple_rec_psci_denied_cmd();
Shruti Guptae68494e2023-11-06 11:04:57 +0000529 break;
Shruti Guptaaffbae82023-08-22 12:51:11 +0100530 case REALM_MULTIPLE_REC_MULTIPLE_CPU_CMD:
531 test_succeed = test_realm_multiple_rec_multiple_cpu_cmd();
Shruti Gupta24597d12023-10-02 10:40:19 +0100532 break;
Shruti Guptabd729192025-01-24 17:02:15 +0000533 case REALM_PLANES_MULTIPLE_REC_MULTIPLE_CPU_CMD:
534 test_succeed = test_realm_multiple_plane_multiple_rec_multiple_cpu_cmd();
535 break;
Javier Almansa Sobrino7c78f7b2024-10-25 11:44:32 +0100536 case REALM_FEAT_DOUBLEFAULT2_TEST:
537 test_realm_feat_doublefault2();
538 test_succeed = true;
539 break;
Shruti Guptae68494e2023-11-06 11:04:57 +0000540 case REALM_INSTR_FETCH_CMD:
541 test_succeed = test_realm_instr_fetch_cmd();
542 break;
543 case REALM_DATA_ACCESS_CMD:
544 test_succeed = test_realm_data_access_cmd();
545 break;
Shruti Gupta55d5db82025-03-03 12:56:04 +0000546 case REALM_PLANE_N_EXCEPTION_CMD:
547 test_succeed = test_plane_exception_cmd();
548 break;
Shruti Gupta9d0cfe82023-04-17 10:57:26 +0100549 case REALM_PAUTH_SET_CMD:
550 test_succeed = test_realm_pauth_set_cmd();
551 break;
552 case REALM_PAUTH_CHECK_CMD:
553 test_succeed = test_realm_pauth_check_cmd();
554 break;
555 case REALM_PAUTH_FAULT:
556 test_succeed = test_realm_pauth_fault();
557 break;
Shruti Gupta2a5abad2024-01-17 13:48:44 +0000558 case REALM_DIT_CHECK_CMD:
559 test_succeed = test_realm_dit_check_cmd();
560 break;
nabkah01002e5692022-10-10 12:36:46 +0100561 case REALM_GET_RSI_VERSION:
Shruti Gupta40de8ec2023-10-12 21:45:12 +0100562 test_succeed = realm_get_rsi_version();
nabkah01002e5692022-10-10 12:36:46 +0100563 break;
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000564 case REALM_PMU_CYCLE:
565 test_succeed = test_pmuv3_cycle_works_realm();
566 break;
Shruti Guptab1b37922024-01-13 21:49:04 +0000567 case REALM_PMU_COUNTER:
568 test_succeed = test_pmuv3_counter();
569 break;
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000570 case REALM_PMU_EVENT:
571 test_succeed = test_pmuv3_event_works_realm();
572 break;
573 case REALM_PMU_PRESERVE:
574 test_succeed = test_pmuv3_rmm_preserves();
575 break;
AlexeiFedorovc398c8f2025-01-16 14:35:48 +0000576 case REALM_PMU_CYCLE_INTERRUPT:
577 test_succeed = test_pmuv3_overflow_interrupt(true);
578 break;
579 case REALM_PMU_EVENT_INTERRUPT:
580 test_succeed = test_pmuv3_overflow_interrupt(false);
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000581 break;
Shruti Gupta369955a2023-04-19 18:05:56 +0100582 case REALM_REQ_FPU_FILL_CMD:
Arunachalam Ganapathy7e514f62023-08-30 13:27:36 +0100583 fpu_state_write_rand(&rl_fpu_state_write);
Shruti Gupta369955a2023-04-19 18:05:56 +0100584 test_succeed = true;
585 break;
586 case REALM_REQ_FPU_CMP_CMD:
Arunachalam Ganapathy7e514f62023-08-30 13:27:36 +0100587 fpu_state_read(&rl_fpu_state_read);
588 test_succeed = !fpu_state_compare(&rl_fpu_state_write,
589 &rl_fpu_state_read);
Arunachalam Ganapathy9af432e2023-06-02 17:18:23 +0100590 break;
Shruti Guptafef86212023-10-17 12:15:38 +0100591 case REALM_REJECT_SET_RIPAS_CMD:
592 test_succeed = test_realm_reject_set_ripas();
593 break;
Shruti Guptabb772192023-10-09 16:08:28 +0100594 case REALM_SET_RIPAS_CMD:
595 test_succeed = test_realm_set_ripas();
596 break;
Arunachalam Ganapathy0bbdc2d2023-04-05 15:30:18 +0100597 case REALM_SVE_RDVL:
598 test_succeed = test_realm_sve_rdvl();
599 break;
600 case REALM_SVE_ID_REGISTERS:
601 test_succeed = test_realm_sve_read_id_registers();
602 break;
603 case REALM_SVE_PROBE_VL:
604 test_succeed = test_realm_sve_probe_vl();
Shruti Gupta369955a2023-04-19 18:05:56 +0100605 break;
Arunachalam Ganapathyc1136a82023-04-12 15:24:44 +0100606 case REALM_SVE_OPS:
607 test_succeed = test_realm_sve_ops();
608 break;
Arunachalam Ganapathy5270d012023-04-19 14:53:42 +0100609 case REALM_SVE_FILL_REGS:
610 test_succeed = test_realm_sve_fill_regs();
611 break;
Arunachalam Ganapathyf3697172023-09-04 15:04:46 +0100612 case REALM_SVE_CMP_REGS:
613 test_succeed = test_realm_sve_cmp_regs();
614 break;
Arunachalam Ganapathy73949a22023-06-05 12:01:05 +0100615 case REALM_SVE_UNDEF_ABORT:
616 test_succeed = test_realm_sve_undef_abort();
617 break;
Arunachalam Ganapathy1768e592023-05-23 13:28:38 +0100618 case REALM_SME_ID_REGISTERS:
619 test_succeed = test_realm_sme_read_id_registers();
620 break;
621 case REALM_SME_UNDEF_ABORT:
622 test_succeed = test_realm_sme_undef_abort();
623 break;
Juan Pablo Conde88ffad22024-10-11 21:22:29 -0500624 case REALM_ATTESTATION:
625 test_succeed = test_realm_attestation();
626 break;
627 case REALM_ATTESTATION_FAULT:
628 test_succeed = test_realm_attestation_fault();
629 break;
Sona Mathewc8f5a2e2025-02-04 15:22:01 -0600630 case REALM_WRITE_BRBCR_EL1:
631 test_succeed = test_realm_write_brbcr_el1_reg();
632 break;
Arunachalam Ganapathyc58e4692025-01-28 12:28:59 +0000633 case REALM_DA_RSI_CALLS:
634 test_succeed = test_realm_da_rsi_calls();
635 break;
Javier Almansa Sobrinoa1fe7382025-04-25 20:45:17 +0100636 case REALM_PLANE_N_INST_FETCH_ABORT:
637 test_succeed = test_realm_plane_n_inst_fetch();
638 break;
Javier Almansa Sobrino8307c332025-06-12 10:30:46 +0100639 case REALM_TEST_FEAT_TCR2:
640 test_succeed = test_realm_feat_tcr2();
641 break;
nabkah01002e5692022-10-10 12:36:46 +0100642 default:
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000643 realm_printf("%s() invalid cmd %u\n", __func__, cmd);
nabkah01002e5692022-10-10 12:36:46 +0100644 break;
645 }
646 }
647
648 if (test_succeed) {
Shruti Gupta91105082024-11-27 05:29:55 +0000649 if (realm_is_plane0()) {
650 rsi_exit_to_host(HOST_CALL_EXIT_SUCCESS_CMD);
651 } else {
652 psi_exit_to_plane0(PSI_CALL_EXIT_SUCCESS_CMD,
653 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL);
654 }
nabkah01002e5692022-10-10 12:36:46 +0100655 } else {
Shruti Gupta91105082024-11-27 05:29:55 +0000656 if (realm_is_plane0()) {
657 rsi_exit_to_host(HOST_CALL_EXIT_FAILED_CMD);
658 } else {
659 psi_exit_to_plane0(PSI_CALL_EXIT_FAILED_CMD,
660 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL);
661 }
nabkah01002e5692022-10-10 12:36:46 +0100662 }
663}