From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pl1-f173.google.com (mail-pl1-f173.google.com [209.85.214.173]) by mx.groups.io with SMTP id smtpd.web10.3899.1687907668154770173 for ; Tue, 27 Jun 2023 16:14:28 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="signature has expired" header.i=@gmail.com header.s=20221208 header.b=qPlIxndo; spf=pass (domain: gmail.com, ip: 209.85.214.173, mailfrom: kuqin12@gmail.com) Received: by mail-pl1-f173.google.com with SMTP id d9443c01a7336-1b80b514fb7so16460595ad.0 for ; Tue, 27 Jun 2023 16:14:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1687907667; x=1690499667; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Yu1UKWduhtyt+KusoIs3EmiXR+jrKG1vIi397D8jGLI=; b=qPlIxndoo7O//xcu1c4b1XmkNGUUmU6rzUfPrU4fwpj5mtDoPa0oUpXHiP4MmpmcKT qXYEGfqaY3atArBe3eUDUGV5cbcBETtmBH42Oq8vuasr+tKpxJ9+ffMVaTj6RwCNdL1o A+IhkS8G085a8f764ZK/nkvUn/zC7O5iwRp0BE3Ty955xANDykdLUQFTfIS0tjs69mzy MZAzWDPl8VplGB6rpVF25SCcCLWXzT6Sf3iTZZpw/G3uyiMOD1z4FXFJHdpNVS3guOop QUJzUtfhgMCQpmXlsy3N9tyKO/gx4jcalh1HetkUKObcZhXbCQreJ0QqHcaCJapIdLF8 mMYA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687907667; x=1690499667; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Yu1UKWduhtyt+KusoIs3EmiXR+jrKG1vIi397D8jGLI=; b=UdFc5em/P1myCDGUl48aldR0O03E1ifNM6fszR1A0Lmh/U01IKVoQjvULTfDHJkH/C 4rx+o5CaHOL9WxKrhoTKi1YsIc0gvXVtmWsDBiTHfcOmhFev5Be9/6s5krkUO7622C5Z DEXws6zDVnQ6Y9oNXKq3yyxp2GkeUYs+Fp+wYUE18OW3syKitlbAAC1q+uZzqngeHuZP aObgAyB5GQ1sQetX5lf8P6jWLL0E/L4g9S6LByupxA5TYJWqNvtyrc0934o0gzjaX+mf cp+AvpqOk8CRinVWvY0ZOSo3W1IcPTvceY1tMdcdDPxlQKvYe91efOkO0m5EUJ5vSo0w Yi9Q== X-Gm-Message-State: AC+VfDwIneb6D3fYlX8TzzRgQl1+0VTfmaJHvbL2rpgfGgF+y2LF56OM SuFL0b+BiOHkP9pyoMQT9WGHW93Dkx8= X-Google-Smtp-Source: ACHHUZ5ah8SYGhlJ8F40LBLjguqMuZSRtc4nErs9HDJekoO7ehQCLblGCqjesT9SVN3It6iObrOUpQ== X-Received: by 2002:a17:902:ef94:b0:1b7:edcd:8dcd with SMTP id iz20-20020a170902ef9400b001b7edcd8dcdmr6283965plb.21.1687907667272; Tue, 27 Jun 2023 16:14:27 -0700 (PDT) Return-Path: Received: from MININT-0U7P5GU.redmond.corp.microsoft.com ([2001:4898:80e8:9:6107:268c:453f:a14b]) by smtp.gmail.com with ESMTPSA id bj8-20020a170902850800b001b7fa81b145sm4768947plb.265.2023.06.27.16.14.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 27 Jun 2023 16:14:26 -0700 (PDT) From: "Kun Qin" To: devel@edk2.groups.io Cc: Leif Lindholm , Ard Biesheuvel , Sami Mujawar , Ronny Hansen , Shriram Masanamuthu Chinnathurai , Preshit Harlikar Subject: [PATCH v3 1/2] ArmPkg: MmCommunicationPei: Introduce MM communicate in PEI Date: Tue, 27 Jun 2023 16:14:19 -0700 Message-ID: <20230627231421.1956-2-kuqin12@gmail.com> X-Mailer: git-send-email 2.41.0.windows.1 In-Reply-To: <20230627231421.1956-1-kuqin12@gmail.com> References: <20230627231421.1956-1-kuqin12@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Kun Qin REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4464 This change introduced the MM communicate support in PEI phase for ARM based platforms. Similar to the DXE counterpart, `PcdMmBufferBase` is used as communicate buffer and SMC will be invoked to communicate to TrustZone when MMI is requested. Cc: Leif Lindholm Cc: Ard Biesheuvel Cc: Sami Mujawar Co-authored-by: Ronny Hansen Co-authored-by: Shriram Masanamuthu Chinnathurai Co-authored-by: Preshit Harlikar Signed-off-by: Kun Qin --- Notes: v2: - Adjustment to CommSize checks [Sami] - Added more debug prints for error returns. =20=20=20=20 v3: - Removed internal header file [Ard] - Added "STATIC" and "CONST" [Ard] ArmPkg/Drivers/MmCommunicationPei/MmCommunicationPei.c | 221 +++++++++++= +++++++++ ArmPkg/ArmPkg.dsc | 2 + ArmPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf | 40 ++++ 3 files changed, 263 insertions(+) diff --git a/ArmPkg/Drivers/MmCommunicationPei/MmCommunicationPei.c b/ArmPk= g/Drivers/MmCommunicationPei/MmCommunicationPei.c new file mode 100644 index 000000000000..5dbe99fc3134 --- /dev/null +++ b/ArmPkg/Drivers/MmCommunicationPei/MmCommunicationPei.c @@ -0,0 +1,221 @@ +/** @file -- MmCommunicationPei.c=0D + Provides an interface to send MM request in PEI=0D +=0D + Copyright (c) 2016-2021, Arm Limited. All rights reserved.
=0D + Copyright (c) Microsoft Corporation.=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +=0D +#include =0D +#include =0D +=0D +#include =0D +#include =0D +=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +/**=0D + MmCommunicationPeim=0D + Communicates with a registered handler.=0D + This function provides a service to send and receive messages from a reg= istered UEFI service during PEI.=0D +=0D + @param[in] This The EFI_PEI_MM_COMMUNICATION_PPI instanc= e.=0D + @param[in, out] CommBuffer Pointer to the data buffer=0D + @param[in, out] CommSize The size of the data buffer being passed= in. On exit, the=0D + size of data being returned. Zero if the= handler does not=0D + wish to reply with any data.=0D +=0D + @retval EFI_SUCCESS The message was successfully posted.=0D + @retval EFI_INVALID_PARAMETER CommBuffer or CommSize was NULL, or *Com= mSize does not=0D + match MessageLength + sizeof (EFI_MM_COM= MUNICATE_HEADER).=0D + @retval EFI_BAD_BUFFER_SIZE The buffer is too large for the MM imple= mentation.=0D + If this error is returned, the MessageLe= ngth field=0D + in the CommBuffer header or the integer = pointed by=0D + CommSize, are updated to reflect the max= imum payload=0D + size the implementation can accommodate.= =0D + @retval EFI_ACCESS_DENIED The CommunicateBuffer parameter or CommS= ize parameter,=0D + if not omitted, are in address range tha= t cannot be=0D + accessed by the MM environment.=0D +**/=0D +STATIC=0D +EFI_STATUS=0D +EFIAPI=0D +MmCommunicationPeim (=0D + IN CONST EFI_PEI_MM_COMMUNICATION_PPI *This,=0D + IN OUT VOID *CommBuffer,=0D + IN OUT UINTN *CommSize=0D + )=0D +{=0D + EFI_MM_COMMUNICATE_HEADER *CommunicateHeader;=0D + EFI_MM_COMMUNICATE_HEADER *TempCommHeader;=0D + ARM_SMC_ARGS CommunicateSmcArgs;=0D + EFI_STATUS Status;=0D + UINTN BufferSize;=0D +=0D + ZeroMem (&CommunicateSmcArgs, sizeof (ARM_SMC_ARGS));=0D +=0D + // Check that our static buffer is looking good.=0D + // We are using PcdMmBufferBase to transfer variable data.=0D + // We are not using the full size of the buffer since there is a cost=0D + // of copying data between Normal and Secure World.=0D + if ((PcdGet64 (PcdMmBufferBase) =3D=3D 0) || (PcdGet64 (PcdMmBufferSize)= =3D=3D 0)) {=0D + ASSERT (PcdGet64 (PcdMmBufferSize) > 0);=0D + ASSERT (PcdGet64 (PcdMmBufferBase) !=3D 0);=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + //=0D + // Check parameters=0D + //=0D + if ((CommBuffer =3D=3D NULL) || (CommSize =3D=3D NULL)) {=0D + ASSERT (CommBuffer !=3D NULL);=0D + ASSERT (CommSize !=3D NULL);=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + // If the length of the CommBuffer is 0 then return the expected length.= =0D + // This case can be used by the consumer of this driver to find out the= =0D + // max size that can be used for allocating CommBuffer.=0D + if ((*CommSize =3D=3D 0) || (*CommSize > (UINTN)PcdGet64 (PcdMmBufferSiz= e))) {=0D + DEBUG ((=0D + DEBUG_ERROR,=0D + "%a Invalid CommSize value 0x%llx!\n",=0D + __func__,=0D + *CommSize=0D + ));=0D + *CommSize =3D (UINTN)PcdGet64 (PcdMmBufferSize);=0D + return EFI_BAD_BUFFER_SIZE;=0D + }=0D +=0D + // Given CommBuffer is not NULL here, we use it to test the legitimacy o= f CommSize.=0D + TempCommHeader =3D (EFI_MM_COMMUNICATE_HEADER *)(UINTN)CommBuffer;=0D +=0D + // CommBuffer is a mandatory parameter. Hence, Rely on=0D + // MessageLength + Header to ascertain the=0D + // total size of the communication payload rather than=0D + // rely on optional CommSize parameter=0D + BufferSize =3D TempCommHeader->MessageLength +=0D + sizeof (TempCommHeader->HeaderGuid) +=0D + sizeof (TempCommHeader->MessageLength);=0D +=0D + //=0D + // If CommSize is supplied it must match MessageLength + sizeof (EFI_MM_= COMMUNICATE_HEADER);=0D + //=0D + if (*CommSize !=3D BufferSize) {=0D + DEBUG ((=0D + DEBUG_ERROR,=0D + "%a Unexpected CommSize value, has: 0x%llx vs. expected: 0x%llx!\n",= =0D + __func__,=0D + *CommSize,=0D + BufferSize=0D + ));=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + // Now we know that the size is something we can handle, copy it over to= the designated comm buffer.=0D + CommunicateHeader =3D (EFI_MM_COMMUNICATE_HEADER *)(UINTN)(PcdGet64 (Pcd= MmBufferBase));=0D +=0D + CopyMem (CommunicateHeader, CommBuffer, *CommSize);=0D +=0D + // SMC Function ID=0D + CommunicateSmcArgs.Arg0 =3D ARM_SMC_ID_MM_COMMUNICATE_AARCH64;=0D +=0D + // Cookie=0D + CommunicateSmcArgs.Arg1 =3D 0;=0D +=0D + // comm_buffer_address (64-bit physical address)=0D + CommunicateSmcArgs.Arg2 =3D (UINTN)CommunicateHeader;=0D +=0D + // comm_size_address (not used, indicated by setting to zero)=0D + CommunicateSmcArgs.Arg3 =3D 0;=0D +=0D + // Call the Standalone MM environment.=0D + ArmCallSmc (&CommunicateSmcArgs);=0D +=0D + switch (CommunicateSmcArgs.Arg0) {=0D + case ARM_SMC_MM_RET_SUCCESS:=0D + // On successful return, the size of data being returned is inferred= from=0D + // MessageLength + Header.=0D + BufferSize =3D CommunicateHeader->MessageLength +=0D + sizeof (CommunicateHeader->HeaderGuid) +=0D + sizeof (CommunicateHeader->MessageLength);=0D + if (BufferSize > (UINTN)PcdGet64 (PcdMmBufferSize)) {=0D + // Something bad has happened, we should have landed in ARM_SMC_MM= _RET_NO_MEMORY=0D + DEBUG ((=0D + DEBUG_ERROR,=0D + "%a Returned buffer exceeds communication buffer limit. Has: 0x%= llx vs. max: 0x%llx!\n",=0D + __func__,=0D + BufferSize,=0D + (UINTN)PcdGet64 (PcdMmBufferSize)=0D + ));=0D + Status =3D EFI_BAD_BUFFER_SIZE;=0D + break;=0D + }=0D +=0D + CopyMem (CommBuffer, CommunicateHeader, BufferSize);=0D + *CommSize =3D BufferSize;=0D + Status =3D EFI_SUCCESS;=0D + break;=0D +=0D + case ARM_SMC_MM_RET_INVALID_PARAMS:=0D + Status =3D EFI_INVALID_PARAMETER;=0D + break;=0D +=0D + case ARM_SMC_MM_RET_DENIED:=0D + Status =3D EFI_ACCESS_DENIED;=0D + break;=0D +=0D + case ARM_SMC_MM_RET_NO_MEMORY:=0D + // Unexpected error since the CommSize was checked for zero length=0D + // prior to issuing the SMC=0D + Status =3D EFI_OUT_OF_RESOURCES;=0D + ASSERT (0);=0D + break;=0D +=0D + default:=0D + Status =3D EFI_ACCESS_DENIED;=0D + ASSERT (0);=0D + break;=0D + }=0D +=0D + return Status;=0D +}=0D +=0D +//=0D +// Module globals for the MM Communication PPI=0D +//=0D +STATIC CONST EFI_PEI_MM_COMMUNICATION_PPI mPeiMmCommunication =3D {=0D + MmCommunicationPeim=0D +};=0D +=0D +STATIC CONST EFI_PEI_PPI_DESCRIPTOR mPeiMmCommunicationPpi =3D {=0D + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),=0D + &gEfiPeiMmCommunicationPpiGuid,=0D + (VOID*)&mPeiMmCommunication=0D +};=0D +=0D +/**=0D + Entry point of PEI MM Communication driver=0D +=0D + @param FileHandle Handle of the file being invoked.=0D + Type EFI_PEI_FILE_HANDLE is defined in FfsFindNextF= ile().=0D + @param PeiServices General purpose services available to every PEIM.=0D +=0D + @retval EFI_SUCCESS If the interface could be successfully installed=0D + @retval Others Returned from PeiServicesInstallPpi()=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +MmCommunicationPeiInitialize (=0D + IN EFI_PEI_FILE_HANDLE FileHandle,=0D + IN CONST EFI_PEI_SERVICES **PeiServices=0D + )=0D +{=0D + return PeiServicesInstallPpi (&mPeiMmCommunicationPpi);=0D +}=0D diff --git a/ArmPkg/ArmPkg.dsc b/ArmPkg/ArmPkg.dsc index 6b938ce8b671..4939b3d59b7f 100644 --- a/ArmPkg/ArmPkg.dsc +++ b/ArmPkg/ArmPkg.dsc @@ -162,6 +162,8 @@ [Components.common] ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf=0D ArmPkg/Universal/Smbios/OemMiscLibNull/OemMiscLibNull.inf=0D =0D + ArmPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf=0D +=0D [Components.AARCH64]=0D ArmPkg/Drivers/ArmPsciMpServicesDxe/ArmPsciMpServicesDxe.inf=0D ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.inf=0D diff --git a/ArmPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf b/Arm= Pkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf new file mode 100644 index 000000000000..c74c53953901 --- /dev/null +++ b/ArmPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf @@ -0,0 +1,40 @@ +## @file -- MmCommunicationPei.inf=0D +# PEI MM Communicate driver=0D +#=0D +# Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.
=0D +# Copyright (c) Microsoft Corporation.=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +##=0D +=0D +[Defines]=0D + INF_VERSION =3D 0x0001001B=0D + BASE_NAME =3D MmCommunicationPei=0D + FILE_GUID =3D 58FFB346-1B75-42C7-AD69-37C652423C1A= =0D + MODULE_TYPE =3D PEIM=0D + VERSION_STRING =3D 1.0=0D + ENTRY_POINT =3D MmCommunicationPeiInitialize=0D +=0D +[Sources]=0D + MmCommunicationPei.c=0D +=0D +[Packages]=0D + MdePkg/MdePkg.dec=0D + MdeModulePkg/MdeModulePkg.dec=0D + ArmPkg/ArmPkg.dec=0D +=0D +[LibraryClasses]=0D + DebugLib=0D + ArmSmcLib=0D + PeimEntryPoint=0D + PeiServicesLib=0D + HobLib=0D +=0D +[Pcd]=0D + gArmTokenSpaceGuid.PcdMmBufferBase=0D + gArmTokenSpaceGuid.PcdMmBufferSize=0D +=0D +[Ppis]=0D + gEfiPeiMmCommunicationPpiGuid ## PRODUCES=0D +=0D +[Depex]=0D + TRUE=0D --=20 2.41.0.windows.1