/** @file

Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.<BR>

SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <PiPei.h>
#include <PiDxe.h>
#include <PiSmm.h>
#include <Library/PeiServicesTablePointerLib.h>
#include <Library/PeiServicesLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/LockBoxLib.h>
#include <Library/HobLib.h>
#include <Library/DebugLib.h>
#include <Library/PcdLib.h>
#include <Protocol/SmmCommunication.h>
#include <Ppi/SmmCommunication.h>
#include <Ppi/SmmAccess.h>
#include <Guid/AcpiS3Context.h>
#include <Guid/SmmLockBox.h>

#include "SmmLockBoxLibPrivate.h"

#if defined (MDE_CPU_IA32)
typedef struct _LIST_ENTRY64 LIST_ENTRY64;
struct _LIST_ENTRY64 {
  LIST_ENTRY64    *ForwardLink;
  UINT32          Reserved1;
  LIST_ENTRY64    *BackLink;
  UINT32          Reserved2;
};

typedef struct {
  EFI_TABLE_HEADER    Hdr;
  UINT64              SmmFirmwareVendor;
  UINT64              SmmFirmwareRevision;
  UINT64              SmmInstallConfigurationTable;
  UINT64              SmmIoMemRead;
  UINT64              SmmIoMemWrite;
  UINT64              SmmIoIoRead;
  UINT64              SmmIoIoWrite;
  UINT64              SmmAllocatePool;
  UINT64              SmmFreePool;
  UINT64              SmmAllocatePages;
  UINT64              SmmFreePages;
  UINT64              SmmStartupThisAp;
  UINT64              CurrentlyExecutingCpu;
  UINT64              NumberOfCpus;
  UINT64              CpuSaveStateSize;
  UINT64              CpuSaveState;
  UINT64              NumberOfTableEntries;
  UINT64              SmmConfigurationTable;
} EFI_SMM_SYSTEM_TABLE2_64;

typedef struct {
  EFI_GUID    VendorGuid;
  UINT64      VendorTable;
} EFI_CONFIGURATION_TABLE64;
#endif

#if defined (MDE_CPU_X64)
typedef LIST_ENTRY              LIST_ENTRY64;
typedef EFI_SMM_SYSTEM_TABLE2   EFI_SMM_SYSTEM_TABLE2_64;
typedef EFI_CONFIGURATION_TABLE EFI_CONFIGURATION_TABLE64;
#endif

/**
  This function return first node of LinkList queue.

  @param LockBoxQueue  LinkList queue

  @return first node of LinkList queue
**/
LIST_ENTRY *
InternalInitLinkDxe (
  IN LIST_ENTRY  *LinkList
  )
{
  if ((sizeof (UINTN) == sizeof (UINT32)) && (FeaturePcdGet (PcdDxeIplSwitchToLongMode))) {
    //
    // 32 PEI + 64 DXE
    //
    return (LIST_ENTRY *)(((LIST_ENTRY64 *)LinkList)->ForwardLink);
  } else {
    return LinkList->ForwardLink;
  }
}

/**
  This function return next node of LinkList.

  @param Link  LinkList node

  @return next node of LinkList
**/
LIST_ENTRY *
InternalNextLinkDxe (
  IN LIST_ENTRY  *Link
  )
{
  if ((sizeof (UINTN) == sizeof (UINT32)) && (FeaturePcdGet (PcdDxeIplSwitchToLongMode))) {
    //
    // 32 PEI + 64 DXE
    //
    return (LIST_ENTRY *)(((LIST_ENTRY64 *)Link)->ForwardLink);
  } else {
    return Link->ForwardLink;
  }
}

