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