REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the MdeModulePkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>
		
			
				
	
	
		
			755 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			755 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @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;
 | 
						|
}
 |