blob: 76ac133f4be6c94862537edb910f9f61a0705fe5 [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{
Jelle Sels45353ba2022-09-30 14:47:56 +0200224 ffa_msg_send_direct_resp_32(msg->destination_id, msg->source_id, 0xff,
Jelle Sels03756662021-05-20 10:41:57 +0200225 error, 0, 0, 0, msg);
226}
227
228static void return_ok(struct ffa_direct_msg *msg)
229{
230
Jelle Sels45353ba2022-09-30 14:47:56 +0200231 ffa_msg_send_direct_resp_32(msg->destination_id,
Jelle Sels03756662021-05-20 10:41:57 +0200232 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{
Jelle Sels45353ba2022-09-30 14:47:56 +0200248 msg->args.args32[1]++;
249 msg->args.args32[2]++;
250 msg->args.args32[3]++;
251 msg->args.args32[4]++;
252 ffa_msg_send_direct_resp_32(msg->destination_id,msg->source_id,
253 SP_TEST_OK, msg->args.args32[1],
254 msg->args.args32[2],msg->args.args32[3],
255 msg->args.args32[4], msg);
Jelle Sels03756662021-05-20 10:41:57 +0200256
257}
258
259static void test_communication(struct ffa_direct_msg *msg)
260{
261 struct ffa_direct_msg sp_msg = {0};
Jelle Sels45353ba2022-09-30 14:47:56 +0200262 uint16_t dst = (uint16_t)msg->args.args32[1];
Jelle Sels03756662021-05-20 10:41:57 +0200263 ffa_result res = FFA_OK;
264
Jelle Sels45353ba2022-09-30 14:47:56 +0200265 sp_msg.args.args32[1] = 0x55;
266 sp_msg.args.args32[2] = 0xAA;
267 sp_msg.args.args32[3] = 0xBB;
268 sp_msg.args.args32[4] = 0xCC;
269 res = ffa_msg_send_direct_req_32(msg->destination_id, dst,
270 EP_TEST_SP_INCREASE,0x55, 0xAA, 0xBB,
271 0xCC, &sp_msg);
Jelle Sels03756662021-05-20 10:41:57 +0200272
273 if (res != FFA_OK) {
274 EMSG("error % in %s:%d"PRId32, res, __FILE__, __LINE__);
275 return_error((uint32_t)ERR_SP_SHARE, msg);
276 return;
277 }
278
Jelle Sels45353ba2022-09-30 14:47:56 +0200279 if (sp_msg.args.args32[1] == 0x56 && sp_msg.args.args32[2] == 0xAB &&
280 sp_msg.args.args32[3] == 0xBC &&sp_msg.args.args32[4] == 0xCD) {
Jelle Sels03756662021-05-20 10:41:57 +0200281 return_ok(msg);
282 } else {
Jelle Sels45353ba2022-09-30 14:47:56 +0200283 DMSG("Failed SP communication %x %x %x %x",
284 sp_msg.args.args32[1],
285 sp_msg.args.args32[2], sp_msg.args.args32[3],
286 sp_msg.args.args32[4]);
Jelle Sels03756662021-05-20 10:41:57 +0200287
288 return_error(ERR_SP_COMMUNICATION, msg);
289 }
290}
291
292static void test_internal_sp(struct ffa_direct_msg *msg)
293{
294 enum errors err = ERR_OK;
295 uint16_t id = 0;
296
297 if (test_ffa_version()) {
298 if (!test_ffa_id_get(&id))
299 err = ERR_ID_GET;
300
301 if (!err && !test_ffa_features())
302 err = ERR_VERSION;
303
304 if (!err && !test_ffa_rxtx_unmap(id))
305 err = ERR_RXTX_UNMAP;
306
307 if (!err && !test_ffa_rxtx_map())
308 err = ERR_RXTX_MAP;
309
310 if (!err && !test_ffa_partition_info_get())
311 err = ERR_PARTITION;
312
313 } else {
314 err = ERR_VERSION;
315 }
316
317 if (err != ERR_OK) {
318 DMSG("Failed at SP test %x", err);
319 return_error((uint32_t)err, msg);
320 }
321
322 return_ok(msg);
323}
324
325static void set_rxtx_buf(struct ffa_mem_transaction_buffer *t_buf,
326 struct ffa_mem_transaction_buffer *r_buf)
327{
328 if (t_buf) {
329 t_buf->buffer = (void*)tx_buffer;
330 t_buf->length = 4096;
331 t_buf->used = false;
332 }
333 if (r_buf) {
334 r_buf->buffer = (void*)rx_buffer;
335 r_buf->length = 4096;
336 r_buf->used = false;
337 }
338}
339
340static void test_mem_retrieve(struct ffa_direct_msg *msg)
341{
342 ffa_result res = FFA_OK;
343 struct sp_memory_descriptor descriptor = {0};
344 struct sp_memory_region regions[1] = {0};
345 struct sp_memory_access_descriptor acc_desc = {0};
346 uint64_t handle = 0;
347 uint32_t out_region_count = 1;
348 uint16_t own_id = 0;
349
350 ffa_id_get(&own_id);
351
Jelle Sels45353ba2022-09-30 14:47:56 +0200352 handle = (uint64_t)msg->args.args32[1] |
353 (((uint64_t)msg->args.args32[2]) << 32);
Jelle Sels03756662021-05-20 10:41:57 +0200354 descriptor.tag = 0;
Jelle Sels45353ba2022-09-30 14:47:56 +0200355 descriptor.sender_id = msg->args.args32[3] & 0xffff;
Jelle Sels03756662021-05-20 10:41:57 +0200356 acc_desc.receiver_id = own_id;
357 acc_desc.data_access = sp_data_access_read_write;
358 res = sp_memory_retrieve(&descriptor, &acc_desc, regions, 1,
359 &out_region_count, handle);
360
361 if (res) {
362 DMSG("Failed retrieving me share");
363 return_error((uint32_t)ERR_MEM_RETRIEVE, msg);
364 return;
365 }
366
367 shared_buffer = regions[0].address;
368 shared_buffer_size = regions[0].page_count * 4096;
369
370 return_ok(msg);
371}
372
373static void test_mem_relinquish(struct ffa_direct_msg *msg)
374{
375 ffa_result res = FFA_OK;
376 struct sp_memory_descriptor descriptor = {0};
377 uint64_t handle = 0;
378 uint16_t endpoint_id = 0;
379 struct sp_memory_transaction_flags flags = {
380 .zero_memory = false,
381 .operation_time_slicing = false,
382 };
383
Jelle Sels45353ba2022-09-30 14:47:56 +0200384 if (msg->args.args32[3] == 1)
Jelle Sels03756662021-05-20 10:41:57 +0200385 flags.zero_memory = true;
386
387 ffa_id_get(&endpoint_id);
Jelle Sels45353ba2022-09-30 14:47:56 +0200388 handle = (uint64_t)msg->args.args32[1] |
389 (((uint64_t)msg->args.args32[2]) << 32);
Jelle Sels03756662021-05-20 10:41:57 +0200390 descriptor.tag = 0;
391
392 res = sp_memory_relinquish(handle, &endpoint_id, 1, &flags);
393 if (res) {
394 DMSG("Failed to relinquish share");
395 return_error((uint32_t)ERR_MEM_RELINQUISH, msg);
396 }
397
398 return_ok(msg);
399}
400
401static void test_mem_sharing(uint16_t service_ep_id, struct ffa_direct_msg *msg)
402{
403 ffa_result res = FFA_OK;
404 struct sp_memory_descriptor desc = { 0 };
405 struct sp_memory_region region = { 0 };
406 uint64_t handle = 0;
407 struct ffa_mem_transaction_buffer t_buf = {0};
408 uint16_t own_id = 0;
409 uint16_t src_id = msg->source_id;
410 struct sp_memory_access_descriptor acc_desc = { };
411
412 my_buf[0] = 0xa;
413 set_rxtx_buf(&t_buf, NULL);
414 ffa_id_get(&own_id);
415
416 region.address = (void*) my_buf;
417 region.page_count = 1;
418 desc.sender_id = own_id;
419 desc.memory_type = sp_memory_type_normal_memory;
420 desc.mem_region_attr.normal_memory.cacheability =
421 sp_cacheability_write_back;
422
423 desc.mem_region_attr.normal_memory.shareability =
424 sp_shareability_inner_shareable;
425
426 acc_desc.data_access = sp_data_access_read_write;
427 acc_desc.instruction_access = sp_instruction_access_not_executable;
428 acc_desc.receiver_id = service_ep_id;
429
430 res = sp_memory_share(&desc, &acc_desc, 1, &region, 1, &handle);
431 if (res != FFA_OK) {
432 EMSG("test_mem_sharing(): error % in %s:%d"PRId32, res,
433 __FILE__,
434 __LINE__);
435 return_error((uint32_t)ERR_SP_SHARE, msg);
436 return;
437 }
438
Jelle Sels45353ba2022-09-30 14:47:56 +0200439 res = ffa_msg_send_direct_req_32(own_id, service_ep_id,
Jelle Sels03756662021-05-20 10:41:57 +0200440 EP_RETRIEVE, handle & 0xffffffff,
441 handle >> 32, own_id, 0, msg);
442
443 if (res != FFA_OK) {
444 EMSG("test_mem_sharing(): error % in %s:%d"PRId32, res,
445 __FILE__,
446 __LINE__);
447 return_error((uint32_t)ERR_SP_SHARE, msg);
448 return;
449 }
450
Jelle Sels45353ba2022-09-30 14:47:56 +0200451 res = ffa_msg_send_direct_req_32(own_id, service_ep_id,
Jelle Sels03756662021-05-20 10:41:57 +0200452 EP_TRY_W_ACCESS, 0,
453 0, 0, 0, msg);
454
455 if (res != FFA_OK) {
456 EMSG("test_mem_sharing(): error % in %s:%d"PRId32, res,
457 __FILE__,
458 __LINE__);
459 return_error((uint32_t)ERR_SP_SHARE, msg);
460 return;
461 }
462
Jelle Sels45353ba2022-09-30 14:47:56 +0200463 res = ffa_msg_send_direct_req_32(own_id, service_ep_id,
Jelle Sels03756662021-05-20 10:41:57 +0200464 EP_RELINQUISH, handle & 0xffffffff,
465 handle >> 32, 0, 0, msg);
466 if (res != FFA_OK) {
467 EMSG("test_mem_sharing(): error % in %s:%d"PRId32, res,
468 __FILE__,
469 __LINE__);
470 return_error((uint32_t)ERR_SP_SHARE, msg);
471 return;
472 }
473
474 res = ffa_mem_reclaim(handle, 0);
475
476 if (res != FFA_OK) {
477 EMSG("test_mem_sharing(): error % in %s:%d"PRId32, res,
478 __FILE__,
479 __LINE__);
480 return_error((uint32_t)ERR_SP_SHARE, msg);
481 return;
482 }
483 msg->destination_id = own_id;
484 msg->source_id = src_id;
485
486 return_ok(msg);
487}
488
489static void test_mem_multi_sharing(struct ffa_direct_msg *msg)
490{
491 ffa_result res = FFA_OK;
492 struct sp_memory_descriptor desc = { 0 };
493 struct sp_memory_region region = { 0 };
494 uint64_t handle = 0;
495 struct ffa_mem_transaction_buffer t_buf = {0};
496 uint16_t own_id = 0;
497 uint16_t src_id = msg->source_id = 0;
498 struct sp_memory_access_descriptor acc_desc[2] = { };
499 uint32_t err = 0;
Jelle Sels45353ba2022-09-30 14:47:56 +0200500 uint16_t endpoint2 = msg->args.args32[1];
501 uint16_t endpoint3 = msg->args.args32[2];
Jelle Sels03756662021-05-20 10:41:57 +0200502
503 my_buf[0] = 0xa;
504 set_rxtx_buf(&t_buf, NULL);
505 ffa_id_get(&own_id);
506
507 region.address = (void*) my_buf;
508 region.page_count = 1;
509 desc.sender_id = own_id;
510 desc.memory_type = sp_memory_type_normal_memory;
511 desc.mem_region_attr.normal_memory.cacheability =
512 sp_cacheability_write_back;
513
514 desc.mem_region_attr.normal_memory.shareability =
515 sp_shareability_inner_shareable;
516
517 acc_desc[0].data_access = sp_data_access_read_write;
518 acc_desc[0].instruction_access = sp_instruction_access_not_executable;
519 acc_desc[0].receiver_id = endpoint2;
520
521 acc_desc[1].data_access = sp_data_access_read_write;
522 acc_desc[1].instruction_access = sp_instruction_access_not_executable;
523 acc_desc[1].receiver_id = endpoint3;
524
525 res = sp_memory_share(&desc, acc_desc, 2, &region, 1, &handle);
526 if (res != FFA_OK) {
527 EMSG("ffa_memory_share(): error %"PRId32, res);
528 err = (uint32_t)ERR_SP_SHARE;
529 goto err;
530 }
531 /* test SP2*/
Jelle Sels45353ba2022-09-30 14:47:56 +0200532 res = ffa_msg_send_direct_req_32(own_id, endpoint2,
Jelle Sels03756662021-05-20 10:41:57 +0200533 EP_RETRIEVE, handle & 0xffffffff,
534 handle >> 32, own_id, 0, msg);
535
536 if (res != FFA_OK) {
537 EMSG("test_mem_multi_sharing(): error % in %s:%d"PRId32, res,
538 __FILE__,
539 __LINE__);
540 return_error((uint32_t)ERR_SP_SHARE, msg);
541 return;
542 }
543
Jelle Sels45353ba2022-09-30 14:47:56 +0200544 res = ffa_msg_send_direct_req_32(own_id, endpoint2,
Jelle Sels03756662021-05-20 10:41:57 +0200545 EP_TRY_W_ACCESS, 0,
546 0, 0, 0, msg);
547
548 if (res != FFA_OK) {
549 EMSG("test_mem_multi_sharing(): error % in %s:%d"PRId32, res,
550 __FILE__,
551 __LINE__);
552 return_error((uint32_t)ERR_SP_SHARE, msg);
553 return;
554 }
555
556 if (my_buf[0] != 0xff) {
557 EMSG("SP2 didn't change the value of the buffer");
558 err = (uint32_t)ERR_SP_SHARE;
559 goto err;
560 }
561
Jelle Sels45353ba2022-09-30 14:47:56 +0200562 res = ffa_msg_send_direct_req_32(own_id, endpoint2,
Jelle Sels03756662021-05-20 10:41:57 +0200563 EP_RELINQUISH, handle & 0xffffffff,
564 handle >> 32, 0, 0, msg);
565
566 if (res != FFA_OK) {
567 EMSG("test_mem_multi_sharing(): error % in %s:%d"PRId32, res,
568 __FILE__,
569 __LINE__);
570 return_error((uint32_t)ERR_SP_SHARE, msg);
571 return;
572 }
573 my_buf[0] = 0xa;
574 /* test SP3*/
Jelle Sels45353ba2022-09-30 14:47:56 +0200575 res = ffa_msg_send_direct_req_32(own_id, endpoint3,
Jelle Sels03756662021-05-20 10:41:57 +0200576 EP_RETRIEVE, handle & 0xffffffff,
577 handle >> 32, own_id, 0, msg);
578
579 if (res != FFA_OK) {
580 EMSG("test_mem_multi_sharing(): error % in %s:%d"PRId32, res,
581 __FILE__,
582 __LINE__);
583 return_error((uint32_t)ERR_SP_SHARE, msg);
584 return;
585 }
586
Jelle Sels45353ba2022-09-30 14:47:56 +0200587 res = ffa_msg_send_direct_req_32(own_id, endpoint3,
Jelle Sels03756662021-05-20 10:41:57 +0200588 EP_TRY_W_ACCESS, 0,
589 0, 0, 0, msg);
590
591 if (res != FFA_OK) {
592 EMSG("test_mem_multi_sharing(): error % in %s:%d"PRId32, res,
593 __FILE__,
594 __LINE__);
595 return_error((uint32_t)ERR_SP_SHARE, msg);
596 return;
597 }
598
599 if (my_buf[0] != 0xff) {
600 EMSG("SP3 didn't change the value of the buffer");
601 err = (uint32_t)ERR_SP_SHARE;
602 goto err;
603 }
604
605 if (ffa_mem_reclaim(handle, 0) == FFA_OK) {
606 EMSG("SP3 didn't relinquish memory yet!");
607 err = (uint32_t)ERR_SP_SHARE;
608 goto err;
609 }
610
Jelle Sels45353ba2022-09-30 14:47:56 +0200611 res = ffa_msg_send_direct_req_32(own_id, endpoint3,
Jelle Sels03756662021-05-20 10:41:57 +0200612 EP_RELINQUISH, handle & 0xffffffff,
613 handle >> 32, 0, 0, msg);
614
615 if (res != FFA_OK) {
616 EMSG("test_mem_multi_sharing(): error % in %s:%d"PRId32, res,
617 __FILE__,
618 __LINE__);
619 return_error((uint32_t)ERR_SP_SHARE, msg);
620 return;
621 }
622
623 if (ffa_mem_reclaim(handle, 0) != FFA_OK) {
624 EMSG("All memory should have been relinquished!");
625 err = (uint32_t)ERR_SP_SHARE;
626 goto err;
627 }
628
629 msg->destination_id = own_id;
630 msg->source_id = src_id;
631 return_ok(msg);
632 return;
633err:
634 msg->destination_id = own_id;
635 msg->source_id = src_id;
636 return_error(err, msg);
637}
638
639static void test_mem_sharing_inccorrect_access(uint16_t service_ep_id,
640 struct ffa_direct_msg *msg)
641{
642 ffa_result res = FFA_OK;
643 struct sp_memory_descriptor desc = { 0 };
644 struct sp_memory_region region = { 0 };
645 uint64_t handle = 0;
646 struct ffa_mem_transaction_buffer t_buf = {0};
647 uint16_t own_id = 0;
648 uint16_t src_id = msg->source_id = 0;
649 struct sp_memory_access_descriptor acc_desc = { };
650
651 set_rxtx_buf(&t_buf, NULL);
652 ffa_id_get(&own_id);
653
654 region.address = (void*) my_buf;
655 region.page_count = 1;
656 desc.sender_id = own_id;
657 desc.memory_type = sp_memory_type_normal_memory;
658 desc.mem_region_attr.normal_memory.cacheability =
659 sp_cacheability_write_back;
660
661 desc.mem_region_attr.normal_memory.shareability =
662 sp_shareability_inner_shareable;
663
664 acc_desc.data_access = sp_data_access_read_write;
665 acc_desc.instruction_access = sp_instruction_access_executable;
666 acc_desc.receiver_id = service_ep_id;
667
668 res = sp_memory_share(&desc, &acc_desc, 1, &region, 1, &handle);
669 if (res == FFA_OK) {
670 EMSG("ffa_memory_share(): error %"PRId32, res);
671 return_error((uint32_t)ERR_SP_SHARE, msg);
672 return;
673 }
674
675 msg->destination_id = own_id;
676 msg->source_id = src_id;
677 return_ok(msg);
678}
679
680static void test_mem_sharing_exc(uint16_t service_ep_id,
681 struct ffa_direct_msg *msg)
682{
683 ffa_result res = FFA_OK;
684 struct sp_memory_descriptor desc = { 0 };
685 struct sp_memory_region region = { 0 };
686 uint64_t handle = 0;
687 uint64_t handle2 = 0;
688 struct ffa_mem_transaction_buffer t_buf = {0};
689 uint16_t own_id = 0;
690 uint16_t src_id = msg->source_id = 0;
691 struct sp_memory_access_descriptor acc_desc = { };
692 uint32_t err = 0;
693
694 set_rxtx_buf(&t_buf, NULL);
695 ffa_id_get(&own_id);
696
697 region.address = (void*) my_buf;
698 region.page_count = 1;
699 desc.sender_id = own_id;
700 desc.memory_type = sp_memory_type_normal_memory;
701 desc.mem_region_attr.normal_memory.cacheability =
702 sp_cacheability_write_back;
703
704 desc.mem_region_attr.normal_memory.shareability =
705 sp_shareability_inner_shareable;
706
707 acc_desc.data_access = sp_data_access_read_write;
708 acc_desc.instruction_access = sp_instruction_access_not_executable;
709 acc_desc.receiver_id = service_ep_id;
710
711 res = sp_memory_share(&desc, &acc_desc, 1, &region, 1, &handle);
712 if (res != FFA_OK) {
713 EMSG("test_mem_sharing_exc(): error %"PRId32, res);
714 err = (uint32_t)ERR_SP_SHARE_EXC;
715 goto err;
716 }
717
718 /*
719 * Try it again, it should fail as we don't have acclusive access
720 * anymore
721 */
722 res = sp_memory_share(&desc, &acc_desc, 1, &region, 1, &handle2);
723 if (res == FFA_OK) {
724 EMSG("test_mem_sharing_exc(): error %"PRId32, res);
725 err = (uint32_t)ERR_SP_SHARE_EXC;
726 goto err;
727 }
728
729 res = ffa_mem_reclaim(handle, 0);
730
731 if (res != FFA_OK) {
732 EMSG("ffa_memory_share(): error % in %s:%d"PRId32, res,
733 __FILE__,
734 __LINE__);
735 return_error((uint32_t)ERR_SP_SHARE, msg);
736 return;
737 }
738
739 msg->destination_id = own_id;
740 msg->source_id = src_id;
741 return_ok(msg);
742 return;
743err:
744 msg->destination_id = own_id;
745 msg->source_id = src_id;
746 return_error(err, msg);
747}
748
749void __noreturn sp_main(struct ffa_init_info *init_info) {
750 struct ffa_direct_msg msg = {0};
751 uint16_t own_id = 0;
752
753 /* Boot phase */
754 if (sp_discovery_own_id_get(&own_id) != SP_RESULT_OK) {
755 EMSG("Couldn't get own_id!!");
756 }
757
758 test_ffa_rxtx_map();
759 /* End of boot phase */
760 ffa_msg_wait(&msg);
761
762 while (1) {
Jelle Sels45353ba2022-09-30 14:47:56 +0200763 enum sp_tests test_case = (enum sp_tests)msg.args.args32[0];
Jelle Sels03756662021-05-20 10:41:57 +0200764
765 DMSG("SP:%x Starting test %s", own_id, sp_test_str[test_case]);
766 switch (test_case) {
767 case EP_TEST_SP:
768 test_internal_sp(&msg);
769 break;
770 case EP_TEST_SP_COMMUNICATION:
771 test_communication(&msg);
772 break;
773 case EP_TEST_SP_INCREASE:
774 test_increase(&msg);
775 break;
776 case EP_TRY_R_ACCESS:
777 test_read_access();
778 return_ok(&msg);
779 break;
780 case EP_TRY_W_ACCESS:
781 test_write_access();
782 return_ok(&msg);
783 break;
784 case EP_RETRIEVE:
785 test_mem_retrieve(&msg);
786 break;
787 case EP_RELINQUISH:
788 test_mem_relinquish(&msg);
789 break;
790 case EP_SP_MEM_SHARING:
Jelle Sels45353ba2022-09-30 14:47:56 +0200791 test_mem_sharing((uint16_t)msg.args.args32[1], &msg);
Jelle Sels03756662021-05-20 10:41:57 +0200792 break;
793 case EP_SP_MEM_SHARING_MULTI:
794 test_mem_multi_sharing(&msg);
795 break;
796 case EP_SP_MEM_SHARING_EXC:
Jelle Sels45353ba2022-09-30 14:47:56 +0200797 test_mem_sharing_exc((uint16_t)msg.args.args32[1],
798 &msg);
Jelle Sels03756662021-05-20 10:41:57 +0200799 break;
800 case EP_SP_MEM_INCORRECT_ACCESS:
801 test_mem_sharing_inccorrect_access(
Jelle Sels45353ba2022-09-30 14:47:56 +0200802 (uint16_t)msg.args.args32[1], &msg);
Jelle Sels03756662021-05-20 10:41:57 +0200803 break;
804 case EP_SP_NOP:
805 return_ok(&msg);
806 break;
807
808 default:
809 return_error((uint32_t)ERR_TEST_NOT_FOUND, &msg);
810 break;
811 }
812 }
813}
814
815void sp_interrupt_handler(uint32_t interrupt_id)
816{
817 (void)interrupt_id;
818 DMSG("Got interrupt %x", interrupt_id);
819}