/** @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; | |
} |