microsoft/mu_feature_ffa

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
0585e78f1afa24d3c50c412af8a8d0b220cf4312

Branches

Tags

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

Clone

HTTPS

Download ZIP

FfaFeaturePkg/Library/ArmFfaLibEx/ArmFfaLibEx.c

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