blob: 131f49b01f074a2483473a743a599b8aebed79bf [file] [log] [blame]
nabkah01002e5692022-10-10 12:36:46 +01001/*
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +01002 * Copyright (c) 2022-2024, 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"
17#include <realm_rsi.h>
AlexeiFedorov2f30f102023-03-13 19:37:46 +000018#include <realm_tests.h>
Javier Almansa Sobrino7c78f7b2024-10-25 11:44:32 +010019#include <serror.h>
Shruti Guptab027f572024-01-02 22:00:29 +000020#include <sync.h>
nabkah01002e5692022-10-10 12:36:46 +010021#include <tftf_lib.h>
22
Arunachalam Ganapathy7e514f62023-08-30 13:27:36 +010023static fpu_state_t rl_fpu_state_write;
24static fpu_state_t rl_fpu_state_read;
Javier Almansa Sobrino7c78f7b2024-10-25 11:44:32 +010025
nabkah01002e5692022-10-10 12:36:46 +010026/*
AlexeiFedorov2f30f102023-03-13 19:37:46 +000027 * This function reads sleep time in ms from shared buffer and spins PE
28 * in a loop for that time period.
nabkah01002e5692022-10-10 12:36:46 +010029 */
30static void realm_sleep_cmd(void)
31{
Shruti Gupta52b5f022023-10-12 22:02:29 +010032 uint64_t sleep = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX);
nabkah01002e5692022-10-10 12:36:46 +010033
Shruti Guptaa276b202023-12-18 10:07:43 +000034 realm_printf("going to sleep for %llums\n", sleep);
nabkah01002e5692022-10-10 12:36:46 +010035 waitms(sleep);
36}
37
Shruti Gupta6bb95102023-10-02 13:21:37 +010038static void realm_loop_cmd(void)
39{
40 while (true) {
41 waitms(500);
42 }
43}
44
nabkah01002e5692022-10-10 12:36:46 +010045/*
46 * This function requests RSI/ABI version from RMM.
47 */
Shruti Gupta40de8ec2023-10-12 21:45:12 +010048static bool realm_get_rsi_version(void)
nabkah01002e5692022-10-10 12:36:46 +010049{
Shruti Gupta40de8ec2023-10-12 21:45:12 +010050 u_register_t version = 0U;
nabkah01002e5692022-10-10 12:36:46 +010051
Shruti Gupta40de8ec2023-10-12 21:45:12 +010052 version = rsi_get_version(RSI_ABI_VERSION_VAL);
nabkah01002e5692022-10-10 12:36:46 +010053 if (version == (u_register_t)SMC_UNKNOWN) {
Shruti Gupta40de8ec2023-10-12 21:45:12 +010054 realm_printf("SMC_RSI_ABI_VERSION failed\n");
55 return false;
nabkah01002e5692022-10-10 12:36:46 +010056 }
57
Shruti Gupta40de8ec2023-10-12 21:45:12 +010058 realm_printf("RSI ABI version %u.%u (expected: %u.%u)\n",
nabkah01002e5692022-10-10 12:36:46 +010059 RSI_ABI_VERSION_GET_MAJOR(version),
60 RSI_ABI_VERSION_GET_MINOR(version),
Shruti Gupta40de8ec2023-10-12 21:45:12 +010061 RSI_ABI_VERSION_GET_MAJOR(RSI_ABI_VERSION_VAL),
62 RSI_ABI_VERSION_GET_MINOR(RSI_ABI_VERSION_VAL));
63 return true;
nabkah01002e5692022-10-10 12:36:46 +010064}
65
Shruti Guptabb772192023-10-09 16:08:28 +010066bool test_realm_set_ripas(void)
67{
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +010068 u_register_t ret, base, new_base, top, new_top;
Shruti Guptabb772192023-10-09 16:08:28 +010069 rsi_ripas_respose_type response;
70 rsi_ripas_type ripas;
71
72 base = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX);
73 top = realm_shared_data_get_my_host_val(HOST_ARG2_INDEX);
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +010074 realm_printf("base=0x%lx top=0x%lx\n", base, top);
75 ret = rsi_ipa_state_get(base, top, &new_top, &ripas);
Shruti Guptabb772192023-10-09 16:08:28 +010076 if (ripas != RSI_EMPTY) {
77 return false;
78 }
79
80 ret = rsi_ipa_state_set(base, top, RSI_RAM,
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +010081 RSI_NO_CHANGE_DESTROYED, &new_base, &response);
82 if ((ret != RSI_SUCCESS) || (response != RSI_ACCEPT)) {
Shruti Guptabb772192023-10-09 16:08:28 +010083 return false;
84 }
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +010085
Shruti Guptabb772192023-10-09 16:08:28 +010086 while (new_base < top) {
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +010087 realm_printf("new_base=0x%lx top=0x%lx\n", new_base, top);
Shruti Guptabb772192023-10-09 16:08:28 +010088 ret = rsi_ipa_state_set(new_base, top, RSI_RAM,
89 RSI_NO_CHANGE_DESTROYED, &new_base, &response);
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +010090 if ((ret != RSI_SUCCESS) || (response != RSI_ACCEPT)) {
Shruti Guptabb772192023-10-09 16:08:28 +010091 realm_printf("rsi_ipa_state_set failed\n");
92 return false;
93 }
94 }
95
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +010096 /* Verify that RIAS has changed for range base-top */
97 ret = rsi_ipa_state_get(base, top, &new_top, &ripas);
98 if ((ret != RSI_SUCCESS) || (ripas != RSI_RAM) || (new_top != top)) {
99 realm_printf("rsi_ipa_state_get failed base=0x%lx top=0x%lx",
100 "new_top=0x%lx ripas=%u ret=0x%lx\n",
101 base, top, ripas);
102 return false;
Shruti Guptabb772192023-10-09 16:08:28 +0100103 }
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100104
Shruti Guptabb772192023-10-09 16:08:28 +0100105 return true;
106}
107
Shruti Guptafef86212023-10-17 12:15:38 +0100108bool test_realm_reject_set_ripas(void)
109{
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100110 u_register_t ret, base, top, new_base, new_top;
Shruti Guptafef86212023-10-17 12:15:38 +0100111 rsi_ripas_respose_type response;
112 rsi_ripas_type ripas;
113
114 base = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX);
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100115 top = base + PAGE_SIZE;
116 ret = rsi_ipa_state_get(base, top, &new_top, &ripas);
117 if ((ret != RSI_SUCCESS) || (ripas != RSI_EMPTY)) {
118 realm_printf("Wrong initial ripas=%u\n", ripas);
Shruti Guptafef86212023-10-17 12:15:38 +0100119 return false;
120 }
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100121 ret = rsi_ipa_state_set(base, top, RSI_RAM,
122 RSI_NO_CHANGE_DESTROYED, &new_base, &response);
123 if ((ret == RSI_SUCCESS) && (response == RSI_REJECT)) {
124 realm_printf("rsi_ipa_state_set passed response=%u\n", response);
125 ret = rsi_ipa_state_get(base, top, &new_top, &ripas);
126 if ((ret == RSI_SUCCESS) && (ripas == RSI_EMPTY) &&
127 (new_top == top)) {
Shruti Guptafef86212023-10-17 12:15:38 +0100128 return true;
129 } else {
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100130 realm_printf("rsi_ipa_state_get failed top=0x%lx",
131 "new_top=0x%lx ripas=%u ret=0x%lx\n",
132 ripas);
Shruti Guptafef86212023-10-17 12:15:38 +0100133 return false;
134 }
135 }
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100136 realm_printf("rsi_ipa_state_set failed ret=0x%lx response=%u\n",
137 ret, response);
Shruti Guptafef86212023-10-17 12:15:38 +0100138 return false;
139}
140
Shruti Gupta2a5abad2024-01-17 13:48:44 +0000141bool test_realm_dit_check_cmd(void)
142{
143 if (is_armv8_4_dit_present()) {
144 write_dit(DIT_BIT);
145 realm_printf("Testing DIT=0x%lx\n", read_dit());
146 /* Test if DIT is preserved after HOST_CALL */
147 if (read_dit() == DIT_BIT) {
148 return true;
149 }
150 }
151 return false;
152}
153
Shruti Guptae68494e2023-11-06 11:04:57 +0000154static bool test_realm_instr_fetch_cmd(void)
155{
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100156 u_register_t base, new_top;
Shruti Guptae68494e2023-11-06 11:04:57 +0000157 void (*func_ptr)(void);
158 rsi_ripas_type ripas;
159
160 base = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX);
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100161 rsi_ipa_state_get(base, base + PAGE_SIZE, &new_top, &ripas);
162 realm_printf("Initial ripas=%u\n", ripas);
163 /* Causes instruction abort */
Shruti Guptae68494e2023-11-06 11:04:57 +0000164 realm_printf("Generate Instruction Abort\n");
165 func_ptr = (void (*)(void))base;
166 func_ptr();
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100167 /* Should not return */
Shruti Guptae68494e2023-11-06 11:04:57 +0000168 return false;
169}
170
171static bool test_realm_data_access_cmd(void)
172{
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100173 u_register_t base, new_top;
Shruti Guptae68494e2023-11-06 11:04:57 +0000174 rsi_ripas_type ripas;
Shruti Guptae68494e2023-11-06 11:04:57 +0000175 base = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX);
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100176 rsi_ipa_state_get(base, base + PAGE_SIZE, &new_top, &ripas);
177 realm_printf("Initial ripas=%u\n", ripas);
178 /* Causes data abort */
Shruti Guptae68494e2023-11-06 11:04:57 +0000179 realm_printf("Generate Data Abort\n");
180 *((volatile uint64_t *)base);
Javier Almansa Sobrino7c78f7b2024-10-25 11:44:32 +0100181
Shruti Guptae68494e2023-11-06 11:04:57 +0000182 return false;
183}
184
Shruti Guptab027f572024-01-02 22:00:29 +0000185static bool realm_exception_handler(void)
186{
187 u_register_t base, far, esr;
188
189 base = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX);
190 far = read_far_el1();
191 esr = read_esr_el1();
192
193 if (far == base) {
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100194 /* Return ESR to Host */
Shruti Guptab027f572024-01-02 22:00:29 +0000195 realm_shared_data_set_my_realm_val(HOST_ARG2_INDEX, esr);
196 rsi_exit_to_host(HOST_CALL_EXIT_SUCCESS_CMD);
197 }
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100198 realm_printf("Realm Abort fail incorrect FAR=0x%lx ESR=0x%lx\n", far, esr);
Shruti Guptab027f572024-01-02 22:00:29 +0000199 rsi_exit_to_host(HOST_CALL_EXIT_FAILED_CMD);
200
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100201 /* Should not return */
Shruti Guptab027f572024-01-02 22:00:29 +0000202 return false;
203}
204
Manish V Badarkhe46d02282024-11-18 16:58:37 +0000205static bool realm_serror_handler_doublefault(bool *incr_elr_elx)
Javier Almansa Sobrino7c78f7b2024-10-25 11:44:32 +0100206{
Manish V Badarkhe46d02282024-11-18 16:58:37 +0000207 *incr_elr_elx = false;
208
Javier Almansa Sobrino7c78f7b2024-10-25 11:44:32 +0100209 if ((read_sctlr2_el1() & SCTLR2_EASE_BIT) != 0UL) {
210 /* The serror exception should have been routed here */
Manish V Badarkhe46d02282024-11-18 16:58:37 +0000211 *incr_elr_elx = true;
212
Javier Almansa Sobrino7c78f7b2024-10-25 11:44:32 +0100213 return true;
214 }
215
216 rsi_exit_to_host(HOST_CALL_EXIT_FAILED_CMD);
217
218 /* Should have never get here */
219 return false;
220}
221
222static bool realm_sync_handler_doublefault(void)
223{
224 if ((read_sctlr2_el1() & SCTLR2_EASE_BIT) == 0UL) {
225 /* The sync exception should have been routed here */
226 return true;
227 }
228
229 rsi_exit_to_host(HOST_CALL_EXIT_FAILED_CMD);
230
231 /* Should have never get here */
232 return false;
233}
234
235static void test_realm_feat_doublefault2(void)
236{
237 u_register_t ease_bit = realm_shared_data_get_my_host_val(HOST_ARG2_INDEX);
238
239 unregister_custom_sync_exception_handler();
240 register_custom_sync_exception_handler(realm_sync_handler_doublefault);
241 register_custom_serror_handler(realm_serror_handler_doublefault);
242
243 if (ease_bit != 0UL) {
244 write_sctlr2_el1(read_sctlr2_el1() | SCTLR2_EASE_BIT);
245 } else {
246 write_sctlr2_el1(read_sctlr2_el1() & ~SCTLR2_EASE_BIT);
247 }
248
249 (void)test_realm_data_access_cmd();
250}
251
nabkah01002e5692022-10-10 12:36:46 +0100252/*
253 * This is the entry function for Realm payload, it first requests the shared buffer
254 * IPA address from Host using HOST_CALL/RSI, it reads the command to be executed,
255 * performs the request, and returns to Host with the execution state SUCCESS/FAILED
256 *
257 * Host in NS world requests Realm to execute certain operations using command
258 * depending on the test case the Host wants to perform.
259 */
260void realm_payload_main(void)
261{
nabkah01002e5692022-10-10 12:36:46 +0100262 bool test_succeed = false;
263
Shruti Guptab027f572024-01-02 22:00:29 +0000264 register_custom_sync_exception_handler(realm_exception_handler);
Javier Almansa Sobrino7c78f7b2024-10-25 11:44:32 +0100265
266 /* No serror handler registered by default */
267 unregister_custom_serror_handler();
268
nabkah01002e5692022-10-10 12:36:46 +0100269 realm_set_shared_structure((host_shared_data_t *)rsi_get_ns_buffer());
Javier Almansa Sobrino7c78f7b2024-10-25 11:44:32 +0100270
Shruti Gupta550e3e82023-08-16 13:20:11 +0100271 if (realm_get_my_shared_structure() != NULL) {
272 uint8_t cmd = realm_shared_data_get_my_realm_cmd();
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000273
nabkah01002e5692022-10-10 12:36:46 +0100274 switch (cmd) {
275 case REALM_SLEEP_CMD:
276 realm_sleep_cmd();
277 test_succeed = true;
278 break;
Shruti Gupta6bb95102023-10-02 13:21:37 +0100279 case REALM_LOOP_CMD:
280 realm_loop_cmd();
281 test_succeed = true;
282 break;
Shruti Gupta24597d12023-10-02 10:40:19 +0100283 case REALM_MULTIPLE_REC_PSCI_DENIED_CMD:
284 test_succeed = test_realm_multiple_rec_psci_denied_cmd();
Shruti Guptae68494e2023-11-06 11:04:57 +0000285 break;
Shruti Guptaaffbae82023-08-22 12:51:11 +0100286 case REALM_MULTIPLE_REC_MULTIPLE_CPU_CMD:
287 test_succeed = test_realm_multiple_rec_multiple_cpu_cmd();
Shruti Gupta24597d12023-10-02 10:40:19 +0100288 break;
Javier Almansa Sobrino7c78f7b2024-10-25 11:44:32 +0100289 case REALM_FEAT_DOUBLEFAULT2_TEST:
290 test_realm_feat_doublefault2();
291 test_succeed = true;
292 break;
Shruti Guptae68494e2023-11-06 11:04:57 +0000293 case REALM_INSTR_FETCH_CMD:
294 test_succeed = test_realm_instr_fetch_cmd();
295 break;
296 case REALM_DATA_ACCESS_CMD:
297 test_succeed = test_realm_data_access_cmd();
298 break;
Shruti Gupta9d0cfe82023-04-17 10:57:26 +0100299 case REALM_PAUTH_SET_CMD:
300 test_succeed = test_realm_pauth_set_cmd();
301 break;
302 case REALM_PAUTH_CHECK_CMD:
303 test_succeed = test_realm_pauth_check_cmd();
304 break;
305 case REALM_PAUTH_FAULT:
306 test_succeed = test_realm_pauth_fault();
307 break;
Shruti Gupta2a5abad2024-01-17 13:48:44 +0000308 case REALM_DIT_CHECK_CMD:
309 test_succeed = test_realm_dit_check_cmd();
310 break;
nabkah01002e5692022-10-10 12:36:46 +0100311 case REALM_GET_RSI_VERSION:
Shruti Gupta40de8ec2023-10-12 21:45:12 +0100312 test_succeed = realm_get_rsi_version();
nabkah01002e5692022-10-10 12:36:46 +0100313 break;
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000314 case REALM_PMU_CYCLE:
315 test_succeed = test_pmuv3_cycle_works_realm();
316 break;
Shruti Guptab1b37922024-01-13 21:49:04 +0000317 case REALM_PMU_COUNTER:
318 test_succeed = test_pmuv3_counter();
319 break;
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000320 case REALM_PMU_EVENT:
321 test_succeed = test_pmuv3_event_works_realm();
322 break;
323 case REALM_PMU_PRESERVE:
324 test_succeed = test_pmuv3_rmm_preserves();
325 break;
326 case REALM_PMU_INTERRUPT:
327 test_succeed = test_pmuv3_overflow_interrupt();
328 break;
Shruti Gupta369955a2023-04-19 18:05:56 +0100329 case REALM_REQ_FPU_FILL_CMD:
Arunachalam Ganapathy7e514f62023-08-30 13:27:36 +0100330 fpu_state_write_rand(&rl_fpu_state_write);
Shruti Gupta369955a2023-04-19 18:05:56 +0100331 test_succeed = true;
332 break;
333 case REALM_REQ_FPU_CMP_CMD:
Arunachalam Ganapathy7e514f62023-08-30 13:27:36 +0100334 fpu_state_read(&rl_fpu_state_read);
335 test_succeed = !fpu_state_compare(&rl_fpu_state_write,
336 &rl_fpu_state_read);
Arunachalam Ganapathy9af432e2023-06-02 17:18:23 +0100337 break;
Shruti Guptafef86212023-10-17 12:15:38 +0100338 case REALM_REJECT_SET_RIPAS_CMD:
339 test_succeed = test_realm_reject_set_ripas();
340 break;
Shruti Guptabb772192023-10-09 16:08:28 +0100341 case REALM_SET_RIPAS_CMD:
342 test_succeed = test_realm_set_ripas();
343 break;
Arunachalam Ganapathy0bbdc2d2023-04-05 15:30:18 +0100344 case REALM_SVE_RDVL:
345 test_succeed = test_realm_sve_rdvl();
346 break;
347 case REALM_SVE_ID_REGISTERS:
348 test_succeed = test_realm_sve_read_id_registers();
349 break;
350 case REALM_SVE_PROBE_VL:
351 test_succeed = test_realm_sve_probe_vl();
Shruti Gupta369955a2023-04-19 18:05:56 +0100352 break;
Arunachalam Ganapathyc1136a82023-04-12 15:24:44 +0100353 case REALM_SVE_OPS:
354 test_succeed = test_realm_sve_ops();
355 break;
Arunachalam Ganapathy5270d012023-04-19 14:53:42 +0100356 case REALM_SVE_FILL_REGS:
357 test_succeed = test_realm_sve_fill_regs();
358 break;
Arunachalam Ganapathyf3697172023-09-04 15:04:46 +0100359 case REALM_SVE_CMP_REGS:
360 test_succeed = test_realm_sve_cmp_regs();
361 break;
Arunachalam Ganapathy73949a22023-06-05 12:01:05 +0100362 case REALM_SVE_UNDEF_ABORT:
363 test_succeed = test_realm_sve_undef_abort();
364 break;
Arunachalam Ganapathy1768e592023-05-23 13:28:38 +0100365 case REALM_SME_ID_REGISTERS:
366 test_succeed = test_realm_sme_read_id_registers();
367 break;
368 case REALM_SME_UNDEF_ABORT:
369 test_succeed = test_realm_sme_undef_abort();
370 break;
nabkah01002e5692022-10-10 12:36:46 +0100371 default:
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000372 realm_printf("%s() invalid cmd %u\n", __func__, cmd);
nabkah01002e5692022-10-10 12:36:46 +0100373 break;
374 }
375 }
376
377 if (test_succeed) {
378 rsi_exit_to_host(HOST_CALL_EXIT_SUCCESS_CMD);
379 } else {
380 rsi_exit_to_host(HOST_CALL_EXIT_FAILED_CMD);
381 }
382}