mirror of https://github.com/acidanthera/audk.git
Remove the implementation limitation in the SmmBaseHelper driver that it assumes the Framework SMM driver to be loaded has a copy in memory.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10258 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
49fd8a3553
commit
673c149801
|
@ -77,6 +77,7 @@ typedef struct {
|
||||||
SMMBASE_FUNCTION Function;
|
SMMBASE_FUNCTION Function;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
SMMBASE_FUNCTION_ARGS Args;
|
SMMBASE_FUNCTION_ARGS Args;
|
||||||
|
EFI_HANDLE SmmBaseImageHandle;
|
||||||
} SMMBASE_FUNCTION_DATA;
|
} SMMBASE_FUNCTION_DATA;
|
||||||
|
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include <Protocol/LoadedImage.h>
|
#include <Protocol/LoadedImage.h>
|
||||||
#include <Protocol/SmmCpuSaveState.h>
|
#include <Protocol/SmmCpuSaveState.h>
|
||||||
#include <Protocol/MpService.h>
|
#include <Protocol/MpService.h>
|
||||||
|
#include <Protocol/LoadPe32Image.h>
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Structure for tracking paired information of registered Framework SMI handler
|
/// Structure for tracking paired information of registered Framework SMI handler
|
||||||
|
@ -59,6 +60,7 @@ typedef struct {
|
||||||
|
|
||||||
EFI_HANDLE mDispatchHandle;
|
EFI_HANDLE mDispatchHandle;
|
||||||
EFI_SMM_CPU_PROTOCOL *mSmmCpu;
|
EFI_SMM_CPU_PROTOCOL *mSmmCpu;
|
||||||
|
EFI_PE32_IMAGE_PROTOCOL *mLoadPe32Image;
|
||||||
EFI_GUID mEfiSmmCpuIoGuid = EFI_SMM_CPU_IO_GUID;
|
EFI_GUID mEfiSmmCpuIoGuid = EFI_SMM_CPU_IO_GUID;
|
||||||
EFI_SMM_BASE_HELPER_READY_PROTOCOL *mSmmBaseHelperReady;
|
EFI_SMM_BASE_HELPER_READY_PROTOCOL *mSmmBaseHelperReady;
|
||||||
EFI_SMM_SYSTEM_TABLE *mFrameworkSmst;
|
EFI_SMM_SYSTEM_TABLE *mFrameworkSmst;
|
||||||
|
@ -174,6 +176,7 @@ ConstructFrameworkSmst (
|
||||||
/**
|
/**
|
||||||
Load a given Framework SMM driver into SMRAM and invoke its entry point.
|
Load a given Framework SMM driver into SMRAM and invoke its entry point.
|
||||||
|
|
||||||
|
@param[in] ParentImageHandle Parent Image Handle.
|
||||||
@param[in] FilePath Location of the image to be installed as the handler.
|
@param[in] FilePath Location of the image to be installed as the handler.
|
||||||
@param[in] SourceBuffer Optional source buffer in case the image file
|
@param[in] SourceBuffer Optional source buffer in case the image file
|
||||||
is in memory.
|
is in memory.
|
||||||
|
@ -189,6 +192,7 @@ ConstructFrameworkSmst (
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
LoadImage (
|
LoadImage (
|
||||||
|
IN EFI_HANDLE ParentImageHandle,
|
||||||
IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
|
IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
|
||||||
IN VOID *SourceBuffer,
|
IN VOID *SourceBuffer,
|
||||||
IN UINTN SourceSize,
|
IN UINTN SourceSize,
|
||||||
|
@ -197,141 +201,63 @@ LoadImage (
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
UINTN PageCount;
|
UINTN PageCount;
|
||||||
EFI_PHYSICAL_ADDRESS Buffer;
|
UINTN OrgPageCount;
|
||||||
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
|
EFI_PHYSICAL_ADDRESS DstBuffer;
|
||||||
EFI_HANDLE PesudoImageHandle;
|
|
||||||
UINTN NumHandles;
|
|
||||||
UINTN Index;
|
|
||||||
EFI_HANDLE *HandleBuffer;
|
|
||||||
EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
|
|
||||||
EFI_DEVICE_PATH *LoadedImageDevicePath;
|
|
||||||
UINTN DevicePathSize;
|
|
||||||
|
|
||||||
if (FilePath == NULL || ImageHandle == NULL) {
|
if (FilePath == NULL || ImageHandle == NULL) {
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
PageCount = 1;
|
||||||
/// Assume Framework SMM driver has an image copy in memory before registering itself into SMRAM.
|
do {
|
||||||
/// Currently only supports load Framework SMM driver from existing image copy in memory.
|
OrgPageCount = PageCount;
|
||||||
/// Load PE32 Image Protocol can be used to support loading Framework SMM driver directly from FV.
|
DstBuffer = (UINTN)-1;
|
||||||
///
|
Status = gSmst->SmmAllocatePages (
|
||||||
if (SourceBuffer == NULL) {
|
AllocateMaxAddress,
|
||||||
Status = gBS->LocateHandleBuffer (
|
EfiRuntimeServicesCode,
|
||||||
ByProtocol,
|
PageCount,
|
||||||
&gEfiLoadedImageDevicePathProtocolGuid,
|
&DstBuffer
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = mLoadPe32Image->LoadPeImage (
|
||||||
|
mLoadPe32Image,
|
||||||
|
ParentImageHandle,
|
||||||
|
FilePath,
|
||||||
|
SourceBuffer,
|
||||||
|
SourceSize,
|
||||||
|
DstBuffer,
|
||||||
|
&PageCount,
|
||||||
|
ImageHandle,
|
||||||
NULL,
|
NULL,
|
||||||
&NumHandles,
|
EFI_LOAD_PE_IMAGE_ATTRIBUTE_NONE
|
||||||
&HandleBuffer
|
|
||||||
);
|
);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return EFI_UNSUPPORTED;
|
FreePages ((VOID *)(UINTN)DstBuffer, OrgPageCount);
|
||||||
}
|
}
|
||||||
|
} while (Status == EFI_BUFFER_TOO_SMALL);
|
||||||
|
|
||||||
DevicePathSize = GetDevicePathSize (FilePath);
|
if (!EFI_ERROR (Status)) {
|
||||||
|
|
||||||
for (Index = 0; Index < NumHandles; Index++) {
|
|
||||||
Status = gBS->HandleProtocol (
|
|
||||||
HandleBuffer[Index],
|
|
||||||
&gEfiLoadedImageDevicePathProtocolGuid,
|
|
||||||
(VOID **)&LoadedImageDevicePath
|
|
||||||
);
|
|
||||||
ASSERT_EFI_ERROR (Status);
|
|
||||||
|
|
||||||
if (GetDevicePathSize (LoadedImageDevicePath) == DevicePathSize &&
|
|
||||||
CompareMem (LoadedImageDevicePath, FilePath, DevicePathSize) == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Index < NumHandles) {
|
|
||||||
Status = gBS->HandleProtocol (
|
|
||||||
HandleBuffer[Index],
|
|
||||||
&gEfiLoadedImageProtocolGuid,
|
|
||||||
(VOID **)&LoadedImage
|
|
||||||
);
|
|
||||||
ASSERT_EFI_ERROR (Status);
|
|
||||||
|
|
||||||
SourceBuffer = LoadedImage->ImageBase;
|
|
||||||
gBS->FreePool (HandleBuffer);
|
|
||||||
} else {
|
|
||||||
gBS->FreePool (HandleBuffer);
|
|
||||||
return EFI_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImageContext.Handle = SourceBuffer;
|
|
||||||
ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Get information about the image being loaded
|
|
||||||
///
|
|
||||||
Status = PeCoffLoaderGetImageInfo (&ImageContext);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Allocate buffer for loading image into SMRAM
|
|
||||||
///
|
|
||||||
PageCount = (UINTN)EFI_SIZE_TO_PAGES (ImageContext.ImageSize + ImageContext.SectionAlignment);
|
|
||||||
Status = gSmst->SmmAllocatePages (AllocateAnyPages, EfiRuntimeServicesCode, PageCount, &Buffer);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImageContext.ImageAddress = (PHYSICAL_ADDRESS)Buffer;
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Align buffer on section boundry
|
|
||||||
///
|
|
||||||
ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;
|
|
||||||
ImageContext.ImageAddress &= ~(ImageContext.SectionAlignment - 1);
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Load the image into SMRAM
|
|
||||||
///
|
|
||||||
Status = PeCoffLoaderLoadImage (&ImageContext);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
goto Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Relocate the image in our new buffer
|
|
||||||
///
|
|
||||||
Status = PeCoffLoaderRelocateImage (&ImageContext);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
goto Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Flush the instruction cache so the image data are written before we execute it
|
|
||||||
///
|
|
||||||
InvalidateInstructionCacheRange ((VOID *)(UINTN) ImageContext.ImageAddress, (UINTN) ImageContext.ImageSize);
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Update MP state in Framework SMST before transferring control to Framework SMM driver entry point
|
/// Update MP state in Framework SMST before transferring control to Framework SMM driver entry point
|
||||||
/// in case it may invoke AP
|
/// in case it may invoke AP
|
||||||
///
|
///
|
||||||
mFrameworkSmst->CurrentlyExecutingCpu = gSmst->CurrentlyExecutingCpu;
|
mFrameworkSmst->CurrentlyExecutingCpu = gSmst->CurrentlyExecutingCpu;
|
||||||
|
|
||||||
///
|
Status = gBS->StartImage (*ImageHandle, NULL, NULL);
|
||||||
/// For Framework SMM, ImageHandle does not have to be a UEFI image handle. The only requirement is that the
|
if (EFI_ERROR (Status)) {
|
||||||
/// ImageHandle is a unique value. Use image base address as the unique value.
|
mLoadPe32Image->UnLoadPeImage (mLoadPe32Image, *ImageHandle);
|
||||||
///
|
*ImageHandle = NULL;
|
||||||
PesudoImageHandle = (EFI_HANDLE)(UINTN)ImageContext.ImageAddress;
|
FreePages ((VOID *)(UINTN)DstBuffer, PageCount);
|
||||||
|
}
|
||||||
Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)ImageContext.EntryPoint) (PesudoImageHandle, gST);
|
|
||||||
if (!EFI_ERROR (Status)) {
|
|
||||||
*ImageHandle = PesudoImageHandle;
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Error:
|
return Status;
|
||||||
FreePages ((VOID *)(UINTN)Buffer, PageCount);
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Thunk service of EFI_SMM_BASE_PROTOCOL.Register().
|
Thunk service of EFI_SMM_BASE_PROTOCOL.Register().
|
||||||
|
|
||||||
|
@ -348,6 +274,7 @@ Register (
|
||||||
Status = EFI_UNSUPPORTED;
|
Status = EFI_UNSUPPORTED;
|
||||||
} else {
|
} else {
|
||||||
Status = LoadImage (
|
Status = LoadImage (
|
||||||
|
FunctionData->SmmBaseImageHandle,
|
||||||
FunctionData->Args.Register.FilePath,
|
FunctionData->Args.Register.FilePath,
|
||||||
FunctionData->Args.Register.SourceBuffer,
|
FunctionData->Args.Register.SourceBuffer,
|
||||||
FunctionData->Args.Register.SourceSize,
|
FunctionData->Args.Register.SourceSize,
|
||||||
|
@ -735,6 +662,12 @@ SmmBaseHelperMain (
|
||||||
Status = gSmst->SmmLocateProtocol (&gEfiSmmCpuProtocolGuid, NULL, (VOID **) &mSmmCpu);
|
Status = gSmst->SmmLocateProtocol (&gEfiSmmCpuProtocolGuid, NULL, (VOID **) &mSmmCpu);
|
||||||
ASSERT_EFI_ERROR (Status);
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Locate PE32 Image Protocol which is used later to load Framework SMM driver
|
||||||
|
///
|
||||||
|
Status = SystemTable->BootServices->LocateProtocol (&gEfiLoadPeImageProtocolGuid, NULL, (VOID **) &mLoadPe32Image);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Get MP Services Protocol
|
// Get MP Services Protocol
|
||||||
//
|
//
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
|
|
||||||
[Packages]
|
[Packages]
|
||||||
MdePkg/MdePkg.dec
|
MdePkg/MdePkg.dec
|
||||||
|
MdeModulePkg/MdeModulePkg.dec
|
||||||
IntelFrameworkPkg/IntelFrameworkPkg.dec
|
IntelFrameworkPkg/IntelFrameworkPkg.dec
|
||||||
EdkCompatibilityPkg/EdkCompatibilityPkg.dec
|
EdkCompatibilityPkg/EdkCompatibilityPkg.dec
|
||||||
|
|
||||||
|
@ -57,6 +58,10 @@
|
||||||
gEfiSmmCpuSaveStateProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
gEfiSmmCpuSaveStateProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||||
gEfiMpServiceProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
gEfiMpServiceProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||||
gEfiSmmCpuIo2ProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
gEfiSmmCpuIo2ProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||||
|
gEfiLoadPeImageProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||||
|
|
||||||
[Depex]
|
[Depex]
|
||||||
gEfiSmmCpuProtocolGuid AND gEfiMpServiceProtocolGuid AND gEfiSmmCpuIo2ProtocolGuid
|
gEfiSmmCpuProtocolGuid AND
|
||||||
|
gEfiMpServiceProtocolGuid AND
|
||||||
|
gEfiSmmCpuIo2ProtocolGuid AND
|
||||||
|
gEfiLoadPeImageProtocolGuid
|
|
@ -75,6 +75,7 @@ SmmBaseHelperService (
|
||||||
UINTN DataSize;
|
UINTN DataSize;
|
||||||
|
|
||||||
mCommunicationData.FunctionData.Status = EFI_UNSUPPORTED;
|
mCommunicationData.FunctionData.Status = EFI_UNSUPPORTED;
|
||||||
|
mCommunicationData.FunctionData.SmmBaseImageHandle = mSmmBaseHandle;
|
||||||
|
|
||||||
if ((mCommunicationData.FunctionData.Function != SmmBaseFunctionCommunicate) && IsInSmm()) {
|
if ((mCommunicationData.FunctionData.Function != SmmBaseFunctionCommunicate) && IsInSmm()) {
|
||||||
///
|
///
|
||||||
|
@ -421,6 +422,8 @@ SmmBaseThunkMain (
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
EFI_EVENT Event;
|
EFI_EVENT Event;
|
||||||
|
|
||||||
|
mSmmBaseHandle = ImageHandle;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Assume only one instance of SMM Base2 Protocol in the system
|
// Assume only one instance of SMM Base2 Protocol in the system
|
||||||
// Locate SMM Base2 Protocol
|
// Locate SMM Base2 Protocol
|
||||||
|
|
Loading…
Reference in New Issue