blob: 01cc7d2831e5459c922d89d07775fcb166867de2 [file] [log] [blame]
Jelle Sels03756662021-05-20 10:41:57 +02001/*
Gabor Toth569309e2023-02-08 07:56:22 +01002 * Copyright (c) 2022-2023, Arm Limited and Contributors. All rights reserved.
Jelle Sels03756662021-05-20 10:41:57 +02003 *
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{
Gabor Toth569309e2023-02-08 07:56:22 +0100224 ffa_msg_send_direct_resp_64(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
Gabor Toth569309e2023-02-08 07:56:22 +0100231 ffa_msg_send_direct_resp_64(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{
Gabor Toth569309e2023-02-08 07:56:22 +0100248 msg->args.args64[1]++;
249 msg->args.args64[2]++;
250 msg->args.args64[3]++;
251 msg->args.args64[4]++;
252 ffa_msg_send_direct_resp_64(msg->destination_id,msg->source_id,
253 SP_TEST_OK, msg->args.args64[1],
254 msg->args.args64[2],msg->args.args64[3],
255 msg->args.args64[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};
Gabor Toth569309e2023-02-08 07:56:22 +0100262 uint16_t dst = (uint16_t)msg->args.args64[1];
Jelle Sels03756662021-05-20 10:41:57 +0200263 ffa_result res = FFA_OK;
264
Gabor Toth569309e2023-02-08 07:56:22 +0100265 sp_msg.args.args64[1] = 0x55;
266 sp_msg.args.args64[2] = 0xAA;
267 sp_msg.args.args64[3] = 0xBB;
268 sp_msg.args.args64[4] = 0xCC;
269
270 res = ffa_msg_send_direct_req_64(msg->destination_id, dst,
Jelle Sels45353ba2022-09-30 14:47:56 +0200271 EP_TEST_SP_INCREASE,0x55, 0xAA, 0xBB,
272 0xCC, &sp_msg);
Jelle Sels03756662021-05-20 10:41:57 +0200273
274 if (res != FFA_OK) {
275 EMSG("error % in %s:%d"PRId32, res, __FILE__, __LINE__);
276 return_error((uint32_t)ERR_SP_SHARE, msg);
277 return;
278 }
279
Gabor Toth569309e2023-02-08 07:56:22 +0100280 if (sp_msg.args.args64[1] == 0x56 && sp_msg.args.args64[2] == 0xAB &&
281 sp_msg.args.args64[3] == 0xBC &&sp_msg.args.args64[4] == 0xCD) {
Jelle Sels03756662021-05-20 10:41:57 +0200282 return_ok(msg);
283 } else {
Imre Kis45df16f2023-03-24 13:27:10 +0100284 DMSG("Failed SP communication %lx %lx %lx %lx",
285 sp_msg.args.args64[1], sp_msg.args.args64[2],
286 sp_msg.args.args64[3], sp_msg.args.args64[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
Gabor Toth569309e2023-02-08 07:56:22 +0100352 handle = (uint64_t)msg->args.args64[1] |
353 (((uint64_t)msg->args.args64[2]) << 32);
Jelle Sels03756662021-05-20 10:41:57 +0200354 descriptor.tag = 0;
Gabor Toth569309e2023-02-08 07:56:22 +0100355 descriptor.sender_id = msg->args.args64[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;
Jelle Sels03756662021-05-20 10:41:57 +0200376 uint64_t handle = 0;
377 uint16_t endpoint_id = 0;
378 struct sp_memory_transaction_flags flags = {
379 .zero_memory = false,
380 .operation_time_slicing = false,
381 };
382
Gabor Toth569309e2023-02-08 07:56:22 +0100383 if (msg->args.args64[3] == 1)
Jelle Sels03756662021-05-20 10:41:57 +0200384 flags.zero_memory = true;
385
386 ffa_id_get(&endpoint_id);
Gabor Toth569309e2023-02-08 07:56:22 +0100387 handle = (uint64_t)msg->args.args64[1] |
388 (((uint64_t)msg->args.args64[2]) << 32);
Jelle Sels03756662021-05-20 10:41:57 +0200389
390 res = sp_memory_relinquish(handle, &endpoint_id, 1, &flags);
391 if (res) {
392 DMSG("Failed to relinquish share");
393 return_error((uint32_t)ERR_MEM_RELINQUISH, msg);
394 }
395
396 return_ok(msg);
397}
398
399static void test_mem_sharing(uint16_t service_ep_id, struct ffa_direct_msg *msg)
400{
401 ffa_result res = FFA_OK;
402 struct sp_memory_descriptor desc = { 0 };
403 struct sp_memory_region region = { 0 };
404 uint64_t handle = 0;
405 struct ffa_mem_transaction_buffer t_buf = {0};
406 uint16_t own_id = 0;
407 uint16_t src_id = msg->source_id;
408 struct sp_memory_access_descriptor acc_desc = { };
409
410 my_buf[0] = 0xa;
411 set_rxtx_buf(&t_buf, NULL);
412 ffa_id_get(&own_id);
413
414 region.address = (void*) my_buf;
415 region.page_count = 1;
416 desc.sender_id = own_id;
417 desc.memory_type = sp_memory_type_normal_memory;
418 desc.mem_region_attr.normal_memory.cacheability =
419 sp_cacheability_write_back;
420
421 desc.mem_region_attr.normal_memory.shareability =
422 sp_shareability_inner_shareable;
423
424 acc_desc.data_access = sp_data_access_read_write;
425 acc_desc.instruction_access = sp_instruction_access_not_executable;
426 acc_desc.receiver_id = service_ep_id;
427
428 res = sp_memory_share(&desc, &acc_desc, 1, &region, 1, &handle);
429 if (res != FFA_OK) {
430 EMSG("test_mem_sharing(): error % in %s:%d"PRId32, res,
431 __FILE__,
432 __LINE__);
433 return_error((uint32_t)ERR_SP_SHARE, msg);
434 return;
435 }
436
Gabor Toth569309e2023-02-08 07:56:22 +0100437 res = ffa_msg_send_direct_req_64(own_id, service_ep_id,
Jelle Sels03756662021-05-20 10:41:57 +0200438 EP_RETRIEVE, handle & 0xffffffff,
439 handle >> 32, own_id, 0, msg);
440
441 if (res != FFA_OK) {
442 EMSG("test_mem_sharing(): error % in %s:%d"PRId32, res,
443 __FILE__,
444 __LINE__);
445 return_error((uint32_t)ERR_SP_SHARE, msg);
446 return;
447 }
448
Gabor Toth569309e2023-02-08 07:56:22 +0100449 res = ffa_msg_send_direct_req_64(own_id, service_ep_id,
Jelle Sels03756662021-05-20 10:41:57 +0200450 EP_TRY_W_ACCESS, 0,
451 0, 0, 0, msg);
452
453 if (res != FFA_OK) {
454 EMSG("test_mem_sharing(): error % in %s:%d"PRId32, res,
455 __FILE__,
456 __LINE__);
457 return_error((uint32_t)ERR_SP_SHARE, msg);
458 return;
459 }
460
Gabor Toth569309e2023-02-08 07:56:22 +0100461 res = ffa_msg_send_direct_req_64(own_id, service_ep_id,
Jelle Sels03756662021-05-20 10:41:57 +0200462 EP_RELINQUISH, handle & 0xffffffff,
463 handle >> 32, 0, 0, msg);
464 if (res != FFA_OK) {
465 EMSG("test_mem_sharing(): error % in %s:%d"PRId32, res,
466 __FILE__,
467 __LINE__);
468 return_error((uint32_t)ERR_SP_SHARE, msg);
469 return;
470 }
471
472 res = ffa_mem_reclaim(handle, 0);
473
474 if (res != FFA_OK) {
475 EMSG("test_mem_sharing(): error % in %s:%d"PRId32, res,
476 __FILE__,
477 __LINE__);
478 return_error((uint32_t)ERR_SP_SHARE, msg);
479 return;
480 }
481 msg->destination_id = own_id;
482 msg->source_id = src_id;
483
484 return_ok(msg);
485}
486
487static void test_mem_multi_sharing(struct ffa_direct_msg *msg)
488{
489 ffa_result res = FFA_OK;
490 struct sp_memory_descriptor desc = { 0 };
491 struct sp_memory_region region = { 0 };
492 uint64_t handle = 0;
493 struct ffa_mem_transaction_buffer t_buf = {0};
494 uint16_t own_id = 0;
495 uint16_t src_id = msg->source_id = 0;
496 struct sp_memory_access_descriptor acc_desc[2] = { };
497 uint32_t err = 0;
Gabor Toth569309e2023-02-08 07:56:22 +0100498 uint16_t endpoint2 = msg->args.args64[1];
499 uint16_t endpoint3 = msg->args.args64[2];
Jelle Sels03756662021-05-20 10:41:57 +0200500
501 my_buf[0] = 0xa;
502 set_rxtx_buf(&t_buf, NULL);
503 ffa_id_get(&own_id);
504
505 region.address = (void*) my_buf;
506 region.page_count = 1;
507 desc.sender_id = own_id;
508 desc.memory_type = sp_memory_type_normal_memory;
509 desc.mem_region_attr.normal_memory.cacheability =
510 sp_cacheability_write_back;
511
512 desc.mem_region_attr.normal_memory.shareability =
513 sp_shareability_inner_shareable;
514
515 acc_desc[0].data_access = sp_data_access_read_write;
516 acc_desc[0].instruction_access = sp_instruction_access_not_executable;
517 acc_desc[0].receiver_id = endpoint2;
518
519 acc_desc[1].data_access = sp_data_access_read_write;
520 acc_desc[1].instruction_access = sp_instruction_access_not_executable;
521 acc_desc[1].receiver_id = endpoint3;
522
523 res = sp_memory_share(&desc, acc_desc, 2, &region, 1, &handle);
524 if (res != FFA_OK) {
525 EMSG("ffa_memory_share(): error %"PRId32, res);
526 err = (uint32_t)ERR_SP_SHARE;
527 goto err;
528 }
529 /* test SP2*/
Gabor Toth569309e2023-02-08 07:56:22 +0100530 res = ffa_msg_send_direct_req_64(own_id, endpoint2,
Jelle Sels03756662021-05-20 10:41:57 +0200531 EP_RETRIEVE, handle & 0xffffffff,
532 handle >> 32, own_id, 0, msg);
533
534 if (res != FFA_OK) {
535 EMSG("test_mem_multi_sharing(): error % in %s:%d"PRId32, res,
536 __FILE__,
537 __LINE__);
538 return_error((uint32_t)ERR_SP_SHARE, msg);
539 return;
540 }
541
Gabor Toth569309e2023-02-08 07:56:22 +0100542 res = ffa_msg_send_direct_req_64(own_id, endpoint2,
Jelle Sels03756662021-05-20 10:41:57 +0200543 EP_TRY_W_ACCESS, 0,
544 0, 0, 0, msg);
545
546 if (res != FFA_OK) {
547 EMSG("test_mem_multi_sharing(): error % in %s:%d"PRId32, res,
548 __FILE__,
549 __LINE__);
550 return_error((uint32_t)ERR_SP_SHARE, msg);
551 return;
552 }
553
554 if (my_buf[0] != 0xff) {
555 EMSG("SP2 didn't change the value of the buffer");
556 err = (uint32_t)ERR_SP_SHARE;
557 goto err;
558 }
559
Gabor Toth569309e2023-02-08 07:56:22 +0100560 res = ffa_msg_send_direct_req_64(own_id, endpoint2,
Jelle Sels03756662021-05-20 10:41:57 +0200561 EP_RELINQUISH, handle & 0xffffffff,
562 handle >> 32, 0, 0, msg);
563
564 if (res != FFA_OK) {
565 EMSG("test_mem_multi_sharing(): error % in %s:%d"PRId32, res,
566 __FILE__,
567 __LINE__);
568 return_error((uint32_t)ERR_SP_SHARE, msg);
569 return;
570 }
571 my_buf[0] = 0xa;
572 /* test SP3*/
Gabor Toth569309e2023-02-08 07:56:22 +0100573 res = ffa_msg_send_direct_req_64(own_id, endpoint3,
Jelle Sels03756662021-05-20 10:41:57 +0200574 EP_RETRIEVE, handle & 0xffffffff,
575 handle >> 32, own_id, 0, msg);
576
577 if (res != FFA_OK) {
578 EMSG("test_mem_multi_sharing(): error % in %s:%d"PRId32, res,
579 __FILE__,
580 __LINE__);
581 return_error((uint32_t)ERR_SP_SHARE, msg);
582 return;
583 }
584
Gabor Toth569309e2023-02-08 07:56:22 +0100585 res = ffa_msg_send_direct_req_64(own_id, endpoint3,
Jelle Sels03756662021-05-20 10:41:57 +0200586 EP_TRY_W_ACCESS, 0,
587 0, 0, 0, msg);
588
589 if (res != FFA_OK) {
590 EMSG("test_mem_multi_sharing(): error % in %s:%d"PRId32, res,
591 __FILE__,
592 __LINE__);
593 return_error((uint32_t)ERR_SP_SHARE, msg);
594 return;
595 }
596
597 if (my_buf[0] != 0xff) {
598 EMSG("SP3 didn't change the value of the buffer");
599 err = (uint32_t)ERR_SP_SHARE;
600 goto err;
601 }
602
603 if (ffa_mem_reclaim(handle, 0) == FFA_OK) {
604 EMSG("SP3 didn't relinquish memory yet!");
605 err = (uint32_t)ERR_SP_SHARE;
606 goto err;
607 }
608
Gabor Toth569309e2023-02-08 07:56:22 +0100609 res = ffa_msg_send_direct_req_64(own_id, endpoint3,
Jelle Sels03756662021-05-20 10:41:57 +0200610 EP_RELINQUISH, handle & 0xffffffff,
611 handle >> 32, 0, 0, msg);
612
613 if (res != FFA_OK) {
614 EMSG("test_mem_multi_sharing(): error % in %s:%d"PRId32, res,
615 __FILE__,
616 __LINE__);
617 return_error((uint32_t)ERR_SP_SHARE, msg);
618 return;
619 }
620
621 if (ffa_mem_reclaim(handle, 0) != FFA_OK) {
622 EMSG("All memory should have been relinquished!");
623 err = (uint32_t)ERR_SP_SHARE;
624 goto err;
625 }
626
627 msg->destination_id = own_id;
628 msg->source_id = src_id;
629 return_ok(msg);
630 return;
631err:
632 msg->destination_id = own_id;
633 msg->source_id = src_id;
634 return_error(err, msg);
635}
636
637static void test_mem_sharing_inccorrect_access(uint16_t service_ep_id,
638 struct ffa_direct_msg *msg)
639{
640 ffa_result res = FFA_OK;
641 struct sp_memory_descriptor desc = { 0 };
642 struct sp_memory_region region = { 0 };
643 uint64_t handle = 0;
644 struct ffa_mem_transaction_buffer t_buf = {0};
645 uint16_t own_id = 0;
646 uint16_t src_id = msg->source_id = 0;
647 struct sp_memory_access_descriptor acc_desc = { };
648
649 set_rxtx_buf(&t_buf, NULL);
650 ffa_id_get(&own_id);
651
652 region.address = (void*) my_buf;
653 region.page_count = 1;
654 desc.sender_id = own_id;
655 desc.memory_type = sp_memory_type_normal_memory;
656 desc.mem_region_attr.normal_memory.cacheability =
657 sp_cacheability_write_back;
658
659 desc.mem_region_attr.normal_memory.shareability =
660 sp_shareability_inner_shareable;
661
662 acc_desc.data_access = sp_data_access_read_write;
663 acc_desc.instruction_access = sp_instruction_access_executable;
664 acc_desc.receiver_id = service_ep_id;
665
666 res = sp_memory_share(&desc, &acc_desc, 1, &region, 1, &handle);
667 if (res == FFA_OK) {
668 EMSG("ffa_memory_share(): error %"PRId32, res);
669 return_error((uint32_t)ERR_SP_SHARE, msg);
670 return;
671 }
672
673 msg->destination_id = own_id;
674 msg->source_id = src_id;
675 return_ok(msg);
676}
677
678static void test_mem_sharing_exc(uint16_t service_ep_id,
679 struct ffa_direct_msg *msg)
680{
681 ffa_result res = FFA_OK;
682 struct sp_memory_descriptor desc = { 0 };
683 struct sp_memory_region region = { 0 };
684 uint64_t handle = 0;
685 uint64_t handle2 = 0;
686 struct ffa_mem_transaction_buffer t_buf = {0};
687 uint16_t own_id = 0;
688 uint16_t src_id = msg->source_id = 0;
689 struct sp_memory_access_descriptor acc_desc = { };
690 uint32_t err = 0;
691
692 set_rxtx_buf(&t_buf, NULL);
693 ffa_id_get(&own_id);
694
695 region.address = (void*) my_buf;
696 region.page_count = 1;
697 desc.sender_id = own_id;
698 desc.memory_type = sp_memory_type_normal_memory;
699 desc.mem_region_attr.normal_memory.cacheability =
700 sp_cacheability_write_back;
701
702 desc.mem_region_attr.normal_memory.shareability =
703 sp_shareability_inner_shareable;
704
705 acc_desc.data_access = sp_data_access_read_write;
706 acc_desc.instruction_access = sp_instruction_access_not_executable;
707 acc_desc.receiver_id = service_ep_id;
708
709 res = sp_memory_share(&desc, &acc_desc, 1, &region, 1, &handle);
710 if (res != FFA_OK) {
711 EMSG("test_mem_sharing_exc(): error %"PRId32, res);
712 err = (uint32_t)ERR_SP_SHARE_EXC;
713 goto err;
714 }
715
716 /*
717 * Try it again, it should fail as we don't have acclusive access
718 * anymore
719 */
720 res = sp_memory_share(&desc, &acc_desc, 1, &region, 1, &handle2);
721 if (res == FFA_OK) {
722 EMSG("test_mem_sharing_exc(): error %"PRId32, res);
723 err = (uint32_t)ERR_SP_SHARE_EXC;
724 goto err;
725 }
726
727 res = ffa_mem_reclaim(handle, 0);
728
729 if (res != FFA_OK) {
730 EMSG("ffa_memory_share(): error % in %s:%d"PRId32, res,
731 __FILE__,
732 __LINE__);
733 return_error((uint32_t)ERR_SP_SHARE, msg);
734 return;
735 }
736
737 msg->destination_id = own_id;
738 msg->source_id = src_id;
739 return_ok(msg);
740 return;
741err:
742 msg->destination_id = own_id;
743 msg->source_id = src_id;
744 return_error(err, msg);
745}
746
747void __noreturn sp_main(struct ffa_init_info *init_info) {
748 struct ffa_direct_msg msg = {0};
749 uint16_t own_id = 0;
750
751 /* Boot phase */
752 if (sp_discovery_own_id_get(&own_id) != SP_RESULT_OK) {
753 EMSG("Couldn't get own_id!!");
754 }
755
756 test_ffa_rxtx_map();
757 /* End of boot phase */
758 ffa_msg_wait(&msg);
759
760 while (1) {
Gabor Toth569309e2023-02-08 07:56:22 +0100761 enum sp_tests test_case = (enum sp_tests)msg.args.args64[0];
Jelle Sels03756662021-05-20 10:41:57 +0200762
763 DMSG("SP:%x Starting test %s", own_id, sp_test_str[test_case]);
764 switch (test_case) {
765 case EP_TEST_SP:
766 test_internal_sp(&msg);
767 break;
768 case EP_TEST_SP_COMMUNICATION:
769 test_communication(&msg);
770 break;
771 case EP_TEST_SP_INCREASE:
772 test_increase(&msg);
773 break;
774 case EP_TRY_R_ACCESS:
775 test_read_access();
776 return_ok(&msg);
777 break;
778 case EP_TRY_W_ACCESS:
779 test_write_access();
780 return_ok(&msg);
781 break;
782 case EP_RETRIEVE:
783 test_mem_retrieve(&msg);
784 break;
785 case EP_RELINQUISH:
786 test_mem_relinquish(&msg);
787 break;
788 case EP_SP_MEM_SHARING:
Gabor Toth569309e2023-02-08 07:56:22 +0100789 test_mem_sharing((uint16_t)msg.args.args64[1], &msg);
Jelle Sels03756662021-05-20 10:41:57 +0200790 break;
791 case EP_SP_MEM_SHARING_MULTI:
792 test_mem_multi_sharing(&msg);
793 break;
794 case EP_SP_MEM_SHARING_EXC:
Gabor Toth569309e2023-02-08 07:56:22 +0100795 test_mem_sharing_exc((uint16_t)msg.args.args64[1],
Jelle Sels45353ba2022-09-30 14:47:56 +0200796 &msg);
Jelle Sels03756662021-05-20 10:41:57 +0200797 break;
798 case EP_SP_MEM_INCORRECT_ACCESS:
799 test_mem_sharing_inccorrect_access(
Gabor Toth569309e2023-02-08 07:56:22 +0100800 (uint16_t)msg.args.args64[1], &msg);
Jelle Sels03756662021-05-20 10:41:57 +0200801 break;
802 case EP_SP_NOP:
803 return_ok(&msg);
804 break;
805
806 default:
807 return_error((uint32_t)ERR_TEST_NOT_FOUND, &msg);
808 break;
809 }
810 }
811}
812
813void sp_interrupt_handler(uint32_t interrupt_id)
814{
815 (void)interrupt_id;
816 DMSG("Got interrupt %x", interrupt_id);
817}