diff --git a/MdeModulePkg/Core/PiSmmCore/Dispatcher.c b/MdeModulePkg/Core/PiSmmCore/Dispatcher.c index cbaf549066..1f85ae8def 100644 --- a/MdeModulePkg/Core/PiSmmCore/Dispatcher.c +++ b/MdeModulePkg/Core/PiSmmCore/Dispatcher.c @@ -103,7 +103,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 @@ -1283,6 +1284,7 @@ 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 (SmmTypeIndex = 0; SmmTypeIndex < sizeof (mSmmFileTypes)/sizeof (EFI_FV_FILETYPE); SmmTypeIndex++) { // @@ -1300,7 +1302,34 @@ 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; + } + } else { + SmmAddToDriverList (Fv, FvHandle, &NameGuid); + } } } while (!EFI_ERROR (GetNextFileStatus)); } diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c index cc7ccec248..7245f201fb 100644 --- a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c +++ b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c @@ -87,6 +87,8 @@ SMM_CORE_SMI_HANDLERS mSmmCoreSmiHandlers[] = { UINTN mFullSmramRangeCount; EFI_SMRAM_DESCRIPTOR *mFullSmramRanges; +EFI_LOADED_IMAGE_PROTOCOL *mSmmCoreLoadedImage; + /** Place holder function until all the SMM System Table Service are available. @@ -520,6 +522,51 @@ SmmEntryPoint ( PERF_END (NULL, "SMM", NULL, 0) ; } +/** + Install LoadedImage protocol for SMM Core. +**/ +VOID +SmmCoreInstallLoadedImage ( + VOID + ) +{ + EFI_STATUS Status; + EFI_HANDLE Handle; + + // + // Allocate a Loaded Image Protocol in EfiBootServicesData + // + Status = gBS->AllocatePool (EfiBootServicesData, sizeof(EFI_LOADED_IMAGE_PROTOCOL), (VOID **)&mSmmCoreLoadedImage); + ASSERT_EFI_ERROR (Status); + + ZeroMem (mSmmCoreLoadedImage, 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. + // + mSmmCoreLoadedImage->Revision = EFI_LOADED_IMAGE_PROTOCOL_REVISION; + mSmmCoreLoadedImage->ParentHandle = gSmmCorePrivate->SmmIplImageHandle; + mSmmCoreLoadedImage->SystemTable = gST; + + mSmmCoreLoadedImage->ImageBase = (VOID *)(UINTN)gSmmCorePrivate->PiSmmCoreImageBase; + mSmmCoreLoadedImage->ImageSize = gSmmCorePrivate->PiSmmCoreImageSize; + mSmmCoreLoadedImage->ImageCodeType = EfiRuntimeServicesCode; + mSmmCoreLoadedImage->ImageDataType = EfiRuntimeServicesData; + + // + // Create a new image handle in the UEFI handle database for the SMM Driver + // + Handle = NULL; + Status = gBS->InstallMultipleProtocolInterfaces ( + &Handle, + &gEfiLoadedImageProtocolGuid, mSmmCoreLoadedImage, + NULL + ); + ASSERT_EFI_ERROR (Status); + + return ; +} + /** The Entry Point for SMM Core @@ -586,5 +633,7 @@ SmmMain ( RegisterSmramProfileHandler (); + SmmCoreInstallLoadedImage (); + return EFI_SUCCESS; } diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h index e34bd8a640..0e9c92abef 100644 --- a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h +++ b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h @@ -959,6 +959,8 @@ SmramProfileReadyToLock ( extern UINTN mFullSmramRangeCount; extern EFI_SMRAM_DESCRIPTOR *mFullSmramRanges; +extern EFI_LOADED_IMAGE_PROTOCOL *mSmmCoreLoadedImage; + // // Page management //