blob: ffa9d81fa74409fde17148a8922c8d476fa163be [file] [log] [blame]
Abdellatif El Khlifi2f403d12023-08-04 14:33:40 +01001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright 2022-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
4 *
5 * Authors:
6 * Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
7 */
8#include <common.h>
9#include <arm_ffa.h>
10#include <arm_ffa_priv.h>
11#include <dm.h>
12#include <log.h>
13#include <malloc.h>
14#include <string.h>
15#include <uuid.h>
16#include <asm/global_data.h>
17#include <dm/device-internal.h>
18#include <dm/devres.h>
19#include <dm/root.h>
20#include <linux/errno.h>
21#include <linux/sizes.h>
22
23DECLARE_GLOBAL_DATA_PTR;
24
25/* Error mapping declarations */
26
27int ffa_to_std_errmap[MAX_NUMBER_FFA_ERR] = {
28 [NOT_SUPPORTED] = -EOPNOTSUPP,
29 [INVALID_PARAMETERS] = -EINVAL,
30 [NO_MEMORY] = -ENOMEM,
31 [BUSY] = -EBUSY,
32 [INTERRUPTED] = -EINTR,
33 [DENIED] = -EACCES,
34 [RETRY] = -EAGAIN,
35 [ABORTED] = -ECANCELED,
36};
37
38static struct ffa_abi_errmap err_msg_map[FFA_ERRMAP_COUNT] = {
39 [FFA_ID_TO_ERRMAP_ID(FFA_VERSION)] = {
40 {
41 [NOT_SUPPORTED] =
42 "NOT_SUPPORTED: A Firmware Framework implementation does not exist",
43 },
44 },
45 [FFA_ID_TO_ERRMAP_ID(FFA_ID_GET)] = {
46 {
47 [NOT_SUPPORTED] =
48 "NOT_SUPPORTED: This function is not implemented at this FF-A instance",
49 },
50 },
51 [FFA_ID_TO_ERRMAP_ID(FFA_FEATURES)] = {
52 {
53 [NOT_SUPPORTED] =
54 "NOT_SUPPORTED: FFA_RXTX_MAP is not implemented at this FF-A instance",
55 },
56 },
57 [FFA_ID_TO_ERRMAP_ID(FFA_PARTITION_INFO_GET)] = {
58 {
59 [NOT_SUPPORTED] =
60 "NOT_SUPPORTED: This function is not implemented at this FF-A instance",
61 [INVALID_PARAMETERS] =
62 "INVALID_PARAMETERS: Unrecognized UUID",
63 [NO_MEMORY] =
64 "NO_MEMORY: Results cannot fit in RX buffer of the caller",
65 [BUSY] =
66 "BUSY: RX buffer of the caller is not free",
67 [DENIED] =
68 "DENIED: Callee is not in a state to handle this request",
69 },
70 },
71 [FFA_ID_TO_ERRMAP_ID(FFA_RXTX_UNMAP)] = {
72 {
73 [NOT_SUPPORTED] =
74 "NOT_SUPPORTED: FFA_RXTX_UNMAP is not implemented at this FF-A instance",
75 [INVALID_PARAMETERS] =
76 "INVALID_PARAMETERS: No buffer pair registered on behalf of the caller",
77 },
78 },
79 [FFA_ID_TO_ERRMAP_ID(FFA_RX_RELEASE)] = {
80 {
81 [NOT_SUPPORTED] =
82 "NOT_SUPPORTED: FFA_RX_RELEASE is not implemented at this FF-A instance",
83 [DENIED] =
84 "DENIED: Caller did not have ownership of the RX buffer",
85 },
86 },
87 [FFA_ID_TO_ERRMAP_ID(FFA_RXTX_MAP)] = {
88 {
89 [NOT_SUPPORTED] =
90 "NOT_SUPPORTED: This function is not implemented at this FF-A instance",
91 [INVALID_PARAMETERS] =
92 "INVALID_PARAMETERS: Field(s) in input parameters incorrectly encoded",
93 [NO_MEMORY] =
94 "NO_MEMORY: Not enough memory",
95 [DENIED] =
96 "DENIED: Buffer pair already registered",
97 },
98 },
99};
100
101/**
102 * ffa_to_std_errno() - convert FF-A error code to standard error code
103 * @ffa_errno: Error code returned by the FF-A ABI
104 *
105 * Map the given FF-A error code as specified
106 * by the spec to a u-boot standard error code.
107 *
108 * Return:
109 *
110 * The standard error code on success. . Otherwise, failure
111 */
112static int ffa_to_std_errno(int ffa_errno)
113{
114 int err_idx = -ffa_errno;
115
116 /* Map the FF-A error code to the standard u-boot error code */
117 if (err_idx > 0 && err_idx < MAX_NUMBER_FFA_ERR)
118 return ffa_to_std_errmap[err_idx];
119 return -EINVAL;
120}
121
122/**
123 * ffa_print_error_log() - print the error log corresponding to the selected FF-A ABI
124 * @ffa_id: FF-A ABI ID
125 * @ffa_errno: Error code returned by the FF-A ABI
126 *
127 * Map the FF-A error code to the error log relevant to the
128 * selected FF-A ABI. Then the error log is printed.
129 *
130 * Return:
131 *
132 * 0 on success. . Otherwise, failure
133 */
134static int ffa_print_error_log(u32 ffa_id, int ffa_errno)
135{
136 int err_idx = -ffa_errno, abi_idx = 0;
137
138 /* Map the FF-A error code to the corresponding error log */
139
140 if (err_idx <= 0 || err_idx >= MAX_NUMBER_FFA_ERR)
141 return -EINVAL;
142
143 if (ffa_id < FFA_FIRST_ID || ffa_id > FFA_LAST_ID)
144 return -EINVAL;
145
146 abi_idx = FFA_ID_TO_ERRMAP_ID(ffa_id);
147 if (abi_idx < 0 || abi_idx >= FFA_ERRMAP_COUNT)
148 return -EINVAL;
149
150 if (!err_msg_map[abi_idx].err_str[err_idx])
151 return -EINVAL;
152
153 log_err("%s\n", err_msg_map[abi_idx].err_str[err_idx]);
154
155 return 0;
156}
157
158/* FF-A ABIs implementation (U-Boot side) */
159
160/**
161 * invoke_ffa_fn() - SMC wrapper
162 * @args: FF-A ABI arguments to be copied to Xn registers
163 * @res: FF-A ABI return data to be copied from Xn registers
164 *
165 * Calls low level SMC implementation.
166 * This function should be implemented by the user driver.
167 */
168void __weak invoke_ffa_fn(ffa_value_t args, ffa_value_t *res)
169{
170}
171
172/**
173 * ffa_get_version_hdlr() - FFA_VERSION handler function
174 * @dev: The FF-A bus device
175 *
176 * Implement FFA_VERSION FF-A function
177 * to get from the secure world the FF-A framework version
178 * FFA_VERSION is used to discover the FF-A framework.
179 *
180 * Return:
181 *
182 * 0 on success. Otherwise, failure
183 */
184int ffa_get_version_hdlr(struct udevice *dev)
185{
186 u16 major, minor;
187 ffa_value_t res = {0};
188 int ffa_errno;
189 struct ffa_priv *uc_priv;
190
191 invoke_ffa_fn((ffa_value_t){
192 .a0 = FFA_SMC_32(FFA_VERSION), .a1 = FFA_VERSION_1_0,
193 }, &res);
194
195 ffa_errno = res.a0;
196 if (ffa_errno < 0) {
197 ffa_print_error_log(FFA_VERSION, ffa_errno);
198 return ffa_to_std_errno(ffa_errno);
199 }
200
201 major = GET_FFA_MAJOR_VERSION(res.a0);
202 minor = GET_FFA_MINOR_VERSION(res.a0);
203
204 log_info("FF-A driver %d.%d\nFF-A framework %d.%d\n",
205 FFA_MAJOR_VERSION, FFA_MINOR_VERSION, major, minor);
206
207 if (major == FFA_MAJOR_VERSION && minor >= FFA_MINOR_VERSION) {
208 log_info("FF-A versions are compatible\n");
209
210 if (dev) {
211 uc_priv = dev_get_uclass_priv(dev);
212 if (uc_priv)
213 uc_priv->fwk_version = res.a0;
214 }
215
216 return 0;
217 }
218
219 log_err("versions are incompatible\nExpected: %d.%d , Found: %d.%d\n",
220 FFA_MAJOR_VERSION, FFA_MINOR_VERSION, major, minor);
221
222 return -EPROTONOSUPPORT;
223}
224
225/**
226 * ffa_get_endpoint_id() - FFA_ID_GET handler function
227 * @dev: The FF-A bus device
228 *
229 * Implement FFA_ID_GET FF-A function
230 * to get from the secure world u-boot endpoint ID
231 *
232 * Return:
233 *
234 * 0 on success. Otherwise, failure
235 */
236static int ffa_get_endpoint_id(struct udevice *dev)
237{
238 ffa_value_t res = {0};
239 int ffa_errno;
240 struct ffa_priv *uc_priv = dev_get_uclass_priv(dev);
241
242 invoke_ffa_fn((ffa_value_t){
243 .a0 = FFA_SMC_32(FFA_ID_GET),
244 }, &res);
245
246 if (res.a0 == FFA_SMC_32(FFA_SUCCESS)) {
247 uc_priv->id = GET_SELF_ENDPOINT_ID((u32)res.a2);
248 log_debug("FF-A endpoint ID is %u\n", uc_priv->id);
249
250 return 0;
251 }
252
253 ffa_errno = res.a2;
254
255 ffa_print_error_log(FFA_ID_GET, ffa_errno);
256
257 return ffa_to_std_errno(ffa_errno);
258}
259
260/**
261 * ffa_set_rxtx_buffers_pages_cnt() - set the minimum number of pages in each of the RX/TX buffers
262 * @dev: The FF-A bus device
263 * @prop_field: properties field obtained from FFA_FEATURES ABI
264 *
265 * Set the minimum number of pages in each of the RX/TX buffers in uc_priv
266 *
267 * Return:
268 *
269 * rxtx_min_pages field contains the returned number of pages
270 * 0 on success. Otherwise, failure
271 */
272static int ffa_set_rxtx_buffers_pages_cnt(struct udevice *dev, u32 prop_field)
273{
274 struct ffa_priv *uc_priv = dev_get_uclass_priv(dev);
275
276 switch (prop_field) {
277 case RXTX_4K:
278 uc_priv->pair.rxtx_min_pages = 1;
279 break;
280 case RXTX_16K:
281 uc_priv->pair.rxtx_min_pages = 4;
282 break;
283 case RXTX_64K:
284 uc_priv->pair.rxtx_min_pages = 16;
285 break;
286 default:
287 log_err("RX/TX buffer size not supported\n");
288 return -EINVAL;
289 }
290
291 return 0;
292}
293
294/**
295 * ffa_get_rxtx_map_features_hdlr() - FFA_FEATURES handler function with FFA_RXTX_MAP argument
296 * @dev: The FF-A bus device
297 *
298 * Implement FFA_FEATURES FF-A function to retrieve the FFA_RXTX_MAP features
299 *
300 * Return:
301 *
302 * 0 on success. Otherwise, failure
303 */
304static int ffa_get_rxtx_map_features_hdlr(struct udevice *dev)
305{
306 ffa_value_t res = {0};
307 int ffa_errno;
308
309 invoke_ffa_fn((ffa_value_t){
310 .a0 = FFA_SMC_32(FFA_FEATURES),
311 .a1 = FFA_SMC_64(FFA_RXTX_MAP),
312 }, &res);
313
314 if (res.a0 == FFA_SMC_32(FFA_SUCCESS))
315 return ffa_set_rxtx_buffers_pages_cnt(dev, res.a2);
316
317 ffa_errno = res.a2;
318 ffa_print_error_log(FFA_FEATURES, ffa_errno);
319
320 return ffa_to_std_errno(ffa_errno);
321}
322
323/**
324 * ffa_free_rxtx_buffers() - free the RX/TX buffers
325 * @dev: The FF-A bus device
326 *
327 * Free the RX/TX buffers
328 */
329static void ffa_free_rxtx_buffers(struct udevice *dev)
330{
331 struct ffa_priv *uc_priv = dev_get_uclass_priv(dev);
332
333 log_debug("Freeing FF-A RX/TX buffers\n");
334
335 if (uc_priv->pair.rxbuf) {
336 free(uc_priv->pair.rxbuf);
337 uc_priv->pair.rxbuf = NULL;
338 }
339
340 if (uc_priv->pair.txbuf) {
341 free(uc_priv->pair.txbuf);
342 uc_priv->pair.txbuf = NULL;
343 }
344}
345
346/**
347 * ffa_alloc_rxtx_buffers() - allocate the RX/TX buffers
348 * @dev: The FF-A bus device
349 *
350 * Used by ffa_map_rxtx_buffers to allocate
351 * the RX/TX buffers before mapping them. The allocated memory is physically
352 * contiguous since memalign ends up calling malloc which allocates
353 * contiguous memory in u-boot.
354 * The size of the memory allocated is the minimum allowed.
355 *
356 * Return:
357 *
358 * 0 on success. Otherwise, failure
359 */
360static int ffa_alloc_rxtx_buffers(struct udevice *dev)
361{
362 u64 bytes;
363 struct ffa_priv *uc_priv = dev_get_uclass_priv(dev);
364
365 log_debug("Using %lu 4KB page(s) for FF-A RX/TX buffers size\n",
366 uc_priv->pair.rxtx_min_pages);
367
368 bytes = uc_priv->pair.rxtx_min_pages * SZ_4K;
369
370 /*
371 * The alignment of the RX and TX buffers must be equal
372 * to the larger translation granule size
373 * Assumption: Memory allocated with memalign is always physically contiguous
374 */
375
376 uc_priv->pair.rxbuf = memalign(bytes, bytes);
377 if (!uc_priv->pair.rxbuf) {
378 log_err("failure to allocate RX buffer\n");
379 return -ENOBUFS;
380 }
381
382 log_debug("FF-A RX buffer at virtual address %p\n", uc_priv->pair.rxbuf);
383
384 uc_priv->pair.txbuf = memalign(bytes, bytes);
385 if (!uc_priv->pair.txbuf) {
386 free(uc_priv->pair.rxbuf);
387 uc_priv->pair.rxbuf = NULL;
388 log_err("failure to allocate the TX buffer\n");
389 return -ENOBUFS;
390 }
391
392 log_debug("FF-A TX buffer at virtual address %p\n", uc_priv->pair.txbuf);
393
394 /* Make sure the buffers are cleared before use */
395 memset(uc_priv->pair.rxbuf, 0, bytes);
396 memset(uc_priv->pair.txbuf, 0, bytes);
397
398 return 0;
399}
400
401/**
402 * ffa_map_rxtx_buffers_hdlr() - FFA_RXTX_MAP handler function
403 * @dev: The FF-A bus device
404 *
405 * Implement FFA_RXTX_MAP FF-A function to map the RX/TX buffers
406 *
407 * Return:
408 *
409 * 0 on success. Otherwise, failure
410 */
411static int ffa_map_rxtx_buffers_hdlr(struct udevice *dev)
412{
413 int ret;
414 ffa_value_t res = {0};
415 int ffa_errno;
416 struct ffa_priv *uc_priv = dev_get_uclass_priv(dev);
417
418 ret = ffa_alloc_rxtx_buffers(dev);
419 if (ret)
420 return ret;
421
422 /*
423 * we need to pass the physical addresses of the RX/TX buffers
424 * in u-boot physical/virtual mapping is 1:1
425 * no need to convert from virtual to physical
426 */
427
428 invoke_ffa_fn((ffa_value_t){
429 .a0 = FFA_SMC_64(FFA_RXTX_MAP),
430 .a1 = map_to_sysmem(uc_priv->pair.txbuf),
431 .a2 = map_to_sysmem(uc_priv->pair.rxbuf),
432 .a3 = uc_priv->pair.rxtx_min_pages,
433 }, &res);
434
435 if (res.a0 == FFA_SMC_32(FFA_SUCCESS)) {
436 log_debug("FF-A RX/TX buffers mapped\n");
437 return 0;
438 }
439
440 ffa_errno = res.a2;
441 ffa_print_error_log(FFA_RXTX_MAP, ffa_errno);
442
443 ffa_free_rxtx_buffers(dev);
444
445 return ffa_to_std_errno(ffa_errno);
446}
447
448/**
449 * ffa_unmap_rxtx_buffers_hdlr() - FFA_RXTX_UNMAP handler function
450 * @dev: The FF-A bus device
451 *
452 * Implement FFA_RXTX_UNMAP FF-A function to unmap the RX/TX buffers
453 *
454 * Return:
455 *
456 * 0 on success. Otherwise, failure
457 */
458int ffa_unmap_rxtx_buffers_hdlr(struct udevice *dev)
459{
460 ffa_value_t res = {0};
461 int ffa_errno;
462 struct ffa_priv *uc_priv;
463
464 log_debug("unmapping FF-A RX/TX buffers\n");
465
466 uc_priv = dev_get_uclass_priv(dev);
467
468 invoke_ffa_fn((ffa_value_t){
469 .a0 = FFA_SMC_32(FFA_RXTX_UNMAP),
470 .a1 = PREP_SELF_ENDPOINT_ID(uc_priv->id),
471 }, &res);
472
473 if (res.a0 == FFA_SMC_32(FFA_SUCCESS)) {
474 ffa_free_rxtx_buffers(dev);
475 return 0;
476 }
477
478 ffa_errno = res.a2;
479 ffa_print_error_log(FFA_RXTX_UNMAP, ffa_errno);
480
481 return ffa_to_std_errno(ffa_errno);
482}
483
484/**
485 * ffa_release_rx_buffer_hdlr() - FFA_RX_RELEASE handler function
486 * @dev: The FF-A bus device
487 *
488 * Invoke FFA_RX_RELEASE FF-A function to release the ownership of the RX buffer
489 *
490 * Return:
491 *
492 * 0 on success. Otherwise, failure
493 */
494static int ffa_release_rx_buffer_hdlr(struct udevice *dev)
495{
496 ffa_value_t res = {0};
497 int ffa_errno;
498
499 invoke_ffa_fn((ffa_value_t){
500 .a0 = FFA_SMC_32(FFA_RX_RELEASE),
501 }, &res);
502
503 if (res.a0 == FFA_SMC_32(FFA_SUCCESS))
504 return 0;
505
506 ffa_errno = res.a2;
507 ffa_print_error_log(FFA_RX_RELEASE, ffa_errno);
508
509 return ffa_to_std_errno(ffa_errno);
510}
511
512/**
513 * ffa_uuid_are_identical() - check whether two given UUIDs are identical
514 * @uuid1: first UUID
515 * @uuid2: second UUID
516 *
517 * Used by ffa_read_partitions_info to search for a UUID in the partitions descriptors table
518 *
519 * Return:
520 *
521 * 1 when UUIDs match. Otherwise, 0
522 */
523static bool ffa_uuid_are_identical(const struct ffa_partition_uuid *uuid1,
524 const struct ffa_partition_uuid *uuid2)
525{
526 if (!uuid1 || !uuid2)
527 return 0;
528
529 return !memcmp(uuid1, uuid2, sizeof(struct ffa_partition_uuid));
530}
531
532/**
533 * ffa_read_partitions_info() - read queried partition data
534 * @dev: The FF-A bus device
535 * @count: The number of partitions queried
536 * @part_uuid: Pointer to the partition(s) UUID
537 *
538 * Read the partitions information returned by the FFA_PARTITION_INFO_GET and saves it in uc_priv
539 *
540 * Return:
541 *
542 * uc_priv is updated with the partition(s) information
543 * 0 is returned on success. Otherwise, failure
544 */
545static int ffa_read_partitions_info(struct udevice *dev, u32 count,
546 struct ffa_partition_uuid *part_uuid)
547{
548 struct ffa_priv *uc_priv = dev_get_uclass_priv(dev);
549
550 if (!count) {
551 log_err("no partition detected\n");
552 return -ENODATA;
553 }
554
555 log_debug("Reading FF-A partitions data from the RX buffer\n");
556
557 if (!part_uuid) {
558 /* Querying information of all partitions */
559 u64 buf_bytes;
560 u64 data_bytes;
561 u32 desc_idx;
562 struct ffa_partition_info *parts_info;
563
564 data_bytes = count * sizeof(struct ffa_partition_desc);
565
566 buf_bytes = uc_priv->pair.rxtx_min_pages * SZ_4K;
567
568 if (data_bytes > buf_bytes) {
569 log_err("partitions data size exceeds the RX buffer size:\n");
570 log_err(" sizes in bytes: data %llu , RX buffer %llu\n",
571 data_bytes,
572 buf_bytes);
573
574 return -ENOMEM;
575 }
576
577 uc_priv->partitions.descs = devm_kmalloc(dev, data_bytes, __GFP_ZERO);
578 if (!uc_priv->partitions.descs) {
579 log_err("cannot allocate partitions data buffer\n");
580 return -ENOMEM;
581 }
582
583 parts_info = uc_priv->pair.rxbuf;
584
585 for (desc_idx = 0 ; desc_idx < count ; desc_idx++) {
586 uc_priv->partitions.descs[desc_idx].info =
587 parts_info[desc_idx];
588
589 log_debug("FF-A partition ID %x : info cached\n",
590 uc_priv->partitions.descs[desc_idx].info.id);
591 }
592
593 uc_priv->partitions.count = count;
594
595 log_debug("%d FF-A partition(s) found and cached\n", count);
596
597 } else {
598 u32 rx_desc_idx, cached_desc_idx;
599 struct ffa_partition_info *parts_info;
600 u8 desc_found;
601
602 parts_info = uc_priv->pair.rxbuf;
603
604 /*
605 * Search for the SP IDs read from the RX buffer
606 * in the already cached SPs.
607 * Update the UUID when ID found.
608 */
609 for (rx_desc_idx = 0; rx_desc_idx < count ; rx_desc_idx++) {
610 desc_found = 0;
611
612 /* Search the current ID in the cached partitions */
613 for (cached_desc_idx = 0;
614 cached_desc_idx < uc_priv->partitions.count;
615 cached_desc_idx++) {
616 /* Save the UUID */
617 if (uc_priv->partitions.descs[cached_desc_idx].info.id ==
618 parts_info[rx_desc_idx].id) {
619 uc_priv->partitions.descs[cached_desc_idx].sp_uuid =
620 *part_uuid;
621
622 desc_found = 1;
623 break;
624 }
625 }
626
627 if (!desc_found)
628 return -ENODATA;
629 }
630 }
631
632 return 0;
633}
634
635/**
636 * ffa_query_partitions_info() - invoke FFA_PARTITION_INFO_GET and save partitions data
637 * @dev: The FF-A bus device
638 * @part_uuid: Pointer to the partition(s) UUID
639 * @pcount: Pointer to the number of partitions variable filled when querying
640 *
641 * Execute the FFA_PARTITION_INFO_GET to query the partitions data.
642 * Then, call ffa_read_partitions_info to save the data in uc_priv.
643 *
644 * After reading the data the RX buffer is released using ffa_release_rx_buffer
645 *
646 * Return:
647 *
648 * When part_uuid is NULL, all partitions data are retrieved from secure world
649 * When part_uuid is non NULL, data for partitions matching the given UUID are
650 * retrieved and the number of partitions is returned
651 * 0 is returned on success. Otherwise, failure
652 */
653static int ffa_query_partitions_info(struct udevice *dev, struct ffa_partition_uuid *part_uuid,
654 u32 *pcount)
655{
656 struct ffa_partition_uuid query_uuid = {0};
657 ffa_value_t res = {0};
658 int ffa_errno;
659
660 /*
661 * If a UUID is specified. Information for one or more
662 * partitions in the system is queried. Otherwise, information
663 * for all installed partitions is queried
664 */
665
666 if (part_uuid) {
667 if (!pcount)
668 return -EINVAL;
669
670 query_uuid = *part_uuid;
671 } else if (pcount) {
672 return -EINVAL;
673 }
674
675 invoke_ffa_fn((ffa_value_t){
676 .a0 = FFA_SMC_32(FFA_PARTITION_INFO_GET),
677 .a1 = query_uuid.a1,
678 .a2 = query_uuid.a2,
679 .a3 = query_uuid.a3,
680 .a4 = query_uuid.a4,
681 }, &res);
682
683 if (res.a0 == FFA_SMC_32(FFA_SUCCESS)) {
684 int ret;
685
686 /*
687 * res.a2 contains the count of partition information descriptors
688 * populated in the RX buffer
689 */
690 if (res.a2) {
691 ret = ffa_read_partitions_info(dev, (u32)res.a2, part_uuid);
692 if (ret) {
693 log_err("failed reading SP(s) data , err (%d)\n", ret);
694 ffa_release_rx_buffer_hdlr(dev);
695 return -EINVAL;
696 }
697 }
698
699 /* Return the SP count (when querying using a UUID) */
700 if (pcount)
701 *pcount = (u32)res.a2;
702
703 /*
704 * After calling FFA_PARTITION_INFO_GET the buffer ownership
705 * is assigned to the consumer (u-boot). So, we need to give
706 * the ownership back to the SPM or hypervisor
707 */
708 ret = ffa_release_rx_buffer_hdlr(dev);
709
710 return ret;
711 }
712
713 ffa_errno = res.a2;
714 ffa_print_error_log(FFA_PARTITION_INFO_GET, ffa_errno);
715
716 return ffa_to_std_errno(ffa_errno);
717}
718
719/**
720 * ffa_get_partitions_info_hdlr() - FFA_PARTITION_INFO_GET handler function
721 * @uuid_str: pointer to the UUID string
722 * @sp_count: address of the variable containing the number of partitions matching the UUID
723 * The variable is set by the driver
724 * @sp_descs: address of the descriptors of the partitions matching the UUID
725 * The address is set by the driver
726 *
727 * Return the number of partitions and their descriptors matching the UUID
728 *
729 * Query the secure partition data from uc_priv.
730 * If not found, invoke FFA_PARTITION_INFO_GET FF-A function to query the partition information
731 * from secure world.
732 *
733 * A client of the FF-A driver should know the UUID of the service it wants to
734 * access. It should use the UUID to request the FF-A driver to provide the
735 * partition(s) information of the service. The FF-A driver uses
736 * PARTITION_INFO_GET to obtain this information. This is implemented through
737 * ffa_get_partitions_info_hdlr() function.
738 * If the partition(s) matching the UUID found, the partition(s) information and the
739 * number are returned.
740 * If no partition matching the UUID is found in the cached area, a new FFA_PARTITION_INFO_GET
741 * call is issued.
742 * If not done yet, the UUID is updated in the cached area.
743 * This assumes that partitions data does not change in the secure world.
744 * Otherwise u-boot will have an outdated partition data. The benefit of caching
745 * the information in the FF-A driver is to accommodate discovery after
746 * ExitBootServices().
747 *
748 * Return:
749 *
750 * @sp_count: the number of partitions
751 * @sp_descs: address of the partitions descriptors
752 *
753 * On success 0 is returned. Otherwise, failure
754 */
755int ffa_get_partitions_info_hdlr(struct udevice *dev, const char *uuid_str,
756 u32 *sp_count, struct ffa_partition_desc **sp_descs)
757{
758 u32 i;
759 struct ffa_partition_uuid part_uuid = {0};
760 struct ffa_priv *uc_priv;
761 struct ffa_partition_desc *rx_descs;
762
763 uc_priv = dev_get_uclass_priv(dev);
764
765 if (!uc_priv->partitions.count || !uc_priv->partitions.descs) {
766 log_err("no partition installed\n");
767 return -EINVAL;
768 }
769
770 if (!uuid_str) {
771 log_err("no UUID provided\n");
772 return -EINVAL;
773 }
774
775 if (!sp_count) {
776 log_err("no count argument provided\n");
777 return -EINVAL;
778 }
779
780 if (!sp_descs) {
781 log_err("no info argument provided\n");
782 return -EINVAL;
783 }
784
785 if (uuid_str_to_le_bin(uuid_str, (unsigned char *)&part_uuid)) {
786 log_err("invalid UUID\n");
787 return -EINVAL;
788 }
789
790 log_debug("Searching FF-A partitions using the provided UUID\n");
791
792 *sp_count = 0;
793 *sp_descs = uc_priv->pair.rxbuf;
794 rx_descs = *sp_descs;
795
796 /* Search in the cached partitions */
797 for (i = 0; i < uc_priv->partitions.count; i++)
798 if (ffa_uuid_are_identical(&uc_priv->partitions.descs[i].sp_uuid,
799 &part_uuid)) {
800 log_debug("FF-A partition ID %x matches the provided UUID\n",
801 uc_priv->partitions.descs[i].info.id);
802
803 (*sp_count)++;
804 *rx_descs++ = uc_priv->partitions.descs[i];
805 }
806
807 if (!(*sp_count)) {
808 int ret;
809
810 log_debug("No FF-A partition found. Querying framework ...\n");
811
812 ret = ffa_query_partitions_info(dev, &part_uuid, sp_count);
813
814 if (!ret) {
815 log_debug("Number of FF-A partition(s) matching the UUID: %d\n", *sp_count);
816
817 if (*sp_count)
818 ret = ffa_get_partitions_info_hdlr(dev, uuid_str, sp_count,
819 sp_descs);
820 else
821 ret = -ENODATA;
822 }
823
824 return ret;
825 }
826
827 return 0;
828}
829
830/**
831 * ffa_cache_partitions_info() - Query and saves all secure partitions data
832 * @dev: The FF-A bus device
833 *
834 * Invoke FFA_PARTITION_INFO_GET FF-A function to query from secure world
835 * all partitions information.
836 *
837 * The FFA_PARTITION_INFO_GET call is issued with nil UUID as an argument.
838 * All installed partitions information are returned. We cache them in uc_priv
839 * and we keep the UUID field empty (in FF-A 1.0 UUID is not provided by the partition descriptor)
840 *
841 * Called at the device probing level.
842 * ffa_cache_partitions_info uses ffa_query_partitions_info to get the data
843 *
844 * Return:
845 *
846 * 0 on success. Otherwise, failure
847 */
848static int ffa_cache_partitions_info(struct udevice *dev)
849{
850 return ffa_query_partitions_info(dev, NULL, NULL);
851}
852
853/**
854 * ffa_msg_send_direct_req_hdlr() - FFA_MSG_SEND_DIRECT_{REQ,RESP} handler function
855 * @dev: The FF-A bus device
856 * @dst_part_id: destination partition ID
857 * @msg: pointer to the message data preallocated by the client (in/out)
858 * @is_smc64: select 64-bit or 32-bit FF-A ABI
859 *
860 * Implement FFA_MSG_SEND_DIRECT_{REQ,RESP}
861 * FF-A functions.
862 *
863 * FFA_MSG_SEND_DIRECT_REQ is used to send the data to the secure partition.
864 * The response from the secure partition is handled by reading the
865 * FFA_MSG_SEND_DIRECT_RESP arguments.
866 *
867 * The maximum size of the data that can be exchanged is 40 bytes which is
868 * sizeof(struct ffa_send_direct_data) as defined by the FF-A specification 1.0
869 * in the section relevant to FFA_MSG_SEND_DIRECT_{REQ,RESP}
870 *
871 * Return:
872 *
873 * 0 on success. Otherwise, failure
874 */
875int ffa_msg_send_direct_req_hdlr(struct udevice *dev, u16 dst_part_id,
876 struct ffa_send_direct_data *msg, bool is_smc64)
877{
878 ffa_value_t res = {0};
879 int ffa_errno;
880 u64 req_mode, resp_mode;
881 struct ffa_priv *uc_priv;
882
883 uc_priv = dev_get_uclass_priv(dev);
884
885 /* No partition installed */
886 if (!uc_priv->partitions.count || !uc_priv->partitions.descs)
887 return -ENODEV;
888
889 if (is_smc64) {
890 req_mode = FFA_SMC_64(FFA_MSG_SEND_DIRECT_REQ);
891 resp_mode = FFA_SMC_64(FFA_MSG_SEND_DIRECT_RESP);
892 } else {
893 req_mode = FFA_SMC_32(FFA_MSG_SEND_DIRECT_REQ);
894 resp_mode = FFA_SMC_32(FFA_MSG_SEND_DIRECT_RESP);
895 }
896
897 invoke_ffa_fn((ffa_value_t){
898 .a0 = req_mode,
899 .a1 = PREP_SELF_ENDPOINT_ID(uc_priv->id) |
900 PREP_PART_ENDPOINT_ID(dst_part_id),
901 .a2 = 0,
902 .a3 = msg->data0,
903 .a4 = msg->data1,
904 .a5 = msg->data2,
905 .a6 = msg->data3,
906 .a7 = msg->data4,
907 }, &res);
908
909 while (res.a0 == FFA_SMC_32(FFA_INTERRUPT))
910 invoke_ffa_fn((ffa_value_t){
911 .a0 = FFA_SMC_32(FFA_RUN),
912 .a1 = res.a1,
913 }, &res);
914
915 if (res.a0 == FFA_SMC_32(FFA_SUCCESS)) {
916 /* Message sent with no response */
917 return 0;
918 }
919
920 if (res.a0 == resp_mode) {
921 /* Message sent with response extract the return data */
922 msg->data0 = res.a3;
923 msg->data1 = res.a4;
924 msg->data2 = res.a5;
925 msg->data3 = res.a6;
926 msg->data4 = res.a7;
927
928 return 0;
929 }
930
931 ffa_errno = res.a2;
932 return ffa_to_std_errno(ffa_errno);
933}
934
935/* FF-A driver operations (used by clients for communicating with FF-A)*/
936
937/**
938 * ffa_partition_info_get() - FFA_PARTITION_INFO_GET driver operation
939 * @uuid_str: pointer to the UUID string
940 * @sp_count: address of the variable containing the number of partitions matching the UUID
941 * The variable is set by the driver
942 * @sp_descs: address of the descriptors of the partitions matching the UUID
943 * The address is set by the driver
944 *
945 * Driver operation for FFA_PARTITION_INFO_GET.
946 * Please see ffa_get_partitions_info_hdlr() description for more details.
947 *
948 * Return:
949 *
950 * @sp_count: the number of partitions
951 * @sp_descs: address of the partitions descriptors
952 *
953 * On success 0 is returned. Otherwise, failure
954 */
955int ffa_partition_info_get(struct udevice *dev, const char *uuid_str,
956 u32 *sp_count, struct ffa_partition_desc **sp_descs)
957{
958 struct ffa_bus_ops *ops = ffa_get_ops(dev);
959
960 if (!ops->partition_info_get)
961 return -ENOSYS;
962
963 return ops->partition_info_get(dev, uuid_str, sp_count, sp_descs);
964}
965
966/**
967 * ffa_sync_send_receive() - FFA_MSG_SEND_DIRECT_{REQ,RESP} driver operation
968 * @dev: The FF-A bus device
969 * @dst_part_id: destination partition ID
970 * @msg: pointer to the message data preallocated by the client (in/out)
971 * @is_smc64: select 64-bit or 32-bit FF-A ABI
972 *
973 * Driver operation for FFA_MSG_SEND_DIRECT_{REQ,RESP}.
974 * Please see ffa_msg_send_direct_req_hdlr() description for more details.
975 *
976 * Return:
977 *
978 * 0 on success. Otherwise, failure
979 */
980int ffa_sync_send_receive(struct udevice *dev, u16 dst_part_id,
981 struct ffa_send_direct_data *msg, bool is_smc64)
982{
983 struct ffa_bus_ops *ops = ffa_get_ops(dev);
984
985 if (!ops->sync_send_receive)
986 return -ENOSYS;
987
988 return ops->sync_send_receive(dev, dst_part_id, msg, is_smc64);
989}
990
991/**
992 * ffa_rxtx_unmap() - FFA_RXTX_UNMAP driver operation
993 * @dev: The FF-A bus device
994 *
995 * Driver operation for FFA_RXTX_UNMAP.
996 * Please see ffa_unmap_rxtx_buffers_hdlr() description for more details.
997 *
998 * Return:
999 *
1000 * 0 on success. Otherwise, failure
1001 */
1002int ffa_rxtx_unmap(struct udevice *dev)
1003{
1004 struct ffa_bus_ops *ops = ffa_get_ops(dev);
1005
1006 if (!ops->rxtx_unmap)
1007 return -ENOSYS;
1008
1009 return ops->rxtx_unmap(dev);
1010}
1011
1012/**
1013 * ffa_do_probe() - probing FF-A framework
1014 * @dev: the FF-A bus device (arm_ffa)
1015 *
1016 * Probing is triggered on demand by clients searching for the uclass.
1017 * At probe level the following actions are done:
1018 * - saving the FF-A framework version in uc_priv
1019 * - querying from secure world the u-boot endpoint ID
1020 * - querying from secure world the supported features of FFA_RXTX_MAP
1021 * - mapping the RX/TX buffers
1022 * - querying from secure world all the partitions information
1023 *
1024 * All data queried from secure world is saved in uc_priv.
1025 *
1026 * Return:
1027 *
1028 * 0 on success. Otherwise, failure
1029 */
1030static int ffa_do_probe(struct udevice *dev)
1031{
1032 int ret;
1033
1034 ret = ffa_get_version_hdlr(dev);
1035 if (ret)
1036 return ret;
1037
1038 ret = ffa_get_endpoint_id(dev);
1039 if (ret)
1040 return ret;
1041
1042 ret = ffa_get_rxtx_map_features_hdlr(dev);
1043 if (ret)
1044 return ret;
1045
1046 ret = ffa_map_rxtx_buffers_hdlr(dev);
1047 if (ret)
1048 return ret;
1049
1050 ret = ffa_cache_partitions_info(dev);
1051 if (ret) {
1052 ffa_unmap_rxtx_buffers_hdlr(dev);
1053 return ret;
1054 }
1055
1056 return 0;
1057}
1058
1059UCLASS_DRIVER(ffa) = {
1060 .name = "ffa",
1061 .id = UCLASS_FFA,
1062 .pre_probe = ffa_do_probe,
1063 .pre_remove = ffa_unmap_rxtx_buffers_hdlr,
1064 .per_device_auto = sizeof(struct ffa_priv)
1065};