blob: 9a63d85ef8884c04db46aeefeab18f32039cfa22 [file] [log] [blame]
J-Alvesbb467d12021-03-18 11:49:35 +00001/*
Daniel Boulbyce386b12022-03-29 18:36:36 +01002 * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
J-Alvesbb467d12021-03-18 11:49:35 +00003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <debug.h>
J-Alves269118a2021-09-22 09:46:11 +01008#include <irq.h>
J-Alvesbb467d12021-03-18 11:49:35 +00009#include <smccc.h>
10
11#include <arch_helpers.h>
12#include <cactus_test_cmds.h>
13#include <ffa_endpoints.h>
14#include <ffa_svc.h>
15#include <platform.h>
16#include <spm_common.h>
Daniel Boulby82bf3392023-07-28 18:32:27 +010017#include <spm_test_helpers.h>
J-Alvesbb467d12021-03-18 11:49:35 +000018#include <test_helpers.h>
19
J-Alvese5f3fe62021-03-18 11:51:20 +000020static const struct ffa_uuid expected_sp_uuids[] = {
21 {PRIMARY_UUID}, {SECONDARY_UUID}, {TERTIARY_UUID}
22};
23
24static ffa_notification_bitmap_t g_notifications = FFA_NOTIFICATION(0) |
25 FFA_NOTIFICATION(1) |
26 FFA_NOTIFICATION(30) |
27 FFA_NOTIFICATION(50) |
28 FFA_NOTIFICATION(63);
29
J-Alvesbb467d12021-03-18 11:49:35 +000030/**
J-Alves4439ece2021-11-05 11:52:54 +000031 * Use FFA_FEATURES to retrieve the ID of:
32 * - Schedule Receiver Interrupt
33 * - Notification Pending Interrupt
34 * - Managed Exit Interrupt
35 * Validate the call works as expected, and they match the used int ID in the
36 * remainder of the tests.
37 */
38test_result_t test_notifications_retrieve_int_ids(void)
39{
Daniel Boulbyce386b12022-03-29 18:36:36 +010040 struct ffa_value ret;
J-Alves4439ece2021-11-05 11:52:54 +000041
42 SKIP_TEST_IF_FFA_VERSION_LESS_THAN(1, 1);
43
44 /* Check if SPMC is OP-TEE at S-EL1 */
45 if (check_spmc_execution_level()) {
46 /* FFA_FEATURES is not yet supported in OP-TEE */
47 return TEST_RESULT_SUCCESS;
48 }
49
50 ret = ffa_features(FFA_FEATURE_NPI);
Karl Meakin0569cc02024-04-17 17:32:35 +010051 if (!is_expected_ffa_error(ret, FFA_ERROR_NOT_SUPPORTED))
J-Alves4439ece2021-11-05 11:52:54 +000052 return TEST_RESULT_FAIL;
J-Alves4439ece2021-11-05 11:52:54 +000053
54 ret = ffa_features(FFA_FEATURE_SRI);
55 if (is_ffa_call_error(ret) ||
56 ffa_feature_intid(ret) != FFA_SCHEDULE_RECEIVER_INTERRUPT_ID) {
57 ERROR("Failed to retrieved SRI (exp: %u, got: %u)\n",
58 FFA_SCHEDULE_RECEIVER_INTERRUPT_ID,
59 ffa_feature_intid(ret));
60
61 return TEST_RESULT_FAIL;
62 }
63
64 ret = ffa_features(FFA_FEATURE_MEI);
Karl Meakin0569cc02024-04-17 17:32:35 +010065 if (!is_expected_ffa_error(ret, FFA_ERROR_NOT_SUPPORTED))
J-Alves4439ece2021-11-05 11:52:54 +000066 return TEST_RESULT_FAIL;
J-Alves4439ece2021-11-05 11:52:54 +000067
68 return TEST_RESULT_SUCCESS;
69}
70
71/**
J-Alvesbb467d12021-03-18 11:49:35 +000072 * Helper to create bitmap for NWd VMs.
73 */
74static bool notifications_bitmap_create(ffa_id_t vm_id,
75 ffa_vcpu_count_t vcpu_count)
76{
77 VERBOSE("Creating bitmap for VM %x; cpu count: %u.\n",
78 vm_id, vcpu_count);
Daniel Boulbyce386b12022-03-29 18:36:36 +010079 struct ffa_value ret = ffa_notification_bitmap_create(vm_id,
80 vcpu_count);
J-Alvesbb467d12021-03-18 11:49:35 +000081
82 return !is_ffa_call_error(ret);
83}
84
85/**
86 * Helper to destroy bitmap for NWd VMs.
87 */
88static bool notifications_bitmap_destroy(ffa_id_t vm_id)
89{
90 VERBOSE("Destroying bitmap of VM %x.\n", vm_id);
Daniel Boulbyce386b12022-03-29 18:36:36 +010091 struct ffa_value ret = ffa_notification_bitmap_destroy(vm_id);
J-Alvesbb467d12021-03-18 11:49:35 +000092
93 return !is_ffa_call_error(ret);
94}
95
96/**
97 * Test notifications bitmap create and destroy interfaces.
98 */
99test_result_t test_ffa_notifications_bitmap_create_destroy(void)
100{
J-Alvesd5d87152021-10-29 11:48:37 +0100101 const ffa_id_t vm_id = VM_ID(1);
J-Alvesbb467d12021-03-18 11:49:35 +0000102
103 SKIP_TEST_IF_FFA_VERSION_LESS_THAN(1, 1);
104
105 if (check_spmc_execution_level()) {
106 VERBOSE("OPTEE as SPMC at S-EL1. Skipping test!\n");
107 return TEST_RESULT_SKIPPED;
108 }
109
110 if (!notifications_bitmap_create(vm_id, PLATFORM_CORE_COUNT)) {
111 return TEST_RESULT_FAIL;
112 }
113
114 if (!notifications_bitmap_destroy(vm_id)) {
115 return TEST_RESULT_FAIL;
116 }
117
118 return TEST_RESULT_SUCCESS;
119}
120
121/**
122 * Test notifications bitmap destroy in a case the bitmap hasn't been created.
123 */
124test_result_t test_ffa_notifications_destroy_not_created(void)
125{
126 SKIP_TEST_IF_FFA_VERSION_LESS_THAN(1, 1);
127
128 if (check_spmc_execution_level()) {
129 VERBOSE("OPTEE as SPMC at S-EL1. Skipping test!\n");
130 return TEST_RESULT_SKIPPED;
131 }
132
Daniel Boulbyce386b12022-03-29 18:36:36 +0100133 struct ffa_value ret = ffa_notification_bitmap_destroy(VM_ID(1));
J-Alvesbb467d12021-03-18 11:49:35 +0000134
135 if (!is_expected_ffa_error(ret, FFA_ERROR_DENIED)) {
136 return TEST_RESULT_FAIL;
137 }
138
139 return TEST_RESULT_SUCCESS;
140}
141
142/**
143 * Test attempt to create notifications bitmap for NWd VM if it had been
144 * already created.
145 */
146test_result_t test_ffa_notifications_create_after_create(void)
147{
Daniel Boulbyce386b12022-03-29 18:36:36 +0100148 struct ffa_value ret;
J-Alvesd5d87152021-10-29 11:48:37 +0100149 const ffa_id_t vm_id = VM_ID(2);
J-Alvesbb467d12021-03-18 11:49:35 +0000150
151 SKIP_TEST_IF_FFA_VERSION_LESS_THAN(1, 1);
152
153 if (check_spmc_execution_level()) {
154 VERBOSE("OPTEE as SPMC at S-EL1. Skipping test!\n");
155 return TEST_RESULT_SKIPPED;
156 }
157
158 /* First successfully create a notifications bitmap */
159 if (!notifications_bitmap_create(vm_id, 1)) {
160 return TEST_RESULT_FAIL;
161 }
162
163 /* Attempt to do the same to the same VM. */
164 ret = ffa_notification_bitmap_create(vm_id, 1);
165
166 if (!is_expected_ffa_error(ret, FFA_ERROR_DENIED)) {
167 return TEST_RESULT_FAIL;
168 }
169
170 /* Destroy to not affect other tests */
171 if (!notifications_bitmap_destroy(vm_id)) {
172 return TEST_RESULT_FAIL;
173 }
174
175 return TEST_RESULT_SUCCESS;
176}
J-Alvese5f3fe62021-03-18 11:51:20 +0000177
178/**
179 * Helper function to test FFA_NOTIFICATION_BIND interface.
180 * Receives all arguments to use 'cactus_notification_bind_send_cmd', and
181 * expected response for the test command.
182 *
183 * Returns:
184 * - 'true' if response was obtained and it was as expected;
185 * - 'false' if there was an error with use of FFA_MSG_SEND_DIRECT_REQ, or
186 * the obtained response was not as expected.
187 */
188static bool request_notification_bind(
189 ffa_id_t cmd_dest, ffa_id_t receiver, ffa_id_t sender,
190 ffa_notification_bitmap_t notifications, uint32_t flags,
191 uint32_t expected_resp, uint32_t error_code)
192{
Daniel Boulbyce386b12022-03-29 18:36:36 +0100193 struct ffa_value ret;
J-Alvese5f3fe62021-03-18 11:51:20 +0000194
195 VERBOSE("TFTF requesting SP to bind notifications!\n");
196
197 ret = cactus_notification_bind_send_cmd(HYP_ID, cmd_dest, receiver,
198 sender, notifications, flags);
199
J-Alvese5554332021-11-04 17:24:57 +0000200 if (!is_expected_cactus_response(ret, expected_resp, error_code)) {
201 ERROR("Failed notifications bind. receiver: %x; sender: %x\n",
202 receiver, sender);
203 return false;
204 }
205
206 return true;
J-Alvese5f3fe62021-03-18 11:51:20 +0000207}
208
209/**
210 * Helper function to test FFA_NOTIFICATION_UNBIND interface.
211 * Receives all arguments to use 'cactus_notification_unbind_send_cmd', and
212 * expected response for the test command.
213 *
214 * Returns:
215 * - 'true' if response was obtained and it was as expected;
216 * - 'false' if there was an error with use of FFA_MSG_SEND_DIRECT_REQ, or
217 * the obtained response was not as expected.
218 */
219static bool request_notification_unbind(
220 ffa_id_t cmd_dest, ffa_id_t receiver, ffa_id_t sender,
221 ffa_notification_bitmap_t notifications, uint32_t expected_resp,
222 uint32_t error_code)
223{
Daniel Boulbyce386b12022-03-29 18:36:36 +0100224 struct ffa_value ret;
J-Alvese5f3fe62021-03-18 11:51:20 +0000225
226 VERBOSE("TFTF requesting SP to unbind notifications!\n");
227
228 ret = cactus_notification_unbind_send_cmd(HYP_ID, cmd_dest, receiver,
229 sender, notifications);
230
J-Alvese5554332021-11-04 17:24:57 +0000231 if (!is_expected_cactus_response(ret, expected_resp, error_code)) {
232 ERROR("Failed notifications unbind. receiver: %x; sender: %x\n",
233 receiver, sender);
234 return false;
235 }
236
237 return true;
J-Alvese5f3fe62021-03-18 11:51:20 +0000238}
239
240/**
241 * Test calls from SPs to the bind and unbind interfaces, expecting success
242 * returns.
243 * This test issues a request via direct messaging to the SP, which executes
244 * the test and responds with the result of the call.
245 */
246test_result_t test_ffa_notifications_sp_bind_unbind(void)
247{
248 CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
249
250 /** First bind... */
251 if (!request_notification_bind(SP_ID(1), SP_ID(1), SP_ID(2),
252 g_notifications, 0, CACTUS_SUCCESS, 0)) {
253 return TEST_RESULT_FAIL;
254 }
255
256 if (!request_notification_bind(SP_ID(1), SP_ID(1), 1,
257 g_notifications, 0, CACTUS_SUCCESS, 0)) {
258 return TEST_RESULT_FAIL;
259 }
260
261 /** ... then unbind using the same arguments. */
262 if (!request_notification_unbind(SP_ID(1), SP_ID(1), SP_ID(2),
263 g_notifications, CACTUS_SUCCESS, 0)) {
264 return TEST_RESULT_FAIL;
265 }
266
267 if (!request_notification_unbind(SP_ID(1), SP_ID(1), 1,
268 g_notifications, CACTUS_SUCCESS, 0)) {
269 return TEST_RESULT_FAIL;
270 }
271
272 return TEST_RESULT_SUCCESS;
273}
274
275/**
276 * Test successful attempt of doing bind and unbind of the same set of
277 * notifications.
278 */
279test_result_t test_ffa_notifications_vm_bind_unbind(void)
280{
281 CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
J-Alvesd5d87152021-10-29 11:48:37 +0100282 const ffa_id_t vm_id = VM_ID(1);
Daniel Boulbyce386b12022-03-29 18:36:36 +0100283 struct ffa_value ret;
J-Alvese5f3fe62021-03-18 11:51:20 +0000284
285 if (!notifications_bitmap_create(vm_id, 1)) {
286 return TEST_RESULT_FAIL;
287 }
288
289 ret = ffa_notification_bind(SP_ID(2), vm_id, 0, g_notifications);
290
291 if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32)) {
292 return TEST_RESULT_FAIL;
293 }
294
295 ret = ffa_notification_unbind(SP_ID(2), vm_id, g_notifications);
296
297 if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32)) {
298 return TEST_RESULT_FAIL;
299 }
300
301 if (!notifications_bitmap_destroy(vm_id)) {
302 return TEST_RESULT_FAIL;
303 }
304
305 return TEST_RESULT_SUCCESS;
306}
307
308/**
309 * Test expected failure of using a NS FF-A ID for the sender.
310 */
311test_result_t test_ffa_notifications_vm_bind_vm(void)
312{
313 CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
J-Alvesd5d87152021-10-29 11:48:37 +0100314 const ffa_id_t vm_id = VM_ID(1);
315 const ffa_id_t sender_id = VM_ID(2);
Daniel Boulbyce386b12022-03-29 18:36:36 +0100316 struct ffa_value ret;
J-Alvese5f3fe62021-03-18 11:51:20 +0000317
318 if (!notifications_bitmap_create(vm_id, 1)) {
319 return TEST_RESULT_FAIL;
320 }
321
322 ret = ffa_notification_bind(sender_id, vm_id, 0, g_notifications);
323
324 if (!is_expected_ffa_error(ret, FFA_ERROR_INVALID_PARAMETER)) {
325 return TEST_RESULT_FAIL;
326 }
327
328 if (!notifications_bitmap_destroy(vm_id)) {
329 return TEST_RESULT_FAIL;
330 }
331
332 return TEST_RESULT_SUCCESS;
333}
334
335/**
336 * Test failure of both bind and unbind in case at least one notification is
337 * already bound to another FF-A endpoint.
338 * Expect error code FFA_ERROR_DENIED.
339 */
340test_result_t test_ffa_notifications_already_bound(void)
341{
342 CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
343
344 /** Bind first to test */
345 if (!request_notification_bind(SP_ID(1), SP_ID(1), SP_ID(2),
346 g_notifications, 0, CACTUS_SUCCESS, 0)) {
347 return TEST_RESULT_FAIL;
348 }
349
350 /** Attempt to bind notifications bound in above request. */
351 if (!request_notification_bind(SP_ID(1), SP_ID(1), SP_ID(3),
352 g_notifications, 0, CACTUS_ERROR,
353 FFA_ERROR_DENIED)) {
354 return TEST_RESULT_FAIL;
355 }
356
357 /** Attempt to unbind notifications bound in initial request. */
358 if (!request_notification_unbind(SP_ID(1), SP_ID(1), SP_ID(3),
359 g_notifications, CACTUS_ERROR,
360 FFA_ERROR_DENIED)) {
361 return TEST_RESULT_FAIL;
362 }
363
364 /** Reset the state the SP's notifications state. */
365 if (!request_notification_unbind(SP_ID(1), SP_ID(1), SP_ID(2),
366 g_notifications, CACTUS_SUCCESS, 0)) {
367 return TEST_RESULT_FAIL;
368 }
369
370 return TEST_RESULT_SUCCESS;
371}
372
373/**
374 * Try to bind/unbind notifications spoofing the identity of the receiver.
375 * Commands will be sent to SP_ID(1), which will use SP_ID(3) as the receiver.
376 * Expect error code FFA_ERROR_INVALID_PARAMETER.
377 */
378test_result_t test_ffa_notifications_bind_unbind_spoofing(void)
379{
380 ffa_notification_bitmap_t notifications = FFA_NOTIFICATION(8);
381
382 CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
383
384 if (!request_notification_bind(SP_ID(1), SP_ID(3), SP_ID(2),
385 notifications, 0, CACTUS_ERROR,
386 FFA_ERROR_INVALID_PARAMETER)) {
387 return TEST_RESULT_FAIL;
388 }
389
390 if (!request_notification_unbind(SP_ID(1), SP_ID(3), SP_ID(2),
391 notifications, CACTUS_ERROR,
392 FFA_ERROR_INVALID_PARAMETER)) {
393 return TEST_RESULT_FAIL;
394 }
395
396 return TEST_RESULT_SUCCESS;
397}
398
399/**
400 * Call FFA_NOTIFICATION_BIND with notifications bitmap zeroed.
401 * Expecting error code FFA_ERROR_INVALID_PARAMETER.
402 */
403test_result_t test_ffa_notifications_bind_unbind_zeroed(void)
404{
405 CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
406
407 if (!request_notification_bind(SP_ID(1), SP_ID(1), SP_ID(2),
408 0, 0, CACTUS_ERROR,
409 FFA_ERROR_INVALID_PARAMETER)) {
410 return TEST_RESULT_FAIL;
411 }
412
413 if (!request_notification_unbind(SP_ID(1), SP_ID(1), SP_ID(2),
414 0, CACTUS_ERROR,
415 FFA_ERROR_INVALID_PARAMETER)) {
416 return TEST_RESULT_FAIL;
417 }
418
419 return TEST_RESULT_SUCCESS;
420}
J-Alvesd63ae4b2021-03-29 15:25:19 +0100421
422/**
423 * Helper function to test FFA_NOTIFICATION_GET interface.
424 * Receives all arguments to use 'cactus_notification_get_send_cmd', and returns
425 * the received response. Depending on the testing scenario, this will allow
426 * to validate if the returned bitmaps are as expected.
427 *
428 * Returns:
429 * - 'true' if response was obtained.
430 * - 'false' if there was an error sending the request.
431 */
432static bool request_notification_get(
J-Alvesc08db422021-10-19 16:15:06 +0100433 ffa_id_t cmd_dest, ffa_id_t receiver, uint32_t vcpu_id, uint32_t flags,
Daniel Boulbyce386b12022-03-29 18:36:36 +0100434 bool check_npi_handled, struct ffa_value *response)
J-Alvesd63ae4b2021-03-29 15:25:19 +0100435{
436 VERBOSE("TFTF requesting SP to get notifications!\n");
437
438 *response = cactus_notification_get_send_cmd(HYP_ID, cmd_dest,
439 receiver, vcpu_id,
J-Alvesc08db422021-10-19 16:15:06 +0100440 flags, check_npi_handled);
J-Alvesd63ae4b2021-03-29 15:25:19 +0100441
442 return is_ffa_direct_response(*response);
443}
444
445static bool request_notification_set(
446 ffa_id_t cmd_dest, ffa_id_t receiver, ffa_id_t sender, uint32_t flags,
J-Alvesf0328472021-09-21 18:32:02 +0100447 ffa_notification_bitmap_t notifications, ffa_id_t echo_dest,
448 uint32_t exp_resp, int32_t exp_error)
J-Alvesd63ae4b2021-03-29 15:25:19 +0100449{
Daniel Boulbyce386b12022-03-29 18:36:36 +0100450 struct ffa_value ret;
J-Alvesd63ae4b2021-03-29 15:25:19 +0100451
452 VERBOSE("TFTF requesting SP %x (as %x) to set notifications to %x\n",
453 cmd_dest, sender, receiver);
454
455 ret = cactus_notifications_set_send_cmd(HYP_ID, cmd_dest, receiver,
J-Alvesf0328472021-09-21 18:32:02 +0100456 sender, flags, notifications,
457 echo_dest);
J-Alvesd63ae4b2021-03-29 15:25:19 +0100458
J-Alvese5554332021-11-04 17:24:57 +0000459 if (!is_expected_cactus_response(ret, exp_resp, exp_error)) {
460 ERROR("Failed notifications set. receiver: %x; sender: %x\n",
461 receiver, sender);
462 return false;
463 }
464
465 return true;
J-Alvesd63ae4b2021-03-29 15:25:19 +0100466}
467
468/**
J-Alves4849c8c2021-10-27 18:49:54 +0100469 * Helper to set notification. If sender is VM, the function will call directly
470 * FFA_NOTIFICATION_SET, if it is an SP it will request the SP to set
471 * notifications. In both cases it is expected a successful outcome.
472 */
473static bool notification_set(ffa_id_t receiver, ffa_id_t sender,
474 uint32_t flags,
475 ffa_notification_bitmap_t notifications)
476{
Daniel Boulbyce386b12022-03-29 18:36:36 +0100477 struct ffa_value ret;
J-Alves4849c8c2021-10-27 18:49:54 +0100478
479 /* Sender sets notifications to receiver. */
480 if (!IS_SP_ID(sender)) {
481 VERBOSE("VM %x Setting notifications %llx to receiver %x\n",
482 sender, notifications, receiver);
483 ret = ffa_notification_set(sender, receiver, flags, notifications);
484
485 if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32)) {
486 ERROR("Failed notifications set. receiver: %x; sender: %x\n",
487 receiver, sender);
488 return false;
489 }
490 return true;
491 }
492
493 return request_notification_set(sender, receiver, sender, flags,
494 notifications, 0, CACTUS_SUCCESS, 0);
495}
496
497/**
J-Alvesd63ae4b2021-03-29 15:25:19 +0100498 * Check that SP's response to CACTUS_NOTIFICATION_GET_CMD is as expected.
499 */
500static bool is_notifications_get_as_expected(
Daniel Boulbyce386b12022-03-29 18:36:36 +0100501 struct ffa_value *ret, uint64_t exp_from_sp, uint64_t exp_from_vm,
J-Alvesd63ae4b2021-03-29 15:25:19 +0100502 ffa_id_t receiver)
503{
504 uint64_t from_sp;
505 uint64_t from_vm;
506 bool success_ret;
507
508 /**
509 * If receiver ID is SP, this is to evaluate the response to test
510 * command 'CACTUS_NOTIFICATION_GET_CMD'.
511 */
512 if (IS_SP_ID(receiver)) {
513 success_ret = (cactus_get_response(*ret) == CACTUS_SUCCESS);
514 from_sp = cactus_notifications_get_from_sp(*ret);
515 from_vm = cactus_notifications_get_from_vm(*ret);
516 } else {
517 /**
518 * Else, this is to evaluate the return of FF-A call:
519 * ffa_notification_get.
520 */
521 success_ret = (ffa_func_id(*ret) == FFA_SUCCESS_SMC32);
J-Alvesc6b92d52024-04-05 14:16:00 +0100522 from_sp = ffa_notification_get_from_sp(*ret);
523 from_vm = ffa_notification_get_from_vm(*ret);
J-Alvesd63ae4b2021-03-29 15:25:19 +0100524 }
525
526 if (success_ret != true ||
527 exp_from_sp != from_sp ||
528 exp_from_vm != from_vm) {
529 VERBOSE("Notifications not as expected:\n"
530 " from sp: %llx exp: %llx\n"
531 " from vm: %llx exp: %llx\n",
532 from_sp, exp_from_sp, from_vm, exp_from_vm);
533 return false;
534 }
535
536 return true;
537}
538
J-Alves16d52d52021-06-14 14:29:37 +0100539static bool is_notifications_info_get_as_expected(
Daniel Boulbyce386b12022-03-29 18:36:36 +0100540 struct ffa_value *ret, uint16_t *ids, uint32_t *lists_sizes,
J-Alves16d52d52021-06-14 14:29:37 +0100541 const uint32_t max_ids_count, uint32_t lists_count, bool more_pending)
542{
J-Alvesc6b92d52024-04-05 14:16:00 +0100543 if (lists_count != ffa_notification_info_get_lists_count(*ret) ||
544 more_pending != ffa_notification_info_get_more_pending(*ret)) {
J-Alves16d52d52021-06-14 14:29:37 +0100545 ERROR("Notification info get not as expected.\n"
546 " Lists counts: %u; more pending %u\n",
J-Alvesc6b92d52024-04-05 14:16:00 +0100547 ffa_notification_info_get_lists_count(*ret),
548 ffa_notification_info_get_more_pending(*ret));
Daniel Boulbyce386b12022-03-29 18:36:36 +0100549 dump_ffa_value(*ret);
J-Alves16d52d52021-06-14 14:29:37 +0100550 return false;
551 }
552
553 for (uint32_t i = 0; i < lists_count; i++) {
554 uint32_t cur_size =
J-Alvesc6b92d52024-04-05 14:16:00 +0100555 ffa_notification_info_get_list_size(*ret,
J-Alves16d52d52021-06-14 14:29:37 +0100556 i + 1);
557
558 if (lists_sizes[i] != cur_size) {
559 ERROR("Expected list size[%u] %u != %u\n", i,
560 lists_sizes[i], cur_size);
561 return false;
562 }
563 }
564
565 /* Compare the IDs list */
Daniel Boulbyce386b12022-03-29 18:36:36 +0100566 if (memcmp(&ret->arg3, ids, sizeof(ids[0]) * max_ids_count) != 0) {
J-Alves16d52d52021-06-14 14:29:37 +0100567 ERROR("List of IDs not as expected\n");
568 return false;
569 }
570
571 return true;
572}
573
J-Alvesd63ae4b2021-03-29 15:25:19 +0100574/**
575 * Helper to bind notification and set it.
576 * If receiver is SP it will request SP to perform the bind, else invokes
577 * FFA_NOTIFICATION_BIND.
578 * If Sender is SP it will request it to perform the set, else invokes
579 * FFA_NOTIFICATION_SET.
580 */
581static bool notification_bind_and_set(ffa_id_t sender,
582 ffa_id_t receiver, ffa_notification_bitmap_t notifications, uint32_t flags)
583{
Daniel Boulbyce386b12022-03-29 18:36:36 +0100584 struct ffa_value ret;
J-Alvesd63ae4b2021-03-29 15:25:19 +0100585 uint32_t flags_bind = flags & FFA_NOTIFICATIONS_FLAG_PER_VCPU;
586
587 /* Receiver binds notifications to sender. */
588 if (!IS_SP_ID(receiver)) {
589 ret = ffa_notification_bind(sender, receiver,
590 flags_bind, notifications);
591
592 if (is_ffa_call_error(ret)) {
593 return false;
594 }
595 } else {
596 if (!request_notification_bind(receiver, receiver, sender,
597 notifications, flags_bind,
598 CACTUS_SUCCESS,
599 0)) {
600 return false;
601 }
602 }
603
J-Alves4849c8c2021-10-27 18:49:54 +0100604 return notification_set(receiver, sender, flags, notifications);
J-Alvesd63ae4b2021-03-29 15:25:19 +0100605}
606
607/**
608 * Helper to request SP to get the notifications and validate the return.
609 */
610static bool notification_get_and_validate(
611 ffa_id_t receiver, ffa_notification_bitmap_t exp_from_sp,
612 ffa_notification_bitmap_t exp_from_vm, uint32_t vcpu_id,
J-Alvesc08db422021-10-19 16:15:06 +0100613 uint32_t flags, bool check_npi_handled)
J-Alvesd63ae4b2021-03-29 15:25:19 +0100614{
Daniel Boulbyce386b12022-03-29 18:36:36 +0100615 struct ffa_value ret;
J-Alvesd63ae4b2021-03-29 15:25:19 +0100616
617 /* Receiver gets pending notifications. */
618 if (IS_SP_ID(receiver)) {
619 request_notification_get(receiver, receiver, vcpu_id, flags,
J-Alvesc08db422021-10-19 16:15:06 +0100620 check_npi_handled, &ret);
J-Alvesd63ae4b2021-03-29 15:25:19 +0100621 } else {
622 ret = ffa_notification_get(receiver, vcpu_id, flags);
623 }
624
625 return is_notifications_get_as_expected(&ret, exp_from_sp, exp_from_vm,
626 receiver);
627}
628
J-Alves16d52d52021-06-14 14:29:37 +0100629static bool notifications_info_get(
630 uint16_t *expected_ids, uint32_t expected_lists_count,
631 uint32_t *expected_lists_sizes, const uint32_t max_ids_count,
632 bool expected_more_pending)
633{
Daniel Boulbyce386b12022-03-29 18:36:36 +0100634 struct ffa_value ret;
J-Alves16d52d52021-06-14 14:29:37 +0100635
636 VERBOSE("Getting pending notification's info.\n");
637
638 ret = ffa_notification_info_get();
639
640 return !is_ffa_call_error(ret) &&
641 is_notifications_info_get_as_expected(&ret, expected_ids,
642 expected_lists_sizes,
643 max_ids_count,
644 expected_lists_count,
645 expected_more_pending);
646}
647
J-Alves269118a2021-09-22 09:46:11 +0100648static volatile int schedule_receiver_interrupt_received;
649
650static int schedule_receiver_interrupt_handler(void *data)
651{
652 assert(schedule_receiver_interrupt_received == 0);
653 schedule_receiver_interrupt_received = 1;
654 return 0;
655}
656
657/**
658 * Enable the Schedule Receiver Interrupt and register the respective
659 * handler.
660 */
661static void schedule_receiver_interrupt_init(void)
662{
663 tftf_irq_register_handler(FFA_SCHEDULE_RECEIVER_INTERRUPT_ID,
664 schedule_receiver_interrupt_handler);
J-Alves269118a2021-09-22 09:46:11 +0100665}
666
667/**
668 * Disable the Schedule Receiver Interrupt and unregister the respective
669 * handler.
670 */
671static void schedule_receiver_interrupt_deinit(void)
672{
J-Alves269118a2021-09-22 09:46:11 +0100673 tftf_irq_unregister_handler(FFA_SCHEDULE_RECEIVER_INTERRUPT_ID);
674 schedule_receiver_interrupt_received = 0;
675}
676
677bool check_schedule_receiver_interrupt_handled(void)
678{
679 if (schedule_receiver_interrupt_received == 1) {
680 VERBOSE("Schedule Receiver Interrupt handled!\n");
681 schedule_receiver_interrupt_received = 0;
682 return true;
683 }
684 VERBOSE("Schedule Receiver Interrupt NOT handled!\n");
685 return false;
686}
687
J-Alvesd63ae4b2021-03-29 15:25:19 +0100688/**
J-Alvesbd909ac2021-10-19 16:37:02 +0100689 * Base function to test notifications signaling with an SP as a receiver.
J-Alvesd63ae4b2021-03-29 15:25:19 +0100690 */
J-Alvesbd909ac2021-10-19 16:37:02 +0100691static test_result_t base_test_global_notifications_signal_sp(
692 const ffa_id_t sender, const ffa_id_t receiver,
J-Alveseb378792024-06-19 13:17:44 +0100693 const ffa_notification_bitmap_t notifications, const uint32_t flags_get,
694 const uint32_t flags_set)
J-Alvesd63ae4b2021-03-29 15:25:19 +0100695{
J-Alves16d52d52021-06-14 14:29:37 +0100696 /* Variables to validate calls to FFA_NOTIFICATION_INFO_GET. */
697 uint16_t ids[FFA_NOTIFICATIONS_INFO_GET_MAX_IDS] = {0};
698 uint32_t lists_count;
699 uint32_t lists_sizes[FFA_NOTIFICATIONS_INFO_GET_MAX_IDS] = {0};
700
701 CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
702
J-Alveseb378792024-06-19 13:17:44 +0100703 if (!IS_SP_ID(receiver)) {
704 ERROR("Receiver is expected to be an SP ID!\n");
705 return TEST_RESULT_FAIL;
706 }
707
J-Alves269118a2021-09-22 09:46:11 +0100708 schedule_receiver_interrupt_init();
709
J-Alvesbd909ac2021-10-19 16:37:02 +0100710 if (!notification_bind_and_set(sender, receiver, notifications,
J-Alveseb378792024-06-19 13:17:44 +0100711 flags_set)) {
J-Alvesd63ae4b2021-03-29 15:25:19 +0100712 return TEST_RESULT_FAIL;
713 }
714
J-Alves5fb14212021-09-21 13:04:48 +0100715 if (!check_schedule_receiver_interrupt_handled()) {
716 return TEST_RESULT_FAIL;
717 }
J-Alves269118a2021-09-22 09:46:11 +0100718
J-Alves16d52d52021-06-14 14:29:37 +0100719 /**
720 * Simple list of IDs expected on return from FFA_NOTIFICATION_INFO_GET.
721 */
722 ids[0] = receiver;
723 lists_count = 1;
724
725 if (!notifications_info_get(ids, lists_count, lists_sizes,
726 FFA_NOTIFICATIONS_INFO_GET_MAX_IDS,
J-Alvesbd909ac2021-10-19 16:37:02 +0100727 false)) {
J-Alves16d52d52021-06-14 14:29:37 +0100728 return TEST_RESULT_FAIL;
729 }
730
J-Alvesbd909ac2021-10-19 16:37:02 +0100731 if (!notification_get_and_validate(
732 receiver, IS_SP_ID(sender) ? notifications : 0,
733 !IS_SP_ID(sender) ? notifications : 0, 0, flags_get, true)) {
J-Alvesd63ae4b2021-03-29 15:25:19 +0100734 return TEST_RESULT_FAIL;
735 }
736
737 if (!request_notification_unbind(receiver, receiver, sender,
738 notifications, CACTUS_SUCCESS, 0)) {
739 return TEST_RESULT_FAIL;
740 }
741
J-Alves269118a2021-09-22 09:46:11 +0100742 schedule_receiver_interrupt_deinit();
743
J-Alvesd63ae4b2021-03-29 15:25:19 +0100744 return TEST_RESULT_SUCCESS;
745}
746
747/**
J-Alvesbd909ac2021-10-19 16:37:02 +0100748 * Test to validate a VM can signal an SP.
749 */
750test_result_t test_ffa_notifications_vm_signals_sp(void)
751{
752 return base_test_global_notifications_signal_sp(
753 1, SP_ID(1), FFA_NOTIFICATION(1) | FFA_NOTIFICATION(60),
J-Alveseb378792024-06-19 13:17:44 +0100754 FFA_NOTIFICATIONS_FLAG_BITMAP_VM, 0);
755}
756
757test_result_t test_ffa_notifications_vm_signals_sp_delay_sri_fail(void)
758{
759 const ffa_id_t sender = 1;
760 const ffa_id_t receiver = SP_ID(1);
761 const ffa_notification_bitmap_t notif = (1LU << 34);
762 struct ffa_value ret;
763
764 CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
765
766 if (!request_notification_bind(receiver, receiver,
767 sender, notif, 0,
768 CACTUS_SUCCESS, 0)) {
769 return TEST_RESULT_FAIL;
770 }
771
772 ret = ffa_notification_set(sender, receiver,
773 FFA_NOTIFICATIONS_FLAG_DELAY_SRI, notif);
774
775 if (!is_expected_ffa_error(ret, FFA_ERROR_INVALID_PARAMETER)) {
776 return TEST_RESULT_FAIL;
777 }
778
779 if (!request_notification_unbind(receiver, receiver, sender,
780 notif, CACTUS_SUCCESS, 0)) {
781 return TEST_RESULT_FAIL;
782 }
783
784 return TEST_RESULT_SUCCESS;
J-Alvesbd909ac2021-10-19 16:37:02 +0100785}
786
787/**
J-Alvesd63ae4b2021-03-29 15:25:19 +0100788 * Test to validate an SP can signal an SP.
789 */
790test_result_t test_ffa_notifications_sp_signals_sp(void)
791{
J-Alvesbd909ac2021-10-19 16:37:02 +0100792 return base_test_global_notifications_signal_sp(
793 SP_ID(1), SP_ID(2), g_notifications,
J-Alveseb378792024-06-19 13:17:44 +0100794 FFA_NOTIFICATIONS_FLAG_BITMAP_SP,
795 FFA_NOTIFICATIONS_FLAG_DELAY_SRI);
J-Alvesd63ae4b2021-03-29 15:25:19 +0100796}
797
798/**
799 * Test to validate an SP can signal a VM.
800 */
801test_result_t test_ffa_notifications_sp_signals_vm(void)
802{
803 CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
804 const ffa_id_t sender = SP_ID(1);
J-Alvesd5d87152021-10-29 11:48:37 +0100805 const ffa_id_t receiver = VM_ID(1);
J-Alvesd63ae4b2021-03-29 15:25:19 +0100806 uint32_t get_flags = FFA_NOTIFICATIONS_FLAG_BITMAP_SP;
Daniel Boulbyce386b12022-03-29 18:36:36 +0100807 struct ffa_value ret;
J-Alves269118a2021-09-22 09:46:11 +0100808 test_result_t result = TEST_RESULT_SUCCESS;
J-Alvesd63ae4b2021-03-29 15:25:19 +0100809
J-Alves16d52d52021-06-14 14:29:37 +0100810 /* Variables to validate calls to FFA_NOTIFICATION_INFO_GET. */
811 uint16_t ids[FFA_NOTIFICATIONS_INFO_GET_MAX_IDS] = {0};
812 uint32_t lists_count;
813 uint32_t lists_sizes[FFA_NOTIFICATIONS_INFO_GET_MAX_IDS] = {0};
814
J-Alvesd63ae4b2021-03-29 15:25:19 +0100815 /* Ask SPMC to allocate notifications bitmap. */
816 if (!notifications_bitmap_create(receiver, 1)) {
J-Alves269118a2021-09-22 09:46:11 +0100817 result = TEST_RESULT_FAIL;
J-Alvesd63ae4b2021-03-29 15:25:19 +0100818 }
819
J-Alves269118a2021-09-22 09:46:11 +0100820 schedule_receiver_interrupt_init();
821
J-Alvesd63ae4b2021-03-29 15:25:19 +0100822 /* Request receiver to bind a set of notifications to the sender. */
J-Alvesfbbbf622021-07-30 16:43:36 +0100823 if (!notification_bind_and_set(sender, receiver, g_notifications,
824 FFA_NOTIFICATIONS_FLAG_DELAY_SRI)) {
J-Alves5fb14212021-09-21 13:04:48 +0100825 result = TEST_RESULT_FAIL;
J-Alvesd63ae4b2021-03-29 15:25:19 +0100826 }
827
J-Alves5fb14212021-09-21 13:04:48 +0100828 if (!check_schedule_receiver_interrupt_handled()) {
829 result = TEST_RESULT_FAIL;
830 }
J-Alves269118a2021-09-22 09:46:11 +0100831
J-Alves16d52d52021-06-14 14:29:37 +0100832 /*
833 * FFA_NOTIFICATION_INFO_GET return list should be simple, containing
834 * only the receiver's ID.
835 */
836 ids[0] = receiver;
837 lists_count = 1;
838
839 if (!notifications_info_get(ids, lists_count, lists_sizes,
840 FFA_NOTIFICATIONS_INFO_GET_MAX_IDS,
841 false)) {
J-Alves269118a2021-09-22 09:46:11 +0100842 result = TEST_RESULT_FAIL;
J-Alves16d52d52021-06-14 14:29:37 +0100843 }
844
J-Alvesd63ae4b2021-03-29 15:25:19 +0100845 /* Get pending notifications, and retrieve response. */
846 if (!notification_get_and_validate(receiver, g_notifications, 0, 0,
J-Alvesc08db422021-10-19 16:15:06 +0100847 get_flags, false)) {
J-Alves5fb14212021-09-21 13:04:48 +0100848 result = TEST_RESULT_FAIL;
J-Alvesd63ae4b2021-03-29 15:25:19 +0100849 }
850
851 ret = ffa_notification_unbind(sender, receiver, g_notifications);
852
853 if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32)) {
J-Alves269118a2021-09-22 09:46:11 +0100854 result = TEST_RESULT_FAIL;
J-Alvesd63ae4b2021-03-29 15:25:19 +0100855 }
856
857 if (!notifications_bitmap_destroy(receiver)) {
J-Alves269118a2021-09-22 09:46:11 +0100858 result = TEST_RESULT_FAIL;
J-Alvesd63ae4b2021-03-29 15:25:19 +0100859 }
860
J-Alves269118a2021-09-22 09:46:11 +0100861 schedule_receiver_interrupt_deinit();
862
863 return result;
J-Alvesd63ae4b2021-03-29 15:25:19 +0100864}
865
866/**
867 * Test to validate it is not possible to unbind a pending notification.
868 */
869test_result_t test_ffa_notifications_unbind_pending(void)
870{
871 CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
872 const ffa_id_t receiver = SP_ID(1);
J-Alvesd5d87152021-10-29 11:48:37 +0100873 const ffa_id_t sender = VM_ID(1);
J-Alvesd63ae4b2021-03-29 15:25:19 +0100874 const ffa_notification_bitmap_t notifications = FFA_NOTIFICATION(30) |
875 FFA_NOTIFICATION(35);
876 uint32_t get_flags = FFA_NOTIFICATIONS_FLAG_BITMAP_VM;
877
J-Alves269118a2021-09-22 09:46:11 +0100878 schedule_receiver_interrupt_init();
879
J-Alvesd63ae4b2021-03-29 15:25:19 +0100880 /* Request receiver to bind a set of notifications to the sender. */
881 if (!notification_bind_and_set(sender, receiver, notifications, 0)) {
882 return TEST_RESULT_FAIL;
883 }
884
885 /*
886 * Attempt to unbind the pending notification, but expect error return
887 * given the notification is pending.
888 */
889 if (!request_notification_unbind(receiver, receiver, sender,
890 FFA_NOTIFICATION(30),
891 CACTUS_ERROR, FFA_ERROR_DENIED)) {
892 return TEST_RESULT_FAIL;
893 }
894
J-Alves269118a2021-09-22 09:46:11 +0100895 if (!check_schedule_receiver_interrupt_handled()) {
896 return TEST_RESULT_FAIL;
897 }
898
J-Alvesd63ae4b2021-03-29 15:25:19 +0100899 /*
900 * Request receiver partition to get pending notifications from VMs.
901 * Only notification 30 is expected.
902 */
903 if (!notification_get_and_validate(receiver, 0, notifications, 0,
J-Alvesc08db422021-10-19 16:15:06 +0100904 get_flags, false)) {
J-Alvesd63ae4b2021-03-29 15:25:19 +0100905 return TEST_RESULT_FAIL;
906 }
907
908 /* Unbind all notifications, to not interfere with other tests. */
909 if (!request_notification_unbind(receiver, receiver, sender,
910 notifications, CACTUS_SUCCESS, 0)) {
911 return TEST_RESULT_FAIL;
912 }
913
J-Alves269118a2021-09-22 09:46:11 +0100914 schedule_receiver_interrupt_deinit();
915
J-Alvesd63ae4b2021-03-29 15:25:19 +0100916 return TEST_RESULT_SUCCESS;
917}
J-Alves16d52d52021-06-14 14:29:37 +0100918
919/**
920 * Test the result of a call to FFA_NOTIFICATION_INFO_GET if no pending
921 * notifications.
922 */
923test_result_t test_ffa_notifications_info_get_none(void)
924{
925 SKIP_TEST_IF_FFA_VERSION_LESS_THAN(1, 1);
926
927 if (check_spmc_execution_level()) {
928 VERBOSE("OPTEE as SPMC at S-EL1. Skipping test!\n");
929 return TEST_RESULT_SKIPPED;
930 }
931
Daniel Boulbyce386b12022-03-29 18:36:36 +0100932 struct ffa_value ret;
J-Alves16d52d52021-06-14 14:29:37 +0100933
934 ret = ffa_notification_info_get();
935
936 if (!is_expected_ffa_error(ret, FFA_ERROR_NO_DATA)) {
937 return TEST_RESULT_FAIL;
938 }
939
940 return TEST_RESULT_SUCCESS;
941}
J-Alves44ec4f72021-07-27 12:07:14 +0100942
943/**
J-Alves5fb14212021-09-21 13:04:48 +0100944 * Test to validate behavior in SWd if the SRI is not delayed. If the
945 * notification setter handled a managed exit it is indicative the SRI was
946 * sent immediately.
947 */
948test_result_t test_ffa_notifications_sp_signals_sp_immediate_sri(void)
949{
950 CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
951 const ffa_id_t sender = SP_ID(1);
952 const ffa_id_t receiver = SP_ID(2);
953 uint32_t get_flags = FFA_NOTIFICATIONS_FLAG_BITMAP_SP;
Daniel Boulbyce386b12022-03-29 18:36:36 +0100954 struct ffa_value ret;
J-Alves5fb14212021-09-21 13:04:48 +0100955 test_result_t result = TEST_RESULT_SUCCESS;
956
957 /** Variables to validate calls to FFA_NOTIFICATION_INFO_GET. */
958 uint16_t ids[FFA_NOTIFICATIONS_INFO_GET_MAX_IDS] = {0};
959 uint32_t lists_count;
960 uint32_t lists_sizes[FFA_NOTIFICATIONS_INFO_GET_MAX_IDS] = {0};
961
962 ids[0] = receiver;
963 lists_count = 1;
964
J-Alves5fb14212021-09-21 13:04:48 +0100965 schedule_receiver_interrupt_init();
966
967 /* Request receiver to bind a set of notifications to the sender. */
968 if (!request_notification_bind(receiver, receiver, sender,
969 g_notifications, 0, CACTUS_SUCCESS, 0)) {
970 result = TEST_RESULT_FAIL;
971 }
972
973 /*
974 * Request sender to set notification, and expect the response is
975 * MANAGED_EXIT_INTERRUPT_ID.
976 */
977 if (!request_notification_set(sender, receiver, sender, 0,
J-Alvesf0328472021-09-21 18:32:02 +0100978 g_notifications, 0,
979 MANAGED_EXIT_INTERRUPT_ID, 0)) {
J-Alves5fb14212021-09-21 13:04:48 +0100980 ERROR("SRI not handled immediately!\n");
981 result = TEST_RESULT_FAIL;
982 } else {
983 VERBOSE("SP %x did a managed exit.\n", sender);
984 }
985
986 if (!check_schedule_receiver_interrupt_handled()) {
987 result = TEST_RESULT_FAIL;
988 }
989
990 /* Call FFA_NOTIFICATION_INFO_GET and validate return. */
991 if (!notifications_info_get(ids, lists_count, lists_sizes,
992 FFA_NOTIFICATIONS_INFO_GET_MAX_IDS,
993 false)) {
994 result = TEST_RESULT_FAIL;
995 }
996
997 /* Validate notification get. */
J-Alvesc08db422021-10-19 16:15:06 +0100998 if (!request_notification_get(receiver, receiver, 0, get_flags, false, &ret) ||
J-Alves5fb14212021-09-21 13:04:48 +0100999 !is_notifications_get_as_expected(&ret, g_notifications, 0,
1000 receiver)) {
1001 result = TEST_RESULT_FAIL;
1002 }
1003
1004 /*
1005 * Resume setter Cactus in the handling of CACTUS_NOTIFICATIONS_SET_CMD.
1006 */
Madhukar Pappireddy92d2e812022-09-19 13:48:13 -05001007 ret = cactus_resume_after_managed_exit(HYP_ID, sender);
J-Alves5fb14212021-09-21 13:04:48 +01001008
1009 /* Expected result to CACTUS_NOTIFICATIONS_SET_CMD. */
1010 if (!is_expected_cactus_response(ret, CACTUS_SUCCESS, 0)) {
1011 result = TEST_RESULT_FAIL;
1012 }
1013
1014 /* Unbind for clean-up. */
1015 if (!request_notification_unbind(receiver, receiver, sender,
1016 g_notifications, CACTUS_SUCCESS, 0)) {
1017 result = TEST_RESULT_FAIL;
1018 }
1019
1020 schedule_receiver_interrupt_deinit();
1021
J-Alves5fb14212021-09-21 13:04:48 +01001022 return result;
1023}
J-Alvesf0328472021-09-21 18:32:02 +01001024
1025/**
1026 * Test to validate behavior in SWd if the SRI is delayed.
1027 */
1028test_result_t test_ffa_notifications_sp_signals_sp_delayed_sri(void)
1029{
1030 CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
1031 const ffa_id_t sender = SP_ID(3);
1032 const ffa_id_t receiver = SP_ID(2);
1033 const ffa_id_t echo_dest = SP_ID(1);
1034 uint32_t echo_dest_cmd_count = 0;
1035 uint32_t get_flags = FFA_NOTIFICATIONS_FLAG_BITMAP_SP;
Daniel Boulbyce386b12022-03-29 18:36:36 +01001036 struct ffa_value ret;
J-Alvesf0328472021-09-21 18:32:02 +01001037 test_result_t result = TEST_RESULT_SUCCESS;
1038
1039 /** Variables to validate calls to FFA_NOTIFICATION_INFO_GET. */
1040 uint16_t ids[FFA_NOTIFICATIONS_INFO_GET_MAX_IDS] = {0};
1041 uint32_t lists_count;
1042 uint32_t lists_sizes[FFA_NOTIFICATIONS_INFO_GET_MAX_IDS] = {0};
1043
1044 ids[0] = receiver;
1045 lists_count = 1;
1046
J-Alvesf0328472021-09-21 18:32:02 +01001047 schedule_receiver_interrupt_init();
1048
1049 /* Request receiver to bind a set of notifications to the sender. */
1050 if (!request_notification_bind(receiver, receiver, sender,
1051 g_notifications, 0, CACTUS_SUCCESS, 0)) {
1052 result = TEST_RESULT_FAIL;
1053 }
1054
1055 ret = cactus_get_req_count_send_cmd(HYP_ID, echo_dest);
1056
1057 if (cactus_get_response(ret) == CACTUS_SUCCESS) {
1058 /*
1059 * Save the command count from the echo_dest, to validate it
1060 * has been incremented after the request to set notifications.
1061 */
1062 echo_dest_cmd_count = cactus_get_req_count(ret);
1063 VERBOSE("Partition %x command count %u.\n", echo_dest,
1064 echo_dest_cmd_count);
1065 } else {
1066 VERBOSE("Failed to get cmds count from %u\n", echo_dest);
1067 result = TEST_RESULT_FAIL;
1068 }
1069
1070 /*
1071 * Request sender to set notification with Delay SRI flag, and specify
1072 * echo destination.
1073 */
1074 if (!request_notification_set(sender, receiver, sender,
1075 FFA_NOTIFICATIONS_FLAG_DELAY_SRI,
1076 g_notifications, echo_dest,
1077 CACTUS_SUCCESS, 0)) {
1078 VERBOSE("Failed to set notifications!\n");
1079 result = TEST_RESULT_FAIL;
1080 }
1081
1082 if (!check_schedule_receiver_interrupt_handled()) {
1083 result = TEST_RESULT_FAIL;
1084 }
1085
1086 /*
1087 * Get command count again from echo_dest, to validate that it has been
1088 * incremented by one. This should indicate the notification setter has
1089 * issued a request to echo_dest right after the notification set, thus
1090 * proving the SRI hasn't been sent right after FFA_NOTIFICATION_SET.
1091 */
1092 ret = cactus_get_req_count_send_cmd(HYP_ID, echo_dest);
1093 if (cactus_get_response(ret) == CACTUS_SUCCESS) {
1094 if (cactus_get_req_count(ret) == echo_dest_cmd_count + 1) {
1095 VERBOSE("SRI successfully delayed.\n");
1096 } else {
1097 VERBOSE("Failed to get cmds count from %u.\n",
1098 echo_dest);
1099 result = TEST_RESULT_FAIL;
1100 }
1101 } else {
1102 VERBOSE("Failed to get cmds count from %x\n", echo_dest);
1103 result = TEST_RESULT_FAIL;
1104 }
1105
1106 /* Call FFA_NOTIFICATION_INFO_GET and validate return. */
1107 if (!notifications_info_get(ids, lists_count, lists_sizes,
1108 FFA_NOTIFICATIONS_INFO_GET_MAX_IDS,
1109 false)) {
1110 result = TEST_RESULT_FAIL;
1111 }
1112
1113 /* Validate notification get. */
J-Alvesc08db422021-10-19 16:15:06 +01001114 if (!request_notification_get(receiver, receiver, 0, get_flags, false, &ret) ||
J-Alvesf0328472021-09-21 18:32:02 +01001115 !is_notifications_get_as_expected(&ret, g_notifications, 0,
1116 receiver)) {
1117 result = TEST_RESULT_FAIL;
1118 }
1119
1120 /* Unbind for clean-up. */
1121 if (!request_notification_unbind(receiver, receiver, sender,
1122 g_notifications, CACTUS_SUCCESS, 0)) {
1123 result = TEST_RESULT_FAIL;
1124 }
1125
1126 schedule_receiver_interrupt_deinit();
1127
J-Alvesf0328472021-09-21 18:32:02 +01001128 return result;
1129}