[edk2][PATCH V1 1/1] ArmPkg: introduce FF-A interface support in MM_COMMUNICATE


Sayanta Pattanayak
 

From: Aditya Angadi <aditya.angadi@arm.com>

With the introduction of Firmware Framework for Arm platforms (FF-A),
normal world and secure world endpoints can use FF-A interface for
communication with each other. In this patch, FFA_MSG_SEND_DIRECT_REQ
and FFA_VERSION interfaces are introduced. This change adds an option
to either use the existing SMC interface or the introduced FF-A
interface based on the value of PcdFfaEnable.

Signed-off-by: Aditya Angadi <aditya.angadi@arm.com>
Signed-off-by: Sayanta Pattanayak <sayanta.pattanayak@arm.com>
---
ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.inf | 3 +
ArmPkg/Include/IndustryStandard/ArmFfaSvc.h | 2 +
ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.c | 73 +++++++++++++=
+++----
3 files changed, 63 insertions(+), 15 deletions(-)

diff --git a/ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.inf b/ArmP=
kg/Drivers/MmCommunicationDxe/MmCommunication.inf
index 05b6de73ff34..da8462755a6f 100644
--- a/ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.inf
+++ b/ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.inf
@@ -52,5 +52,8 @@
gArmTokenSpaceGuid.PcdMmBufferBase
gArmTokenSpaceGuid.PcdMmBufferSize
=20
+[FeaturePcd.AARCH64]
+ gArmTokenSpaceGuid.PcdFfaEnable
+
[Depex]
gEfiCpuArchProtocolGuid
diff --git a/ArmPkg/Include/IndustryStandard/ArmFfaSvc.h b/ArmPkg/Include=
/IndustryStandard/ArmFfaSvc.h
index 65b8343ade61..5a300a7295db 100644
--- a/ArmPkg/Include/IndustryStandard/ArmFfaSvc.h
+++ b/ArmPkg/Include/IndustryStandard/ArmFfaSvc.h
@@ -19,6 +19,8 @@
#define ARM_SVC_ID_FFA_VERSION_AARCH32 0x84000063
#define ARM_SVC_ID_FFA_MSG_SEND_DIRECT_REQ_AARCH64 0xC400006F
#define ARM_SVC_ID_FFA_MSG_SEND_DIRECT_RESP_AARCH64 0xC4000070
+#define ARM_SVC_ID_FFA_SUCCESS_AARCH64 0xC4000061
+#define ARM_SVC_ID_FFA_SUCCESS_AARCH32 0x84000060
=20
#define SPM_MAJOR_VERSION_FFA 1
#define SPM_MINOR_VERSION_FFA 0
diff --git a/ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.c b/ArmPkg=
/Drivers/MmCommunicationDxe/MmCommunication.c
index b1e309580988..ff15903473ad 100644
--- a/ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.c
+++ b/ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.c
@@ -18,6 +18,7 @@
=20
#include <Protocol/MmCommunication2.h>
=20
+#include <IndustryStandard/ArmFfaSvc.h>
#include <IndustryStandard/ArmStdSmc.h>
=20
#include "MmCommunicate.h"
@@ -73,6 +74,7 @@ MmCommunication2Communicate (
ARM_SMC_ARGS CommunicateSmcArgs;
EFI_STATUS Status;
UINTN BufferSize;
+ UINTN Ret;
=20
Status =3D EFI_ACCESS_DENIED;
BufferSize =3D 0;
@@ -124,26 +126,55 @@ MmCommunication2Communicate (
return EFI_BAD_BUFFER_SIZE;
}
=20
- // SMC Function ID
- CommunicateSmcArgs.Arg0 =3D ARM_SMC_ID_MM_COMMUNICATE_AARCH64;
-
- // Cookie
- CommunicateSmcArgs.Arg1 =3D 0;
-
// Copy Communication Payload
CopyMem ((VOID *)mNsCommBuffMemRegion.VirtualBase, CommBufferVirtual, =
BufferSize);
=20
- // comm_buffer_address (64-bit physical address)
- CommunicateSmcArgs.Arg2 =3D (UINTN)mNsCommBuffMemRegion.PhysicalBase;
+ // Use the FF-A interface if enabled.
+ if (FeaturePcdGet (PcdFfaEnable)) {
+ // FF-A Interface ID for direct message communication
+ CommunicateSmcArgs.Arg0 =3D ARM_SVC_ID_FFA_MSG_SEND_DIRECT_REQ_AARCH=
64;
=20
- // comm_size_address (not used, indicated by setting to zero)
- CommunicateSmcArgs.Arg3 =3D 0;
+ // FF-A Destination EndPoint ID, not used as of now
+ CommunicateSmcArgs.Arg1 =3D 0x0;
+
+ // Reserved for future use(MBZ)
+ CommunicateSmcArgs.Arg2 =3D 0x0;
+
+ // Arg3 onwards are the IMPLEMENTATION DEFINED FF-A parameters
+ // SMC Function ID
+ CommunicateSmcArgs.Arg3 =3D ARM_SMC_ID_MM_COMMUNICATE_AARCH64;
+
+ // Cookie
+ CommunicateSmcArgs.Arg4 =3D 0x0;
+
+ // comm_buffer_address (64-bit physical address)
+ CommunicateSmcArgs.Arg5 =3D (UINTN)mNsCommBuffMemRegion.PhysicalBase=
;
+
+ // comm_size_address (not used, indicated by setting to zero)
+ CommunicateSmcArgs.Arg6 =3D 0;
+ } else {
+ // SMC Function ID
+ CommunicateSmcArgs.Arg0 =3D ARM_SMC_ID_MM_COMMUNICATE_AARCH64;
+
+ // Cookie
+ CommunicateSmcArgs.Arg1 =3D 0;
+
+ // comm_buffer_address (64-bit physical address)
+ CommunicateSmcArgs.Arg2 =3D (UINTN)mNsCommBuffMemRegion.PhysicalBase=
;
+
+ // comm_size_address (not used, indicated by setting to zero)
+ CommunicateSmcArgs.Arg3 =3D 0;
+ }
=20
// Call the Standalone MM environment.
ArmCallSmc (&CommunicateSmcArgs);
=20
- switch (CommunicateSmcArgs.Arg0) {
- case ARM_SMC_MM_RET_SUCCESS:
+ Ret =3D CommunicateSmcArgs.Arg0;
+
+ if ((FeaturePcdGet (PcdFfaEnable) &&
+ (Ret =3D=3D ARM_SVC_ID_FFA_SUCCESS_AARCH64)) ||
+ (Ret =3D=3D ARM_SMC_MM_RET_SUCCESS))
+ {
ZeroMem (CommBufferVirtual, BufferSize);
// On successful return, the size of data being returned is inferred=
from
// MessageLength + Header.
@@ -158,8 +189,14 @@ MmCommunication2Communicate (
BufferSize
);
Status =3D EFI_SUCCESS;
- break;
+ return Status;
+ }
=20
+ if (FeaturePcdGet (PcdFfaEnable))
+ Ret =3D CommunicateSmcArgs.Arg2;
+
+ // Error Codes are same for FF-A and SMC interface
+ switch (Ret) {
case ARM_SMC_MM_RET_INVALID_PARAMS:
Status =3D EFI_INVALID_PARAMETER;
break;
@@ -233,8 +270,14 @@ GetMmCompatibility ()
UINT32 MmVersion;
ARM_SMC_ARGS MmVersionArgs;
=20
- // MM_VERSION uses SMC32 calling conventions
- MmVersionArgs.Arg0 =3D ARM_SMC_ID_MM_VERSION_AARCH32;
+ if (FeaturePcdGet (PcdFfaEnable)) {
+ MmVersionArgs.Arg0 =3D ARM_SVC_ID_FFA_VERSION_AARCH32;
+ MmVersionArgs.Arg1 =3D MM_CALLER_MAJOR_VER << MM_MAJOR_VER_SHIFT;
+ MmVersionArgs.Arg1 |=3D MM_CALLER_MINOR_VER;
+ } else {
+ // MM_VERSION uses SMC32 calling conventions
+ MmVersionArgs.Arg0 =3D ARM_SMC_ID_MM_VERSION_AARCH32;
+ }
=20
ArmCallSmc (&MmVersionArgs);
=20
--=20
2.17.1

Join devel@edk2.groups.io to automatically receive all group messages.