/**
  This function find LockBox by GUID from SMRAM.

  @param LockBoxQueue The LockBox queue in SMRAM
  @param Guid         The guid to indentify the LockBox

  @return LockBoxData
**/
SMM_LOCK_BOX_DATA *
InternalFindLockBoxByGuidFromSmram (
  IN LIST_ENTRY  *LockBoxQueue,
  IN EFI_GUID    *Guid
  )
{
  LIST_ENTRY         *Link;
  SMM_LOCK_BOX_DATA  *LockBox;

  for (Link = InternalInitLinkDxe (LockBoxQueue);
       Link != LockBoxQueue;
       Link = InternalNextLinkDxe (Link))
  {
    LockBox = BASE_CR (
                Link,
                SMM_LOCK_BOX_DATA,
                Link
                );
    if (CompareGuid (&LockBox->Guid, Guid)) {
      return LockBox;
    }
  }

  return NULL;
}

/**
  Get VendorTable by VendorGuid in Smst.

  @param Signature  Signature of SMM_S3_RESUME_STATE
  @param Smst       SMM system table
  @param VendorGuid vendor guid

  @return vendor table.
**/
VOID *
InternalSmstGetVendorTableByGuid (
  IN UINT64                 Signature,
  IN EFI_SMM_SYSTEM_TABLE2  *Smst,
  IN EFI_GUID               *VendorGuid
  )
{
  EFI_CONFIGURATION_TABLE    *SmmConfigurationTable;
  UINTN                      NumberOfTableEntries;
  UINTN                      Index;
  EFI_SMM_SYSTEM_TABLE2_64   *Smst64;
  EFI_CONFIGURATION_TABLE64  *SmmConfigurationTable64;

  if ((sizeof (UINTN) == sizeof (UINT32)) && (FeaturePcdGet (PcdDxeIplSwitchToLongMode))) {
    //
    // 32 PEI + 64 DXE
    //
    Smst64                  = (EFI_SMM_SYSTEM_TABLE2_64 *)Smst;
    SmmConfigurationTable64 = (EFI_CONFIGURATION_TABLE64 *)(UINTN)Smst64->SmmConfigurationTable;
    NumberOfTableEntries    = (UINTN)Smst64->NumberOfTableEntries;
    for (Index = 0; Index < NumberOfTableEntries; Index++) {
      if (CompareGuid (&SmmConfigurationTable64[Index].VendorGuid, VendorGuid)) {
        return (VOID *)(UINTN)SmmConfigurationTable64[Index].VendorTable;
      }
    }

    return NULL;
  } else {
    SmmConfigurationTable = Smst->SmmConfigurationTable;
    NumberOfTableEntries  = Smst->NumberOfTableEntries;
    for (Index = 0; Index < NumberOfTableEntries; Index++) {
      if (CompareGuid (&SmmConfigurationTable[Index].VendorGuid, VendorGuid)) {
        return (VOID *)SmmConfigurationTable[Index].VendorTable;
      }
    }

    return NULL;
  }
}

/**
  Get SMM LockBox context.

  @return SMM LockBox context.
**/
SMM_LOCK_BOX_CONTEXT *
InternalGetSmmLockBoxContext (
  VOID
  )
{
  EFI_SMRAM_DESCRIPTOR  *SmramDescriptor;
  SMM_S3_RESUME_STATE   *SmmS3ResumeState;
  VOID                  *GuidHob;
  SMM_LOCK_BOX_CONTEXT  *SmmLockBoxContext;

  GuidHob = GetFirstGuidHob (&gEfiAcpiVariableGuid);
  ASSERT (GuidHob != NULL);
  SmramDescriptor  = (EFI_SMRAM_DESCRIPTOR *)GET_GUID_HOB_DATA (GuidHob);
  SmmS3ResumeState = (SMM_S3_RESUME_STATE *)(UINTN)SmramDescriptor->CpuStart;

  SmmLockBoxContext = (SMM_LOCK_BOX_CONTEXT *)InternalSmstGetVendorTableByGuid (
                                                SmmS3ResumeState->Signature,
                                                (EFI_SMM_SYSTEM_TABLE2 *)(UINTN)SmmS3ResumeState->Smst,
                                                &gEfiSmmLockBoxCommunicationGuid
                                                );
  ASSERT (SmmLockBoxContext != NULL);

  return SmmLockBoxContext;
}

