From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=217.140.101.70; helo=foss.arm.com; envelope-from=supreeth.venkatesh@arm.com; receiver=edk2-devel@lists.01.org Received: from foss.arm.com (foss.arm.com [217.140.101.70]) by ml01.01.org (Postfix) with ESMTP id 1ECA4203525F2 for ; Thu, 26 Oct 2017 08:11:03 -0700 (PDT) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 310B815AD; Thu, 26 Oct 2017 08:14:50 -0700 (PDT) Received: from [10.0.2.15] (u203142.usa.arm.com [10.118.30.109]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id B4D903F24A; Thu, 26 Oct 2017 08:14:49 -0700 (PDT) Message-ID: <1509030889.3071.0.camel@arm.com> From: Supreeth Venkatesh To: Udit Kumar , "edk2-devel@lists.01.org" Cc: "leif.lindholm@linaro.org" , "ard.biesheuvel@linaro.org" Date: Thu, 26 Oct 2017 10:14:49 -0500 In-Reply-To: References: <20171025163258.47961-1-supreeth.venkatesh@arm.com> <20171025163258.47961-3-supreeth.venkatesh@arm.com> X-Mailer: Evolution 3.18.5.2-0ubuntu3.2 Mime-Version: 1.0 Subject: Re: [PATCH v2 2/3] ArmPkg/Drivers: Add EFI_MM_COMMUNICATION_PROTOCOL DXE driver. X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 26 Oct 2017 15:11:04 -0000 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8bit On Thu, 2017-10-26 at 05:05 +0000, Udit Kumar wrote: > Hi  > > > > > +  Status = gBS->AllocatePages (AllocateAddress, > > +                               EfiRuntimeServicesData, > > +                               EFI_SIZE_TO_PAGES > > (mNsCommBuffMemRegion.Length), > > +                               &mNsCommBuffMemRegion.PhysicalBase) > > ; > > +  if (EFI_ERROR (Status)) { > > +    DEBUG ((DEBUG_ERROR, "MmCommunicateInitialize: Failed to > > allocate MM- > > NS Buffer Memory Space\n")); > > +    return EFI_INVALID_PARAMETER; > > +  } > > + > > +  // Install the communication protocol  Status = > > + gBS->InstallProtocolInterface (&mMmCommunicateHandle, > > +                                          &gEfiMmCommunicationProt > > ocolGuid, > > +                                          EFI_NATIVE_INTERFACE, > > +                                          &mMmCommunication);  if > > + (EFI_ERROR(Status)) { > > +    DEBUG ((DEBUG_ERROR, "MmCommunicationInitialize: Failed to > > install MM > > communication protocol\n")); > In case of error, you could free the above allocated memory  > > > > > +    return EFI_INVALID_PARAMETER; > > +   Thanks. Yes. It could be done. I will fix it in next version. > Regards > Udit  > > > > > -----Original Message----- > > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf > > Of > > Supreeth Venkatesh > > Sent: Wednesday, October 25, 2017 10:03 PM > > To: edk2-devel@lists.01.org > > Cc: leif.lindholm@linaro.org; ard.biesheuvel@linaro.org > > Subject: [edk2] [PATCH v2 2/3] ArmPkg/Drivers: Add > > EFI_MM_COMMUNICATION_PROTOCOL DXE driver. > > > > PI v1.5 Specification Volume 4 defines Management Mode Core > > Interface and > > defines EFI_MM_COMMUNICATION_PROTOCOL. This protocol provides a > > means of communicating between drivers outside of MM and MMI > > handlers > > inside of MM. > > > > This patch implements the EFI_MM_COMMUNICATION_PROTOCOL DXE > > runtime driver for AARCH64 platforms. It uses SMCs allocated from > > the standard > > SMC range defined in > > https://emea01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fi > > nfocen > > ter.arm.com%2Fhelp%2Ftopic%2Fcom.arm.doc.den0060a%2FDEN0060A_ARM_ > > MM_Interface_Specification.pdf&data=02%7C01%7Cudit.kumar%40nxp.com% > > 7 > > C43194cfd48f84756da6908d51bc6185b%7C686ea1d3bc2b4c6fa92cd99c5c3016 > > 35%7C0%7C1%7C636445460008712743&sdata=Nk9bnFSzqB4zxCcyd4C2HyqZ2a > > Iluu%2FWKXOVho4a6g8%3D&reserved=0 > > to communicate with the standalone MM environment in the secure > > world. > > > > Contributed-under: TianoCore Contribution Agreement 1.1 > > Signed-off-by: Achin Gupta > > Signed-off-by: Supreeth Venkatesh > > --- > >  .../Drivers/MmCommunicationDxe/MmCommunication.c   | 339 > > +++++++++++++++++++++ > >  1 file changed, 339 insertions(+) > >  create mode 100644 > > ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.c > > > > diff --git a/ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.c > > b/ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.c > > new file mode 100644 > > index 0000000000..ecf70e666c > > --- /dev/null > > +++ b/ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.c > > @@ -0,0 +1,339 @@ > > +/** @file > > + > > +  Copyright (c) 2016-2017, ARM Limited. All rights reserved. > > + > > +  This program and the accompanying materials  are licensed and > > made > > + available under the terms and conditions of the BSD > > License  which > > + accompanies this distribution.  The full text of the license may > > be > > + found at > > + > > + https://emea01.safelinks.protection.outlook.com/?url=http%3A%2F%2 > > Fopen > > + source.org%2Flicenses%2Fbsd- > > license.php&data=02%7C01%7Cudit.kumar%40nx > > + > > p.com%7C43194cfd48f84756da6908d51bc6185b%7C686ea1d3bc2b4c6fa92cd9 > > 9c5c3 > > + > > 01635%7C0%7C0%7C636445460008712743&sdata=%2Fw7nb5B%2Bw3NKLV4v > > 5LwcaQ0%2 > > + F6gh2Cva%2FEyDsb69NEAM%3D&reserved=0 > > + > > +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > > BASIS, > > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > > EXPRESS OR IMPLIED. > > + > > +**/ > > + > > +#include > > +#include > > +#include > > +#include > > +#include #include > > > > +#include #include > > + > > +#include > > + > > +#include > > + > > +#include > > + > > +/** > > +  Communicates with a registered handler. > > + > > +  This function provides an interface to send and receive messages > > to > > + the  Standalone MM environment on behalf of UEFI services.  This > > + function is part  of the MM Communication Protocol that may be > > called > > + in physical mode prior to > > +  SetVirtualAddressMap() and in virtual mode after > > SetVirtualAddressMap(). > > + > > +  @param[in]      This                The > > EFI_MM_COMMUNICATION_PROTOCOL > > instance. > > +  @param[in, out] CommBuffer          A pointer to the buffer to > > convey into > > MMRAM. > > +  @param[in, out] CommSize            The size of the data buffer > > being passed > > in.On exit, the size of data > > +                                      being returned. Zero if the > > handler does not wish to reply > > with any data. > > + > > +  @retval EFI_SUCCESS                 The message was successfully > > posted. > > +  @retval EFI_INVALID_PARAMETER       The CommBuffer was NULL. > > +  @retval EFI_BAD_BUFFER_SIZE         The buffer is too large for > > the MM > > implementation. If this error is > > +                                      returned, the MessageLength > > field in the CommBuffer > > header or the integer > > +                                      pointed by CommSize are > > updated to reflect the maximum > > payload size the > > +                                      implementation can > > accommodate. > > +  @retval EFI_ACCESS_DENIED           The CommunicateBuffer > > parameter or > > CommSize parameter, if not omitted, > > +                                      are in address range that > > cannot > > +be accessed by the MM environment **/ EFI_STATUS EFIAPI > > +MmCommunicationCommunicate ( > > +  IN CONST EFI_MM_COMMUNICATION_PROTOCOL  *This, > > +  IN OUT VOID                             *CommBuffer, > > +  IN OUT UINTN                            *CommSize    OPTIONAL > > +  ); > > + > > +// > > +// Address, Length of the pre-allocated buffer for communication > > with > > +the secure // world. > > +// > > +STATIC ARM_MEMORY_REGION_DESCRIPTOR  mNsCommBuffMemRegion; > > + > > +// Notification event when virtual address map is set. > > +STATIC EFI_EVENT  mSetVirtualAddressMapEvent; > > + > > +// > > +// Handle to install the MM Communication Protocol // STATIC > > EFI_HANDLE > > +mMmCommunicateHandle; > > + > > +// > > +// MM Communication Protocol instance > > +// > > +EFI_MM_COMMUNICATION_PROTOCOL  mMmCommunication = { > > +  MmCommunicationCommunicate > > +}; > > + > > +/** > > +  Communicates with a registered handler. > > + > > +  This function provides an interface to send and receive messages > > to > > + the  Standalone MM environment on behalf of UEFI services.  This > > + function is part  of the MM Communication Protocol that may be > > called > > + in physical mode prior to > > +  SetVirtualAddressMap() and in virtual mode after > > SetVirtualAddressMap(). > > + > > +  @param[in]      This                The > > EFI_MM_COMMUNICATION_PROTOCOL > > instance. > > +  @param[in, out] CommBuffer          A pointer to the buffer to > > convey into > > SMRAM. > > +  @param[in, out] CommSize            The size of the data buffer > > being passed > > in.On exit, the size of data > > +                                      being returned. Zero if the > > handler does not wish to reply > > with any data. > > + > > +  @retval EFI_SUCCESS                 The message was successfully > > posted. > > +  @retval EFI_INVALID_PARAMETER       The CommBuffer was NULL. > > +  @retval EFI_BAD_BUFFER_SIZE         The buffer is too large for > > the MM > > implementation. If this error is > > +                                      returned, the MessageLength > > field in the CommBuffer > > header or the integer > > +                                      pointed by CommSize are > > updated to reflect the maximum > > payload size the > > +                                      implementation can > > accommodate. > > +  @retval EFI_ACCESS_DENIED           The CommunicateBuffer > > parameter or > > CommSize parameter, if not omitted, > > +                                      are in address range that > > cannot > > +be accessed by the MM environment **/ EFI_STATUS EFIAPI > > +MmCommunicationCommunicate ( > > +  IN CONST EFI_MM_COMMUNICATION_PROTOCOL  *This, > > +  IN OUT VOID                             *CommBuffer, > > +  IN OUT UINTN                            *CommSize > > +  ) > > +{ > > +  EFI_MM_COMMUNICATE_HEADER   *CommunicateHeader; > > +  ARM_SMC_ARGS                CommunicateSmcArgs; > > +  EFI_STATUS                  Status; > > +  UINTN                       BufferSize; > > + > > +  CommunicateHeader = CommBuffer; > > +  Status = EFI_SUCCESS; > > +  BufferSize = 0; > > + > > +  ZeroMem (&CommunicateSmcArgs, sizeof (ARM_SMC_ARGS)); > > + > > +  // > > +  // Check parameters > > +  // > > +  if (CommBuffer == NULL) { > > +    return EFI_INVALID_PARAMETER; > > +  } > > + > > +  // If the length of the CommBuffer is 0 then return the expected > > length. > > +  if (CommSize) { > > +    if (*CommSize == 0) { > > +      *CommSize = mNsCommBuffMemRegion.Length; > > +      return EFI_BAD_BUFFER_SIZE; > > +    } > > +    // > > +    // CommSize must hold HeaderGuid and MessageLength > > +    // > > +    if (*CommSize < sizeof (EFI_MM_COMMUNICATE_HEADER)) { > > +        return EFI_INVALID_PARAMETER; > > +    } > > +    BufferSize = *CommSize; > > +  } else { > > +    BufferSize = CommunicateHeader->MessageLength + > > +                 sizeof (CommunicateHeader->HeaderGuid) + > > +                 sizeof (CommunicateHeader->MessageLength); > > +  } > > + > > +  // > > +  // If the buffer size is 0 or greater than what can be tolerated > > by > > + the MM  // environment then return the expected size. > > +  // > > +  if ((BufferSize == 0) || > > +      (BufferSize > mNsCommBuffMemRegion.Length)) { > > +    CommunicateHeader->MessageLength = mNsCommBuffMemRegion.Length > > - > > +                                       sizeof (CommunicateHeader- > > >HeaderGuid) - > > +                                       sizeof (CommunicateHeader- > > >MessageLength); > > +    return EFI_BAD_BUFFER_SIZE; > > +  } > > + > > +  // SMC Function ID > > +  CommunicateSmcArgs.Arg0 = > > ARM_SMC_ID_MM_COMMUNICATE_AARCH64; > > + > > +  // Reserved for Future. Must be Zero. > > +  CommunicateSmcArgs.Arg1 = 0; > > + > > +  if (mNsCommBuffMemRegion.VirtualBase) { > > +    CopyMem ((VOID *)mNsCommBuffMemRegion.VirtualBase, CommBuffer, > > + BufferSize);  } > > + > > +  // For the SMC64 version, this parameter is a 64-bit Physical > > Address > > + (PA)  // or Intermediate Physical Address (IPA). > > +  // For the SMC32 version, this parameter is a 32-bit PA or IPA. > > +  CommunicateSmcArgs.Arg2 = > > (UINTN)mNsCommBuffMemRegion.PhysicalBase; > > + > > +  // comm_size_address is a PA or an IPA that holds the size of > > the  // > > + communication buffer being passed in. This parameter is > > optional  // > > + and can be omitted by passing a zero. > > +  // ARM does not recommend using it since this might require > > the  // > > + implementation to create a separate memory mapping for the > > parameter. > > +  // ARM recommends storing the buffer size in the buffer itself. > > +  CommunicateSmcArgs.Arg3 = 0; > > + > > +  // Call the Standalone MM environment. > > +  ArmCallSmc (&CommunicateSmcArgs); > > + > > +  Status = CommunicateSmcArgs.Arg0; > > +  switch (Status) { > > +  case ARM_SMC_MM_RET_SUCCESS: > > +    // On exit, the size of data being returned is inferred from > > +    // CommSize or MessageLength + Header. > > +    CopyMem (CommBuffer, (const VOID > > *)mNsCommBuffMemRegion.VirtualBase, BufferSize); > > +    break; > > + > > +  case ARM_SMC_MM_RET_NOT_SUPPORTED: > > +  case ARM_SMC_MM_RET_INVALID_PARAMS: > > +    Status = EFI_INVALID_PARAMETER; > > +    break; > > + > > +  case ARM_SMC_MM_RET_DENIED: > > +    Status = EFI_ACCESS_DENIED; > > +    break; > > + > > +  case ARM_SMC_MM_RET_NO_MEMORY: > > +    // Unexpected error since the CommSize was checked for zero > > length > > +    // prior to issuing the SMC > > +  default: > > +    Status = EFI_ACCESS_DENIED; > > +    ASSERT (0); > > +  } > > + > > +  return Status; > > +} > > + > > +/** > > +  Notification callback on SetVirtualAddressMap event. > > + > > +  This function notifies the MM communication protocol interface > > on > > + SetVirtualAddressMap event and converts pointers used in this > > driver > > + from physical to virtual address. > > + > > +  @param  Event          SetVirtualAddressMap event. > > +  @param  Context        A context when the SetVirtualAddressMap > > triggered. > > + > > +  @retval EFI_SUCCESS    The function executed successfully. > > +  @retval Other          Some error occurred when executing this > > function. > > + > > +**/ > > +STATIC > > +VOID > > +EFIAPI > > +NotifySetVirtualAddressMap ( > > +  IN EFI_EVENT  Event, > > +  IN VOID      *Context > > +  ) > > +{ > > +  EFI_STATUS  Status; > > + > > +  Status = gRT->ConvertPointer (EFI_OPTIONAL_PTR, > > +                                (VOID > > **)&mNsCommBuffMemRegion.VirtualBase > > +                               ); > > +  if (EFI_ERROR (Status)) { > > +    DEBUG ((DEBUG_ERROR, "NotifySetVirtualAddressMap(): Unable to > > + convert MM runtime pointer. Status:0x%x\n", Status));  } > > + > > +} > > + > > +/** > > +  The Entry Point for MM Communication > > + > > +  This function installs the MM communication protocol interface > > and > > + finds out  what type of buffer management will be required prior > > to > > + invoking the  communication SMC. > > + > > +  @param  ImageHandle    The firmware allocated handle for the EFI > > image. > > +  @param  SystemTable    A pointer to the EFI System Table. > > + > > +  @retval EFI_SUCCESS    The entry point is executed successfully. > > +  @retval Other          Some error occurred when executing this > > entry point. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +MmCommunicationInitialize ( > > +  IN EFI_HANDLE         ImageHandle, > > +  IN EFI_SYSTEM_TABLE  *SystemTable > > +  ) > > +{ > > +  EFI_STATUS                 Status; > > + > > +  mNsCommBuffMemRegion.PhysicalBase = 0; > > + mNsCommBuffMemRegion.VirtualBase = 0; > > mNsCommBuffMemRegion.Length = > > + 0; > > + > > +  mNsCommBuffMemRegion.PhysicalBase = PcdGet64 > > (PcdMmBufferBase);  // > > + During boot , Virtual and Physical are same > > + mNsCommBuffMemRegion.VirtualBase = > > mNsCommBuffMemRegion.PhysicalBase; > > +  mNsCommBuffMemRegion.Length = PcdGet64 (PcdMmBufferSize); > > + > > +  if (mNsCommBuffMemRegion.PhysicalBase == 0) { > > +    DEBUG ((DEBUG_ERROR, "MmCommunicateInitialize: Invalid MM > > Buffer > > Base Address.\n")); > > +    return EFI_INVALID_PARAMETER; > > +  } > > + > > +  if (mNsCommBuffMemRegion.Length == 0) { > > +    DEBUG ((DEBUG_ERROR, "MmCommunicateInitialize: Maximum Buffer > > Size > > is zero.\n")); > > +    return EFI_INVALID_PARAMETER; > > +  } > > + > > +  Status = gDS->AddMemorySpace (EfiGcdMemoryTypeSystemMemory, > > +                                mNsCommBuffMemRegion.PhysicalBase, > > +                                mNsCommBuffMemRegion.Length, > > +                                EFI_MEMORY_WB | > > +                                EFI_MEMORY_XP | > > +                                EFI_MEMORY_RUNTIME);  if > > (EFI_ERROR > > + (Status)) { > > +    DEBUG ((DEBUG_ERROR, "MmCommunicateInitialize: Failed to add > > MM-NS > > Buffer Memory Space\n")); > > +    return EFI_INVALID_PARAMETER; > > +  } > > + > > +  Status = gDS- > > > > > > SetMemorySpaceAttributes(mNsCommBuffMemRegion.PhysicalBase, > > +                                         mNsCommBuffMemRegion.Leng > > th, > > +                                         EFI_MEMORY_WB | > > + EFI_MEMORY_XP);  if (EFI_ERROR (Status)) { > > +    DEBUG ((DEBUG_ERROR, "MmCommunicateInitialize: Failed to set > > MM-NS > > Buffer Memory attributes\n")); > > +    return EFI_INVALID_PARAMETER; > > +  } > > + > > +  Status = gBS->AllocatePages (AllocateAddress, > > +                               EfiRuntimeServicesData, > > +                               EFI_SIZE_TO_PAGES > > (mNsCommBuffMemRegion.Length), > > +                               &mNsCommBuffMemRegion.PhysicalBase) > > ; > > +  if (EFI_ERROR (Status)) { > > +    DEBUG ((DEBUG_ERROR, "MmCommunicateInitialize: Failed to > > allocate MM- > > NS Buffer Memory Space\n")); > > +    return EFI_INVALID_PARAMETER; > > +  } > > + > > +  // Install the communication protocol  Status = > > + gBS->InstallProtocolInterface (&mMmCommunicateHandle, > > +                                          &gEfiMmCommunicationProt > > ocolGuid, > > +                                          EFI_NATIVE_INTERFACE, > > +                                          &mMmCommunication);  if > > + (EFI_ERROR(Status)) { > > +    DEBUG ((DEBUG_ERROR, "MmCommunicationInitialize: Failed to > > install MM > > communication protocol\n")); > > +    return EFI_INVALID_PARAMETER; > > +  } > > + > > +  // Register notification callback when  virtual address is > > associated > > + // with the physical address. > > +  // Create a Set Virtual Address Map event. > > +  // > > +  Status = gBS->CreateEvent > > (EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,  // > > Type > > +                             TPL_NOTIFY,                         / > > / NotifyTpl > > +                             NotifySetVirtualAddressMap,         / > > / NotifyFunction > > +                             NULL,                               / > > / NotifyContext > > +                             &mSetVirtualAddressMapEvent         / > > / Event > > +                            ); > > +  ASSERT_EFI_ERROR (Status); > > + > > +  return Status; > > +} > > -- > > 2.14.1 > > > > _______________________________________________ > > edk2-devel mailing list > > edk2-devel@lists.01.org > > https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2F > > lists.01 > > .org%2Fmailman%2Flistinfo%2Fedk2- > > devel&data=02%7C01%7Cudit.kumar%40nxp.com%7C43194cfd48f84756da690 > > 8d51bc6185b%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C6364454 > > 60008712743&sdata=3DNXnOuo8%2FVFL6Sha%2FeidNhuh4JoILCVQs1HcGAhvr > > Y%3D&reserved=0