From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by mx.groups.io with SMTP id smtpd.web11.1250.1689086253937089093 for ; Tue, 11 Jul 2023 07:37:34 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: arm.com, ip: 217.140.110.172, mailfrom: nishant.sharma@arm.com) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id DEA8D1FB; Tue, 11 Jul 2023 07:38:15 -0700 (PDT) Received: from usa.arm.com (iss-desktop02.cambridge.arm.com [10.1.196.79]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id C0A883F740; Tue, 11 Jul 2023 07:37:32 -0700 (PDT) From: "Nishant Sharma" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Sami Mujawar , Thomas Abraham , Sayanta Pattanayak , Achin Gupta Subject: [edk2-platforms][PATCH V1 18/20] ArmPkg/MmCommunicationDxe: Discover the StMM SP Date: Tue, 11 Jul 2023 15:36:56 +0100 Message-Id: <20230711143658.781597-19-nishant.sharma@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230711143658.781597-1-nishant.sharma@arm.com> References: <20230711143658.781597-1-nishant.sharma@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Achin Gupta This patch adds support for discovering the presence of the SP using the EFI_MM_COMMUNICATION_PROTOCOL GUID that implements Standalone MM drivers. This is done by querying the framework through FFA_PARTITION_INFO_GET whether any partition that implements the EFI_MM_COMMUNICATION_PROTOCOL is present or not. The partition ID and its properties are stashed for use in subsequent communication with the StMM SP. Signed-off-by: Achin Gupta Signed-off-by: Nishant Sharma --- ArmPkg/Include/IndustryStandard/ArmFfaSvc.h | 24 +++++ ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.c | 93 +++++++++++++++= ++++- 2 files changed, 114 insertions(+), 3 deletions(-) diff --git a/ArmPkg/Include/IndustryStandard/ArmFfaSvc.h b/ArmPkg/Include= /IndustryStandard/ArmFfaSvc.h index f78442a465e1..530af8bd3c2e 100644 --- a/ArmPkg/Include/IndustryStandard/ArmFfaSvc.h +++ b/ArmPkg/Include/IndustryStandard/ArmFfaSvc.h @@ -19,6 +19,9 @@ #define ARM_SVC_ID_FFA_VERSION_AARCH32 0x84000063 #define ARM_SVC_ID_FFA_RXTX_MAP_AARCH32 0x84000066 #define ARM_SVC_ID_FFA_RXTX_MAP_AARCH64 0xC4000066 +#define ARM_SVC_ID_FFA_RX_RELEASE_AARCH32 0x84000065 +#define ARM_SVC_ID_FFA_RXTX_UNMAP_AARCH32 0x84000067 +#define ARM_SVC_ID_FFA_PARTITION_INFO_GET_AARCH32 0x84000068 #define ARM_SVC_ID_FFA_ID_GET_AARCH32 0x84000069 #define ARM_SVC_ID_FFA_MSG_SEND_DIRECT_REQ_AARCH32 0x8400006F #define ARM_SVC_ID_FFA_MSG_SEND_DIRECT_RESP_AARCH32 0x84000070 @@ -154,4 +157,25 @@ typedef struct { UINT64 Reserved; } EFI_FFA_BOOT_INFO_HEADER; =20 +// FF-A partition information descriptor +typedef struct { + UINT16 PartId; + UINT16 EcCnt; + UINT32 PartProps; + UINT32 PartGuid[4]; +} EFI_FFA_PART_INFO_DESC; + +#define PART_INFO_PROP_MASK 0x3f +#define PART_INFO_PROP_SHIFT 0 +#define PART_INFO_PROP_DIR_MSG_RECV_BIT (1u << 0) +#define PART_INFO_PROP_DIR_MSG_SEND_BIT (1u << 1) +#define PART_INFO_PROP_INDIR_MSG_BIT (1u << 2) +#define PART_INFO_PROP_NOTIFICATIONS_BIT (1u << 3) +#define PART_INFO_PROP_EP_TYPE_MASK 0x3 +#define PART_INFO_PROP_EP_TYPE_SHIFT 4 +#define PART_INFO_PROP_EP_PE 0 +#define PART_INFO_PROP_EP_SEPID_IND 1 +#define PART_INFO_PROP_EP_SEPID_DEP 2 +#define PART_INFO_PROP_EP_AUX 3 + #endif // ARM_FFA_SVC_H_ diff --git a/ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.c b/ArmPkg= /Drivers/MmCommunicationDxe/MmCommunication.c index 39a1b329b9ea..94a5d96c051d 100644 --- a/ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.c +++ b/ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.c @@ -8,6 +8,7 @@ =20 #include #include +#include #include #include #include @@ -28,6 +29,11 @@ // STATIC UINT16 mFfaPartId; =20 +// Partition information of the StMM SP if FF-A support is enabled +// TODO: Revisit assumption that there is only a single StMM SP +// +STATIC EFI_FFA_PART_INFO_DESC mStmmPartInfo; + // // RX/TX pair if FF-A support is enabled // @@ -298,7 +304,9 @@ GetMmCompatibility ( { EFI_STATUS Status; UINT32 MmVersion; + UINT32 SmccUuid[4]; ARM_SMC_ARGS SmcArgs =3D {0}; + EFI_GUID MmCommProtGuid =3D EFI_MM_COMMUNICATION_PROTOCOL_GUID; =20 if (FixedPcdGet32 (PcdFfaEnable) !=3D 0) { SmcArgs.Arg0 =3D ARM_SVC_ID_FFA_VERSION_AARCH32; @@ -335,14 +343,21 @@ GetMmCompatibility ( Status =3D EFI_UNSUPPORTED; } =20 - // If FF-A is supported then discover our ID and register our RX/TX bu= ffers. + // If FF-A is supported then discover the StMM SP's presence, ID, our = ID and + // register our RX/TX buffers. if (FixedPcdGet32 (PcdFfaEnable) !=3D 0) { + EFI_FFA_PART_INFO_DESC *StmmPartInfo; + // Get our ID ZeroMem(&SmcArgs, sizeof(SmcArgs)); SmcArgs.Arg0 =3D ARM_SVC_ID_FFA_ID_GET_AARCH32; ArmCallSmc (&SmcArgs); if (SmcArgs.Arg0 =3D=3D ARM_SVC_ID_FFA_ERROR_AARCH32) { - DEBUG ((DEBUG_ERROR, "Unable to retrieve FF-A partition ID (%d).\n= ", SmcArgs.Arg2)); + DEBUG (( + DEBUG_ERROR, + "Unable to retrieve FF-A partition ID (%d).\n", + SmcArgs.Arg2 + )); return EFI_UNSUPPORTED; } DEBUG ((DEBUG_INFO, "FF-A partition ID =3D 0x%lx.\n", SmcArgs.Arg2))= ; @@ -355,11 +370,83 @@ GetMmCompatibility ( SmcArgs.Arg3 =3D EFI_PAGE_SIZE / SIZE_4KB; ArmCallSmc (&SmcArgs); if (SmcArgs.Arg0 =3D=3D ARM_SVC_ID_FFA_ERROR_AARCH32) { - DEBUG ((DEBUG_ERROR, "Unable to register FF-A RX/TX buffers (%d).\= n", SmcArgs.Arg2)); + DEBUG (( + DEBUG_ERROR, + "Unable to register FF-A RX/TX buffers (%d).\n", + SmcArgs.Arg2 + )); return EFI_UNSUPPORTED; } =20 + // Discover the StMM SP after converting the EFI_GUID to a format TF= -A will + // understand. + SmcArgs.Arg0 =3D ARM_SVC_ID_FFA_PARTITION_INFO_GET_AARCH32; + MmCommProtGuid.Data2 +=3D MmCommProtGuid.Data3; + MmCommProtGuid.Data3 =3D MmCommProtGuid.Data2 - MmCommProtGuid.Data3= ; + MmCommProtGuid.Data2 =3D MmCommProtGuid.Data2 - MmCommProtGuid.Data3= ; + CopyMem ((VOID *) SmccUuid, (VOID *) &MmCommProtGuid, sizeof(EFI_GUI= D)); + SmcArgs.Arg1 =3D SmccUuid[0]; + SmcArgs.Arg2 =3D SmccUuid[1]; + SmcArgs.Arg3 =3D SmccUuid[2]; + SmcArgs.Arg3 =3D SwapBytes32(SmcArgs.Arg3); + SmcArgs.Arg4 =3D SmccUuid[3]; + SmcArgs.Arg4 =3D SwapBytes32(SmcArgs.Arg4); + ArmCallSmc (&SmcArgs); + if (SmcArgs.Arg0 =3D=3D ARM_SVC_ID_FFA_ERROR_AARCH32) { + DEBUG (( + DEBUG_ERROR, + "Unable to discover FF-A StMM SP (%d).\n", + SmcArgs.Arg2 + )); + goto ffa_init_error; + } + + // Retrieve the partition information from the RX buffer + StmmPartInfo =3D (EFI_FFA_PART_INFO_DESC *) FfaRxBuf; + + // TODO: Sanity check the partition type. + DEBUG ((DEBUG_INFO, "Discovered FF-A StMM SP.")); + DEBUG (( + DEBUG_INFO, + "ID =3D 0x%lx, Execution contexts =3D %d, Properties =3D 0x%lx. \n= ", + StmmPartInfo->PartId, + StmmPartInfo->EcCnt, + StmmPartInfo->PartProps + )); + + // Make a local copy + mStmmPartInfo =3D *StmmPartInfo; + + // Release the RX buffer + ZeroMem(&SmcArgs, sizeof(SmcArgs)); + SmcArgs.Arg0 =3D ARM_SVC_ID_FFA_RX_RELEASE_AARCH32; + SmcArgs.Arg1 =3D mFfaPartId; + ArmCallSmc (&SmcArgs); + + // This should really never fail since there is only a single CPU bo= oting + // and another CPU could not have released the RX buffer before us. + if (SmcArgs.Arg0 =3D=3D ARM_SVC_ID_FFA_ERROR_AARCH32) { + DEBUG (( + DEBUG_ERROR, + "Unable to release FF-A RX buffer (%d).\n", + SmcArgs.Arg2 + )); + ASSERT (0); + goto ffa_init_error; + } + return EFI_SUCCESS; + + ffa_init_error: + // Release the RX/TX pair before exiting. + ZeroMem(&SmcArgs, sizeof(SmcArgs)); + SmcArgs.Arg0 =3D ARM_SVC_ID_FFA_RXTX_UNMAP_AARCH32; + SmcArgs.Arg1 =3D mFfaPartId << 16; // TODO: Use a macro for shift + ArmCallSmc (&SmcArgs); + + // We do not bother checking the error code of the RXTX_UNMAP invoca= tion + // since we did map the buffers and this call must succeed. + return EFI_UNSUPPORTED; } =20 return Status; --=20 2.34.1