microsoft/mu_feature_ffa

Public

mirrored fromhttps://github.com/microsoft/mu_feature_ffaAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v0.1.2

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

FfaFeaturePkg/Library/ArmFfaLibEx/ArmFfaLibEx.c

973lines · modecode

1// SPDX-License-Identifier: BSD-3-Clause
2
3/*
4 * Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
5 * Copyright (c), Microsoft Corporation.
6 */
7
8#include <Uefi.h>
9#include <IndustryStandard/ArmFfaSvc.h>
10#include <IndustryStandard/ArmFfaPartInfo.h>
11#include <Library/BaseLib.h>
12#include <Library/DebugLib.h>
13#include <Library/ArmFfaLib.h>
14#include <Library/ArmSvcLib.h>
15#include <Library/ArmSmcLib.h>
16#include <Library/BaseMemoryLib.h>
17#include <Library/ArmFfaLibEx.h>
18#include <Library/PlatformFfaInterruptLib.h>
19
20extern UINT16 gPartId;
21
22/**
23 This function is used to prepare a GUID for FF-A.
24
25 The FF-A expects a GUID to be in a specific format. This function
26 manipulates the input Guid to be understood by the FF-A.
27
28 Note: This function is symmetric, i.e., calling it twice will return the
29 original GUID. Thus, it can be used to prepare and restore the GUID.
30
31 @param Guid - Supplies the pointer for original GUID. This is the one you
32 get from VS GUID creator.
33
34 @retval None.
35**/
36VOID
37FfaPrepareGuid (
38 IN OUT EFI_GUID *Guid
39 )
40{
41 UINT32 *Data32;
42 UINT16 *Data16;
43
44 if (Guid == NULL) {
45 return;
46 }
47
48 Data32 = (UINT32 *)Guid;
49 Data32[0] = SwapBytes32 (Data32[0]);
50 Data16 = (UINT16 *)&Data32[1];
51 Data16[0] = SwapBytes16 (Data16[0]);
52 Data16[1] = SwapBytes16 (Data16[1]);
53}
54
55STATIC
56VOID
57ArmCallSxc (
58 ARM_SXC_ARGS *Request,
59 ARM_SXC_ARGS *Response
60 )
61{
62 ARM_SXC_ARGS LocalParams;
63
64 CopyMem (&LocalParams, Request, sizeof (ARM_SXC_ARGS));
65
66 /*
67 * The ArmCallSxc function is a wrapper around the ffa_params structure
68 * which checks the current execution level and calls the appropriate
69 * conduit.
70 */
71 if (PcdGetBool (PcdFfaLibConduitSmc) == 1) {
72 ArmCallSmc ((ARM_SMC_ARGS *)&LocalParams);
73 } else {
74 ArmCallSvc ((ARM_SVC_ARGS *)&LocalParams);
75 }
76
77 CopyMem (Response, &LocalParams, sizeof (ARM_SXC_ARGS));
78}
79
80/*
81 * Unpacks the content of the ffa instruction Response into an ffa_direct_msg structure.
82 */
83STATIC
84VOID
85FfaUnpackDirectMessage (
86 ARM_SXC_ARGS *Response,
87 DIRECT_MSG_ARGS_EX *Message
88 )
89{
90 Message->FunctionId = Response->Arg0;
91 Message->SourceId = (Response->Arg1 >> 16);
92 Message->DestinationId = Response->Arg1;
93
94 if ((Message->FunctionId == ARM_FID_FFA_MSG_SEND_DIRECT_REQ_AARCH32) ||
95 (Message->FunctionId == ARM_FID_FFA_MSG_SEND_DIRECT_REQ_AARCH64))
96 {
97 Message->Arg0 = Response->Arg2;
98 Message->Arg1 = Response->Arg3;
99 Message->Arg2 = Response->Arg4;
100 Message->Arg3 = Response->Arg5;
101 Message->Arg4 = Response->Arg6;
102 Message->Arg5 = Response->Arg7;
103 } else {
104 CopyMem (&Message->ServiceGuid, &Response->Arg2, sizeof (EFI_GUID));
105 FfaPrepareGuid (&Message->ServiceGuid);
106 Message->Arg0 = Response->Arg4;
107 Message->Arg1 = Response->Arg5;
108 Message->Arg2 = Response->Arg6;
109 Message->Arg3 = Response->Arg7;
110 Message->Arg4 = Response->Arg8;
111 Message->Arg5 = Response->Arg9;
112 Message->Arg6 = Response->Arg10;
113 Message->Arg7 = Response->Arg11;
114 Message->Arg8 = Response->Arg12;
115 Message->Arg9 = Response->Arg13;
116 Message->Arg10 = Response->Arg14;
117 Message->Arg11 = Response->Arg15;
118 Message->Arg12 = Response->Arg16;
119 Message->Arg13 = Response->Arg17;
120 }
121}
122
123/*
124 * Packs the content of the ffa_direct_msg into a Request message.
125 */
126STATIC
127VOID
128FfaPackDirectMessage (
129 OUT ARM_SXC_ARGS *Request,
130 IN DIRECT_MSG_ARGS_EX *Message
131 )
132{
133 EFI_GUID ServiceGuid;
134
135 Request->Arg0 = Message->FunctionId;
136
137 /* NOTE: There is a DIRECT_RESP define in ffa_api_defines.h, this may need to be updated
138 * in the future if the defines differ, for now they are identical. */
139 Request->Arg1 = ((UINT32)Message->SourceId << 16) | Message->DestinationId;
140
141 if ((Message->FunctionId == ARM_FID_FFA_MSG_SEND_DIRECT_REQ_AARCH32) ||
142 (Message->FunctionId == ARM_FID_FFA_MSG_SEND_DIRECT_REQ_AARCH64) ||
143 (Message->FunctionId == ARM_FID_FFA_MSG_SEND_DIRECT_RESP_AARCH32) ||
144 (Message->FunctionId == ARM_FID_FFA_MSG_SEND_DIRECT_RESP_AARCH64))
145 {
146 Request->Arg2 = Message->Arg0;
147 Request->Arg3 = Message->Arg1;
148 Request->Arg4 = Message->Arg2;
149 Request->Arg5 = Message->Arg3;
150 Request->Arg6 = Message->Arg4;
151 Request->Arg7 = Message->Arg5;
152 } else {
153 CopyMem (&ServiceGuid, &Message->ServiceGuid, sizeof (EFI_GUID));
154 FfaPrepareGuid (&ServiceGuid);
155 CopyMem (&Request->Arg2, &ServiceGuid, sizeof (EFI_GUID));
156 Request->Arg4 = Message->Arg0;
157 Request->Arg5 = Message->Arg1;
158 Request->Arg6 = Message->Arg2;
159 Request->Arg7 = Message->Arg3;
160 Request->Arg8 = Message->Arg4;
161 Request->Arg9 = Message->Arg5;
162 Request->Arg10 = Message->Arg6;
163 Request->Arg11 = Message->Arg7;
164 Request->Arg12 = Message->Arg8;
165 Request->Arg13 = Message->Arg9;
166 Request->Arg14 = Message->Arg10;
167 Request->Arg15 = Message->Arg11;
168 Request->Arg16 = Message->Arg12;
169 Request->Arg17 = Message->Arg13;
170 }
171}
172
173/*
174 * The end of the interrupt handler is indicated by an FFA_MSG_WAIT call.
175 */
176STATIC
177VOID
178FfaReturnFromInterrupt (
179 ARM_SXC_ARGS *Result
180 )
181{
182 ARM_SXC_ARGS Request = { 0 };
183
184 Request.Arg0 = ARM_FID_FFA_WAIT;
185 ArmCallSxc (&Request, Result);
186}
187
188EFI_STATUS
189EFIAPI
190FfaMessageWait (
191 OUT DIRECT_MSG_ARGS_EX *Message
192 )
193{
194 ARM_SXC_ARGS Request = { 0 };
195 ARM_SXC_ARGS Result = { 0 };
196
197 Request.Arg0 = ARM_FID_FFA_WAIT;
198
199 ArmCallSxc (&Request, &Result);
200
201 while (Result.Arg0 == ARM_FID_FFA_INTERRUPT) {
202 SecurePartitionInterruptHandler ((UINT32)Result.Arg2);
203 FfaReturnFromInterrupt (&Result);
204 }
205
206 if (Result.Arg0 == ARM_FID_FFA_ERROR) {
207 return FfaStatusToEfiStatus (Result.Arg2);
208 } else if ((Result.Arg0 == ARM_FID_FFA_MSG_SEND_DIRECT_REQ_AARCH32) ||
209 (Result.Arg0 == ARM_FID_FFA_MSG_SEND_DIRECT_REQ_AARCH64) ||
210 (Result.Arg0 == ARM_FID_FFA_MSG_SEND_DIRECT_REQ2))
211 {
212 FfaUnpackDirectMessage (&Result, Message);
213 } else {
214 ASSERT (Result.Arg0 == ARM_FID_FFA_SUCCESS_AARCH32);
215 *Message = (DIRECT_MSG_ARGS_EX) {
216 .FunctionId = Result.Arg0
217 };
218 }
219
220 return EFI_SUCCESS;
221}
222
223EFI_STATUS
224EFIAPI
225FfaMessageSendDirectReq2 (
226 IN UINT16 DestPartId,
227 IN EFI_GUID *ServiceGuid OPTIONAL,
228 IN OUT DIRECT_MSG_ARGS_EX *ImpDefArgs
229 )
230{
231 ARM_SXC_ARGS InputArgs = { 0 };
232 ARM_SXC_ARGS Result = { 0 };
233
234 ImpDefArgs->FunctionId = ARM_FID_FFA_MSG_SEND_DIRECT_REQ2;
235 ImpDefArgs->SourceId = gPartId;
236 ImpDefArgs->DestinationId = DestPartId;
237 if (ServiceGuid != NULL) {
238 CopyMem (&(ImpDefArgs->ServiceGuid), ServiceGuid, sizeof (EFI_GUID));
239 } else {
240 ZeroMem (&(ImpDefArgs->ServiceGuid), sizeof (EFI_GUID));
241 }
242
243 FfaPackDirectMessage (&InputArgs, ImpDefArgs);
244
245 ArmCallSxc (&InputArgs, &Result);
246
247 while (Result.Arg0 == ARM_FID_FFA_INTERRUPT) {
248 SecurePartitionInterruptHandler ((UINT32)Result.Arg2);
249 FfaReturnFromInterrupt (&Result);
250 }
251
252 if (Result.Arg0 == ARM_FID_FFA_ERROR) {
253 return FfaStatusToEfiStatus (Result.Arg2);
254 } else if (Result.Arg0 == ARM_FID_FFA_MSG_SEND_DIRECT_RESP2) {
255 FfaUnpackDirectMessage (&Result, ImpDefArgs);
256 } else {
257 ASSERT (Result.Arg0 == ARM_FID_FFA_SUCCESS_AARCH32);
258 *ImpDefArgs = (DIRECT_MSG_ARGS_EX) {
259 .FunctionId = Result.Arg0
260 };
261 }
262
263 return EFI_SUCCESS;
264}
265
266STATIC
267EFI_STATUS
268FfaMessageSendDirectResp (
269 IN UINT32 FunctionId,
270 IN DIRECT_MSG_ARGS_EX *Request,
271 OUT DIRECT_MSG_ARGS_EX *Response
272 )
273{
274 ARM_SXC_ARGS InputArgs = { 0 };
275 ARM_SXC_ARGS Result = { 0 };
276
277 Request->FunctionId = FunctionId;
278 FfaPackDirectMessage (&InputArgs, Request);
279
280 ArmCallSxc (&InputArgs, &Result);
281
282 while (Result.Arg0 == ARM_FID_FFA_INTERRUPT) {
283 SecurePartitionInterruptHandler ((UINT32)Result.Arg2);
284 FfaReturnFromInterrupt (&Result);
285 }
286
287 if (Result.Arg0 == ARM_FID_FFA_ERROR) {
288 return FfaStatusToEfiStatus (Result.Arg2);
289 } else if ((Result.Arg0 == ARM_FID_FFA_MSG_SEND_DIRECT_REQ_AARCH32) ||
290 (Result.Arg0 == ARM_FID_FFA_MSG_SEND_DIRECT_REQ_AARCH64) ||
291 (Result.Arg0 == ARM_FID_FFA_MSG_SEND_DIRECT_REQ2))
292 {
293 FfaUnpackDirectMessage (&Result, Response);
294 } else {
295 ASSERT (Result.Arg0 == ARM_FID_FFA_SUCCESS_AARCH32);
296 *Response = (DIRECT_MSG_ARGS_EX) {
297 .FunctionId = Result.Arg0
298 };
299 }
300
301 return EFI_SUCCESS;
302}
303
304EFI_STATUS
305EFIAPI
306FfaMessageSendDirectResp32 (
307 IN DIRECT_MSG_ARGS_EX *Request,
308 OUT DIRECT_MSG_ARGS_EX *Response
309 )
310{
311 return FfaMessageSendDirectResp (
312 ARM_FID_FFA_MSG_SEND_DIRECT_RESP_AARCH32,
313 Request,
314 Response
315 );
316}
317
318EFI_STATUS
319EFIAPI
320FfaMessageSendDirectResp64 (
321 IN DIRECT_MSG_ARGS_EX *Request,
322 OUT DIRECT_MSG_ARGS_EX *Response
323 )
324{
325 return FfaMessageSendDirectResp (
326 ARM_FID_FFA_MSG_SEND_DIRECT_RESP_AARCH64,
327 Request,
328 Response
329 );
330}
331
332EFI_STATUS
333EFIAPI
334FfaMessageSendDirectResp2 (
335 IN DIRECT_MSG_ARGS_EX *Request,
336 OUT DIRECT_MSG_ARGS_EX *Response
337 )
338{
339 return FfaMessageSendDirectResp (
340 ARM_FID_FFA_MSG_SEND_DIRECT_RESP2,
341 Request,
342 Response
343 );
344}
345
346EFI_STATUS
347EFIAPI
348FfaNsResInfoGet (
349 IN UINT16 TargetId,
350 IN UINT64 Flags,
351 OUT UINT32 *WrittenSize,
352 OUT UINT32 *RemainingSize
353 )
354{
355 ARM_SXC_ARGS Request = { 0 };
356 ARM_SXC_ARGS Result = { 0 };
357
358 if ((WrittenSize == NULL) || (RemainingSize == NULL)) {
359 return EFI_INVALID_PARAMETER;
360 }
361
362 Request.Arg0 = ARM_FID_FFA_NS_RES_INFO_GET;
363 Request.Arg1 = TargetId;
364 Request.Arg2 = Flags;
365
366 ArmCallSxc (&Request, &Result);
367
368 if (Result.Arg0 == ARM_FID_FFA_ERROR) {
369 return FfaStatusToEfiStatus (Result.Arg2);
370 }
371
372 *WrittenSize = Result.Arg2 >> 32;
373 *RemainingSize = Result.Arg2;
374
375 return EFI_SUCCESS;
376}
377
378EFI_STATUS
379EFIAPI
380FfaMemDonate (
381 UINT32 TotalLength,
382 UINT32 FragmentLength,
383 VOID *BufferAddr,
384 UINT32 PageCount,
385 UINT64 *Handle
386 )
387{
388 ARM_SXC_ARGS Request = { 0 };
389 ARM_SXC_ARGS Result = { 0 };
390
391 Request.Arg0 = (BufferAddr) ? ARM_FID_FFA_MEM_DONATE_AARCH64 : ARM_FID_FFA_MEM_DONATE_AARCH32;
392 Request.Arg1 = TotalLength;
393 Request.Arg2 = FragmentLength;
394 Request.Arg3 = (UINTN)BufferAddr;
395 Request.Arg4 = PageCount;
396
397 ArmCallSxc (&Request, &Result);
398
399 if (Result.Arg0 == ARM_FID_FFA_ERROR) {
400 *Handle = 0U;
401 return FfaStatusToEfiStatus (Result.Arg2);
402 }
403
404 /*
405 * There are no 64-bit parameters returned with FFA_SUCCESS, the SPMC
406 * will use the default 32-bit version.
407 */
408 ASSERT (Result.Arg0 == ARM_FID_FFA_SUCCESS_AARCH32);
409 *Handle = ((UINT64)Result.Arg3 << 32) | Result.Arg2;
410 return EFI_SUCCESS;
411}
412
413EFI_STATUS
414EFIAPI
415FfaNotificationSet (
416 IN UINT16 DestinationId,
417 IN UINT64 Flags,
418 IN UINT64 NotificationBitmap
419 )
420{
421 ARM_SXC_ARGS Request = { 0 };
422 ARM_SXC_ARGS Result = { 0 };
423
424 Request.Arg0 = ARM_FID_FFA_NOTIFICATION_SET;
425 Request.Arg1 = ((UINT32)gPartId << 16) | DestinationId;
426 Request.Arg2 = Flags;
427 Request.Arg3 = (UINT32)NotificationBitmap;
428 Request.Arg4 = (UINT32)(NotificationBitmap >> 32);
429
430 ArmCallSxc (&Request, &Result);
431
432 if (Result.Arg0 == ARM_FID_FFA_ERROR) {
433 return FfaStatusToEfiStatus (Result.Arg2);
434 }
435
436 return EFI_SUCCESS;
437}
438
439EFI_STATUS
440EFIAPI
441FfaNotificationGet (
442 IN UINT16 VCpuId,
443 IN UINT64 Flags,
444 IN UINT64 *NotificationBitmap
445 )
446{
447 ARM_SXC_ARGS Request = { 0 };
448 ARM_SXC_ARGS Result = { 0 };
449
450 Request.Arg0 = ARM_FID_FFA_NOTIFICATION_GET;
451 Request.Arg1 = ((UINT32)VCpuId << 16) | gPartId;
452 Request.Arg2 = Flags;
453
454 ArmCallSxc (&Request, &Result);
455
456 if (Result.Arg0 == ARM_FID_FFA_ERROR) {
457 return FfaStatusToEfiStatus (Result.Arg2);
458 }
459
460 switch (Flags) {
461 case ARM_FFA_NOTIFICATION_FLAG_BITMAP_SP:
462 *NotificationBitmap = ((UINT64)Result.Arg3 << 32) | Result.Arg2;
463 break;
464 case ARM_FFA_NOTIFICATION_FLAG_BITMAP_VM:
465 *NotificationBitmap = ((UINT64)Result.Arg5 << 32) | Result.Arg4;
466 break;
467 case ARM_FFA_NOTIFICATION_FLAG_BITMAP_HYP:
468 *NotificationBitmap = ((UINT64)Result.Arg7 << 32) | Result.Arg6;
469 break;
470 default:
471 return EFI_UNSUPPORTED;
472 }
473
474 return EFI_SUCCESS;
475}
476
477EFI_STATUS
478EFIAPI
479FfaPartitionInfoGetRegs (
480 IN EFI_GUID *ServiceGuid,
481 IN UINT16 StartIndex,
482 IN OUT UINT16 *Tag OPTIONAL,
483 IN OUT UINT32 *PartDescCount,
484 OUT EFI_FFA_PART_INFO_DESC *PartDesc OPTIONAL
485 )
486{
487 EFI_GUID ServiceGuidMangled;
488 UINT64 Metadata = 0;
489 UINT16 TagValue = 0;
490 UINT16 CurrentIndex = 0;
491 UINT32 Count = 0;
492
493 ARM_SXC_ARGS Request = { 0 };
494 ARM_SXC_ARGS Result = { 0 };
495
496 if (PartDesc == NULL) {
497 return EFI_INVALID_PARAMETER;
498 }
499
500 if (Tag != NULL) {
501 TagValue = *Tag;
502 }
503
504 if (ServiceGuid != NULL) {
505 CopyMem (&ServiceGuidMangled, ServiceGuid, sizeof (EFI_GUID));
506 } else {
507 ZeroMem (&ServiceGuidMangled, sizeof (EFI_GUID));
508 }
509
510 FfaPrepareGuid (&ServiceGuidMangled);
511 Request.Arg0 = ARM_FID_FFA_PARTITION_INFO_GET_REGS;
512 CopyMem (&Request.Arg1, &ServiceGuidMangled, sizeof (EFI_GUID));
513 Request.Arg3 = ((UINT32)TagValue << 16) | StartIndex;
514
515 ArmCallSxc (&Request, &Result);
516
517 if (Result.Arg0 == ARM_FID_FFA_ERROR) {
518 return FfaStatusToEfiStatus (Result.Arg2);
519 }
520
521 Metadata = Result.Arg2;
522 CurrentIndex = (UINT16)((Metadata >> 16) & 0xFFFF);
523 Count = CurrentIndex - StartIndex + 1;
524 if ((PartDesc == NULL) ||
525 (*PartDescCount < Count))
526 {
527 *PartDescCount = Count;
528 return EFI_BUFFER_TOO_SMALL;
529 }
530
531 *PartDescCount = Count;
532 for (UINTN Index = 0; Index < Count; Index++) {
533 CopyMem (PartDesc + Index, (VOID *)((UINTN)(&Result.Arg3) + Index * sizeof (EFI_FFA_PART_INFO_DESC)), sizeof (EFI_FFA_PART_INFO_DESC));
534 FfaPrepareGuid ((EFI_GUID *)PartDesc->PartitionUuid);
535 }
536
537 if (Tag != NULL) {
538 *Tag = (UINT16)((Metadata >> 32) & 0xFFFF);
539 }
540
541 return EFI_SUCCESS;
542}
543
544EFI_STATUS
545EFIAPI
546FfaNotificationBitmapCreate (
547 IN UINT16 VCpuCount
548 )
549{
550 ARM_SXC_ARGS Request = { 0 };
551 ARM_SXC_ARGS Result = { 0 };
552
553 Request.Arg0 = ARM_FID_FFA_NOTIFICATION_BITMAP_CREATE;
554 Request.Arg1 = gPartId;
555 Request.Arg2 = VCpuCount;
556
557 ArmCallSxc (&Request, &Result);
558
559 if (Result.Arg0 == ARM_FID_FFA_ERROR) {
560 return FfaStatusToEfiStatus (Result.Arg2);
561 }
562
563 return EFI_SUCCESS;
564}
565
566EFI_STATUS
567EFIAPI
568FfaNotificationBitmapDestroy (
569 VOID
570 )
571{
572 ARM_SXC_ARGS Request = { 0 };
573 ARM_SXC_ARGS Result = { 0 };
574
575 Request.Arg0 = ARM_FID_FFA_NOTIFICATION_BITMAP_DESTROY;
576 Request.Arg1 = gPartId;
577
578 ArmCallSxc (&Request, &Result);
579
580 if (Result.Arg0 == ARM_FID_FFA_ERROR) {
581 return FfaStatusToEfiStatus (Result.Arg2);
582 }
583
584 return EFI_SUCCESS;
585}
586
587EFI_STATUS
588EFIAPI
589FfaNotificationBind (
590 IN UINT16 DestinationId,
591 IN UINT32 Flags,
592 IN UINT64 NotificationBitmap
593 )
594{
595 ARM_SXC_ARGS Request = { 0 };
596 ARM_SXC_ARGS Result = { 0 };
597
598 Request.Arg0 = ARM_FID_FFA_NOTIFICATION_BIND;
599 Request.Arg1 = ((UINT32)DestinationId << 16) | gPartId;
600 Request.Arg2 = Flags;
601 Request.Arg3 = (UINT32)NotificationBitmap;
602 Request.Arg4 = (UINT32)(NotificationBitmap >> 32);
603
604 ArmCallSxc (&Request, &Result);
605
606 if (Result.Arg0 == ARM_FID_FFA_ERROR) {
607 return FfaStatusToEfiStatus (Result.Arg2);
608 }
609
610 return EFI_SUCCESS;
611}
612
613EFI_STATUS
614EFIAPI
615FfaNotificationUnbind (
616 IN UINT16 DestinationId,
617 IN UINT64 NotificationBitmap
618 )
619{
620 ARM_SXC_ARGS Request = { 0 };
621 ARM_SXC_ARGS Result = { 0 };
622
623 Request.Arg0 = ARM_FID_FFA_NOTIFICATION_UNBIND;
624 Request.Arg1 = ((UINT32)DestinationId << 16) | gPartId;
625 Request.Arg2 = 0;
626 Request.Arg3 = (UINT32)NotificationBitmap;
627 Request.Arg4 = (UINT32)(NotificationBitmap >> 32);
628
629 ArmCallSxc (&Request, &Result);
630
631 if (Result.Arg0 == ARM_FID_FFA_ERROR) {
632 return FfaStatusToEfiStatus (Result.Arg2);
633 }
634
635 return EFI_SUCCESS;
636}
637
638EFI_STATUS
639EFIAPI
640FfaMemDonateRxTx (
641 UINT32 TotalLength,
642 UINT32 FragmentLength,
643 UINT64 *Handle
644 )
645{
646 return FfaMemDonate (TotalLength, FragmentLength, NULL, 0, Handle);
647}
648
649EFI_STATUS
650EFIAPI
651FfaMemLend (
652 UINT32 TotalLength,
653 UINT32 FragmentLength,
654 VOID *BufferAddr,
655 UINT32 PageCount,
656 UINT64 *Handle
657 )
658{
659 ARM_SXC_ARGS Request = { 0 };
660 ARM_SXC_ARGS Result = { 0 };
661
662 Request.Arg0 = (BufferAddr) ? ARM_FID_FFA_MEM_LEND_AARCH64 : ARM_FID_FFA_MEM_LEND_AARCH32;
663 Request.Arg1 = TotalLength;
664 Request.Arg2 = FragmentLength;
665 Request.Arg3 = (UINTN)BufferAddr;
666 Request.Arg4 = PageCount;
667
668 ArmCallSxc (&Request, &Result);
669
670 if (Result.Arg0 == ARM_FID_FFA_ERROR) {
671 *Handle = 0U;
672 return FfaStatusToEfiStatus (Result.Arg2);
673 }
674
675 /*
676 * There are no 64-bit parameters returned with FFA_SUCCESS, the SPMC
677 * will use the default 32-bit version.
678 */
679 ASSERT (Result.Arg0 == ARM_FID_FFA_SUCCESS_AARCH32);
680 *Handle = ((UINT64)Result.Arg3 << 32) | Result.Arg2;
681 return EFI_SUCCESS;
682}
683
684EFI_STATUS
685EFIAPI
686FfaMemLendRxTx (
687 UINT32 TotalLength,
688 UINT32 FragmentLength,
689 UINT64 *Handle
690 )
691{
692 return FfaMemLend (TotalLength, FragmentLength, NULL, 0, Handle);
693}
694
695EFI_STATUS
696EFIAPI
697FfaMemShare (
698 UINT32 TotalLength,
699 UINT32 FragmentLength,
700 VOID *BufferAddr,
701 UINT32 PageCount,
702 UINT64 *Handle
703 )
704{
705 ARM_SXC_ARGS Request = { 0 };
706 ARM_SXC_ARGS Result = { 0 };
707
708 Request.Arg0 = (BufferAddr) ? ARM_FID_FFA_MEM_SHARE_AARCH64 : ARM_FID_FFA_MEM_SHARE_AARCH32;
709 Request.Arg1 = TotalLength;
710 Request.Arg2 = FragmentLength;
711 Request.Arg3 = (UINTN)BufferAddr;
712 Request.Arg4 = PageCount;
713
714 ArmCallSxc (&Request, &Result);
715
716 if (Result.Arg0 == ARM_FID_FFA_ERROR) {
717 *Handle = 0U;
718 return FfaStatusToEfiStatus (Result.Arg2);
719 }
720
721 /*
722 * There are no 64-bit parameters returned with FFA_SUCCESS, the SPMC
723 * will use the default 32-bit version.
724 */
725 ASSERT (Result.Arg0 == ARM_FID_FFA_SUCCESS_AARCH32);
726 *Handle = ((UINT64)Result.Arg3 << 32) | Result.Arg2;
727 return EFI_SUCCESS;
728}
729
730EFI_STATUS
731EFIAPI
732FfaMemShareRxTx (
733 UINT32 TotalLength,
734 UINT32 FragmentLength,
735 UINT64 *Handle
736 )
737{
738 return FfaMemShare (TotalLength, FragmentLength, NULL, 0, Handle);
739}
740
741EFI_STATUS
742EFIAPI
743FfaMemRetrieveReq (
744 UINT32 TotalLength,
745 UINT32 FragmentLength,
746 VOID *BufferAddr,
747 UINT32 PageCount,
748 UINT32 *RespTotalLength,
749 UINT32 *RespFragmentLength
750 )
751{
752 ARM_SXC_ARGS Request = { 0 };
753 ARM_SXC_ARGS Result = { 0 };
754
755 Request.Arg0 = (BufferAddr) ? ARM_FID_FFA_MEM_RETRIEVE_REQ_AARCH64 : ARM_FID_FFA_MEM_RETRIEVE_REQ_AARCH32;
756 Request.Arg1 = TotalLength;
757 Request.Arg2 = FragmentLength;
758 Request.Arg3 = (UINTN)BufferAddr;
759 Request.Arg4 = PageCount;
760
761 ArmCallSxc (&Request, &Result);
762
763 if (Result.Arg0 == ARM_FID_FFA_ERROR) {
764 *RespTotalLength = 0U;
765 *RespFragmentLength = 0U;
766 return FfaStatusToEfiStatus (Result.Arg2);
767 }
768
769 ASSERT (Result.Arg0 == ARM_FID_FFA_MEM_RETRIEVE_RESP);
770 *RespTotalLength = Result.Arg1;
771 *RespFragmentLength = Result.Arg2;
772 return EFI_SUCCESS;
773}
774
775EFI_STATUS
776EFIAPI
777FfaMemRetrieveReqRxTx (
778 UINT32 TotalLength,
779 UINT32 FragmentLength,
780 UINT32 *RespTotalLength,
781 UINT32 *RespFragmentLength
782 )
783{
784 return FfaMemRetrieveReq (
785 TotalLength,
786 FragmentLength,
787 NULL,
788 0,
789 RespTotalLength,
790 RespFragmentLength
791 );
792}
793
794EFI_STATUS
795EFIAPI
796FfaMemRelinquish (
797 VOID
798 )
799{
800 ARM_SXC_ARGS Request = { 0 };
801 ARM_SXC_ARGS Result = { 0 };
802
803 Request.Arg0 = ARM_FID_FFA_MEM_RETRIEVE_RELINQUISH;
804
805 ArmCallSxc (&Request, &Result);
806
807 if (Result.Arg0 == ARM_FID_FFA_ERROR) {
808 return FfaStatusToEfiStatus (Result.Arg2);
809 }
810
811 ASSERT (Result.Arg0 == ARM_FID_FFA_SUCCESS_AARCH32);
812 return EFI_SUCCESS;
813}
814
815EFI_STATUS
816EFIAPI
817FfaMemReclaim (
818 UINT64 Handle,
819 UINT32 Flags
820 )
821{
822 ARM_SXC_ARGS Request = { 0 };
823 ARM_SXC_ARGS Result = { 0 };
824 UINT32 HandleHi = 0;
825 UINT32 HandleLo = 0;
826
827 HandleHi = (Handle >> 32) & MAX_UINT32;
828 HandleLo = Handle & MAX_UINT32;
829
830 Request.Arg0 = ARM_FID_FFA_MEM_RETRIEVE_RECLAIM;
831 Request.Arg1 = HandleLo;
832 Request.Arg2 = HandleHi;
833 Request.Arg3 = Flags;
834
835 ArmCallSxc (&Request, &Result);
836
837 if (Result.Arg0 == ARM_FID_FFA_ERROR) {
838 return FfaStatusToEfiStatus (Result.Arg2);
839 }
840
841 ASSERT (Result.Arg0 == ARM_FID_FFA_SUCCESS_AARCH32);
842 return EFI_SUCCESS;
843}
844
845EFI_STATUS
846EFIAPI
847FfaMemPermGet (
848 CONST VOID *BaseAddr,
849 UINT32 *MemoryPerm
850 )
851{
852 ARM_SXC_ARGS Request = { 0 };
853 ARM_SXC_ARGS Result = { 0 };
854
855 Request.Arg0 = ARM_FID_FFA_MEM_PERM_GET_AARCH32;
856 Request.Arg1 = (UINTN)BaseAddr;
857
858 ArmCallSxc (&Request, &Result);
859
860 if (Result.Arg0 == ARM_FID_FFA_ERROR) {
861 return FfaStatusToEfiStatus (Result.Arg2);
862 }
863
864 ASSERT (Result.Arg0 == ARM_FID_FFA_SUCCESS_AARCH32);
865 *MemoryPerm = Result.Arg2;
866 return EFI_SUCCESS;
867}
868
869EFI_STATUS
870EFIAPI
871FfaMemPermSet (
872 CONST VOID *BaseAddr,
873 UINT32 PageCount,
874 UINT32 MemoryPerm
875 )
876{
877 ARM_SXC_ARGS Request = { 0 };
878 ARM_SXC_ARGS Result = { 0 };
879
880 ASSERT ((MemoryPerm & ARM_FFA_MEM_PERM_RESERVED_MASK) == 0);
881
882 Request.Arg0 = ARM_FID_FFA_MEM_PERM_SET_AARCH32;
883 Request.Arg1 = (UINTN)BaseAddr;
884 Request.Arg2 = PageCount;
885 Request.Arg3 = MemoryPerm;
886
887 ArmCallSxc (&Request, &Result);
888
889 if (Result.Arg0 == ARM_FID_FFA_ERROR) {
890 return FfaStatusToEfiStatus (Result.Arg2);
891 }
892
893 ASSERT (Result.Arg0 == ARM_FID_FFA_SUCCESS_AARCH32);
894 return EFI_SUCCESS;
895}
896
897EFI_STATUS
898EFIAPI
899FfaConsoleLog32 (
900 CONST CHAR8 *Message,
901 UINTN Length
902 )
903{
904 ARM_SXC_ARGS Request = { 0 };
905 ARM_SXC_ARGS Result = { 0 };
906 UINT32 CharLists[6] = { 0 };
907
908 ASSERT (Length > 0 && Length <= sizeof (CharLists));
909
910 CopyMem (CharLists, Message, MIN (Length, sizeof (CharLists)));
911
912 Request.Arg0 = ARM_FID_FFA_CONSOLE_LOG_AARCH32;
913 Request.Arg1 = Length;
914 Request.Arg2 = CharLists[0];
915 Request.Arg3 = CharLists[1];
916 Request.Arg4 = CharLists[2];
917 Request.Arg5 = CharLists[3];
918 Request.Arg6 = CharLists[4];
919 Request.Arg7 = CharLists[5];
920
921 ArmCallSxc (&Request, &Result);
922
923 if (Result.Arg0 == ARM_FID_FFA_ERROR) {
924 return FfaStatusToEfiStatus (Result.Arg2);
925 }
926
927 ASSERT (Result.Arg0 == ARM_FID_FFA_SUCCESS_AARCH32);
928 return EFI_SUCCESS;
929}
930
931EFI_STATUS
932EFIAPI
933FfaConsoleLog64 (
934 CONST char *Message,
935 UINTN Length
936 )
937{
938 ARM_SXC_ARGS Request = { 0 };
939 ARM_SXC_ARGS Result = { 0 };
940 UINT64 CharLists[16] = { 0 };
941
942 ASSERT (Length > 0 && Length <= sizeof (CharLists));
943
944 CopyMem (CharLists, Message, MIN (Length, sizeof (CharLists)));
945
946 Request.Arg0 = ARM_FID_FFA_CONSOLE_LOG_AARCH64;
947 Request.Arg1 = Length;
948 Request.Arg2 = CharLists[0];
949 Request.Arg3 = CharLists[1];
950 Request.Arg4 = CharLists[2];
951 Request.Arg5 = CharLists[3];
952 Request.Arg6 = CharLists[4];
953 Request.Arg7 = CharLists[5];
954 Request.Arg8 = CharLists[6];
955 Request.Arg9 = CharLists[7];
956 Request.Arg10 = CharLists[8];
957 Request.Arg11 = CharLists[9];
958 Request.Arg12 = CharLists[10];
959 Request.Arg13 = CharLists[11];
960 Request.Arg14 = CharLists[12];
961 Request.Arg15 = CharLists[13];
962 Request.Arg16 = CharLists[14];
963 Request.Arg17 = CharLists[15];
964
965 ArmCallSxc (&Request, &Result);
966
967 if (Result.Arg0 == ARM_FID_FFA_ERROR) {
968 return FfaStatusToEfiStatus (Result.Arg2);
969 }
970
971 ASSERT (Result.Arg0 == ARM_FID_FFA_SUCCESS_AARCH32);
972 return EFI_SUCCESS;
973}
974