mirror of https://github.com/acidanthera/audk.git
173 lines
6.4 KiB
C
173 lines
6.4 KiB
C
/** @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;
|
|
}
|