]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg: Add SmmLockBox PEI implementation
authorjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 2 Aug 2011 21:06:13 +0000 (21:06 +0000)
committerjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 2 Aug 2011 21:06:13 +0000 (21:06 +0000)
Signed-off-by: jljusten
Reviewed-by: rsun3
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12077 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.c [new file with mode: 0644]
MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf [new file with mode: 0644]
MdeModulePkg/MdeModulePkg.dsc

diff --git a/MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.c b/MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.c
new file mode 100644 (file)
index 0000000..bd3204b
--- /dev/null
@@ -0,0 +1,741 @@
+/** @file\r
+\r
+Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>\r
+\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions\r
+of the BSD License which accompanies this distribution.  The\r
+full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <PiPei.h>\r
+#include <PiDxe.h>\r
+#include <PiSmm.h>\r
+#include <Library/PeiServicesTablePointerLib.h>\r
+#include <Library/PeiServicesLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/LockBoxLib.h>\r
+#include <Library/HobLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Protocol/SmmCommunication.h>\r
+#include <Ppi/SmmCommunication.h>\r
+#include <Ppi/SmmAccess.h>\r
+#include <Guid/AcpiS3Context.h>\r
+#include <Guid/SmmLockBox.h>\r
+\r
+#include "SmmLockBoxLibPrivate.h"\r
+\r
+#if defined (MDE_CPU_IA32)\r
+typedef struct _LIST_ENTRY64 LIST_ENTRY64;\r
+struct _LIST_ENTRY64 {\r
+  LIST_ENTRY64  *ForwardLink;\r
+  UINT32        Reserved1;\r
+  LIST_ENTRY64  *BackLink;\r
+  UINT32        Reserved2;\r
+};\r
+\r
+typedef struct {\r
+  EFI_TABLE_HEADER    Hdr;\r
+  UINT64              SmmFirmwareVendor;\r
+  UINT64              SmmFirmwareRevision;\r
+  UINT64              SmmInstallConfigurationTable;\r
+  UINT64              SmmIoMemRead;\r
+  UINT64              SmmIoMemWrite;\r
+  UINT64              SmmIoIoRead;\r
+  UINT64              SmmIoIoWrite;\r
+  UINT64              SmmAllocatePool;\r
+  UINT64              SmmFreePool;\r
+  UINT64              SmmAllocatePages;\r
+  UINT64              SmmFreePages;\r
+  UINT64              SmmStartupThisAp;\r
+  UINT64              CurrentlyExecutingCpu;\r
+  UINT64              NumberOfCpus;\r
+  UINT64              CpuSaveStateSize;\r
+  UINT64              CpuSaveState;\r
+  UINT64              NumberOfTableEntries;\r
+  UINT64              SmmConfigurationTable;\r
+} EFI_SMM_SYSTEM_TABLE2_64;\r
+\r
+typedef struct {\r
+  EFI_GUID                          VendorGuid;\r
+  UINT64                            VendorTable;\r
+} EFI_CONFIGURATION_TABLE64;\r
+#endif\r
+\r
+#if defined (MDE_CPU_X64)\r
+typedef LIST_ENTRY LIST_ENTRY64;\r
+typedef EFI_SMM_SYSTEM_TABLE2 EFI_SMM_SYSTEM_TABLE2_64;\r
+typedef EFI_CONFIGURATION_TABLE EFI_CONFIGURATION_TABLE64;\r
+#endif\r
+\r
+/**\r
+  This function return first node of LinkList queue.\r
+\r
+  @param LockBoxQueue  LinkList queue\r
+\r
+  @return first node of LinkList queue\r
+**/\r
+LIST_ENTRY *\r
+InternalInitLinkDxe (\r
+  IN LIST_ENTRY *LinkList\r
+  )\r
+{\r
+  if ((sizeof(UINTN) == sizeof(UINT32)) && (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) ) {\r
+    //\r
+    // 32 PEI + 64 DXE\r
+    //\r
+    return (LIST_ENTRY *)(((LIST_ENTRY64 *)LinkList)->ForwardLink);\r
+  } else {\r
+    return LinkList->ForwardLink;\r
+  }\r
+}\r
+\r
+/**\r
+  This function return next node of LinkList.\r
+\r
+  @param Link  LinkList node\r
+\r
+  @return next node of LinkList\r
+**/\r
+LIST_ENTRY *\r
+InternalNextLinkDxe (\r
+  IN LIST_ENTRY *Link\r
+  )\r
+{\r
+  if ((sizeof(UINTN) == sizeof(UINT32)) && (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) ) {\r
+    //\r
+    // 32 PEI + 64 DXE\r
+    //\r
+    return (LIST_ENTRY *)(((LIST_ENTRY64 *)Link)->ForwardLink);\r
+  } else {\r
+    return Link->ForwardLink;\r
+  }\r
+}\r
+\r
+/**\r
+  This function find LockBox by GUID from SMRAM.\r
+\r
+  @param LockBoxQueue The LockBox queue in SMRAM\r
+  @param Guid         The guid to indentify the LockBox\r
+\r
+  @return LockBoxData\r
+**/\r
+SMM_LOCK_BOX_DATA *\r
+InternalFindLockBoxByGuidFromSmram (\r
+  IN LIST_ENTRY *LockBoxQueue,\r
+  IN EFI_GUID   *Guid\r
+  )\r
+{\r
+  LIST_ENTRY                    *Link;\r
+  SMM_LOCK_BOX_DATA             *LockBox;\r
+\r
+  for (Link = InternalInitLinkDxe (LockBoxQueue);\r
+       Link != LockBoxQueue;\r
+       Link = InternalNextLinkDxe (Link)) {\r
+    LockBox = BASE_CR (\r
+                Link,\r
+                SMM_LOCK_BOX_DATA,\r
+                Link\r
+                );\r
+    if (CompareGuid (&LockBox->Guid, Guid)) {\r
+      return LockBox;\r
+    }\r
+  }\r
+  return NULL;\r
+}\r
+\r
+/**\r
+  Get VendorTable by VendorGuid in Smst.\r
+\r
+  @param Signature  Signature of SMM_S3_RESUME_STATE\r
+  @param Smst       SMM system table\r
+  @param VendorGuid vendor guid\r
+\r
+  @return vendor table.\r
+**/\r
+VOID *\r
+InternalSmstGetVendorTableByGuid (\r
+  IN UINT64                                        Signature,\r
+  IN EFI_SMM_SYSTEM_TABLE2                         *Smst,\r
+  IN EFI_GUID                                      *VendorGuid\r
+  )\r
+{\r
+  EFI_CONFIGURATION_TABLE                       *SmmConfigurationTable;\r
+  UINTN                                         NumberOfTableEntries;\r
+  UINTN                                         Index;\r
+  EFI_SMM_SYSTEM_TABLE2_64                      *Smst64;\r
+  EFI_CONFIGURATION_TABLE64                     *SmmConfigurationTable64;\r
+\r
+  if ((sizeof(UINTN) == sizeof(UINT32)) && (FeaturePcdGet (PcdDxeIplSwitchToLongMode))) {\r
+    //\r
+    // 32 PEI + 64 DXE\r
+    //\r
+    Smst64 = (EFI_SMM_SYSTEM_TABLE2_64 *)Smst;\r
+    SmmConfigurationTable64 = (EFI_CONFIGURATION_TABLE64 *)(UINTN)Smst64->SmmConfigurationTable;\r
+    NumberOfTableEntries = (UINTN)Smst64->NumberOfTableEntries;\r
+    for (Index = 0; Index < NumberOfTableEntries; Index++) {\r
+      if (CompareGuid (&SmmConfigurationTable64[Index].VendorGuid, VendorGuid)) {\r
+        return (VOID *)(UINTN)SmmConfigurationTable64[Index].VendorTable;\r
+      }\r
+    }\r
+    return NULL;\r
+  } else {\r
+    SmmConfigurationTable = Smst->SmmConfigurationTable;\r
+    NumberOfTableEntries = Smst->NumberOfTableEntries;\r
+    for (Index = 0; Index < NumberOfTableEntries; Index++) {\r
+      if (CompareGuid (&SmmConfigurationTable[Index].VendorGuid, VendorGuid)) {\r
+        return (VOID *)SmmConfigurationTable[Index].VendorTable;\r
+      }\r
+    }\r
+    return NULL;\r
+  }\r
+}\r
+\r
+/**\r
+  Get SMM LockBox context.\r
+\r
+  @return SMM LockBox context.\r
+**/\r
+SMM_LOCK_BOX_CONTEXT *\r
+InternalGetSmmLockBoxContext (\r
+  VOID\r
+  )\r
+{\r
+  EFI_SMRAM_DESCRIPTOR                          *SmramDescriptor;\r
+  SMM_S3_RESUME_STATE                           *SmmS3ResumeState;\r
+  VOID                                          *GuidHob;\r
+  SMM_LOCK_BOX_CONTEXT                          *SmmLockBoxContext;\r
+\r
+  GuidHob = GetFirstGuidHob (&gEfiAcpiVariableGuid);\r
+  ASSERT (GuidHob != NULL);\r
+  SmramDescriptor = (EFI_SMRAM_DESCRIPTOR *) GET_GUID_HOB_DATA (GuidHob);\r
+  SmmS3ResumeState = (SMM_S3_RESUME_STATE *)(UINTN)SmramDescriptor->CpuStart;\r
+\r
+  SmmLockBoxContext = (SMM_LOCK_BOX_CONTEXT *)InternalSmstGetVendorTableByGuid (\r
+                                                SmmS3ResumeState->Signature,\r
+                                                (EFI_SMM_SYSTEM_TABLE2 *)(UINTN)SmmS3ResumeState->Smst,\r
+                                                &gEfiSmmLockBoxCommunicationGuid\r
+                                                );\r
+  ASSERT (SmmLockBoxContext != NULL);\r
+\r
+  return SmmLockBoxContext;\r
+}\r
+\r
+/**\r
+  This function will restore confidential information from lockbox in SMRAM directly.\r
+\r
+  @param Guid   the guid to identify the confidential information\r
+  @param Buffer the address of the restored confidential information\r
+                NULL means restored to original address, Length MUST be NULL at same time.\r
+  @param Length the length of the restored confidential information\r
+\r
+  @retval RETURN_SUCCESS            the information is restored successfully.\r
+  @retval RETURN_WRITE_PROTECTED    Buffer and Length are NULL, but the LockBox has no \r
+                                    LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE attribute.\r
+  @retval RETURN_BUFFER_TOO_SMALL   the Length is too small to hold the confidential information.\r
+  @retval RETURN_NOT_FOUND          the requested GUID not found.\r
+**/\r
+EFI_STATUS\r
+InternalRestoreLockBoxFromSmram (\r
+  IN  GUID                        *Guid,\r
+  IN  VOID                        *Buffer, OPTIONAL\r
+  IN  OUT UINTN                   *Length  OPTIONAL\r
+  )\r
+{\r
+  PEI_SMM_ACCESS_PPI             *SmmAccess;\r
+  UINTN                          Index;\r
+  EFI_STATUS                     Status;\r
+  SMM_LOCK_BOX_CONTEXT           *SmmLockBoxContext;\r
+  LIST_ENTRY                     *LockBoxQueue;\r
+  SMM_LOCK_BOX_DATA              *LockBox;\r
+  VOID                           *RestoreBuffer;\r
+\r
+  //\r
+  // Get needed resource\r
+  //\r
+  Status = PeiServicesLocatePpi (\r
+             &gPeiSmmAccessPpiGuid,\r
+             0,\r
+             NULL,\r
+             (VOID **)&SmmAccess\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    for (Index = 0; !EFI_ERROR (Status); Index++) {\r
+      Status = SmmAccess->Open ((EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), SmmAccess, Index);\r
+    }\r
+  }\r
+\r
+  //\r
+  // Get LockBox context\r
+  //\r
+  SmmLockBoxContext = InternalGetSmmLockBoxContext ();\r
+  LockBoxQueue = (LIST_ENTRY *)(UINTN)SmmLockBoxContext->LockBoxDataAddress;\r
+\r
+  //\r
+  // We do NOT check Buffer address in SMRAM, because if SMRAM not locked, we trust the caller.\r
+  //\r
+\r
+  //\r
+  // Restore this, Buffer and Length MUST be both NULL or both non-NULL\r
+  //\r
+\r
+  //\r
+  // Find LockBox\r
+  //\r
+  LockBox = InternalFindLockBoxByGuidFromSmram (LockBoxQueue, Guid);\r
+  if (LockBox == NULL) {\r
+    //\r
+    // Not found\r
+    //\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  //\r
+  // Set RestoreBuffer\r
+  //\r
+  if (Buffer != NULL) {\r
+    //\r
+    // restore to new buffer\r
+    //\r
+    RestoreBuffer = Buffer;\r
+  } else {\r
+    //\r
+    // restore to original buffer\r
+    //\r
+    if ((LockBox->Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE) == 0) {\r
+      return EFI_WRITE_PROTECTED;\r
+    }\r
+    RestoreBuffer = (VOID *)(UINTN)LockBox->Buffer;\r
+  }\r
+\r
+  //\r
+  // Set RestoreLength\r
+  //\r
+  if (Length != NULL) {\r
+    if (*Length < (UINTN)LockBox->Length) {\r
+      //\r
+      // Input buffer is too small to hold all data.\r
+      //\r
+      *Length = (UINTN)LockBox->Length;\r
+      return EFI_BUFFER_TOO_SMALL;\r
+    }\r
+    *Length = (UINTN)LockBox->Length;\r
+  }\r
+\r
+  //\r
+  // Restore data\r
+  //\r
+  CopyMem (RestoreBuffer, (VOID *)(UINTN)LockBox->SmramBuffer, (UINTN)LockBox->Length);\r
+\r
+  //\r
+  // Done\r
+  //\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  This function will restore confidential information from all lockbox which have RestoreInPlace attribute.\r
+\r
+  @retval RETURN_SUCCESS            the information is restored successfully.\r
+**/\r
+EFI_STATUS\r
+InternalRestoreAllLockBoxInPlaceFromSmram (\r
+  VOID\r
+  )\r
+{\r
+  PEI_SMM_ACCESS_PPI             *SmmAccess;\r
+  UINTN                          Index;\r
+  EFI_STATUS                     Status;\r
+  SMM_LOCK_BOX_CONTEXT           *SmmLockBoxContext;\r
+  LIST_ENTRY                     *LockBoxQueue;\r
+  SMM_LOCK_BOX_DATA              *LockBox;\r
+  LIST_ENTRY                     *Link;\r
+\r
+  //\r
+  // Get needed resource\r
+  //\r
+  Status = PeiServicesLocatePpi (\r
+             &gPeiSmmAccessPpiGuid,\r
+             0,\r
+             NULL,\r
+             (VOID **)&SmmAccess\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    for (Index = 0; !EFI_ERROR (Status); Index++) {\r
+      Status = SmmAccess->Open ((EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), SmmAccess, Index);\r
+    }\r
+  }\r
+\r
+  //\r
+  // Get LockBox context\r
+  //\r
+  SmmLockBoxContext = InternalGetSmmLockBoxContext ();\r
+  LockBoxQueue = (LIST_ENTRY *)(UINTN)SmmLockBoxContext->LockBoxDataAddress;\r
+\r
+  //\r
+  // We do NOT check Buffer address in SMRAM, because if SMRAM not locked, we trust the caller.\r
+  //\r
+\r
+  //\r
+  // Restore all, Buffer and Length MUST be NULL\r
+  //\r
+  for (Link = InternalInitLinkDxe (LockBoxQueue);\r
+       Link != LockBoxQueue;\r
+       Link = InternalNextLinkDxe (Link)) {\r
+    LockBox = BASE_CR (\r
+                Link,\r
+                SMM_LOCK_BOX_DATA,\r
+                Link\r
+                );\r
+    if ((LockBox->Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE) != 0) {\r
+      //\r
+      // Restore data\r
+      //\r
+      CopyMem ((VOID *)(UINTN)LockBox->Buffer, (VOID *)(UINTN)LockBox->SmramBuffer, (UINTN)LockBox->Length);\r
+    }\r
+  }\r
+  //\r
+  // Done\r
+  //\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  This function will save confidential information to lockbox.\r
+\r
+  @param Guid       the guid to identify the confidential information\r
+  @param Buffer     the address of the confidential information\r
+  @param Length     the length of the confidential information\r
+\r
+  @retval RETURN_SUCCESS            the information is saved successfully.\r
+  @retval RETURN_INVALID_PARAMETER  the Guid is NULL, or Buffer is NULL, or Length is 0\r
+  @retval RETURN_ALREADY_STARTED    the requested GUID already exist.\r
+  @retval RETURN_OUT_OF_RESOURCES   no enough resource to save the information.\r
+  @retval RETURN_ACCESS_DENIED      it is too late to invoke this interface\r
+  @retval RETURN_NOT_STARTED        it is too early to invoke this interface\r
+  @retval RETURN_UNSUPPORTED        the service is not supported by implementaion.\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+SaveLockBox (\r
+  IN  GUID                        *Guid,\r
+  IN  VOID                        *Buffer,\r
+  IN  UINTN                       Length\r
+  )\r
+{\r
+  ASSERT (FALSE);\r
+\r
+  //\r
+  // No support to save at PEI phase\r
+  //\r
+  return RETURN_UNSUPPORTED;\r
+}\r
+\r
+/**\r
+  This function will set lockbox attributes.\r
+\r
+  @param Guid       the guid to identify the confidential information\r
+  @param Attributes the attributes of the lockbox\r
+\r
+  @retval RETURN_SUCCESS            the information is saved successfully.\r
+  @retval RETURN_INVALID_PARAMETER  attributes is invalid.\r
+  @retval RETURN_NOT_FOUND          the requested GUID not found.\r
+  @retval RETURN_ACCESS_DENIED      it is too late to invoke this interface\r
+  @retval RETURN_NOT_STARTED        it is too early to invoke this interface\r
+  @retval RETURN_UNSUPPORTED        the service is not supported by implementaion.\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+SetLockBoxAttributes (\r
+  IN  GUID                        *Guid,\r
+  IN  UINT64                      Attributes\r
+  )\r
+{\r
+  ASSERT (FALSE);\r
+\r
+  //\r
+  // No support to save at PEI phase\r
+  //\r
+  return RETURN_UNSUPPORTED;\r
+}\r
+\r
+/**\r
+  This function will update confidential information to lockbox.\r
+\r
+  @param Guid   the guid to identify the original confidential information\r
+  @param Offset the offset of the original confidential information\r
+  @param Buffer the address of the updated confidential information\r
+  @param Length the length of the updated confidential information\r
+\r
+  @retval RETURN_SUCCESS            the information is saved successfully.\r
+  @retval RETURN_INVALID_PARAMETER  the Guid is NULL, or Buffer is NULL, or Length is 0.\r
+  @retval RETURN_NOT_FOUND          the requested GUID not found.\r
+  @retval RETURN_BUFFER_TOO_SMALL   the original buffer to too small to hold new information.\r
+  @retval RETURN_ACCESS_DENIED      it is too late to invoke this interface\r
+  @retval RETURN_NOT_STARTED        it is too early to invoke this interface\r
+  @retval RETURN_UNSUPPORTED        the service is not supported by implementaion.\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+UpdateLockBox (\r
+  IN  GUID                        *Guid,\r
+  IN  UINTN                       Offset,\r
+  IN  VOID                        *Buffer,\r
+  IN  UINTN                       Length\r
+  )\r
+{\r
+  ASSERT (FALSE);\r
+\r
+  //\r
+  // No support to update at PEI phase\r
+  //\r
+  return RETURN_UNSUPPORTED;\r
+}\r
+\r
+/**\r
+  This function will restore confidential information from lockbox.\r
+\r
+  @param Guid   the guid to identify the confidential information\r
+  @param Buffer the address of the restored confidential information\r
+                NULL means restored to original address, Length MUST be NULL at same time.\r
+  @param Length the length of the restored confidential information\r
+\r
+  @retval RETURN_SUCCESS            the information is restored successfully.\r
+  @retval RETURN_INVALID_PARAMETER  the Guid is NULL, or one of Buffer and Length is NULL.\r
+  @retval RETURN_WRITE_PROTECTED    Buffer and Length are NULL, but the LockBox has no \r
+                                    LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE attribute.\r
+  @retval RETURN_BUFFER_TOO_SMALL   the Length is too small to hold the confidential information.\r
+  @retval RETURN_NOT_FOUND          the requested GUID not found.\r
+  @retval RETURN_NOT_STARTED        it is too early to invoke this interface\r
+  @retval RETURN_ACCESS_DENIED      not allow to restore to the address\r
+  @retval RETURN_UNSUPPORTED        the service is not supported by implementaion.\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+RestoreLockBox (\r
+  IN  GUID                        *Guid,\r
+  IN  VOID                        *Buffer, OPTIONAL\r
+  IN  OUT UINTN                   *Length  OPTIONAL\r
+  )\r
+{\r
+  EFI_STATUS                         Status;\r
+  EFI_PEI_SMM_COMMUNICATION_PPI      *SmmCommunicationPpi;\r
+  EFI_SMM_LOCK_BOX_PARAMETER_RESTORE *LockBoxParameterRestore;\r
+  EFI_SMM_COMMUNICATE_HEADER         *CommHeader;\r
+  UINT8                              CommBuffer[sizeof(EFI_GUID) + sizeof(UINT64) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_RESTORE)];\r
+  UINTN                              CommSize;\r
+  UINT64                             MessageLength;\r
+\r
+  //\r
+  // Please aware that there is UINTN in EFI_SMM_COMMUNICATE_HEADER. It might be UINT64 in DXE, while it is UINT32 in PEI.\r
+  // typedef struct {\r
+  //   EFI_GUID  HeaderGuid;\r
+  //   UINTN     MessageLength;\r
+  //   UINT8     Data[1];\r
+  // } EFI_SMM_COMMUNICATE_HEADER;\r
+  //\r
+\r
+  DEBUG ((EFI_D_INFO, "SmmLockBoxPeiLib RestoreLockBox - Enter\n"));\r
+\r
+  //\r
+  // Basic check\r
+  //\r
+  if ((Guid == NULL) ||\r
+      ((Buffer == NULL) && (Length != NULL)) ||\r
+      ((Buffer != NULL) && (Length == NULL))) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Get needed resource\r
+  //\r
+  Status = PeiServicesLocatePpi (\r
+             &gEfiPeiSmmCommunicationPpiGuid,\r
+             0,\r
+             NULL,\r
+             (VOID **)&SmmCommunicationPpi\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_NOT_STARTED;\r
+  }\r
+\r
+  //\r
+  // Prepare parameter\r
+  //\r
+  CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0];\r
+  CopyMem (&CommHeader->HeaderGuid, &gEfiSmmLockBoxCommunicationGuid, sizeof(gEfiSmmLockBoxCommunicationGuid));\r
+  if ((sizeof(UINTN) == sizeof(UINT32)) && (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) ) {\r
+    MessageLength = sizeof(*LockBoxParameterRestore);\r
+    CopyMem (&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, MessageLength)], &MessageLength, sizeof(MessageLength));\r
+  } else {\r
+    CommHeader->MessageLength = sizeof(*LockBoxParameterRestore);\r
+  }\r
+\r
+  DEBUG ((EFI_D_INFO, "SmmLockBoxPeiLib CommBuffer - %x\n", &CommBuffer[0]));\r
+  if ((sizeof(UINTN) == sizeof(UINT32)) && (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) ) {\r
+    LockBoxParameterRestore = (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE *)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, MessageLength) + sizeof(UINT64)];\r
+  } else {\r
+    LockBoxParameterRestore = (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE *)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, MessageLength) + sizeof(UINTN)];\r
+  }\r
+  DEBUG ((EFI_D_INFO, "SmmLockBoxPeiLib LockBoxParameterRestore - %x\n", LockBoxParameterRestore));\r
+  LockBoxParameterRestore->Header.Command    = EFI_SMM_LOCK_BOX_COMMAND_RESTORE;\r
+  LockBoxParameterRestore->Header.DataLength = sizeof(*LockBoxParameterRestore);\r
+  LockBoxParameterRestore->Header.ReturnStatus = (UINT64)-1;\r
+  if (Guid != 0) {\r
+    CopyMem (&LockBoxParameterRestore->Guid, Guid, sizeof(*Guid));\r
+  } else {\r
+    ZeroMem (&LockBoxParameterRestore->Guid, sizeof(*Guid));\r
+  }\r
+  LockBoxParameterRestore->Buffer = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer;\r
+  if (Length != NULL) {\r
+    LockBoxParameterRestore->Length = (EFI_PHYSICAL_ADDRESS)*Length;\r
+  } else {\r
+    LockBoxParameterRestore->Length = 0;\r
+  }\r
+\r
+  //\r
+  // Send command\r
+  //\r
+  CommSize = sizeof(CommBuffer);\r
+  Status = SmmCommunicationPpi->Communicate (\r
+                                  SmmCommunicationPpi,\r
+                                  &CommBuffer[0],\r
+                                  &CommSize\r
+                                  );\r
+  if (Status == EFI_NOT_STARTED) {\r
+    //\r
+    // Pei SMM communication not ready yet, so we access SMRAM directly\r
+    //\r
+    DEBUG ((EFI_D_INFO, "SmmLockBoxPeiLib Communicate - (%r)\n", Status));\r
+    Status = InternalRestoreLockBoxFromSmram (Guid, Buffer, Length);\r
+    LockBoxParameterRestore->Header.ReturnStatus = (UINT64)Status;\r
+    if (Length != NULL) {\r
+      LockBoxParameterRestore->Length = (UINT64)*Length;\r
+    }\r
+  }\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  if (Length != NULL) {\r
+    *Length = (UINTN)LockBoxParameterRestore->Length;\r
+  }\r
+\r
+  Status = (EFI_STATUS)LockBoxParameterRestore->Header.ReturnStatus;\r
+  if (Status != EFI_SUCCESS) {\r
+    // Need or MAX_BIT, because there might be case that SMM is X64 while PEI is IA32.\r
+    Status |= MAX_BIT;\r
+  }\r
+\r
+  DEBUG ((EFI_D_INFO, "SmmLockBoxPeiLib RestoreLockBox - Exit (%r)\n", Status));\r
+\r
+  //\r
+  // Done\r
+  //\r
+  return Status;\r
+}\r
+\r
+/**\r
+  This function will restore confidential information from all lockbox which have RestoreInPlace attribute.\r
+\r
+  @retval RETURN_SUCCESS            the information is restored successfully.\r
+  @retval RETURN_NOT_STARTED        it is too early to invoke this interface\r
+  @retval RETURN_UNSUPPORTED        the service is not supported by implementaion.\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+RestoreAllLockBoxInPlace (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                                      Status;\r
+  EFI_PEI_SMM_COMMUNICATION_PPI                   *SmmCommunicationPpi;\r
+  EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE *LockBoxParameterRestoreAllInPlace;\r
+  EFI_SMM_COMMUNICATE_HEADER                      *CommHeader;\r
+  UINT8                                           CommBuffer[sizeof(EFI_GUID) + sizeof(UINT64) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE)];\r
+  UINTN                                           CommSize;\r
+  UINT64                                          MessageLength;\r
+\r
+  //\r
+  // Please aware that there is UINTN in EFI_SMM_COMMUNICATE_HEADER. It might be UINT64 in DXE, while it is UINT32 in PEI.\r
+  // typedef struct {\r
+  //   EFI_GUID  HeaderGuid;\r
+  //   UINTN     MessageLength;\r
+  //   UINT8     Data[1];\r
+  // } EFI_SMM_COMMUNICATE_HEADER;\r
+  //\r
+\r
+  DEBUG ((EFI_D_INFO, "SmmLockBoxPeiLib RestoreAllLockBoxInPlace - Enter\n"));\r
+\r
+  //\r
+  // Get needed resource\r
+  //\r
+  Status = PeiServicesLocatePpi (\r
+             &gEfiPeiSmmCommunicationPpiGuid,\r
+             0,\r
+             NULL,\r
+             (VOID **)&SmmCommunicationPpi\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_NOT_STARTED;\r
+  }\r
+\r
+  //\r
+  // Prepare parameter\r
+  //\r
+  CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0];\r
+  CopyMem (&CommHeader->HeaderGuid, &gEfiSmmLockBoxCommunicationGuid, sizeof(gEfiSmmLockBoxCommunicationGuid));\r
+  if ((sizeof(UINTN) == sizeof(UINT32)) && (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) ) {\r
+    MessageLength = sizeof(*LockBoxParameterRestoreAllInPlace);\r
+    CopyMem (&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, MessageLength)], &MessageLength, sizeof(MessageLength));\r
+  } else {\r
+    CommHeader->MessageLength = sizeof(*LockBoxParameterRestoreAllInPlace);\r
+  }\r
+\r
+  if ((sizeof(UINTN) == sizeof(UINT32)) && (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) ) {\r
+    LockBoxParameterRestoreAllInPlace = (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE *)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, MessageLength) + sizeof(UINT64)];\r
+  } else {\r
+    LockBoxParameterRestoreAllInPlace = (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE *)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, MessageLength) + sizeof(UINTN)];\r
+  }\r
+  LockBoxParameterRestoreAllInPlace->Header.Command    = EFI_SMM_LOCK_BOX_COMMAND_RESTORE_ALL_IN_PLACE;\r
+  LockBoxParameterRestoreAllInPlace->Header.DataLength = sizeof(*LockBoxParameterRestoreAllInPlace);\r
+  LockBoxParameterRestoreAllInPlace->Header.ReturnStatus = (UINT64)-1;\r
+\r
+  //\r
+  // Send command\r
+  //\r
+  CommSize = sizeof(CommBuffer);\r
+  Status = SmmCommunicationPpi->Communicate (\r
+                                  SmmCommunicationPpi,\r
+                                  &CommBuffer[0],\r
+                                  &CommSize\r
+                                  );\r
+  if (Status == EFI_NOT_STARTED) {\r
+    //\r
+    // Pei SMM communication not ready yet, so we access SMRAM directly\r
+    //\r
+    DEBUG ((EFI_D_INFO, "SmmLockBoxPeiLib Communicate - (%r)\n", Status));\r
+    Status = InternalRestoreAllLockBoxInPlaceFromSmram ();\r
+    LockBoxParameterRestoreAllInPlace->Header.ReturnStatus = (UINT64)Status;\r
+  }\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  Status = (EFI_STATUS)LockBoxParameterRestoreAllInPlace->Header.ReturnStatus;\r
+  if (Status != EFI_SUCCESS) {\r
+    // Need or MAX_BIT, because there might be case that SMM is X64 while PEI is IA32.\r
+    Status |= MAX_BIT;\r
+  }\r
+\r
+  DEBUG ((EFI_D_INFO, "SmmLockBoxPeiLib RestoreAllLockBoxInPlace - Exit (%r)\n", Status));\r
+\r
+  //\r
+  // Done\r
+  //\r
+  return Status;\r
+}\r
+\r
diff --git a/MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf b/MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf
new file mode 100644 (file)
index 0000000..b84408c
--- /dev/null
@@ -0,0 +1,56 @@
+## @file\r
+#  Component description file for LockBox library.\r
+#\r
+#  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+#\r
+#  This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions\r
+#  of the BSD License which accompanies this distribution.  The\r
+#  full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = SmmLockBoxPeiLib\r
+  FILE_GUID                      = 5F5E6140-E7BA-4bd6-B85F-236B5BCD8E1E\r
+  MODULE_TYPE                    = PEIM\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = LockBoxLib|PEIM\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 \r
+#\r
+\r
+[Sources]\r
+  SmmLockBoxPeiLib.c\r
+  SmmLockBoxLibPrivate.h\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+\r
+[LibraryClasses]\r
+  PeiServicesTablePointerLib\r
+  PeiServicesLib\r
+  BaseLib\r
+  BaseMemoryLib\r
+  HobLib\r
+  DebugLib\r
+\r
+[FeaturePcd]\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode\r
+\r
+[Guids]\r
+  gEfiSmmLockBoxCommunicationGuid       ## CONSUMED\r
+  gEfiAcpiVariableGuid               ## CONSUMED\r
+\r
+[Ppis]\r
+  gEfiPeiSmmCommunicationPpiGuid     ## CONSUMED\r
+  gPeiSmmAccessPpiGuid               ## CONSUMED\r
index af66ca13870e42b032a62bae7aecf20ce0225f84..b44b1e752389b2084e549a6dd8e5f01c3154d48e 100644 (file)
@@ -99,6 +99,7 @@
   HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf\r
   MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf\r
   ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf\r
+  LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf\r
 \r
 [LibraryClasses.common.DXE_CORE]\r
   HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf\r
   MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf\r
   MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatformHookLibNull.inf\r
   MdeModulePkg/Library/DxeDebugPrintErrorLevelLib/DxeDebugPrintErrorLevelLib.inf\r
+  MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf\r
   MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.inf\r
   MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.inf\r
 \r