--- /dev/null
+/** @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