X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FCore%2FPiSmmCore%2FDispatcher.c;h=1c88c8fb17c57ea2177dac2a565fc4cb867095e9;hp=b2e3d6a1e7415b93ffc8f2c13f11ce18328671d1;hb=9d510e61fceee7b92955ef9a3c20343752d8ce3f;hpb=022ff6bbba14e86ad721de66d43e0ddb2109ff8a
diff --git a/MdeModulePkg/Core/PiSmmCore/Dispatcher.c b/MdeModulePkg/Core/PiSmmCore/Dispatcher.c
index b2e3d6a1e7..1c88c8fb17 100644
--- a/MdeModulePkg/Core/PiSmmCore/Dispatcher.c
+++ b/MdeModulePkg/Core/PiSmmCore/Dispatcher.c
@@ -27,14 +27,9 @@
Depex - Dependency Expresion.
- Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.
- 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.
+ Copyright (c) 2014, Hewlett-Packard Development Company, L.P.
+ Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -102,7 +97,8 @@ BOOLEAN gRequestDispatch = FALSE;
//
EFI_FV_FILETYPE mSmmFileTypes[] = {
EFI_FV_FILETYPE_SMM,
- EFI_FV_FILETYPE_COMBINED_SMM_DXE
+ EFI_FV_FILETYPE_COMBINED_SMM_DXE,
+ EFI_FV_FILETYPE_SMM_CORE,
//
// Note: DXE core will process the FV image file, so skip it in SMM core
// EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
@@ -124,19 +120,19 @@ EFI_SECURITY2_ARCH_PROTOCOL *mSecurity2 = NULL;
//
// The global variable is defined for Loading modules at fixed address feature to track the SMM code
-// memory range usage. It is a bit mapped array in which every bit indicates the correspoding
-// memory page available or not.
+// memory range usage. It is a bit mapped array in which every bit indicates the corresponding
+// memory page available or not.
//
GLOBAL_REMOVE_IF_UNREFERENCED UINT64 *mSmmCodeMemoryRangeUsageBitMap=NULL;
/**
- To check memory usage bit map array to figure out if the memory range in which the image will be loaded is available or not. If
- memory range is avaliable, the function will mark the correponding bits to 1 which indicates the memory range is used.
- The function is only invoked when load modules at fixed address feature is enabled.
-
- @param ImageBase The base addres the image will be loaded at.
+ To check memory usage bit map array to figure out if the memory range in which the image will be loaded is available or not. If
+ memory range is available, the function will mark the corresponding bits to 1 which indicates the memory range is used.
+ The function is only invoked when load modules at fixed address feature is enabled.
+
+ @param ImageBase The base address the image will be loaded at.
@param ImageSize The size of the image
-
+
@retval EFI_SUCCESS The memory range the image will be loaded in is available
@retval EFI_NOT_FOUND The memory range the image will be loaded in is not available
**/
@@ -147,7 +143,7 @@ CheckAndMarkFixLoadingMemoryUsageBitMap (
)
{
UINT32 SmmCodePageNumber;
- UINT64 SmmCodeSize;
+ UINT64 SmmCodeSize;
EFI_PHYSICAL_ADDRESS SmmCodeBase;
UINTN BaseOffsetPageNumber;
UINTN TopOffsetPageNumber;
@@ -158,11 +154,11 @@ CheckAndMarkFixLoadingMemoryUsageBitMap (
SmmCodePageNumber = PcdGet32(PcdLoadFixAddressSmmCodePageNumber);
SmmCodeSize = EFI_PAGES_TO_SIZE (SmmCodePageNumber);
SmmCodeBase = gLoadModuleAtFixAddressSmramBase;
-
+
//
- // If the memory usage bit map is not initialized, do it. Every bit in the array
+ // If the memory usage bit map is not initialized, do it. Every bit in the array
// indicate the status of the corresponding memory page, available or not
- //
+ //
if (mSmmCodeMemoryRangeUsageBitMap == NULL) {
mSmmCodeMemoryRangeUsageBitMap = AllocateZeroPool(((SmmCodePageNumber / 64) + 1)*sizeof(UINT64));
}
@@ -176,38 +172,38 @@ CheckAndMarkFixLoadingMemoryUsageBitMap (
// see if the memory range for loading the image is in the SMM code range.
//
if (SmmCodeBase + SmmCodeSize < ImageBase + ImageSize || SmmCodeBase > ImageBase) {
- return EFI_NOT_FOUND;
- }
+ return EFI_NOT_FOUND;
+ }
//
// Test if the memory is avalaible or not.
- //
- BaseOffsetPageNumber = (UINTN)EFI_SIZE_TO_PAGES((UINT32)(ImageBase - SmmCodeBase));
- TopOffsetPageNumber = (UINTN)EFI_SIZE_TO_PAGES((UINT32)(ImageBase + ImageSize - SmmCodeBase));
+ //
+ BaseOffsetPageNumber = EFI_SIZE_TO_PAGES((UINT32)(ImageBase - SmmCodeBase));
+ TopOffsetPageNumber = EFI_SIZE_TO_PAGES((UINT32)(ImageBase + ImageSize - SmmCodeBase));
for (Index = BaseOffsetPageNumber; Index < TopOffsetPageNumber; Index ++) {
if ((mSmmCodeMemoryRangeUsageBitMap[Index / 64] & LShiftU64(1, (Index % 64))) != 0) {
//
// This page is already used.
//
- return EFI_NOT_FOUND;
+ return EFI_NOT_FOUND;
}
}
-
+
//
// Being here means the memory range is available. So mark the bits for the memory range
- //
+ //
for (Index = BaseOffsetPageNumber; Index < TopOffsetPageNumber; Index ++) {
mSmmCodeMemoryRangeUsageBitMap[Index / 64] |= LShiftU64(1, (Index % 64));
}
- return EFI_SUCCESS;
+ return EFI_SUCCESS;
}
/**
- Get the fixed loadding address from image header assigned by build tool. This function only be called
+ Get the fixed loading address from image header assigned by build tool. This function only be called
when Loading module at Fixed address feature enabled.
-
+
@param ImageContext Pointer to the image context structure that describes the PE/COFF
image that needs to be examined by this function.
@retval EFI_SUCCESS An fixed loading address is assigned to this image by build tools .
- @retval EFI_NOT_FOUND The image has no assigned fixed loadding address.
+ @retval EFI_NOT_FOUND The image has no assigned fixed loading address.
**/
EFI_STATUS
@@ -215,82 +211,80 @@ GetPeCoffImageFixLoadingAssignedAddress(
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
)
{
- UINTN SectionHeaderOffset;
- EFI_STATUS Status;
- EFI_IMAGE_SECTION_HEADER SectionHeader;
- EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr;
- EFI_PHYSICAL_ADDRESS FixLoaddingAddress;
- UINT16 Index;
- UINTN Size;
- UINT16 NumberOfSections;
- UINT64 ValueInSectionHeader;
-
- FixLoaddingAddress = 0;
- Status = EFI_NOT_FOUND;
-
- //
- // Get PeHeader pointer
- //
- ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((CHAR8* )ImageContext->Handle + ImageContext->PeCoffHeaderOffset);
- SectionHeaderOffset = (UINTN)(
- ImageContext->PeCoffHeaderOffset +
- sizeof (UINT32) +
- sizeof (EFI_IMAGE_FILE_HEADER) +
- ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader
- );
- NumberOfSections = ImgHdr->Pe32.FileHeader.NumberOfSections;
-
- //
- // Get base address from the first section header that doesn't point to code section.
- //
- for (Index = 0; Index < NumberOfSections; Index++) {
- //
- // Read section header from file
- //
- Size = sizeof (EFI_IMAGE_SECTION_HEADER);
- Status = ImageContext->ImageRead (
+ UINTN SectionHeaderOffset;
+ EFI_STATUS Status;
+ EFI_IMAGE_SECTION_HEADER SectionHeader;
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr;
+ EFI_PHYSICAL_ADDRESS FixLoadingAddress;
+ UINT16 Index;
+ UINTN Size;
+ UINT16 NumberOfSections;
+ UINT64 ValueInSectionHeader;
+
+ FixLoadingAddress = 0;
+ Status = EFI_NOT_FOUND;
+
+ //
+ // Get PeHeader pointer
+ //
+ ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((CHAR8* )ImageContext->Handle + ImageContext->PeCoffHeaderOffset);
+ SectionHeaderOffset = ImageContext->PeCoffHeaderOffset +
+ sizeof (UINT32) +
+ sizeof (EFI_IMAGE_FILE_HEADER) +
+ ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader;
+ NumberOfSections = ImgHdr->Pe32.FileHeader.NumberOfSections;
+
+ //
+ // Get base address from the first section header that doesn't point to code section.
+ //
+ for (Index = 0; Index < NumberOfSections; Index++) {
+ //
+ // Read section header from file
+ //
+ Size = sizeof (EFI_IMAGE_SECTION_HEADER);
+ Status = ImageContext->ImageRead (
ImageContext->Handle,
SectionHeaderOffset,
&Size,
&SectionHeader
);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- Status = EFI_NOT_FOUND;
-
- if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) {
- //
- // Build tool will save the address in PointerToRelocations & PointerToLineNumbers fields in the first section header
- // that doesn't point to code section in image header.So there is an assumption that when the feature is enabled,
- // if a module with a loading address assigned by tools, the PointerToRelocations & PointerToLineNumbers fields
- // should not be Zero, or else, these 2 fileds should be set to Zero
- //
- ValueInSectionHeader = ReadUnaligned64((UINT64*)&SectionHeader.PointerToRelocations);
- if (ValueInSectionHeader != 0) {
- //
- // Found first section header that doesn't point to code section in which uild tool saves the
- // offset to SMRAM base as image base in PointerToRelocations & PointerToLineNumbers fields
- //
- FixLoaddingAddress = (EFI_PHYSICAL_ADDRESS)(gLoadModuleAtFixAddressSmramBase + (INT64)ValueInSectionHeader);
- //
- // Check if the memory range is avaliable.
- //
- Status = CheckAndMarkFixLoadingMemoryUsageBitMap (FixLoaddingAddress, (UINTN)(ImageContext->ImageSize + ImageContext->SectionAlignment));
- if (!EFI_ERROR(Status)) {
- //
- // The assigned address is valid. Return the specified loadding address
- //
- ImageContext->ImageAddress = FixLoaddingAddress;
- }
- }
- break;
- }
- SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);
- }
- DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED INFO: Loading module at fixed address %x, Status = %r\n", FixLoaddingAddress, Status));
- return Status;
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = EFI_NOT_FOUND;
+
+ if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) {
+ //
+ // Build tool will save the address in PointerToRelocations & PointerToLineNumbers fields in the first section header
+ // that doesn't point to code section in image header.So there is an assumption that when the feature is enabled,
+ // if a module with a loading address assigned by tools, the PointerToRelocations & PointerToLineNumbers fields
+ // should not be Zero, or else, these 2 fields should be set to Zero
+ //
+ ValueInSectionHeader = ReadUnaligned64((UINT64*)&SectionHeader.PointerToRelocations);
+ if (ValueInSectionHeader != 0) {
+ //
+ // Found first section header that doesn't point to code section in which build tool saves the
+ // offset to SMRAM base as image base in PointerToRelocations & PointerToLineNumbers fields
+ //
+ FixLoadingAddress = (EFI_PHYSICAL_ADDRESS)(gLoadModuleAtFixAddressSmramBase + (INT64)ValueInSectionHeader);
+ //
+ // Check if the memory range is available.
+ //
+ Status = CheckAndMarkFixLoadingMemoryUsageBitMap (FixLoadingAddress, (UINTN)(ImageContext->ImageSize + ImageContext->SectionAlignment));
+ if (!EFI_ERROR(Status)) {
+ //
+ // The assigned address is valid. Return the specified loading address
+ //
+ ImageContext->ImageAddress = FixLoadingAddress;
+ }
+ }
+ break;
+ }
+ SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);
+ }
+ DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED INFO: Loading module at fixed address %x, Status = %r\n", FixLoadingAddress, Status));
+ return Status;
}
/**
Loads an EFI image into SMRAM.
@@ -321,13 +315,9 @@ SmmLoadImage (
EFI_DEVICE_PATH_PROTOCOL *HandleFilePath;
EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
- UINT64 Tick;
- Tick = 0;
- PERF_CODE (
- Tick = GetPerformanceCounter ();
- );
-
+ PERF_LOAD_IMAGE_BEGIN (DriverEntry->ImageHandle);
+
Buffer = NULL;
Size = 0;
Fv = DriverEntry->Fv;
@@ -402,7 +392,7 @@ SmmLoadImage (
&AuthenticationStatus
);
}
-
+
if (EFI_ERROR (Status)) {
if (Buffer != NULL) {
gBS->FreePool (Buffer);
@@ -426,7 +416,7 @@ SmmLoadImage (
//
// Verify the Authentication Status through the Security Architectural Protocol
// Only on images that have been read using Firmware Volume protocol.
- // All SMM images are from FV protocol.
+ // All SMM images are from FV protocol.
//
if (!EFI_ERROR (SecurityStatus) && (mSecurity != NULL)) {
SecurityStatus = mSecurity->FileAuthenticationState (
@@ -440,7 +430,7 @@ SmmLoadImage (
Status = SecurityStatus;
return Status;
}
-
+
//
// Initialize ImageContext
//
@@ -472,7 +462,7 @@ SmmLoadImage (
// following statements is to bypass SmmFreePages
//
PageCount = 0;
- DstBuffer = (UINTN)gLoadModuleAtFixAddressSmramBase;
+ DstBuffer = (UINTN)gLoadModuleAtFixAddressSmramBase;
} else {
DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED ERROR: Failed to load module at fixed address. \n"));
//
@@ -480,7 +470,7 @@ SmmLoadImage (
//
PageCount = (UINTN)EFI_SIZE_TO_PAGES((UINTN)ImageContext.ImageSize + ImageContext.SectionAlignment);
DstBuffer = (UINTN)(-1);
-
+
Status = SmmAllocatePages (
AllocateMaxAddress,
EfiRuntimeServicesCode,
@@ -490,15 +480,15 @@ SmmLoadImage (
if (EFI_ERROR (Status)) {
if (Buffer != NULL) {
gBS->FreePool (Buffer);
- }
+ }
return Status;
- }
+ }
ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)DstBuffer;
}
} else {
PageCount = (UINTN)EFI_SIZE_TO_PAGES((UINTN)ImageContext.ImageSize + ImageContext.SectionAlignment);
DstBuffer = (UINTN)(-1);
-
+
Status = SmmAllocatePages (
AllocateMaxAddress,
EfiRuntimeServicesCode,
@@ -511,14 +501,14 @@ SmmLoadImage (
}
return Status;
}
-
+
ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)DstBuffer;
}
//
- // Align buffer on section boundry
+ // Align buffer on section boundary
//
ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;
- ImageContext.ImageAddress &= ~(ImageContext.SectionAlignment - 1);
+ ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS)ImageContext.SectionAlignment - 1);
//
// Load the image to our new buffer
@@ -553,7 +543,7 @@ SmmLoadImage (
// Save Image EntryPoint in DriverEntry
//
DriverEntry->ImageEntryPoint = ImageContext.EntryPoint;
- DriverEntry->ImageBuffer = DstBuffer;
+ DriverEntry->ImageBuffer = DstBuffer;
DriverEntry->NumberOfPage = PageCount;
//
@@ -568,6 +558,7 @@ SmmLoadImage (
return Status;
}
+ ZeroMem (DriverEntry->LoadedImage, sizeof (EFI_LOADED_IMAGE_PROTOCOL));
//
// Fill in the remaining fields of the Loaded Image Protocol instance.
// Note: ImageBase is an SMRAM address that can not be accessed outside of SMRAM if SMRAM window is closed.
@@ -577,6 +568,11 @@ SmmLoadImage (
DriverEntry->LoadedImage->SystemTable = gST;
DriverEntry->LoadedImage->DeviceHandle = DeviceHandle;
+ DriverEntry->SmmLoadedImage.Revision = EFI_LOADED_IMAGE_PROTOCOL_REVISION;
+ DriverEntry->SmmLoadedImage.ParentHandle = gSmmCorePrivate->SmmIplImageHandle;
+ DriverEntry->SmmLoadedImage.SystemTable = gST;
+ DriverEntry->SmmLoadedImage.DeviceHandle = DeviceHandle;
+
//
// Make an EfiBootServicesData buffer copy of FilePath
//
@@ -590,11 +586,30 @@ SmmLoadImage (
}
CopyMem (DriverEntry->LoadedImage->FilePath, FilePath, GetDevicePathSize (FilePath));
- DriverEntry->LoadedImage->ImageBase = (VOID *)(UINTN)DriverEntry->ImageBuffer;
+ DriverEntry->LoadedImage->ImageBase = (VOID *)(UINTN) ImageContext.ImageAddress;
DriverEntry->LoadedImage->ImageSize = ImageContext.ImageSize;
DriverEntry->LoadedImage->ImageCodeType = EfiRuntimeServicesCode;
DriverEntry->LoadedImage->ImageDataType = EfiRuntimeServicesData;
+ //
+ // Make a buffer copy of FilePath
+ //
+ Status = SmmAllocatePool (EfiRuntimeServicesData, GetDevicePathSize(FilePath), (VOID **)&DriverEntry->SmmLoadedImage.FilePath);
+ if (EFI_ERROR (Status)) {
+ if (Buffer != NULL) {
+ gBS->FreePool (Buffer);
+ }
+ gBS->FreePool (DriverEntry->LoadedImage->FilePath);
+ SmmFreePages (DstBuffer, PageCount);
+ return Status;
+ }
+ CopyMem (DriverEntry->SmmLoadedImage.FilePath, FilePath, GetDevicePathSize(FilePath));
+
+ DriverEntry->SmmLoadedImage.ImageBase = (VOID *)(UINTN) ImageContext.ImageAddress;
+ DriverEntry->SmmLoadedImage.ImageSize = ImageContext.ImageSize;
+ DriverEntry->SmmLoadedImage.ImageCodeType = EfiRuntimeServicesCode;
+ DriverEntry->SmmLoadedImage.ImageDataType = EfiRuntimeServicesData;
+
//
// Create a new image handle in the UEFI handle database for the SMM Driver
//
@@ -605,8 +620,18 @@ SmmLoadImage (
NULL
);
- PERF_START (DriverEntry->ImageHandle, "LoadImage:", NULL, Tick);
- PERF_END (DriverEntry->ImageHandle, "LoadImage:", NULL, 0);
+ //
+ // Create a new image handle in the SMM handle database for the SMM Driver
+ //
+ DriverEntry->SmmImageHandle = NULL;
+ Status = SmmInstallProtocolInterface (
+ &DriverEntry->SmmImageHandle,
+ &gEfiLoadedImageProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &DriverEntry->SmmLoadedImage
+ );
+
+ PERF_LOAD_IMAGE_END (DriverEntry->ImageHandle);
//
// Print the load address and the PDB file name if it is available
@@ -667,20 +692,20 @@ SmmLoadImage (
//
// Free buffer allocated by Fv->ReadSection.
//
- // The UEFI Boot Services FreePool() function must be used because Fv->ReadSection
+ // The UEFI Boot Services FreePool() function must be used because Fv->ReadSection
// used the UEFI Boot Services AllocatePool() function
//
Status = gBS->FreePool(Buffer);
if (!EFI_ERROR (Status) && EFI_ERROR (SecurityStatus)) {
Status = SecurityStatus;
}
- return Status;
+ return Status;
}
/**
Preprocess dependency expression and update DriverEntry to reflect the
state of Before and After dependencies. If DriverEntry->Before
- or DriverEntry->After is set it will never be cleared.
+ or DriverEntry->After is set it will never be cleared.
@param DriverEntry DriverEntry element to update .
@@ -779,7 +804,7 @@ SmmGetDepexSectionAndPreProccess (
drivers to run. Drain the mScheduledQueue and load and start a PE
image for each driver. Search the mDiscoveredList to see if any driver can
be placed on the mScheduledQueue. If no drivers are placed on the
- mScheduledQueue exit the function.
+ mScheduledQueue exit the function.
@retval EFI_SUCCESS All of the SMM Drivers that could be dispatched
have been run and the SMM Entry Point has been
@@ -872,11 +897,37 @@ SmmDispatcher (
//
// For each SMM driver, pass NULL as ImageHandle
//
- PERF_START (DriverEntry->ImageHandle, "StartImage:", NULL, 0);
+ RegisterSmramProfileImage (DriverEntry, TRUE);
+ PERF_START_IMAGE_BEGIN (DriverEntry->ImageHandle);
Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)DriverEntry->ImageEntryPoint)(DriverEntry->ImageHandle, gST);
- PERF_END (DriverEntry->ImageHandle, "StartImage:", NULL, 0);
+ PERF_START_IMAGE_END (DriverEntry->ImageHandle);
if (EFI_ERROR(Status)){
+ UnregisterSmramProfileImage (DriverEntry, TRUE);
SmmFreePages(DriverEntry->ImageBuffer, DriverEntry->NumberOfPage);
+ //
+ // Uninstall LoadedImage
+ //
+ Status = gBS->UninstallProtocolInterface (
+ DriverEntry->ImageHandle,
+ &gEfiLoadedImageProtocolGuid,
+ DriverEntry->LoadedImage
+ );
+ if (!EFI_ERROR (Status)) {
+ if (DriverEntry->LoadedImage->FilePath != NULL) {
+ gBS->FreePool (DriverEntry->LoadedImage->FilePath);
+ }
+ gBS->FreePool (DriverEntry->LoadedImage);
+ }
+ Status = SmmUninstallProtocolInterface (
+ DriverEntry->SmmImageHandle,
+ &gEfiLoadedImageProtocolGuid,
+ &DriverEntry->SmmLoadedImage
+ );
+ if (!EFI_ERROR(Status)) {
+ if (DriverEntry->SmmLoadedImage.FilePath != NULL) {
+ SmmFreePool (DriverEntry->SmmLoadedImage.FilePath);
+ }
+ }
}
REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
@@ -888,11 +939,11 @@ SmmDispatcher (
if (!PreviousSmmEntryPointRegistered && gSmmCorePrivate->SmmEntryPointRegistered) {
//
- // Return immediately if the SMM Entry Point was registered by the SMM
+ // Return immediately if the SMM Entry Point was registered by the SMM
// Driver that was just dispatched. The SMM IPL will reinvoke the SMM
- // Core Dispatcher. This is required so SMM Mode may be enabled as soon
- // as all the dependent SMM Drivers for SMM Mode have been dispatched.
- // Once the SMM Entry Point has been registered, then SMM Mode will be
+ // Core Dispatcher. This is required so SMM Mode may be enabled as soon
+ // as all the dependent SMM Drivers for SMM Mode have been dispatched.
+ // Once the SMM Entry Point has been registered, then SMM Mode will be
// used.
//
gRequestDispatch = TRUE;
@@ -1211,7 +1262,9 @@ SmmDriverDispatchHandler (
EFI_SMM_DRIVER_ENTRY *DriverEntry;
EFI_GUID *AprioriFile;
UINTN AprioriEntryCount;
- UINTN Index;
+ UINTN HandleIndex;
+ UINTN SmmTypeIndex;
+ UINTN AprioriIndex;
LIST_ENTRY *Link;
UINT32 AuthenticationStatus;
UINTN SizeOfBuffer;
@@ -1228,8 +1281,8 @@ SmmDriverDispatchHandler (
return EFI_NOT_FOUND;
}
- for (Index = 0; Index < HandleCount; Index++) {
- FvHandle = HandleBuffer[Index];
+ for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
+ FvHandle = HandleBuffer[HandleIndex];
if (FvHasBeenProcessed (FvHandle)) {
//
@@ -1263,14 +1316,15 @@ SmmDriverDispatchHandler (
//
// Discover Drivers in FV and add them to the Discovered Driver List.
// Process EFI_FV_FILETYPE_SMM type and then EFI_FV_FILETYPE_COMBINED_SMM_DXE
+ // EFI_FV_FILETYPE_SMM_CORE is processed to produce a Loaded Image protocol for the core
//
- for (Index = 0; Index < sizeof (mSmmFileTypes)/sizeof (EFI_FV_FILETYPE); Index++) {
+ for (SmmTypeIndex = 0; SmmTypeIndex < sizeof (mSmmFileTypes)/sizeof (EFI_FV_FILETYPE); SmmTypeIndex++) {
//
// Initialize the search key
//
Key = 0;
do {
- Type = mSmmFileTypes[Index];
+ Type = mSmmFileTypes[SmmTypeIndex];
GetNextFileStatus = Fv->GetNextFile (
Fv,
&Key,
@@ -1280,7 +1334,55 @@ SmmDriverDispatchHandler (
&Size
);
if (!EFI_ERROR (GetNextFileStatus)) {
- SmmAddToDriverList (Fv, FvHandle, &NameGuid);
+ if (Type == EFI_FV_FILETYPE_SMM_CORE) {
+ //
+ // If this is the SMM core fill in it's DevicePath & DeviceHandle
+ //
+ if (mSmmCoreLoadedImage->FilePath == NULL) {
+ //
+ // Maybe one special FV contains only one SMM_CORE module, so its device path must
+ // be initialized completely.
+ //
+ EfiInitializeFwVolDevicepathNode (&mFvDevicePath.File, &NameGuid);
+ SetDevicePathEndNode (&mFvDevicePath.End);
+
+ //
+ // Make an EfiBootServicesData buffer copy of FilePath
+ //
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath),
+ (VOID **)&mSmmCoreLoadedImage->FilePath
+ );
+ ASSERT_EFI_ERROR (Status);
+ CopyMem (mSmmCoreLoadedImage->FilePath, &mFvDevicePath, GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath));
+
+ mSmmCoreLoadedImage->DeviceHandle = FvHandle;
+ }
+ if (mSmmCoreDriverEntry->SmmLoadedImage.FilePath == NULL) {
+ //
+ // Maybe one special FV contains only one SMM_CORE module, so its device path must
+ // be initialized completely.
+ //
+ EfiInitializeFwVolDevicepathNode (&mFvDevicePath.File, &NameGuid);
+ SetDevicePathEndNode (&mFvDevicePath.End);
+
+ //
+ // Make a buffer copy FilePath
+ //
+ Status = SmmAllocatePool (
+ EfiRuntimeServicesData,
+ GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath),
+ (VOID **)&mSmmCoreDriverEntry->SmmLoadedImage.FilePath
+ );
+ ASSERT_EFI_ERROR (Status);
+ CopyMem (mSmmCoreDriverEntry->SmmLoadedImage.FilePath, &mFvDevicePath, GetDevicePathSize((EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath));
+
+ mSmmCoreDriverEntry->SmmLoadedImage.DeviceHandle = FvHandle;
+ }
+ } else {
+ SmmAddToDriverList (Fv, FvHandle, &NameGuid);
+ }
}
} while (!EFI_ERROR (GetNextFileStatus));
}
@@ -1311,10 +1413,10 @@ SmmDriverDispatchHandler (
// is only valid for the FV that it resided in.
//
- for (Index = 0; Index < AprioriEntryCount; Index++) {
+ for (AprioriIndex = 0; AprioriIndex < AprioriEntryCount; AprioriIndex++) {
for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
DriverEntry = CR(Link, EFI_SMM_DRIVER_ENTRY, Link, EFI_SMM_DRIVER_ENTRY_SIGNATURE);
- if (CompareGuid (&DriverEntry->FileName, &AprioriFile[Index]) &&
+ if (CompareGuid (&DriverEntry->FileName, &AprioriFile[AprioriIndex]) &&
(FvHandle == DriverEntry->FvHandle)) {
DriverEntry->Dependent = FALSE;
DriverEntry->Scheduled = TRUE;
@@ -1329,14 +1431,14 @@ SmmDriverDispatchHandler (
//
// Free data allocated by Fv->ReadSection ()
//
- // The UEFI Boot Services FreePool() function must be used because Fv->ReadSection
+ // The UEFI Boot Services FreePool() function must be used because Fv->ReadSection
// used the UEFI Boot Services AllocatePool() function
//
gBS->FreePool (AprioriFile);
}
//
- // Execute the SMM Dispatcher on any newly discovered FVs and previously
+ // Execute the SMM Dispatcher on any newly discovered FVs and previously
// discovered SMM drivers that have been discovered but not dispatched.
//
Status = SmmDispatcher ();
@@ -1348,7 +1450,7 @@ SmmDriverDispatchHandler (
if (*CommBufferSize > 0) {
if (Status == EFI_NOT_READY) {
//
- // If a the SMM Core Entry Point was just registered, then set flag to
+ // If a the SMM Core Entry Point was just registered, then set flag to
// request the SMM Dispatcher to be restarted.
//
*(UINT8 *)CommBuffer = COMM_BUFFER_SMM_DISPATCH_RESTART;