blob: 8deaa3606d2eff403319e65631278f40f15bfb93 [file] [log] [blame]
Jelle Sels03756662021-05-20 10:41:57 +02001/*
2 * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <assert.h>
8#include <ffa_api.h>
9#include <ffa_internal_api.h>
10#include <ffa_memory_descriptors.h>
11#include <sp_api.h>
12#include <sp_discovery.h>
13#include <sp_memory_management.h>
14#include <sp_rxtx.h>
15#include <string.h>
16#include <trace.h>
17
18#define SP_TEST_OK 0xaa
19
20static volatile uint8_t tx_buffer[4096] __aligned(4096);
21static volatile uint8_t rx_buffer[4096] __aligned(4096);
22static volatile uint8_t my_buf[4096] __aligned(4096);
23static volatile uint8_t *shared_buffer;
24static size_t shared_buffer_size;
25
26
27
28enum errors {
29 ERR_OK,
30 ERR_VERSION,
31 ERR_ID_GET,
32 ERR_FEATURES,
33 ERR_SP_COMMUNICATION,
34 ERR_RXTX_MAP,
35 ERR_PARTITION,
36 ERR_RXTX_UNMAP,
37 ERR_MEM_INCORRECT_ACCESS,
38 ERR_MEM_RETRIEVE,
39 ERR_MEM_RELINQUISH,
40 ERR_SP_SHARE,
41 ERR_SP_SHARE_EXC,
42 ERR_TEST_NOT_FOUND
43};
44
45enum sp_tests {
46 EP_TEST_SP,
47 EP_TEST_SP_COMMUNICATION,
48 EP_TEST_SP_INCREASE,
49 EP_TRY_R_ACCESS,
50 EP_TRY_W_ACCESS,
51 EP_RETRIEVE,
52 EP_RELINQUISH,
53 EP_SP_MEM_SHARING,
54 EP_SP_MEM_SHARING_MULTI,
55 EP_SP_MEM_SHARING_EXC,
56 EP_SP_MEM_INCORRECT_ACCESS,
57 EP_SP_NOP
58};
59
60const char* sp_test_str[]= {
61 "EP_TEST_SP",
62 "EP_TEST_SP_COMMUNICATION",
63 "EP_TEST_SP_INCREASE",
64 "EP_TRY_R_ACCESS",
65 "EP_TRY_W_ACCESS",
66 "EP_RETRIEVE",
67 "EP_RELINQUISH",
68 "EP_SP_MEM_SHARING",
69 "EP_SP_MEM_SHARING_MULTI",
70 "EP_SP_MEM_SHARING_EXC",
71 "EP_SP_MEM_INCORRECT_ACCESS",
72 "EP_SP_NOP"
73};
74
75static bool test_ffa_version(void)
76{
77 sp_result result = SP_RESULT_OK;
78 uint16_t major = 0;
79 uint16_t minor = 0;
80
81 IMSG("Testing ffa_version()\n");
82
83 result = sp_discovery_ffa_version_get(&major, &minor);
84 if (result == SP_RESULT_OK) {
85 IMSG("ffa_version(): %"PRIu32".%"PRIu32"\n", major, minor);
86
87 return true;
88 } else if (result == FFA_NOT_SUPPORTED) {
89 IMSG("ffa_version(): not supported\n");
90 } else {
91 EMSG("ffa_version(): unknown error %"PRId32"\n", result);
92 }
93
94 return false;
95}
96
97static bool test_ffa_id_get(uint16_t *id)
98{
99 sp_result result = SP_RESULT_OK;
100
101 IMSG("Testing ffa_id_get()\n");
102
103 result = sp_discovery_own_id_get(id);
104 if (result == SP_RESULT_OK) {
105 IMSG("ffa_id_get(): 0x%"PRIx16"\n", *id);
106
107 return true;
108 } else if (result == FFA_NOT_SUPPORTED) {
109 IMSG("ffa_id_get(): not supported\n");
110 } else {
111 EMSG("ffa_id_get(): unknown error %"PRId32"\n", result);
112 }
113
114 return false;
115}
116
117static bool test_ffa_features(void)
118{
119 ffa_result result = FFA_OK;
120 struct ffa_interface_properties properties = {0};
121
122 IMSG("Testing ffa_features(FFA_RXTX_MAP)\n");
123
124 result = ffa_features(FFA_RXTX_MAP_32, &properties);
125 if (result == FFA_OK) {
126 static const char * const sizes[] = {
127 "4kB", "64kB", "16kB", "reserved"};
128 uint32_t buffer_size = properties.interface_properties[0] &
129 0x3U;
130
131 IMSG("ffa_features(): minimum buffer size=%s\n",
132 sizes[buffer_size]);
133 return true;
134 } else if (result == FFA_NOT_SUPPORTED) {
135 IMSG("ffa_features(): not supported\n");
136 } else {
137 EMSG("ffa_features(): unknown error %"PRId32"\n", result);
138 }
139 return false;
140}
141
142static bool test_ffa_rxtx_map(void)
143{
144 sp_result result = SP_RESULT_OK;
145
146 IMSG("Testing ffa_rxtx_map(%p %p, 1)\n", tx_buffer, rx_buffer);
147
148 result = sp_rxtx_buffer_map((void*)tx_buffer,(void*)rx_buffer,
149 sizeof(rx_buffer));
150 if (result == FFA_OK) {
151 IMSG("ffa_rxtx_map(): success\n");
152 return true;
153 } else if (result == FFA_NOT_SUPPORTED) {
154 IMSG("ffa_rxtx_map(): not supported\n");
155 } else {
156 EMSG("ffa_rxtx_map(): unknown error %"PRId32"\n", result);
157 }
158
159 return false;
160}
161
162static bool test_ffa_partition_info_get(void)
163{
164 sp_result result = SP_RESULT_OK;
165 struct sp_partition_info partitions[10] = {0};
166 uint32_t i = 0;
167 uint32_t count = 10;
168
169 IMSG("Testing ffa_partition_info_get(nil)\n");
170
171 result = sp_discovery_partition_info_get_all(partitions, &count);
172 if (result == SP_RESULT_OK) {
173
174 IMSG("ffa_partition_info_get(): count=%"PRIu32"\n", count);
175
176 for (i = 0; i < count; i++) {
177 IMSG("partition #%u: ID=%u, execution_count=%u \
178 direct request = %c, send direcy request = %c, \
179 indirect request = %c\n",
180 i, partitions[i].partition_id,
181 partitions[i].execution_context_count,
182 partitions[i].supports_direct_requests ? '1': '0',
183 partitions[i].can_send_direct_requests ? '1': '0',
184 partitions[i].supports_indirect_requests ? '1':
185 '0'
186 );
187 }
188
189 IMSG("Testing ffa_rx_release()\n");
190
191 result = ffa_rx_release();
192 if (result == FFA_OK) {
193 IMSG("ffa_rx_release(): success\n");
194 return true;
195 } else if (result == FFA_NOT_SUPPORTED) {
196 IMSG("ffa_rx_release(): not supported\n");
197 return false;
198 }
199 EMSG("ffa_rx_release(): unknown error %"PRId32"\n", result);
200 return false;
201 } else if (result == FFA_NOT_SUPPORTED) {
202 IMSG("ffa_partition_info_get(): not supported\n");
203 return false;
204 }
205 EMSG("ffa_partition_info_get(): unknown error %"PRId32"\n", result);
206 return false;
207}
208
209static bool test_ffa_rxtx_unmap()
210{
211 sp_result result = SP_RESULT_OK;
212
213 result = sp_rxtx_buffer_unmap();
214 if (result == SP_RESULT_OK) {
215 IMSG("sp_rxtx_buffer_unmap(): success\n");
216 return true;
217 }
218 EMSG("sp_rxtx_buffer_unmap(): unknown error %"PRId32"\n", result);
219 return false;
220}
221
222static void return_error(uint32_t error, struct ffa_direct_msg *msg)
223{
224 ffa_msg_send_direct_resp(msg->destination_id, msg->source_id, 0xff,
225 error, 0, 0, 0, msg);
226}
227
228static void return_ok(struct ffa_direct_msg *msg)
229{
230
231 ffa_msg_send_direct_resp(msg->destination_id,
232 msg->source_id, SP_TEST_OK, 0, 0, 0, 0, msg);
233}
234
235static bool test_read_access(void)
236{
237 return (shared_buffer[0] != 5);
238
239}
240
241static void test_write_access(void)
242{
243 shared_buffer[0] = 0xff;
244}
245
246static void test_increase(struct ffa_direct_msg *msg)
247{
248 msg->args[1]++;
249 msg->args[2]++;
250 msg->args[3]++;
251 msg->args[4]++;
252 ffa_msg_send_direct_resp(msg->destination_id,msg->source_id, SP_TEST_OK,
253 msg->args[1], msg->args[2], msg->args[3],
254 msg->args[4], msg);
255
256}
257
258static void test_communication(struct ffa_direct_msg *msg)
259{
260 struct ffa_direct_msg sp_msg = {0};
261 uint16_t dst = (uint16_t)msg->args[1];
262 ffa_result res = FFA_OK;
263
264 sp_msg.args[1] = 0x55;
265 sp_msg.args[2] = 0xAA;
266 sp_msg.args[3] = 0xBB;
267 sp_msg.args[4] = 0xCC;
268 res = ffa_msg_send_direct_req(msg->destination_id, dst, EP_TEST_SP_INCREASE,
269 0x55, 0xAA, 0xBB, 0xCC, &sp_msg);
270
271 if (res != FFA_OK) {
272 EMSG("error % in %s:%d"PRId32, res, __FILE__, __LINE__);
273 return_error((uint32_t)ERR_SP_SHARE, msg);
274 return;
275 }
276
277 if (sp_msg.args[1] == 0x56 && sp_msg.args[2] == 0xAB &&
278 sp_msg.args[3] == 0xBC &&sp_msg.args[4] == 0xCD) {
279 return_ok(msg);
280 } else {
281 DMSG("Failed SP communication %x %x %x %x",sp_msg.args[1],
282 sp_msg.args[2], sp_msg.args[3], sp_msg.args[4]);
283
284 return_error(ERR_SP_COMMUNICATION, msg);
285 }
286}
287
288static void test_internal_sp(struct ffa_direct_msg *msg)
289{
290 enum errors err = ERR_OK;
291 uint16_t id = 0;
292
293 if (test_ffa_version()) {
294 if (!test_ffa_id_get(&id))
295 err = ERR_ID_GET;
296
297 if (!err && !test_ffa_features())
298 err = ERR_VERSION;
299
300 if (!err && !test_ffa_rxtx_unmap(id))
301 err = ERR_RXTX_UNMAP;
302
303 if (!err && !test_ffa_rxtx_map())
304 err = ERR_RXTX_MAP;
305
306 if (!err && !test_ffa_partition_info_get())
307 err = ERR_PARTITION;
308
309 } else {
310 err = ERR_VERSION;
311 }
312
313 if (err != ERR_OK) {
314 DMSG("Failed at SP test %x", err);
315 return_error((uint32_t)err, msg);
316 }
317
318 return_ok(msg);
319}
320
321static void set_rxtx_buf(struct ffa_mem_transaction_buffer *t_buf,
322 struct ffa_mem_transaction_buffer *r_buf)
323{
324 if (t_buf) {
325 t_buf->buffer = (void*)tx_buffer;
326 t_buf->length = 4096;
327 t_buf->used = false;
328 }
329 if (r_buf) {
330 r_buf->buffer = (void*)rx_buffer;
331 r_buf->length = 4096;
332 r_buf->used = false;
333 }
334}
335
336static void test_mem_retrieve(struct ffa_direct_msg *msg)
337{
338 ffa_result res = FFA_OK;
339 struct sp_memory_descriptor descriptor = {0};
340 struct sp_memory_region regions[1] = {0};
341 struct sp_memory_access_descriptor acc_desc = {0};
342 uint64_t handle = 0;
343 uint32_t out_region_count = 1;
344 uint16_t own_id = 0;
345
346 ffa_id_get(&own_id);
347
348 handle = (uint64_t)msg->args[1] | (((uint64_t)msg->args[2]) << 32);
349 descriptor.tag = 0;
350 descriptor.sender_id = msg->args[3] & 0xffff;
351 acc_desc.receiver_id = own_id;
352 acc_desc.data_access = sp_data_access_read_write;
353 res = sp_memory_retrieve(&descriptor, &acc_desc, regions, 1,
354 &out_region_count, handle);
355
356 if (res) {
357 DMSG("Failed retrieving me share");
358 return_error((uint32_t)ERR_MEM_RETRIEVE, msg);
359 return;
360 }
361
362 shared_buffer = regions[0].address;
363 shared_buffer_size = regions[0].page_count * 4096;
364
365 return_ok(msg);
366}
367
368static void test_mem_relinquish(struct ffa_direct_msg *msg)
369{
370 ffa_result res = FFA_OK;
371 struct sp_memory_descriptor descriptor = {0};
372 uint64_t handle = 0;
373 uint16_t endpoint_id = 0;
374 struct sp_memory_transaction_flags flags = {
375 .zero_memory = false,
376 .operation_time_slicing = false,
377 };
378
379 if (msg->args[3] == 1)
380 flags.zero_memory = true;
381
382 ffa_id_get(&endpoint_id);
383 handle = (uint64_t)msg->args[1] | (((uint64_t)msg->args[2]) << 32);
384 descriptor.tag = 0;
385
386 res = sp_memory_relinquish(handle, &endpoint_id, 1, &flags);
387 if (res) {
388 DMSG("Failed to relinquish share");
389 return_error((uint32_t)ERR_MEM_RELINQUISH, msg);
390 }
391
392 return_ok(msg);
393}
394
395static void test_mem_sharing(uint16_t service_ep_id, struct ffa_direct_msg *msg)
396{
397 ffa_result res = FFA_OK;
398 struct sp_memory_descriptor desc = { 0 };
399 struct sp_memory_region region = { 0 };
400 uint64_t handle = 0;
401 struct ffa_mem_transaction_buffer t_buf = {0};
402 uint16_t own_id = 0;
403 uint16_t src_id = msg->source_id;
404 struct sp_memory_access_descriptor acc_desc = { };
405
406 my_buf[0] = 0xa;
407 set_rxtx_buf(&t_buf, NULL);
408 ffa_id_get(&own_id);
409
410 region.address = (void*) my_buf;
411 region.page_count = 1;
412 desc.sender_id = own_id;
413 desc.memory_type = sp_memory_type_normal_memory;
414 desc.mem_region_attr.normal_memory.cacheability =
415 sp_cacheability_write_back;
416
417 desc.mem_region_attr.normal_memory.shareability =
418 sp_shareability_inner_shareable;
419
420 acc_desc.data_access = sp_data_access_read_write;
421 acc_desc.instruction_access = sp_instruction_access_not_executable;
422 acc_desc.receiver_id = service_ep_id;
423
424 res = sp_memory_share(&desc, &acc_desc, 1, &region, 1, &handle);
425 if (res != FFA_OK) {
426 EMSG("test_mem_sharing(): error % in %s:%d"PRId32, res,
427 __FILE__,
428 __LINE__);
429 return_error((uint32_t)ERR_SP_SHARE, msg);
430 return;
431 }
432
433 res = ffa_msg_send_direct_req(own_id, service_ep_id,
434 EP_RETRIEVE, handle & 0xffffffff,
435 handle >> 32, own_id, 0, msg);
436
437 if (res != FFA_OK) {
438 EMSG("test_mem_sharing(): error % in %s:%d"PRId32, res,
439 __FILE__,
440 __LINE__);
441 return_error((uint32_t)ERR_SP_SHARE, msg);
442 return;
443 }
444
445 res = ffa_msg_send_direct_req(own_id, service_ep_id,
446 EP_TRY_W_ACCESS, 0,
447 0, 0, 0, msg);
448
449 if (res != FFA_OK) {
450 EMSG("test_mem_sharing(): error % in %s:%d"PRId32, res,
451 __FILE__,
452 __LINE__);
453 return_error((uint32_t)ERR_SP_SHARE, msg);
454 return;
455 }
456
457 res = ffa_msg_send_direct_req(own_id, service_ep_id,
458 EP_RELINQUISH, handle & 0xffffffff,
459 handle >> 32, 0, 0, msg);
460 if (res != FFA_OK) {
461 EMSG("test_mem_sharing(): error % in %s:%d"PRId32, res,
462 __FILE__,
463 __LINE__);
464 return_error((uint32_t)ERR_SP_SHARE, msg);
465 return;
466 }
467
468 res = ffa_mem_reclaim(handle, 0);
469
470 if (res != FFA_OK) {
471 EMSG("test_mem_sharing(): error % in %s:%d"PRId32, res,
472 __FILE__,
473 __LINE__);
474 return_error((uint32_t)ERR_SP_SHARE, msg);
475 return;
476 }
477 msg->destination_id = own_id;
478 msg->source_id = src_id;
479
480 return_ok(msg);
481}
482
483static void test_mem_multi_sharing(struct ffa_direct_msg *msg)
484{
485 ffa_result res = FFA_OK;
486 struct sp_memory_descriptor desc = { 0 };
487 struct sp_memory_region region = { 0 };
488 uint64_t handle = 0;
489 struct ffa_mem_transaction_buffer t_buf = {0};
490 uint16_t own_id = 0;
491 uint16_t src_id = msg->source_id = 0;
492 struct sp_memory_access_descriptor acc_desc[2] = { };
493 uint32_t err = 0;
494 uint16_t endpoint2 = msg->args[1];
495 uint16_t endpoint3 = msg->args[2];
496
497 my_buf[0] = 0xa;
498 set_rxtx_buf(&t_buf, NULL);
499 ffa_id_get(&own_id);
500
501 region.address = (void*) my_buf;
502 region.page_count = 1;
503 desc.sender_id = own_id;
504 desc.memory_type = sp_memory_type_normal_memory;
505 desc.mem_region_attr.normal_memory.cacheability =
506 sp_cacheability_write_back;
507
508 desc.mem_region_attr.normal_memory.shareability =
509 sp_shareability_inner_shareable;
510
511 acc_desc[0].data_access = sp_data_access_read_write;
512 acc_desc[0].instruction_access = sp_instruction_access_not_executable;
513 acc_desc[0].receiver_id = endpoint2;
514
515 acc_desc[1].data_access = sp_data_access_read_write;
516 acc_desc[1].instruction_access = sp_instruction_access_not_executable;
517 acc_desc[1].receiver_id = endpoint3;
518
519 res = sp_memory_share(&desc, acc_desc, 2, &region, 1, &handle);
520 if (res != FFA_OK) {
521 EMSG("ffa_memory_share(): error %"PRId32, res);
522 err = (uint32_t)ERR_SP_SHARE;
523 goto err;
524 }
525 /* test SP2*/
526 res = ffa_msg_send_direct_req(own_id, endpoint2,
527 EP_RETRIEVE, handle & 0xffffffff,
528 handle >> 32, own_id, 0, msg);
529
530 if (res != FFA_OK) {
531 EMSG("test_mem_multi_sharing(): error % in %s:%d"PRId32, res,
532 __FILE__,
533 __LINE__);
534 return_error((uint32_t)ERR_SP_SHARE, msg);
535 return;
536 }
537
538 res = ffa_msg_send_direct_req(own_id, endpoint2,
539 EP_TRY_W_ACCESS, 0,
540 0, 0, 0, msg);
541
542 if (res != FFA_OK) {
543 EMSG("test_mem_multi_sharing(): error % in %s:%d"PRId32, res,
544 __FILE__,
545 __LINE__);
546 return_error((uint32_t)ERR_SP_SHARE, msg);
547 return;
548 }
549
550 if (my_buf[0] != 0xff) {
551 EMSG("SP2 didn't change the value of the buffer");
552 err = (uint32_t)ERR_SP_SHARE;
553 goto err;
554 }
555
556 res = ffa_msg_send_direct_req(own_id, endpoint2,
557 EP_RELINQUISH, handle & 0xffffffff,
558 handle >> 32, 0, 0, msg);
559
560 if (res != FFA_OK) {
561 EMSG("test_mem_multi_sharing(): error % in %s:%d"PRId32, res,
562 __FILE__,
563 __LINE__);
564 return_error((uint32_t)ERR_SP_SHARE, msg);
565 return;
566 }
567 my_buf[0] = 0xa;
568 /* test SP3*/
569 res = ffa_msg_send_direct_req(own_id, endpoint3,
570 EP_RETRIEVE, handle & 0xffffffff,
571 handle >> 32, own_id, 0, msg);
572
573 if (res != FFA_OK) {
574 EMSG("test_mem_multi_sharing(): error % in %s:%d"PRId32, res,
575 __FILE__,
576 __LINE__);
577 return_error((uint32_t)ERR_SP_SHARE, msg);
578 return;
579 }
580
581 res = ffa_msg_send_direct_req(own_id, endpoint3,
582 EP_TRY_W_ACCESS, 0,
583 0, 0, 0, msg);
584
585 if (res != FFA_OK) {
586 EMSG("test_mem_multi_sharing(): error % in %s:%d"PRId32, res,
587 __FILE__,
588 __LINE__);
589 return_error((uint32_t)ERR_SP_SHARE, msg);
590 return;
591 }
592
593 if (my_buf[0] != 0xff) {
594 EMSG("SP3 didn't change the value of the buffer");
595 err = (uint32_t)ERR_SP_SHARE;
596 goto err;
597 }
598
599 if (ffa_mem_reclaim(handle, 0) == FFA_OK) {
600 EMSG("SP3 didn't relinquish memory yet!");
601 err = (uint32_t)ERR_SP_SHARE;
602 goto err;
603 }
604
605 res = ffa_msg_send_direct_req(own_id, endpoint3,
606 EP_RELINQUISH, handle & 0xffffffff,
607 handle >> 32, 0, 0, msg);
608
609 if (res != FFA_OK) {
610 EMSG("test_mem_multi_sharing(): error % in %s:%d"PRId32, res,
611 __FILE__,
612 __LINE__);
613 return_error((uint32_t)ERR_SP_SHARE, msg);
614 return;
615 }
616
617 if (ffa_mem_reclaim(handle, 0) != FFA_OK) {
618 EMSG("All memory should have been relinquished!");
619 err = (uint32_t)ERR_SP_SHARE;
620 goto err;
621 }
622
623 msg->destination_id = own_id;
624 msg->source_id = src_id;
625 return_ok(msg);
626 return;
627err:
628 msg->destination_id = own_id;
629 msg->source_id = src_id;
630 return_error(err, msg);
631}
632
633static void test_mem_sharing_inccorrect_access(uint16_t service_ep_id,
634 struct ffa_direct_msg *msg)
635{
636 ffa_result res = FFA_OK;
637 struct sp_memory_descriptor desc = { 0 };
638 struct sp_memory_region region = { 0 };
639 uint64_t handle = 0;
640 struct ffa_mem_transaction_buffer t_buf = {0};
641 uint16_t own_id = 0;
642 uint16_t src_id = msg->source_id = 0;
643 struct sp_memory_access_descriptor acc_desc = { };
644
645 set_rxtx_buf(&t_buf, NULL);
646 ffa_id_get(&own_id);
647
648 region.address = (void*) my_buf;
649 region.page_count = 1;
650 desc.sender_id = own_id;
651 desc.memory_type = sp_memory_type_normal_memory;
652 desc.mem_region_attr.normal_memory.cacheability =
653 sp_cacheability_write_back;
654
655 desc.mem_region_attr.normal_memory.shareability =
656 sp_shareability_inner_shareable;
657
658 acc_desc.data_access = sp_data_access_read_write;
659 acc_desc.instruction_access = sp_instruction_access_executable;
660 acc_desc.receiver_id = service_ep_id;
661
662 res = sp_memory_share(&desc, &acc_desc, 1, &region, 1, &handle);
663 if (res == FFA_OK) {
664 EMSG("ffa_memory_share(): error %"PRId32, res);
665 return_error((uint32_t)ERR_SP_SHARE, msg);
666 return;
667 }
668
669 msg->destination_id = own_id;
670 msg->source_id = src_id;
671 return_ok(msg);
672}
673
674static void test_mem_sharing_exc(uint16_t service_ep_id,
675 struct ffa_direct_msg *msg)
676{
677 ffa_result res = FFA_OK;
678 struct sp_memory_descriptor desc = { 0 };
679 struct sp_memory_region region = { 0 };
680 uint64_t handle = 0;
681 uint64_t handle2 = 0;
682 struct ffa_mem_transaction_buffer t_buf = {0};
683 uint16_t own_id = 0;
684 uint16_t src_id = msg->source_id = 0;
685 struct sp_memory_access_descriptor acc_desc = { };
686 uint32_t err = 0;
687
688 set_rxtx_buf(&t_buf, NULL);
689 ffa_id_get(&own_id);
690
691 region.address = (void*) my_buf;
692 region.page_count = 1;
693 desc.sender_id = own_id;
694 desc.memory_type = sp_memory_type_normal_memory;
695 desc.mem_region_attr.normal_memory.cacheability =
696 sp_cacheability_write_back;
697
698 desc.mem_region_attr.normal_memory.shareability =
699 sp_shareability_inner_shareable;
700
701 acc_desc.data_access = sp_data_access_read_write;
702 acc_desc.instruction_access = sp_instruction_access_not_executable;
703 acc_desc.receiver_id = service_ep_id;
704
705 res = sp_memory_share(&desc, &acc_desc, 1, &region, 1, &handle);
706 if (res != FFA_OK) {
707 EMSG("test_mem_sharing_exc(): error %"PRId32, res);
708 err = (uint32_t)ERR_SP_SHARE_EXC;
709 goto err;
710 }
711
712 /*
713 * Try it again, it should fail as we don't have acclusive access
714 * anymore
715 */
716 res = sp_memory_share(&desc, &acc_desc, 1, &region, 1, &handle2);
717 if (res == FFA_OK) {
718 EMSG("test_mem_sharing_exc(): error %"PRId32, res);
719 err = (uint32_t)ERR_SP_SHARE_EXC;
720 goto err;
721 }
722
723 res = ffa_mem_reclaim(handle, 0);
724
725 if (res != FFA_OK) {
726 EMSG("ffa_memory_share(): error % in %s:%d"PRId32, res,
727 __FILE__,
728 __LINE__);
729 return_error((uint32_t)ERR_SP_SHARE, msg);
730 return;
731 }
732
733 msg->destination_id = own_id;
734 msg->source_id = src_id;
735 return_ok(msg);
736 return;
737err:
738 msg->destination_id = own_id;
739 msg->source_id = src_id;
740 return_error(err, msg);
741}
742
743void __noreturn sp_main(struct ffa_init_info *init_info) {
744 struct ffa_direct_msg msg = {0};
745 uint16_t own_id = 0;
746
747 /* Boot phase */
748 if (sp_discovery_own_id_get(&own_id) != SP_RESULT_OK) {
749 EMSG("Couldn't get own_id!!");
750 }
751
752 test_ffa_rxtx_map();
753 /* End of boot phase */
754 ffa_msg_wait(&msg);
755
756 while (1) {
757 enum sp_tests test_case = (enum sp_tests)msg.args[0];
758
759 DMSG("SP:%x Starting test %s", own_id, sp_test_str[test_case]);
760 switch (test_case) {
761 case EP_TEST_SP:
762 test_internal_sp(&msg);
763 break;
764 case EP_TEST_SP_COMMUNICATION:
765 test_communication(&msg);
766 break;
767 case EP_TEST_SP_INCREASE:
768 test_increase(&msg);
769 break;
770 case EP_TRY_R_ACCESS:
771 test_read_access();
772 return_ok(&msg);
773 break;
774 case EP_TRY_W_ACCESS:
775 test_write_access();
776 return_ok(&msg);
777 break;
778 case EP_RETRIEVE:
779 test_mem_retrieve(&msg);
780 break;
781 case EP_RELINQUISH:
782 test_mem_relinquish(&msg);
783 break;
784 case EP_SP_MEM_SHARING:
785 test_mem_sharing((uint16_t)msg.args[1], &msg);
786 break;
787 case EP_SP_MEM_SHARING_MULTI:
788 test_mem_multi_sharing(&msg);
789 break;
790 case EP_SP_MEM_SHARING_EXC:
791 test_mem_sharing_exc((uint16_t)msg.args[1], &msg);
792 break;
793 case EP_SP_MEM_INCORRECT_ACCESS:
794 test_mem_sharing_inccorrect_access(
795 (uint16_t)msg.args[1], &msg);
796 break;
797 case EP_SP_NOP:
798 return_ok(&msg);
799 break;
800
801 default:
802 return_error((uint32_t)ERR_TEST_NOT_FOUND, &msg);
803 break;
804 }
805 }
806}
807
808void sp_interrupt_handler(uint32_t interrupt_id)
809{
810 (void)interrupt_id;
811 DMSG("Got interrupt %x", interrupt_id);
812}