blob: 47f9b9ff241e7ba852951c4fa9eeacf559353fb2 [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>
Shruti Guptab027f572024-01-02 22:00:29 +000019#include <sync.h>
nabkah01002e5692022-10-10 12:36:46 +010020#include <tftf_lib.h>
21
Arunachalam Ganapathy7e514f62023-08-30 13:27:36 +010022static fpu_state_t rl_fpu_state_write;
23static fpu_state_t rl_fpu_state_read;
nabkah01002e5692022-10-10 12:36:46 +010024/*
AlexeiFedorov2f30f102023-03-13 19:37:46 +000025 * This function reads sleep time in ms from shared buffer and spins PE
26 * in a loop for that time period.
nabkah01002e5692022-10-10 12:36:46 +010027 */
28static void realm_sleep_cmd(void)
29{
Shruti Gupta52b5f022023-10-12 22:02:29 +010030 uint64_t sleep = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX);
nabkah01002e5692022-10-10 12:36:46 +010031
Shruti Guptaa276b202023-12-18 10:07:43 +000032 realm_printf("going to sleep for %llums\n", sleep);
nabkah01002e5692022-10-10 12:36:46 +010033 waitms(sleep);
34}
35
Shruti Gupta6bb95102023-10-02 13:21:37 +010036static void realm_loop_cmd(void)
37{
38 while (true) {
39 waitms(500);
40 }
41}
42
nabkah01002e5692022-10-10 12:36:46 +010043/*
44 * This function requests RSI/ABI version from RMM.
45 */
Shruti Gupta40de8ec2023-10-12 21:45:12 +010046static bool realm_get_rsi_version(void)
nabkah01002e5692022-10-10 12:36:46 +010047{
Shruti Gupta40de8ec2023-10-12 21:45:12 +010048 u_register_t version = 0U;
nabkah01002e5692022-10-10 12:36:46 +010049
Shruti Gupta40de8ec2023-10-12 21:45:12 +010050 version = rsi_get_version(RSI_ABI_VERSION_VAL);
nabkah01002e5692022-10-10 12:36:46 +010051 if (version == (u_register_t)SMC_UNKNOWN) {
Shruti Gupta40de8ec2023-10-12 21:45:12 +010052 realm_printf("SMC_RSI_ABI_VERSION failed\n");
53 return false;
nabkah01002e5692022-10-10 12:36:46 +010054 }
55
Shruti Gupta40de8ec2023-10-12 21:45:12 +010056 realm_printf("RSI ABI version %u.%u (expected: %u.%u)\n",
nabkah01002e5692022-10-10 12:36:46 +010057 RSI_ABI_VERSION_GET_MAJOR(version),
58 RSI_ABI_VERSION_GET_MINOR(version),
Shruti Gupta40de8ec2023-10-12 21:45:12 +010059 RSI_ABI_VERSION_GET_MAJOR(RSI_ABI_VERSION_VAL),
60 RSI_ABI_VERSION_GET_MINOR(RSI_ABI_VERSION_VAL));
61 return true;
nabkah01002e5692022-10-10 12:36:46 +010062}
63
Shruti Guptabb772192023-10-09 16:08:28 +010064bool test_realm_set_ripas(void)
65{
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +010066 u_register_t ret, base, new_base, top, new_top;
Shruti Guptabb772192023-10-09 16:08:28 +010067 rsi_ripas_respose_type response;
68 rsi_ripas_type ripas;
69
70 base = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX);
71 top = realm_shared_data_get_my_host_val(HOST_ARG2_INDEX);
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +010072 realm_printf("base=0x%lx top=0x%lx\n", base, top);
73 ret = rsi_ipa_state_get(base, top, &new_top, &ripas);
Shruti Guptabb772192023-10-09 16:08:28 +010074 if (ripas != RSI_EMPTY) {
75 return false;
76 }
77
78 ret = rsi_ipa_state_set(base, top, RSI_RAM,
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +010079 RSI_NO_CHANGE_DESTROYED, &new_base, &response);
80 if ((ret != RSI_SUCCESS) || (response != RSI_ACCEPT)) {
Shruti Guptabb772192023-10-09 16:08:28 +010081 return false;
82 }
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +010083
Shruti Guptabb772192023-10-09 16:08:28 +010084 while (new_base < top) {
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +010085 realm_printf("new_base=0x%lx top=0x%lx\n", new_base, top);
Shruti Guptabb772192023-10-09 16:08:28 +010086 ret = rsi_ipa_state_set(new_base, top, RSI_RAM,
87 RSI_NO_CHANGE_DESTROYED, &new_base, &response);
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +010088 if ((ret != RSI_SUCCESS) || (response != RSI_ACCEPT)) {
Shruti Guptabb772192023-10-09 16:08:28 +010089 realm_printf("rsi_ipa_state_set failed\n");
90 return false;
91 }
92 }
93
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +010094 /* Verify that RIAS has changed for range base-top */
95 ret = rsi_ipa_state_get(base, top, &new_top, &ripas);
96 if ((ret != RSI_SUCCESS) || (ripas != RSI_RAM) || (new_top != top)) {
97 realm_printf("rsi_ipa_state_get failed base=0x%lx top=0x%lx",
98 "new_top=0x%lx ripas=%u ret=0x%lx\n",
99 base, top, ripas);
100 return false;
Shruti Guptabb772192023-10-09 16:08:28 +0100101 }
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100102
Shruti Guptabb772192023-10-09 16:08:28 +0100103 return true;
104}
105
Shruti Guptafef86212023-10-17 12:15:38 +0100106bool test_realm_reject_set_ripas(void)
107{
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100108 u_register_t ret, base, top, new_base, new_top;
Shruti Guptafef86212023-10-17 12:15:38 +0100109 rsi_ripas_respose_type response;
110 rsi_ripas_type ripas;
111
112 base = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX);
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100113 top = base + PAGE_SIZE;
114 ret = rsi_ipa_state_get(base, top, &new_top, &ripas);
115 if ((ret != RSI_SUCCESS) || (ripas != RSI_EMPTY)) {
116 realm_printf("Wrong initial ripas=%u\n", ripas);
Shruti Guptafef86212023-10-17 12:15:38 +0100117 return false;
118 }
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100119 ret = rsi_ipa_state_set(base, top, RSI_RAM,
120 RSI_NO_CHANGE_DESTROYED, &new_base, &response);
121 if ((ret == RSI_SUCCESS) && (response == RSI_REJECT)) {
122 realm_printf("rsi_ipa_state_set passed response=%u\n", response);
123 ret = rsi_ipa_state_get(base, top, &new_top, &ripas);
124 if ((ret == RSI_SUCCESS) && (ripas == RSI_EMPTY) &&
125 (new_top == top)) {
Shruti Guptafef86212023-10-17 12:15:38 +0100126 return true;
127 } else {
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100128 realm_printf("rsi_ipa_state_get failed top=0x%lx",
129 "new_top=0x%lx ripas=%u ret=0x%lx\n",
130 ripas);
Shruti Guptafef86212023-10-17 12:15:38 +0100131 return false;
132 }
133 }
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100134 realm_printf("rsi_ipa_state_set failed ret=0x%lx response=%u\n",
135 ret, response);
Shruti Guptafef86212023-10-17 12:15:38 +0100136 return false;
137}
138
Shruti Gupta2a5abad2024-01-17 13:48:44 +0000139bool test_realm_dit_check_cmd(void)
140{
141 if (is_armv8_4_dit_present()) {
142 write_dit(DIT_BIT);
143 realm_printf("Testing DIT=0x%lx\n", read_dit());
144 /* Test if DIT is preserved after HOST_CALL */
145 if (read_dit() == DIT_BIT) {
146 return true;
147 }
148 }
149 return false;
150}
151
Shruti Guptae68494e2023-11-06 11:04:57 +0000152static bool test_realm_instr_fetch_cmd(void)
153{
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100154 u_register_t base, new_top;
Shruti Guptae68494e2023-11-06 11:04:57 +0000155 void (*func_ptr)(void);
156 rsi_ripas_type ripas;
157
158 base = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX);
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100159 rsi_ipa_state_get(base, base + PAGE_SIZE, &new_top, &ripas);
160 realm_printf("Initial ripas=%u\n", ripas);
161 /* Causes instruction abort */
Shruti Guptae68494e2023-11-06 11:04:57 +0000162 realm_printf("Generate Instruction Abort\n");
163 func_ptr = (void (*)(void))base;
164 func_ptr();
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100165 /* Should not return */
Shruti Guptae68494e2023-11-06 11:04:57 +0000166 return false;
167}
168
169static bool test_realm_data_access_cmd(void)
170{
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100171 u_register_t base, new_top;
Shruti Guptae68494e2023-11-06 11:04:57 +0000172 rsi_ripas_type ripas;
Shruti Guptae68494e2023-11-06 11:04:57 +0000173 base = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX);
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100174 rsi_ipa_state_get(base, base + PAGE_SIZE, &new_top, &ripas);
175 realm_printf("Initial ripas=%u\n", ripas);
176 /* Causes data abort */
Shruti Guptae68494e2023-11-06 11:04:57 +0000177 realm_printf("Generate Data Abort\n");
178 *((volatile uint64_t *)base);
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100179 /* Should not return */
Shruti Guptae68494e2023-11-06 11:04:57 +0000180 return false;
181}
182
Shruti Guptab027f572024-01-02 22:00:29 +0000183static bool realm_exception_handler(void)
184{
185 u_register_t base, far, esr;
186
187 base = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX);
188 far = read_far_el1();
189 esr = read_esr_el1();
190
191 if (far == base) {
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100192 /* Return ESR to Host */
Shruti Guptab027f572024-01-02 22:00:29 +0000193 realm_shared_data_set_my_realm_val(HOST_ARG2_INDEX, esr);
194 rsi_exit_to_host(HOST_CALL_EXIT_SUCCESS_CMD);
195 }
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100196 realm_printf("Realm Abort fail incorrect FAR=0x%lx ESR=0x%lx\n", far, esr);
Shruti Guptab027f572024-01-02 22:00:29 +0000197 rsi_exit_to_host(HOST_CALL_EXIT_FAILED_CMD);
198
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100199 /* Should not return */
Shruti Guptab027f572024-01-02 22:00:29 +0000200 return false;
201}
202
nabkah01002e5692022-10-10 12:36:46 +0100203/*
204 * This is the entry function for Realm payload, it first requests the shared buffer
205 * IPA address from Host using HOST_CALL/RSI, it reads the command to be executed,
206 * performs the request, and returns to Host with the execution state SUCCESS/FAILED
207 *
208 * Host in NS world requests Realm to execute certain operations using command
209 * depending on the test case the Host wants to perform.
210 */
211void realm_payload_main(void)
212{
nabkah01002e5692022-10-10 12:36:46 +0100213 bool test_succeed = false;
214
Shruti Guptab027f572024-01-02 22:00:29 +0000215 register_custom_sync_exception_handler(realm_exception_handler);
nabkah01002e5692022-10-10 12:36:46 +0100216 realm_set_shared_structure((host_shared_data_t *)rsi_get_ns_buffer());
Shruti Gupta550e3e82023-08-16 13:20:11 +0100217 if (realm_get_my_shared_structure() != NULL) {
218 uint8_t cmd = realm_shared_data_get_my_realm_cmd();
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000219
nabkah01002e5692022-10-10 12:36:46 +0100220 switch (cmd) {
221 case REALM_SLEEP_CMD:
222 realm_sleep_cmd();
223 test_succeed = true;
224 break;
Shruti Gupta6bb95102023-10-02 13:21:37 +0100225 case REALM_LOOP_CMD:
226 realm_loop_cmd();
227 test_succeed = true;
228 break;
Shruti Gupta24597d12023-10-02 10:40:19 +0100229 case REALM_MULTIPLE_REC_PSCI_DENIED_CMD:
230 test_succeed = test_realm_multiple_rec_psci_denied_cmd();
Shruti Guptae68494e2023-11-06 11:04:57 +0000231 break;
Shruti Guptaaffbae82023-08-22 12:51:11 +0100232 case REALM_MULTIPLE_REC_MULTIPLE_CPU_CMD:
233 test_succeed = test_realm_multiple_rec_multiple_cpu_cmd();
Shruti Gupta24597d12023-10-02 10:40:19 +0100234 break;
Shruti Guptae68494e2023-11-06 11:04:57 +0000235 case REALM_INSTR_FETCH_CMD:
236 test_succeed = test_realm_instr_fetch_cmd();
237 break;
238 case REALM_DATA_ACCESS_CMD:
239 test_succeed = test_realm_data_access_cmd();
240 break;
Shruti Gupta9d0cfe82023-04-17 10:57:26 +0100241 case REALM_PAUTH_SET_CMD:
242 test_succeed = test_realm_pauth_set_cmd();
243 break;
244 case REALM_PAUTH_CHECK_CMD:
245 test_succeed = test_realm_pauth_check_cmd();
246 break;
247 case REALM_PAUTH_FAULT:
248 test_succeed = test_realm_pauth_fault();
249 break;
Shruti Gupta2a5abad2024-01-17 13:48:44 +0000250 case REALM_DIT_CHECK_CMD:
251 test_succeed = test_realm_dit_check_cmd();
252 break;
nabkah01002e5692022-10-10 12:36:46 +0100253 case REALM_GET_RSI_VERSION:
Shruti Gupta40de8ec2023-10-12 21:45:12 +0100254 test_succeed = realm_get_rsi_version();
nabkah01002e5692022-10-10 12:36:46 +0100255 break;
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000256 case REALM_PMU_CYCLE:
257 test_succeed = test_pmuv3_cycle_works_realm();
258 break;
Shruti Guptab1b37922024-01-13 21:49:04 +0000259 case REALM_PMU_COUNTER:
260 test_succeed = test_pmuv3_counter();
261 break;
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000262 case REALM_PMU_EVENT:
263 test_succeed = test_pmuv3_event_works_realm();
264 break;
265 case REALM_PMU_PRESERVE:
266 test_succeed = test_pmuv3_rmm_preserves();
267 break;
268 case REALM_PMU_INTERRUPT:
269 test_succeed = test_pmuv3_overflow_interrupt();
270 break;
Shruti Gupta369955a2023-04-19 18:05:56 +0100271 case REALM_REQ_FPU_FILL_CMD:
Arunachalam Ganapathy7e514f62023-08-30 13:27:36 +0100272 fpu_state_write_rand(&rl_fpu_state_write);
Shruti Gupta369955a2023-04-19 18:05:56 +0100273 test_succeed = true;
274 break;
275 case REALM_REQ_FPU_CMP_CMD:
Arunachalam Ganapathy7e514f62023-08-30 13:27:36 +0100276 fpu_state_read(&rl_fpu_state_read);
277 test_succeed = !fpu_state_compare(&rl_fpu_state_write,
278 &rl_fpu_state_read);
Arunachalam Ganapathy9af432e2023-06-02 17:18:23 +0100279 break;
Shruti Guptafef86212023-10-17 12:15:38 +0100280 case REALM_REJECT_SET_RIPAS_CMD:
281 test_succeed = test_realm_reject_set_ripas();
282 break;
Shruti Guptabb772192023-10-09 16:08:28 +0100283 case REALM_SET_RIPAS_CMD:
284 test_succeed = test_realm_set_ripas();
285 break;
Arunachalam Ganapathy0bbdc2d2023-04-05 15:30:18 +0100286 case REALM_SVE_RDVL:
287 test_succeed = test_realm_sve_rdvl();
288 break;
289 case REALM_SVE_ID_REGISTERS:
290 test_succeed = test_realm_sve_read_id_registers();
291 break;
292 case REALM_SVE_PROBE_VL:
293 test_succeed = test_realm_sve_probe_vl();
Shruti Gupta369955a2023-04-19 18:05:56 +0100294 break;
Arunachalam Ganapathyc1136a82023-04-12 15:24:44 +0100295 case REALM_SVE_OPS:
296 test_succeed = test_realm_sve_ops();
297 break;
Arunachalam Ganapathy5270d012023-04-19 14:53:42 +0100298 case REALM_SVE_FILL_REGS:
299 test_succeed = test_realm_sve_fill_regs();
300 break;
Arunachalam Ganapathyf3697172023-09-04 15:04:46 +0100301 case REALM_SVE_CMP_REGS:
302 test_succeed = test_realm_sve_cmp_regs();
303 break;
Arunachalam Ganapathy73949a22023-06-05 12:01:05 +0100304 case REALM_SVE_UNDEF_ABORT:
305 test_succeed = test_realm_sve_undef_abort();
306 break;
Arunachalam Ganapathy1768e592023-05-23 13:28:38 +0100307 case REALM_SME_ID_REGISTERS:
308 test_succeed = test_realm_sme_read_id_registers();
309 break;
310 case REALM_SME_UNDEF_ABORT:
311 test_succeed = test_realm_sme_undef_abort();
312 break;
nabkah01002e5692022-10-10 12:36:46 +0100313 default:
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000314 realm_printf("%s() invalid cmd %u\n", __func__, cmd);
nabkah01002e5692022-10-10 12:36:46 +0100315 break;
316 }
317 }
318
319 if (test_succeed) {
320 rsi_exit_to_host(HOST_CALL_EXIT_SUCCESS_CMD);
321 } else {
322 rsi_exit_to_host(HOST_CALL_EXIT_FAILED_CMD);
323 }
324}