/**
  This function will restore confidential information from lockbox in SMRAM directly.

  @param Guid   the guid to identify the confidential information
  @param Buffer the address of the restored confidential information
                NULL means restored to original address, Length MUST be NULL at same time.
  @param Length the length of the restored confidential information

  @retval RETURN_SUCCESS            the information is restored successfully.
  @retval RETURN_WRITE_PROTECTED    Buffer and Length are NULL, but the LockBox has no
                                    LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE attribute.
  @retval RETURN_BUFFER_TOO_SMALL   the Length is too small to hold the confidential information.
  @retval RETURN_NOT_FOUND          the requested GUID not found.
**/
EFI_STATUS
InternalRestoreLockBoxFromSmram (
  IN  GUID       *Guid,
  IN  VOID       *Buffer  OPTIONAL,
  IN  OUT UINTN  *Length  OPTIONAL
  )
{
  PEI_SMM_ACCESS_PPI    *SmmAccess;
  UINTN                 Index;
  EFI_STATUS            Status;
  SMM_LOCK_BOX_CONTEXT  *SmmLockBoxContext;
  LIST_ENTRY            *LockBoxQueue;
  SMM_LOCK_BOX_DATA     *LockBox;
  VOID                  *RestoreBuffer;

  //
  // Get needed resource
  //
  Status = PeiServicesLocatePpi (
             &gPeiSmmAccessPpiGuid,
             0,
             NULL,
             (VOID **)&SmmAccess
             );
  if (!EFI_ERROR (Status)) {
    for (Index = 0; !EFI_ERROR (Status); Index++) {
      Status = SmmAccess->Open ((EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), SmmAccess, Index);
    }
  }

  //
  // Get LockBox context
  //
  SmmLockBoxContext = InternalGetSmmLockBoxContext ();
  LockBoxQueue      = (LIST_ENTRY *)(UINTN)SmmLockBoxContext->LockBoxDataAddress;

  //
  // We do NOT check Buffer address in SMRAM, because if SMRAM not locked, we trust the caller.
  //

  //
  // Restore this, Buffer and Length MUST be both NULL or both non-NULL
  //

  //
  // Find LockBox
  //
  LockBox = InternalFindLockBoxByGuidFromSmram (LockBoxQueue, Guid);
  if (LockBox == NULL) {
    //
    // Not found
    //
    return EFI_NOT_FOUND;
  }

  //
  // Set RestoreBuffer
  //
  if (Buffer != NULL) {
    //
    // restore to new buffer
    //
    RestoreBuffer = Buffer;
  } else {
    //
    // restore to original buffer
    //
    if ((LockBox->Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE) == 0) {
      return EFI_WRITE_PROTECTED;
    }

    RestoreBuffer = (VOID *)(UINTN)LockBox->Buffer;
  }

  //
  // Set RestoreLength
  //
  if (Length != NULL) {
    if (*Length < (UINTN)LockBox->Length) {
      //
      // Input buffer is too small to hold all data.
      //
      *Length = (UINTN)LockBox->Length;
      return EFI_BUFFER_TOO_SMALL;
    }

    *Length = (UINTN)LockBox->Length;
  }

  //
  // Restore data
  //
  CopyMem (RestoreBuffer, (VOID *)(UINTN)LockBox->SmramBuffer, (UINTN)LockBox->Length);

  //
  // Done
  //
  return EFI_SUCCESS;
}

