blob: fa9c7eabbf865418b184252ed1336fc4598235bf [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 {
Jelle Sels45353ba2022-09-30 14:47:56 +0200284 DMSG("Failed SP communication %x %x %x %x",
Gabor Toth569309e2023-02-08 07:56:22 +0100285 sp_msg.args.args64[1],
286 sp_msg.args.args64[2], sp_msg.args.args64[3],
287 sp_msg.args.args64[4]);
Jelle Sels03756662021-05-20 10:41:57 +0200288
289 return_error(ERR_SP_COMMUNICATION, msg);
290 }
291}
292
293static void test_internal_sp(struct ffa_direct_msg *msg)
294{
295 enum errors err = ERR_OK;
296 uint16_t id = 0;
297
298 if (test_ffa_version()) {
299 if (!test_ffa_id_get(&id))
300 err = ERR_ID_GET;
301
302 if (!err && !test_ffa_features())
303 err = ERR_VERSION;
304
305 if (!err && !test_ffa_rxtx_unmap(id))
306 err = ERR_RXTX_UNMAP;
307
308 if (!err && !test_ffa_rxtx_map())
309 err = ERR_RXTX_MAP;
310
311 if (!err && !test_ffa_partition_info_get())
312 err = ERR_PARTITION;
313
314 } else {
315 err = ERR_VERSION;
316 }
317
318 if (err != ERR_OK) {
319 DMSG("Failed at SP test %x", err);
320 return_error((uint32_t)err, msg);
321 }
322
323 return_ok(msg);
324}
325
326static void set_rxtx_buf(struct ffa_mem_transaction_buffer *t_buf,
327 struct ffa_mem_transaction_buffer *r_buf)
328{
329 if (t_buf) {
330 t_buf->buffer = (void*)tx_buffer;
331 t_buf->length = 4096;
332 t_buf->used = false;
333 }
334 if (r_buf) {
335 r_buf->buffer = (void*)rx_buffer;
336 r_buf->length = 4096;
337 r_buf->used = false;
338 }
339}
340
341static void test_mem_retrieve(struct ffa_direct_msg *msg)
342{
343 ffa_result res = FFA_OK;
344 struct sp_memory_descriptor descriptor = {0};
345 struct sp_memory_region regions[1] = {0};
346 struct sp_memory_access_descriptor acc_desc = {0};
347 uint64_t handle = 0;
348 uint32_t out_region_count = 1;
349 uint16_t own_id = 0;
350
351 ffa_id_get(&own_id);
352
Gabor Toth569309e2023-02-08 07:56:22 +0100353 handle = (uint64_t)msg->args.args64[1] |
354 (((uint64_t)msg->args.args64[2]) << 32);
Jelle Sels03756662021-05-20 10:41:57 +0200355 descriptor.tag = 0;
Gabor Toth569309e2023-02-08 07:56:22 +0100356 descriptor.sender_id = msg->args.args64[3] & 0xffff;
Jelle Sels03756662021-05-20 10:41:57 +0200357 acc_desc.receiver_id = own_id;
358 acc_desc.data_access = sp_data_access_read_write;
359 res = sp_memory_retrieve(&descriptor, &acc_desc, regions, 1,
360 &out_region_count, handle);
361
362 if (res) {
363 DMSG("Failed retrieving me share");
364 return_error((uint32_t)ERR_MEM_RETRIEVE, msg);
365 return;
366 }
367
368 shared_buffer = regions[0].address;
369 shared_buffer_size = regions[0].page_count * 4096;
370
371 return_ok(msg);
372}
373
374static void test_mem_relinquish(struct ffa_direct_msg *msg)
375{
376 ffa_result res = FFA_OK;
377 struct sp_memory_descriptor descriptor = {0};
378 uint64_t handle = 0;
379 uint16_t endpoint_id = 0;
380 struct sp_memory_transaction_flags flags = {
381 .zero_memory = false,
382 .operation_time_slicing = false,
383 };
384
Gabor Toth569309e2023-02-08 07:56:22 +0100385 if (msg->args.args64[3] == 1)
Jelle Sels03756662021-05-20 10:41:57 +0200386 flags.zero_memory = true;
387
388 ffa_id_get(&endpoint_id);
Gabor Toth569309e2023-02-08 07:56:22 +0100389 handle = (uint64_t)msg->args.args64[1] |
390 (((uint64_t)msg->args.args64[2]) << 32);
Jelle Sels03756662021-05-20 10:41:57 +0200391 descriptor.tag = 0;
392
393 res = sp_memory_relinquish(handle, &endpoint_id, 1, &flags);
394 if (res) {
395 DMSG("Failed to relinquish share");
396 return_error((uint32_t)ERR_MEM_RELINQUISH, msg);
397 }
398
399 return_ok(msg);
400}
401
402static void test_mem_sharing(uint16_t service_ep_id, struct ffa_direct_msg *msg)
403{
404 ffa_result res = FFA_OK;
405 struct sp_memory_descriptor desc = { 0 };
406 struct sp_memory_region region = { 0 };
407 uint64_t handle = 0;
408 struct ffa_mem_transaction_buffer t_buf = {0};
409 uint16_t own_id = 0;
410 uint16_t src_id = msg->source_id;
411 struct sp_memory_access_descriptor acc_desc = { };
412
413 my_buf[0] = 0xa;
414 set_rxtx_buf(&t_buf, NULL);
415 ffa_id_get(&own_id);
416
417 region.address = (void*) my_buf;
418 region.page_count = 1;
419 desc.sender_id = own_id;
420 desc.memory_type = sp_memory_type_normal_memory;
421 desc.mem_region_attr.normal_memory.cacheability =
422 sp_cacheability_write_back;
423
424 desc.mem_region_attr.normal_memory.shareability =
425 sp_shareability_inner_shareable;
426
427 acc_desc.data_access = sp_data_access_read_write;
428 acc_desc.instruction_access = sp_instruction_access_not_executable;
429 acc_desc.receiver_id = service_ep_id;
430
431 res = sp_memory_share(&desc, &acc_desc, 1, &region, 1, &handle);
432 if (res != FFA_OK) {
433 EMSG("test_mem_sharing(): error % in %s:%d"PRId32, res,
434 __FILE__,
435 __LINE__);
436 return_error((uint32_t)ERR_SP_SHARE, msg);
437 return;
438 }
439
Gabor Toth569309e2023-02-08 07:56:22 +0100440 res = ffa_msg_send_direct_req_64(own_id, service_ep_id,
Jelle Sels03756662021-05-20 10:41:57 +0200441 EP_RETRIEVE, handle & 0xffffffff,
442 handle >> 32, own_id, 0, msg);
443
444 if (res != FFA_OK) {
445 EMSG("test_mem_sharing(): error % in %s:%d"PRId32, res,
446 __FILE__,
447 __LINE__);
448 return_error((uint32_t)ERR_SP_SHARE, msg);
449 return;
450 }
451
Gabor Toth569309e2023-02-08 07:56:22 +0100452 res = ffa_msg_send_direct_req_64(own_id, service_ep_id,
Jelle Sels03756662021-05-20 10:41:57 +0200453 EP_TRY_W_ACCESS, 0,
454 0, 0, 0, msg);
455
456 if (res != FFA_OK) {
457 EMSG("test_mem_sharing(): error % in %s:%d"PRId32, res,
458 __FILE__,
459 __LINE__);
460 return_error((uint32_t)ERR_SP_SHARE, msg);
461 return;
462 }
463
Gabor Toth569309e2023-02-08 07:56:22 +0100464 res = ffa_msg_send_direct_req_64(own_id, service_ep_id,
Jelle Sels03756662021-05-20 10:41:57 +0200465 EP_RELINQUISH, handle & 0xffffffff,
466 handle >> 32, 0, 0, msg);
467 if (res != FFA_OK) {
468 EMSG("test_mem_sharing(): error % in %s:%d"PRId32, res,
469 __FILE__,
470 __LINE__);
471 return_error((uint32_t)ERR_SP_SHARE, msg);
472 return;
473 }
474
475 res = ffa_mem_reclaim(handle, 0);
476
477 if (res != FFA_OK) {
478 EMSG("test_mem_sharing(): error % in %s:%d"PRId32, res,
479 __FILE__,
480 __LINE__);
481 return_error((uint32_t)ERR_SP_SHARE, msg);
482 return;
483 }
484 msg->destination_id = own_id;
485 msg->source_id = src_id;
486
487 return_ok(msg);
488}
489
490static void test_mem_multi_sharing(struct ffa_direct_msg *msg)
491{
492 ffa_result res = FFA_OK;
493 struct sp_memory_descriptor desc = { 0 };
494 struct sp_memory_region region = { 0 };
495 uint64_t handle = 0;
496 struct ffa_mem_transaction_buffer t_buf = {0};
497 uint16_t own_id = 0;
498 uint16_t src_id = msg->source_id = 0;
499 struct sp_memory_access_descriptor acc_desc[2] = { };
500 uint32_t err = 0;
Gabor Toth569309e2023-02-08 07:56:22 +0100501 uint16_t endpoint2 = msg->args.args64[1];
502 uint16_t endpoint3 = msg->args.args64[2];
Jelle Sels03756662021-05-20 10:41:57 +0200503
504 my_buf[0] = 0xa;
505 set_rxtx_buf(&t_buf, NULL);
506 ffa_id_get(&own_id);
507
508 region.address = (void*) my_buf;
509 region.page_count = 1;
510 desc.sender_id = own_id;
511 desc.memory_type = sp_memory_type_normal_memory;
512 desc.mem_region_attr.normal_memory.cacheability =
513 sp_cacheability_write_back;
514
515 desc.mem_region_attr.normal_memory.shareability =
516 sp_shareability_inner_shareable;
517
518 acc_desc[0].data_access = sp_data_access_read_write;
519 acc_desc[0].instruction_access = sp_instruction_access_not_executable;
520 acc_desc[0].receiver_id = endpoint2;
521
522 acc_desc[1].data_access = sp_data_access_read_write;
523 acc_desc[1].instruction_access = sp_instruction_access_not_executable;
524 acc_desc[1].receiver_id = endpoint3;
525
526 res = sp_memory_share(&desc, acc_desc, 2, &region, 1, &handle);
527 if (res != FFA_OK) {
528 EMSG("ffa_memory_share(): error %"PRId32, res);
529 err = (uint32_t)ERR_SP_SHARE;
530 goto err;
531 }
532 /* test SP2*/
Gabor Toth569309e2023-02-08 07:56:22 +0100533 res = ffa_msg_send_direct_req_64(own_id, endpoint2,
Jelle Sels03756662021-05-20 10:41:57 +0200534 EP_RETRIEVE, handle & 0xffffffff,
535 handle >> 32, own_id, 0, msg);
536
537 if (res != FFA_OK) {
538 EMSG("test_mem_multi_sharing(): error % in %s:%d"PRId32, res,
539 __FILE__,
540 __LINE__);
541 return_error((uint32_t)ERR_SP_SHARE, msg);
542 return;
543 }
544
Gabor Toth569309e2023-02-08 07:56:22 +0100545 res = ffa_msg_send_direct_req_64(own_id, endpoint2,
Jelle Sels03756662021-05-20 10:41:57 +0200546 EP_TRY_W_ACCESS, 0,
547 0, 0, 0, msg);
548
549 if (res != FFA_OK) {
550 EMSG("test_mem_multi_sharing(): error % in %s:%d"PRId32, res,
551 __FILE__,
552 __LINE__);
553 return_error((uint32_t)ERR_SP_SHARE, msg);
554 return;
555 }
556
557 if (my_buf[0] != 0xff) {
558 EMSG("SP2 didn't change the value of the buffer");
559 err = (uint32_t)ERR_SP_SHARE;
560 goto err;
561 }
562
Gabor Toth569309e2023-02-08 07:56:22 +0100563 res = ffa_msg_send_direct_req_64(own_id, endpoint2,
Jelle Sels03756662021-05-20 10:41:57 +0200564 EP_RELINQUISH, handle & 0xffffffff,
565 handle >> 32, 0, 0, msg);
566
567 if (res != FFA_OK) {
568 EMSG("test_mem_multi_sharing(): error % in %s:%d"PRId32, res,
569 __FILE__,
570 __LINE__);
571 return_error((uint32_t)ERR_SP_SHARE, msg);
572 return;
573 }
574 my_buf[0] = 0xa;
575 /* test SP3*/
Gabor Toth569309e2023-02-08 07:56:22 +0100576 res = ffa_msg_send_direct_req_64(own_id, endpoint3,
Jelle Sels03756662021-05-20 10:41:57 +0200577 EP_RETRIEVE, handle & 0xffffffff,
578 handle >> 32, own_id, 0, msg);
579
580 if (res != FFA_OK) {
581 EMSG("test_mem_multi_sharing(): error % in %s:%d"PRId32, res,
582 __FILE__,
583 __LINE__);
584 return_error((uint32_t)ERR_SP_SHARE, msg);
585 return;
586 }
587
Gabor Toth569309e2023-02-08 07:56:22 +0100588 res = ffa_msg_send_direct_req_64(own_id, endpoint3,
Jelle Sels03756662021-05-20 10:41:57 +0200589 EP_TRY_W_ACCESS, 0,
590 0, 0, 0, msg);
591
592 if (res != FFA_OK) {
593 EMSG("test_mem_multi_sharing(): error % in %s:%d"PRId32, res,
594 __FILE__,
595 __LINE__);
596 return_error((uint32_t)ERR_SP_SHARE, msg);
597 return;
598 }
599
600 if (my_buf[0] != 0xff) {
601 EMSG("SP3 didn't change the value of the buffer");
602 err = (uint32_t)ERR_SP_SHARE;
603 goto err;
604 }
605
606 if (ffa_mem_reclaim(handle, 0) == FFA_OK) {
607 EMSG("SP3 didn't relinquish memory yet!");
608 err = (uint32_t)ERR_SP_SHARE;
609 goto err;
610 }
611
Gabor Toth569309e2023-02-08 07:56:22 +0100612 res = ffa_msg_send_direct_req_64(own_id, endpoint3,
Jelle Sels03756662021-05-20 10:41:57 +0200613 EP_RELINQUISH, handle & 0xffffffff,
614 handle >> 32, 0, 0, msg);
615
616 if (res != FFA_OK) {
617 EMSG("test_mem_multi_sharing(): error % in %s:%d"PRId32, res,
618 __FILE__,
619 __LINE__);
620 return_error((uint32_t)ERR_SP_SHARE, msg);
621 return;
622 }
623
624 if (ffa_mem_reclaim(handle, 0) != FFA_OK) {
625 EMSG("All memory should have been relinquished!");
626 err = (uint32_t)ERR_SP_SHARE;
627 goto err;
628 }
629
630 msg->destination_id = own_id;
631 msg->source_id = src_id;
632 return_ok(msg);
633 return;
634err:
635 msg->destination_id = own_id;
636 msg->source_id = src_id;
637 return_error(err, msg);
638}
639
640static void test_mem_sharing_inccorrect_access(uint16_t service_ep_id,
641 struct ffa_direct_msg *msg)
642{
643 ffa_result res = FFA_OK;
644 struct sp_memory_descriptor desc = { 0 };
645 struct sp_memory_region region = { 0 };
646 uint64_t handle = 0;
647 struct ffa_mem_transaction_buffer t_buf = {0};
648 uint16_t own_id = 0;
649 uint16_t src_id = msg->source_id = 0;
650 struct sp_memory_access_descriptor acc_desc = { };
651
652 set_rxtx_buf(&t_buf, NULL);
653 ffa_id_get(&own_id);
654
655 region.address = (void*) my_buf;
656 region.page_count = 1;
657 desc.sender_id = own_id;
658 desc.memory_type = sp_memory_type_normal_memory;
659 desc.mem_region_attr.normal_memory.cacheability =
660 sp_cacheability_write_back;
661
662 desc.mem_region_attr.normal_memory.shareability =
663 sp_shareability_inner_shareable;
664
665 acc_desc.data_access = sp_data_access_read_write;
666 acc_desc.instruction_access = sp_instruction_access_executable;
667 acc_desc.receiver_id = service_ep_id;
668
669 res = sp_memory_share(&desc, &acc_desc, 1, &region, 1, &handle);
670 if (res == FFA_OK) {
671 EMSG("ffa_memory_share(): error %"PRId32, res);
672 return_error((uint32_t)ERR_SP_SHARE, msg);
673 return;
674 }
675
676 msg->destination_id = own_id;
677 msg->source_id = src_id;
678 return_ok(msg);
679}
680
681static void test_mem_sharing_exc(uint16_t service_ep_id,
682 struct ffa_direct_msg *msg)
683{
684 ffa_result res = FFA_OK;
685 struct sp_memory_descriptor desc = { 0 };
686 struct sp_memory_region region = { 0 };
687 uint64_t handle = 0;
688 uint64_t handle2 = 0;
689 struct ffa_mem_transaction_buffer t_buf = {0};
690 uint16_t own_id = 0;
691 uint16_t src_id = msg->source_id = 0;
692 struct sp_memory_access_descriptor acc_desc = { };
693 uint32_t err = 0;
694
695 set_rxtx_buf(&t_buf, NULL);
696 ffa_id_get(&own_id);
697
698 region.address = (void*) my_buf;
699 region.page_count = 1;
700 desc.sender_id = own_id;
701 desc.memory_type = sp_memory_type_normal_memory;
702 desc.mem_region_attr.normal_memory.cacheability =
703 sp_cacheability_write_back;
704
705 desc.mem_region_attr.normal_memory.shareability =
706 sp_shareability_inner_shareable;
707
708 acc_desc.data_access = sp_data_access_read_write;
709 acc_desc.instruction_access = sp_instruction_access_not_executable;
710 acc_desc.receiver_id = service_ep_id;
711
712 res = sp_memory_share(&desc, &acc_desc, 1, &region, 1, &handle);
713 if (res != FFA_OK) {
714 EMSG("test_mem_sharing_exc(): error %"PRId32, res);
715 err = (uint32_t)ERR_SP_SHARE_EXC;
716 goto err;
717 }
718
719 /*
720 * Try it again, it should fail as we don't have acclusive access
721 * anymore
722 */
723 res = sp_memory_share(&desc, &acc_desc, 1, &region, 1, &handle2);
724 if (res == FFA_OK) {
725 EMSG("test_mem_sharing_exc(): error %"PRId32, res);
726 err = (uint32_t)ERR_SP_SHARE_EXC;
727 goto err;
728 }
729
730 res = ffa_mem_reclaim(handle, 0);
731
732 if (res != FFA_OK) {
733 EMSG("ffa_memory_share(): error % in %s:%d"PRId32, res,
734 __FILE__,
735 __LINE__);
736 return_error((uint32_t)ERR_SP_SHARE, msg);
737 return;
738 }
739
740 msg->destination_id = own_id;
741 msg->source_id = src_id;
742 return_ok(msg);
743 return;
744err:
745 msg->destination_id = own_id;
746 msg->source_id = src_id;
747 return_error(err, msg);
748}
749
750void __noreturn sp_main(struct ffa_init_info *init_info) {
751 struct ffa_direct_msg msg = {0};
752 uint16_t own_id = 0;
753
754 /* Boot phase */
755 if (sp_discovery_own_id_get(&own_id) != SP_RESULT_OK) {
756 EMSG("Couldn't get own_id!!");
757 }
758
759 test_ffa_rxtx_map();
760 /* End of boot phase */
761 ffa_msg_wait(&msg);
762
763 while (1) {
Gabor Toth569309e2023-02-08 07:56:22 +0100764 enum sp_tests test_case = (enum sp_tests)msg.args.args64[0];
Jelle Sels03756662021-05-20 10:41:57 +0200765
766 DMSG("SP:%x Starting test %s", own_id, sp_test_str[test_case]);
767 switch (test_case) {
768 case EP_TEST_SP:
769 test_internal_sp(&msg);
770 break;
771 case EP_TEST_SP_COMMUNICATION:
772 test_communication(&msg);
773 break;
774 case EP_TEST_SP_INCREASE:
775 test_increase(&msg);
776 break;
777 case EP_TRY_R_ACCESS:
778 test_read_access();
779 return_ok(&msg);
780 break;
781 case EP_TRY_W_ACCESS:
782 test_write_access();
783 return_ok(&msg);
784 break;
785 case EP_RETRIEVE:
786 test_mem_retrieve(&msg);
787 break;
788 case EP_RELINQUISH:
789 test_mem_relinquish(&msg);
790 break;
791 case EP_SP_MEM_SHARING:
Gabor Toth569309e2023-02-08 07:56:22 +0100792 test_mem_sharing((uint16_t)msg.args.args64[1], &msg);
Jelle Sels03756662021-05-20 10:41:57 +0200793 break;
794 case EP_SP_MEM_SHARING_MULTI:
795 test_mem_multi_sharing(&msg);
796 break;
797 case EP_SP_MEM_SHARING_EXC:
Gabor Toth569309e2023-02-08 07:56:22 +0100798 test_mem_sharing_exc((uint16_t)msg.args.args64[1],
Jelle Sels45353ba2022-09-30 14:47:56 +0200799 &msg);
Jelle Sels03756662021-05-20 10:41:57 +0200800 break;
801 case EP_SP_MEM_INCORRECT_ACCESS:
802 test_mem_sharing_inccorrect_access(
Gabor Toth569309e2023-02-08 07:56:22 +0100803 (uint16_t)msg.args.args64[1], &msg);
Jelle Sels03756662021-05-20 10:41:57 +0200804 break;
805 case EP_SP_NOP:
806 return_ok(&msg);
807 break;
808
809 default:
810 return_error((uint32_t)ERR_TEST_NOT_FOUND, &msg);
811 break;
812 }
813 }
814}
815
816void sp_interrupt_handler(uint32_t interrupt_id)
817{
818 (void)interrupt_id;
819 DMSG("Got interrupt %x", interrupt_id);
820}