microsoft/mu_feature_ffa

Public

mirrored from https://github.com/microsoft/mu_feature_ffaAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
fix_upload

Branches

Tags

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

Clone

HTTPS

Download ZIP

FfaFeaturePkg/Library/ArmFfaLibEx/ArmFfaLibEx.c

941lines · modeblame

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