/**
  This function will restore confidential information from all lockbox which have RestoreInPlace attribute.

  @retval RETURN_SUCCESS            the information is restored successfully.
**/
EFI_STATUS
InternalRestoreAllLockBoxInPlaceFromSmram (
  VOID
  )
{
  PEI_SMM_ACCESS_PPI    *SmmAccess;
  UINTN                 Index;
  EFI_STATUS            Status;
  SMM_LOCK_BOX_CONTEXT  *SmmLockBoxContext;
  LIST_ENTRY            *LockBoxQueue;
  SMM_LOCK_BOX_DATA     *LockBox;
  LIST_ENTRY            *Link;

  //
  // Get needed resource
  //
  Status = PeiServicesLocatePpi (
             &gPeiSmmAccessPpiGuid,
             0,
             NULL,
             (VOID **)&SmmAccess
             );
  if (!EFI_ERROR (Status)) {
    for (Index = 0; !EFI_ERROR (Status); Index++) {
      Status = SmmAccess->Open ((EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), SmmAccess, Index);
    }
  }

  //
  // Get LockBox context
  //
  SmmLockBoxContext = InternalGetSmmLockBoxContext ();
  LockBoxQueue      = (LIST_ENTRY *)(UINTN)SmmLockBoxContext->LockBoxDataAddress;

  //
  // We do NOT check Buffer address in SMRAM, because if SMRAM not locked, we trust the caller.
  //

  //
  // Restore all, Buffer and Length MUST be NULL
  //
  for (Link = InternalInitLinkDxe (LockBoxQueue);
       Link != LockBoxQueue;
       Link = InternalNextLinkDxe (Link))
  {
    LockBox = BASE_CR (
                Link,
                SMM_LOCK_BOX_DATA,
                Link
                );
    if ((LockBox->Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE) != 0) {
      //
      // Restore data
      //
      CopyMem ((VOID *)(UINTN)LockBox->Buffer, (VOID *)(UINTN)LockBox->SmramBuffer, (UINTN)LockBox->Length);
    }
  }

  //
  // Done
  //
  return EFI_SUCCESS;
}

/**
  This function will save confidential information to lockbox.

  @param Guid       the guid to identify the confidential information
  @param Buffer     the address of the confidential information
  @param Length     the length of the confidential information

  @retval RETURN_SUCCESS            the information is saved successfully.
  @retval RETURN_INVALID_PARAMETER  the Guid is NULL, or Buffer is NULL, or Length is 0
  @retval RETURN_ALREADY_STARTED    the requested GUID already exist.
  @retval RETURN_OUT_OF_RESOURCES   no enough resource to save the information.
  @retval RETURN_ACCESS_DENIED      it is too late to invoke this interface
  @retval RETURN_NOT_STARTED        it is too early to invoke this interface
  @retval RETURN_UNSUPPORTED        the service is not supported by implementaion.
**/
RETURN_STATUS
EFIAPI
SaveLockBox (
  IN  GUID   *Guid,
  IN  VOID   *Buffer,
  IN  UINTN  Length
  )
{
  ASSERT (FALSE);

  //
  // No support to save at PEI phase
  //
  return RETURN_UNSUPPORTED;
}

/**
  This function will set lockbox attributes.

  @param Guid       the guid to identify the confidential information
  @param Attributes the attributes of the lockbox

  @retval RETURN_SUCCESS            the information is saved successfully.
  @retval RETURN_INVALID_PARAMETER  attributes is invalid.
  @retval RETURN_NOT_FOUND          the requested GUID not found.
  @retval RETURN_ACCESS_DENIED      it is too late to invoke this interface
  @retval RETURN_NOT_STARTED        it is too early to invoke this interface
  @retval RETURN_UNSUPPORTED        the service is not supported by implementaion.
**/
RETURN_STATUS
EFIAPI
SetLockBoxAttributes (
  IN  GUID    *Guid,
  IN  UINT64  Attributes
  )
{
  ASSERT (FALSE);

  //
  // No support to save at PEI phase
  //
  return RETURN_UNSUPPORTED;
}

