| /** @file | |
| Copyright (c) 2014 - 2015, 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 <PiSmm.h> | |
| #include <Library/BaseLib.h> | |
| #include <Library/MemoryAllocationLib.h> | |
| #include <Library/UefiBootServicesTableLib.h> | |
| #include <Library/SmmServicesTableLib.h> | |
| #include <Library/DevicePathLib.h> | |
| #include <Library/BaseMemoryLib.h> | |
| #include <Library/DebugLib.h> | |
| #include <Library/PcdLib.h> | |
| #include <Protocol/SmmCommunication.h> | |
| #include <Guid/MemoryProfile.h> | |
| EFI_SMM_COMMUNICATION_PROTOCOL *mSmmCommunication = NULL; | |
| /** | |
| Get the GUID file name from the file path. | |
| @param FilePath File path. | |
| @return The GUID file name from the file path. | |
| **/ | |
| EFI_GUID * | |
| GetFileNameFromFilePath ( | |
| IN EFI_DEVICE_PATH_PROTOCOL *FilePath | |
| ) | |
| { | |
| MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *ThisFilePath; | |
| ThisFilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) FilePath; | |
| while (!IsDevicePathEnd (ThisFilePath)) { | |
| if ((DevicePathType (ThisFilePath) == MEDIA_DEVICE_PATH) && (DevicePathSubType (ThisFilePath) == MEDIA_PIWG_FW_FILE_DP)) { | |
| return &ThisFilePath->FvFileName; | |
| } | |
| ThisFilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) NextDevicePathNode (ThisFilePath); | |
| } | |
| return NULL; | |
| } | |
| /** | |
| Register SMM image to SMRAM profile. | |
| @param[in] FilePath File path of the image. | |
| @param[in] ImageBuffer Image base address. | |
| @param[in] NumberOfPage Number of page. | |
| @retval TRUE Register success. | |
| @retval FALSE Register fail. | |
| **/ | |
| BOOLEAN | |
| RegisterSmramProfileImage ( | |
| IN EFI_DEVICE_PATH_PROTOCOL *FilePath, | |
| IN PHYSICAL_ADDRESS ImageBuffer, | |
| IN UINTN NumberOfPage | |
| ) | |
| { | |
| EFI_GUID *FileName; | |
| EFI_STATUS Status; | |
| UINTN CommSize; | |
| UINT8 CommBuffer[sizeof (EFI_GUID) + sizeof (UINTN) + sizeof (SMRAM_PROFILE_PARAMETER_REGISTER_IMAGE)]; | |
| EFI_SMM_COMMUNICATE_HEADER *CommHeader; | |
| SMRAM_PROFILE_PARAMETER_REGISTER_IMAGE *CommRegisterImage; | |
| if ((PcdGet8 (PcdMemoryProfilePropertyMask) & BIT1) == 0) { | |
| return FALSE; | |
| } | |
| FileName = GetFileNameFromFilePath (FilePath); | |
| if (mSmmCommunication == NULL) { | |
| Status = gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **) &mSmmCommunication); | |
| ASSERT_EFI_ERROR (Status); | |
| } | |
| CommHeader = (EFI_SMM_COMMUNICATE_HEADER *) &CommBuffer[0]; | |
| CopyMem (&CommHeader->HeaderGuid, &gEdkiiMemoryProfileGuid, sizeof (gEdkiiMemoryProfileGuid)); | |
| CommHeader->MessageLength = sizeof (SMRAM_PROFILE_PARAMETER_REGISTER_IMAGE); | |
| CommRegisterImage = (SMRAM_PROFILE_PARAMETER_REGISTER_IMAGE *)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)]; | |
| CommRegisterImage->Header.Command = SMRAM_PROFILE_COMMAND_REGISTER_IMAGE; | |
| CommRegisterImage->Header.DataLength = sizeof (*CommRegisterImage); | |
| CommRegisterImage->Header.ReturnStatus = (UINT64)-1; | |
| CopyMem (&CommRegisterImage->FileName, FileName, sizeof(EFI_GUID)); | |
| CommRegisterImage->ImageBuffer = ImageBuffer; | |
| CommRegisterImage->NumberOfPage = NumberOfPage; | |
| CommSize = sizeof (EFI_GUID) + sizeof (UINTN) + CommHeader->MessageLength; | |
| Status = mSmmCommunication->Communicate (mSmmCommunication, CommBuffer, &CommSize); | |
| ASSERT_EFI_ERROR (Status); | |
| if (CommRegisterImage->Header.ReturnStatus != 0) { | |
| return FALSE; | |
| } | |
| return TRUE; | |
| } | |
| /** | |
| Unregister SMM image from SMRAM profile. | |
| @param[in] FilePath File path of the image. | |
| @param[in] ImageBuffer Image base address. | |
| @param[in] NumberOfPage Number of page. | |
| @retval TRUE Unregister success. | |
| @retval FALSE Unregister fail. | |
| **/ | |
| BOOLEAN | |
| UnregisterSmramProfileImage ( | |
| IN EFI_DEVICE_PATH_PROTOCOL *FilePath, | |
| IN PHYSICAL_ADDRESS ImageBuffer, | |
| IN UINTN NumberOfPage | |
| ) | |
| { | |
| EFI_GUID *FileName; | |
| EFI_STATUS Status; | |
| UINTN CommSize; | |
| UINT8 CommBuffer[sizeof (EFI_GUID) + sizeof (UINTN) + sizeof (SMRAM_PROFILE_PARAMETER_UNREGISTER_IMAGE)]; | |
| EFI_SMM_COMMUNICATE_HEADER *CommHeader; | |
| SMRAM_PROFILE_PARAMETER_UNREGISTER_IMAGE *CommUnregisterImage; | |
| if ((PcdGet8 (PcdMemoryProfilePropertyMask) & BIT1) == 0) { | |
| return FALSE; | |
| } | |
| FileName = GetFileNameFromFilePath (FilePath); | |
| if (mSmmCommunication == NULL) { | |
| Status = gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **) &mSmmCommunication); | |
| ASSERT_EFI_ERROR (Status); | |
| } | |
| CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0]; | |
| CopyMem (&CommHeader->HeaderGuid, &gEdkiiMemoryProfileGuid, sizeof(gEdkiiMemoryProfileGuid)); | |
| CommHeader->MessageLength = sizeof(SMRAM_PROFILE_PARAMETER_UNREGISTER_IMAGE); | |
| CommUnregisterImage = (SMRAM_PROFILE_PARAMETER_UNREGISTER_IMAGE *)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)]; | |
| CommUnregisterImage->Header.Command = SMRAM_PROFILE_COMMAND_UNREGISTER_IMAGE; | |
| CommUnregisterImage->Header.DataLength = sizeof (*CommUnregisterImage); | |
| CommUnregisterImage->Header.ReturnStatus = (UINT64)-1; | |
| CopyMem (&CommUnregisterImage->FileName, FileName, sizeof(EFI_GUID)); | |
| CommUnregisterImage->ImageBuffer = ImageBuffer; | |
| CommUnregisterImage->NumberOfPage = NumberOfPage; | |
| CommSize = sizeof (EFI_GUID) + sizeof (UINTN) + CommHeader->MessageLength; | |
| Status = mSmmCommunication->Communicate (mSmmCommunication, CommBuffer, &CommSize); | |
| ASSERT_EFI_ERROR (Status); | |
| if (CommUnregisterImage->Header.ReturnStatus != 0) { | |
| return FALSE; | |
| } | |
| return TRUE; | |
| } |