microsoft/mu_feature_ffa

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v0.1.3

Branches

Tags

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

Clone

HTTPS

Download ZIP

FfaFeaturePkg/Library/ArmFfaLibEx/ArmFfaLibEx.c

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