/**
  This function will update confidential information to lockbox.

  @param Guid   the guid to identify the original confidential information
  @param Offset the offset of the original confidential information
  @param Buffer the address of the updated confidential information
  @param Length the length of the updated confidential information

  @retval RETURN_SUCCESS            the information is saved successfully.
  @retval RETURN_INVALID_PARAMETER  the Guid is NULL, or Buffer is NULL, or Length is 0.
  @retval RETURN_NOT_FOUND          the requested GUID not found.
  @retval RETURN_BUFFER_TOO_SMALL   for lockbox without attribute LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY,
                                    the original buffer to too small to hold new information.
  @retval RETURN_OUT_OF_RESOURCES   for lockbox with attribute LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY,
                                    no enough resource to save the information.
  @retval RETURN_ACCESS_DENIED      it is too late to invoke this interface
  @retval RETURN_NOT_STARTED        it is too early to invoke this interface
  @retval RETURN_UNSUPPORTED        the service is not supported by implementaion.
**/
RETURN_STATUS
EFIAPI
UpdateLockBox (
  IN  GUID   *Guid,
  IN  UINTN  Offset,
  IN  VOID   *Buffer,
  IN  UINTN  Length
  )
{
  ASSERT (FALSE);

  //
  // No support to update at PEI phase
  //
  return RETURN_UNSUPPORTED;
}

