| /** @file | |
| Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR> | |
| This program and the accompanying materials | |
| are licensed and made available under the terms and conditions | |
| of the BSD License which accompanies this distribution. The | |
| full text of the license may be found at | |
| http://opensource.org/licenses/bsd-license.php | |
| THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
| **/ | |
| #include <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 the original buffer to too small to hold new 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 ((EFI_D_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 ((EFI_D_INFO, "SmmLockBoxPeiLib LocatePpi - (%r)\n", Status)); | |
| Status = InternalRestoreLockBoxFromSmram (Guid, Buffer, Length); | |
| DEBUG ((EFI_D_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 ((EFI_D_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 ((EFI_D_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 ((EFI_D_INFO, "SmmLockBoxPeiLib Communicate - (%r)\n", Status)); | |
| Status = InternalRestoreLockBoxFromSmram (Guid, Buffer, Length); | |
| LockBoxParameterRestore->Header.ReturnStatus = (UINT64)Status; | |
| if (Length != NULL) { | |
| LockBoxParameterRestore->Length = (UINT64)*Length; | |
| } | |
| } | |
| ASSERT_EFI_ERROR (Status); | |
| 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 ((EFI_D_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 ((EFI_D_INFO, "SmmLockBoxPeiLib RestoreAllLockBoxInPlace - Enter\n")); | |
| // | |
| // Get needed resource | |
| // | |
| Status = PeiServicesLocatePpi ( | |
| &gEfiPeiSmmCommunicationPpiGuid, | |
| 0, | |
| NULL, | |
| (VOID **)&SmmCommunicationPpi | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| DEBUG ((EFI_D_INFO, "SmmLockBoxPeiLib LocatePpi - (%r)\n", Status)); | |
| Status = InternalRestoreAllLockBoxInPlaceFromSmram (); | |
| DEBUG ((EFI_D_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 ((EFI_D_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 ((EFI_D_INFO, "SmmLockBoxPeiLib RestoreAllLockBoxInPlace - Exit (%r)\n", Status)); | |
| // | |
| // Done | |
| // | |
| return Status; | |
| } | |