/**
  This function will restore confidential information from lockbox.

  @param Guid   the guid to identify the confidential information
  @param Buffer the address of the restored confidential information
                NULL means restored to original address, Length MUST be NULL at same time.
  @param Length the length of the restored confidential information

  @retval RETURN_SUCCESS            the information is restored successfully.
  @retval RETURN_INVALID_PARAMETER  the Guid is NULL, or one of Buffer and Length is NULL.
  @retval RETURN_WRITE_PROTECTED    Buffer and Length are NULL, but the LockBox has no
                                    LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE attribute.
  @retval RETURN_BUFFER_TOO_SMALL   the Length is too small to hold the confidential information.
  @retval RETURN_NOT_FOUND          the requested GUID not found.
  @retval RETURN_NOT_STARTED        it is too early to invoke this interface
  @retval RETURN_ACCESS_DENIED      not allow to restore to the address
  @retval RETURN_UNSUPPORTED        the service is not supported by implementaion.
**/
RETURN_STATUS
EFIAPI
RestoreLockBox (
  IN  GUID       *Guid,
  IN  VOID       *Buffer  OPTIONAL,
  IN  OUT UINTN  *Length  OPTIONAL
  )
{
  EFI_STATUS                          Status;
  EFI_PEI_SMM_COMMUNICATION_PPI       *SmmCommunicationPpi;
  EFI_SMM_LOCK_BOX_PARAMETER_RESTORE  *LockBoxParameterRestore;
  EFI_SMM_COMMUNICATE_HEADER          *CommHeader;
  UINT8                               CommBuffer[sizeof (EFI_GUID) + sizeof (UINT64) + sizeof (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE)];
  UINTN                               CommSize;
  UINT64                              MessageLength;

  //
  // Please aware that there is UINTN in EFI_SMM_COMMUNICATE_HEADER. It might be UINT64 in DXE, while it is UINT32 in PEI.
  // typedef struct {
  //   EFI_GUID  HeaderGuid;
  //   UINTN     MessageLength;
  //   UINT8     Data[1];
  // } EFI_SMM_COMMUNICATE_HEADER;
  //

  DEBUG ((DEBUG_INFO, "SmmLockBoxPeiLib RestoreLockBox - Enter\n"));

  //
  // Basic check
  //
  if ((Guid == NULL) ||
      ((Buffer == NULL) && (Length != NULL)) ||
      ((Buffer != NULL) && (Length == NULL)))
  {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Get needed resource
  //
  Status = PeiServicesLocatePpi (
             &gEfiPeiSmmCommunicationPpiGuid,
             0,
             NULL,
             (VOID **)&SmmCommunicationPpi
             );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_INFO, "SmmLockBoxPeiLib LocatePpi - (%r)\n", Status));
    Status = InternalRestoreLockBoxFromSmram (Guid, Buffer, Length);
    DEBUG ((DEBUG_INFO, "SmmLockBoxPeiLib RestoreLockBox - Exit (%r)\n", Status));
    return Status;
  }

  //
  // Prepare parameter
  //
  CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0];
  CopyMem (&CommHeader->HeaderGuid, &gEfiSmmLockBoxCommunicationGuid, sizeof (gEfiSmmLockBoxCommunicationGuid));
  if ((sizeof (UINTN) == sizeof (UINT32)) && (FeaturePcdGet (PcdDxeIplSwitchToLongMode))) {
    MessageLength = sizeof (*LockBoxParameterRestore);
    CopyMem (&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, MessageLength)], &MessageLength, sizeof (MessageLength));
  } else {
    CommHeader->MessageLength = sizeof (*LockBoxParameterRestore);
  }

  DEBUG ((DEBUG_INFO, "SmmLockBoxPeiLib CommBuffer - %x\n", &CommBuffer[0]));
  if ((sizeof (UINTN) == sizeof (UINT32)) && (FeaturePcdGet (PcdDxeIplSwitchToLongMode))) {
    LockBoxParameterRestore = (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE *)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, MessageLength) + sizeof (UINT64)];
  } else {
    LockBoxParameterRestore = (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE *)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, MessageLength) + sizeof (UINTN)];
  }

  DEBUG ((DEBUG_INFO, "SmmLockBoxPeiLib LockBoxParameterRestore - %x\n", LockBoxParameterRestore));
  LockBoxParameterRestore->Header.Command      = EFI_SMM_LOCK_BOX_COMMAND_RESTORE;
  LockBoxParameterRestore->Header.DataLength   = sizeof (*LockBoxParameterRestore);
  LockBoxParameterRestore->Header.ReturnStatus = (UINT64)-1;
  if (Guid != 0) {
    CopyMem (&LockBoxParameterRestore->Guid, Guid, sizeof (*Guid));
  } else {
    ZeroMem (&LockBoxParameterRestore->Guid, sizeof (*Guid));
  }

  LockBoxParameterRestore->Buffer = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer;
  if (Length != NULL) {
    LockBoxParameterRestore->Length = (EFI_PHYSICAL_ADDRESS)*Length;
  } else {
    LockBoxParameterRestore->Length = 0;
  }

  //
  // Send command
  //
  CommSize = sizeof (CommBuffer);
  Status   = SmmCommunicationPpi->Communicate (
                                    SmmCommunicationPpi,
                                    &CommBuffer[0],
                                    &CommSize
                                    );
  if (Status == EFI_NOT_STARTED) {
    //
    // Pei SMM communication not ready yet, so we access SMRAM directly
    //
    DEBUG ((DEBUG_INFO, "SmmLockBoxPeiLib Communicate - (%r)\n", Status));
    Status                                       = InternalRestoreLockBoxFromSmram (Guid, Buffer, Length);
    LockBoxParameterRestore->Header.ReturnStatus = (UINT64)Status;
    if (Length != NULL) {
      LockBoxParameterRestore->Length = (UINT64)*Length;
    }
  }

  if (Length != NULL) {
    *Length = (UINTN)LockBoxParameterRestore->Length;
  }

  Status = (EFI_STATUS)LockBoxParameterRestore->Header.ReturnStatus;
  if (Status != EFI_SUCCESS) {
    // Need or MAX_BIT, because there might be case that SMM is X64 while PEI is IA32.
    Status |= MAX_BIT;
  }

  DEBUG ((DEBUG_INFO, "SmmLockBoxPeiLib RestoreLockBox - Exit (%r)\n", Status));

  //
  // Done
  //
  return Status;
}

/**
  This function will restore confidential information from all lockbox which have RestoreInPlace attribute.

  @retval RETURN_SUCCESS            the information is restored successfully.
  @retval RETURN_NOT_STARTED        it is too early to invoke this interface
  @retval RETURN_UNSUPPORTED        the service is not supported by implementaion.
**/
RETURN_STATUS
EFIAPI
RestoreAllLockBoxInPlace (
  VOID
  )
{
  EFI_STATUS                                       Status;
  EFI_PEI_SMM_COMMUNICATION_PPI                    *SmmCommunicationPpi;
  EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE  *LockBoxParameterRestoreAllInPlace;
  EFI_SMM_COMMUNICATE_HEADER                       *CommHeader;
  UINT8                                            CommBuffer[sizeof (EFI_GUID) + sizeof (UINT64) + sizeof (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE)];
  UINTN                                            CommSize;
  UINT64                                           MessageLength;

  //
  // Please aware that there is UINTN in EFI_SMM_COMMUNICATE_HEADER. It might be UINT64 in DXE, while it is UINT32 in PEI.
  // typedef struct {
  //   EFI_GUID  HeaderGuid;
  //   UINTN     MessageLength;
  //   UINT8     Data[1];
  // } EFI_SMM_COMMUNICATE_HEADER;
  //

  DEBUG ((DEBUG_INFO, "SmmLockBoxPeiLib RestoreAllLockBoxInPlace - Enter\n"));

  //
  // Get needed resource
  //
  Status = PeiServicesLocatePpi (
             &gEfiPeiSmmCommunicationPpiGuid,
             0,
             NULL,
             (VOID **)&SmmCommunicationPpi
             );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_INFO, "SmmLockBoxPeiLib LocatePpi - (%r)\n", Status));
    Status = InternalRestoreAllLockBoxInPlaceFromSmram ();
    DEBUG ((DEBUG_INFO, "SmmLockBoxPeiLib RestoreAllLockBoxInPlace - Exit (%r)\n", Status));
    return Status;
  }

  //
  // Prepare parameter
  //
  CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0];
  CopyMem (&CommHeader->HeaderGuid, &gEfiSmmLockBoxCommunicationGuid, sizeof (gEfiSmmLockBoxCommunicationGuid));
  if ((sizeof (UINTN) == sizeof (UINT32)) && (FeaturePcdGet (PcdDxeIplSwitchToLongMode))) {
    MessageLength = sizeof (*LockBoxParameterRestoreAllInPlace);
    CopyMem (&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, MessageLength)], &MessageLength, sizeof (MessageLength));
  } else {
    CommHeader->MessageLength = sizeof (*LockBoxParameterRestoreAllInPlace);
  }

  if ((sizeof (UINTN) == sizeof (UINT32)) && (FeaturePcdGet (PcdDxeIplSwitchToLongMode))) {
    LockBoxParameterRestoreAllInPlace = (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE *)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, MessageLength) + sizeof (UINT64)];
  } else {
    LockBoxParameterRestoreAllInPlace = (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE *)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, MessageLength) + sizeof (UINTN)];
  }

  LockBoxParameterRestoreAllInPlace->Header.Command      = EFI_SMM_LOCK_BOX_COMMAND_RESTORE_ALL_IN_PLACE;
  LockBoxParameterRestoreAllInPlace->Header.DataLength   = sizeof (*LockBoxParameterRestoreAllInPlace);
  LockBoxParameterRestoreAllInPlace->Header.ReturnStatus = (UINT64)-1;

  //
  // Send command
  //
  CommSize = sizeof (CommBuffer);
  Status   = SmmCommunicationPpi->Communicate (
                                    SmmCommunicationPpi,
                                    &CommBuffer[0],
                                    &CommSize
                                    );
  if (Status == EFI_NOT_STARTED) {
    //
    // Pei SMM communication not ready yet, so we access SMRAM directly
    //
    DEBUG ((DEBUG_INFO, "SmmLockBoxPeiLib Communicate - (%r)\n", Status));
    Status                                                 = InternalRestoreAllLockBoxInPlaceFromSmram ();
    LockBoxParameterRestoreAllInPlace->Header.ReturnStatus = (UINT64)Status;
  }

  ASSERT_EFI_ERROR (Status);

  Status = (EFI_STATUS)LockBoxParameterRestoreAllInPlace->Header.ReturnStatus;
  if (Status != EFI_SUCCESS) {
    // Need or MAX_BIT, because there might be case that SMM is X64 while PEI is IA32.
    Status |= MAX_BIT;
  }

  DEBUG ((DEBUG_INFO, "SmmLockBoxPeiLib RestoreAllLockBoxInPlace - Exit (%r)\n", Status));

  //
  // Done
  //
  return Status;
}
