]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/PiSmmCore/Dispatcher.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Core / PiSmmCore / Dispatcher.c
index cbaf549066e33d51f9bcf59f4f1cebb04a7b4673..1c88c8fb17c57ea2177dac2a565fc4cb867095e9 100644 (file)
   Depex - Dependency Expresion.\r
 \r
   Copyright (c) 2014, Hewlett-Packard Development Company, L.P.\r
-  Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>\r
-  This program and the accompanying materials are licensed and made available \r
-  under the terms and conditions of the BSD License which accompanies this \r
-  distribution.  The full text of the license may be found at        \r
-  http://opensource.org/licenses/bsd-license.php                                            \r
-\r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -103,7 +97,8 @@ BOOLEAN  gRequestDispatch = FALSE;
 //\r
 EFI_FV_FILETYPE mSmmFileTypes[] = {\r
   EFI_FV_FILETYPE_SMM,\r
-  EFI_FV_FILETYPE_COMBINED_SMM_DXE\r
+  EFI_FV_FILETYPE_COMBINED_SMM_DXE,\r
+  EFI_FV_FILETYPE_SMM_CORE,\r
   //\r
   // Note: DXE core will process the FV image file, so skip it in SMM core\r
   // EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE\r
@@ -125,19 +120,19 @@ EFI_SECURITY2_ARCH_PROTOCOL *mSecurity2 = NULL;
 \r
 //\r
 // The global variable is defined for Loading modules at fixed address feature to track the SMM code\r
-// memory range usage. It is a bit mapped array in which every bit indicates the correspoding \r
-// memory page available or not. \r
+// memory range usage. It is a bit mapped array in which every bit indicates the corresponding\r
+// memory page available or not.\r
 //\r
 GLOBAL_REMOVE_IF_UNREFERENCED    UINT64                *mSmmCodeMemoryRangeUsageBitMap=NULL;\r
 \r
 /**\r
-  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 \r
-  memory range is avaliable, the function will mark the correponding bits to 1 which indicates the memory range is used.\r
-  The function is only invoked when load modules at fixed address feature is enabled. \r
-  \r
-  @param  ImageBase                The base addres the image will be loaded at.\r
+  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\r
+  memory range is available, the function will mark the corresponding bits to 1 which indicates the memory range is used.\r
+  The function is only invoked when load modules at fixed address feature is enabled.\r
+\r
+  @param  ImageBase                The base address the image will be loaded at.\r
   @param  ImageSize                The size of the image\r
-  \r
+\r
   @retval EFI_SUCCESS              The memory range the image will be loaded in is available\r
   @retval EFI_NOT_FOUND            The memory range the image will be loaded in is not available\r
 **/\r
@@ -148,7 +143,7 @@ CheckAndMarkFixLoadingMemoryUsageBitMap (
   )\r
 {\r
    UINT32                             SmmCodePageNumber;\r
-   UINT64                             SmmCodeSize; \r
+   UINT64                             SmmCodeSize;\r
    EFI_PHYSICAL_ADDRESS               SmmCodeBase;\r
    UINTN                              BaseOffsetPageNumber;\r
    UINTN                              TopOffsetPageNumber;\r
@@ -159,11 +154,11 @@ CheckAndMarkFixLoadingMemoryUsageBitMap (
    SmmCodePageNumber = PcdGet32(PcdLoadFixAddressSmmCodePageNumber);\r
    SmmCodeSize = EFI_PAGES_TO_SIZE (SmmCodePageNumber);\r
    SmmCodeBase = gLoadModuleAtFixAddressSmramBase;\r
-   \r
+\r
    //\r
-   // If the memory usage bit map is not initialized,  do it. Every bit in the array \r
+   // If the memory usage bit map is not initialized,  do it. Every bit in the array\r
    // indicate the status of the corresponding memory page, available or not\r
-   // \r
+   //\r
    if (mSmmCodeMemoryRangeUsageBitMap == NULL) {\r
      mSmmCodeMemoryRangeUsageBitMap = AllocateZeroPool(((SmmCodePageNumber / 64) + 1)*sizeof(UINT64));\r
    }\r
@@ -177,38 +172,38 @@ CheckAndMarkFixLoadingMemoryUsageBitMap (
    // see if the memory range for loading the image is in the SMM code range.\r
    //\r
    if (SmmCodeBase + SmmCodeSize <  ImageBase + ImageSize || SmmCodeBase >  ImageBase) {\r
-     return EFI_NOT_FOUND;   \r
-   }   \r
+     return EFI_NOT_FOUND;\r
+   }\r
    //\r
    // Test if the memory is avalaible or not.\r
-   // \r
-   BaseOffsetPageNumber = (UINTN)EFI_SIZE_TO_PAGES((UINT32)(ImageBase - SmmCodeBase));\r
-   TopOffsetPageNumber  = (UINTN)EFI_SIZE_TO_PAGES((UINT32)(ImageBase + ImageSize - SmmCodeBase));\r
+   //\r
+   BaseOffsetPageNumber = EFI_SIZE_TO_PAGES((UINT32)(ImageBase - SmmCodeBase));\r
+   TopOffsetPageNumber  = EFI_SIZE_TO_PAGES((UINT32)(ImageBase + ImageSize - SmmCodeBase));\r
    for (Index = BaseOffsetPageNumber; Index < TopOffsetPageNumber; Index ++) {\r
      if ((mSmmCodeMemoryRangeUsageBitMap[Index / 64] & LShiftU64(1, (Index % 64))) != 0) {\r
        //\r
        // This page is already used.\r
        //\r
-       return EFI_NOT_FOUND;  \r
+       return EFI_NOT_FOUND;\r
      }\r
    }\r
-   \r
+\r
    //\r
    // Being here means the memory range is available.  So mark the bits for the memory range\r
-   // \r
+   //\r
    for (Index = BaseOffsetPageNumber; Index < TopOffsetPageNumber; Index ++) {\r
      mSmmCodeMemoryRangeUsageBitMap[Index / 64] |= LShiftU64(1, (Index % 64));\r
    }\r
-   return  EFI_SUCCESS;   \r
+   return  EFI_SUCCESS;\r
 }\r
 /**\r
-  Get the fixed loadding address from image header assigned by build tool. This function only be called \r
+  Get the fixed loading address from image header assigned by build tool. This function only be called\r
   when Loading module at Fixed address feature enabled.\r
-  \r
+\r
   @param  ImageContext              Pointer to the image context structure that describes the PE/COFF\r
                                     image that needs to be examined by this function.\r
   @retval EFI_SUCCESS               An fixed loading address is assigned to this image by build tools .\r
-  @retval EFI_NOT_FOUND             The image has no assigned fixed loadding address.\r
+  @retval EFI_NOT_FOUND             The image has no assigned fixed loading address.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -216,82 +211,80 @@ GetPeCoffImageFixLoadingAssignedAddress(
   IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext\r
   )\r
 {\r
-        UINTN                              SectionHeaderOffset;\r
-        EFI_STATUS                         Status;\r
-        EFI_IMAGE_SECTION_HEADER           SectionHeader;\r
-        EFI_IMAGE_OPTIONAL_HEADER_UNION    *ImgHdr;\r
-        EFI_PHYSICAL_ADDRESS               FixLoaddingAddress;\r
-        UINT16                             Index;\r
-        UINTN                              Size; \r
-        UINT16                             NumberOfSections;\r
-        UINT64                             ValueInSectionHeader;\r
-        \r
-        FixLoaddingAddress = 0;\r
-        Status = EFI_NOT_FOUND;\r
-       \r
-        //\r
-   // Get PeHeader pointer\r
-   //\r
-   ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((CHAR8* )ImageContext->Handle + ImageContext->PeCoffHeaderOffset);\r
-        SectionHeaderOffset = (UINTN)(\r
-                                 ImageContext->PeCoffHeaderOffset +\r
-                                 sizeof (UINT32) +\r
-                                 sizeof (EFI_IMAGE_FILE_HEADER) +\r
-                                 ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader\r
-                                 );\r
-   NumberOfSections = ImgHdr->Pe32.FileHeader.NumberOfSections;\r
-     \r
-   //\r
-   // Get base address from the first section header that doesn't point to code section.\r
-   //\r
-   for (Index = 0; Index < NumberOfSections; Index++) {\r
-     //\r
-     // Read section header from file\r
-     //\r
-     Size = sizeof (EFI_IMAGE_SECTION_HEADER);\r
-     Status = ImageContext->ImageRead (\r
+  UINTN                              SectionHeaderOffset;\r
+  EFI_STATUS                         Status;\r
+  EFI_IMAGE_SECTION_HEADER           SectionHeader;\r
+  EFI_IMAGE_OPTIONAL_HEADER_UNION    *ImgHdr;\r
+  EFI_PHYSICAL_ADDRESS               FixLoadingAddress;\r
+  UINT16                             Index;\r
+  UINTN                              Size;\r
+  UINT16                             NumberOfSections;\r
+  UINT64                             ValueInSectionHeader;\r
+\r
+  FixLoadingAddress = 0;\r
+  Status = EFI_NOT_FOUND;\r
+\r
+  //\r
+  // Get PeHeader pointer\r
+  //\r
+  ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((CHAR8* )ImageContext->Handle + ImageContext->PeCoffHeaderOffset);\r
+  SectionHeaderOffset = ImageContext->PeCoffHeaderOffset +\r
+                        sizeof (UINT32) +\r
+                        sizeof (EFI_IMAGE_FILE_HEADER) +\r
+                        ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader;\r
+  NumberOfSections = ImgHdr->Pe32.FileHeader.NumberOfSections;\r
+\r
+  //\r
+  // Get base address from the first section header that doesn't point to code section.\r
+  //\r
+  for (Index = 0; Index < NumberOfSections; Index++) {\r
+    //\r
+    // Read section header from file\r
+    //\r
+    Size = sizeof (EFI_IMAGE_SECTION_HEADER);\r
+    Status = ImageContext->ImageRead (\r
                               ImageContext->Handle,\r
                               SectionHeaderOffset,\r
                               &Size,\r
                               &SectionHeader\r
                               );\r
-     if (EFI_ERROR (Status)) {\r
-       return Status;\r
-     }\r
-     \r
-     Status = EFI_NOT_FOUND;\r
-     \r
-     if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) {\r
-       //\r
-       // Build tool will save the address in PointerToRelocations & PointerToLineNumbers fields in the first section header \r
-       // that doesn't point to code section in image header.So there is an assumption that when the feature is enabled,\r
-       // if a module with a loading address assigned by tools, the PointerToRelocations & PointerToLineNumbers fields\r
-       // should not be Zero, or else, these 2 fileds should be set to Zero\r
-       //\r
-       ValueInSectionHeader = ReadUnaligned64((UINT64*)&SectionHeader.PointerToRelocations);\r
-       if (ValueInSectionHeader != 0) {\r
-         //\r
-         // Found first section header that doesn't point to code section in which uild tool saves the\r
-         // offset to SMRAM base as image base in PointerToRelocations & PointerToLineNumbers fields\r
-         //      \r
-         FixLoaddingAddress = (EFI_PHYSICAL_ADDRESS)(gLoadModuleAtFixAddressSmramBase + (INT64)ValueInSectionHeader);\r
-         //\r
-         // Check if the memory range is avaliable.\r
-         //\r
-         Status = CheckAndMarkFixLoadingMemoryUsageBitMap (FixLoaddingAddress, (UINTN)(ImageContext->ImageSize + ImageContext->SectionAlignment));\r
-         if (!EFI_ERROR(Status)) {\r
-           //\r
-           // The assigned address is valid. Return the specified loadding address\r
-           //\r
-           ImageContext->ImageAddress = FixLoaddingAddress;\r
-         }\r
-       }\r
-       break;     \r
-     }\r
-     SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);     \r
-   }\r
-   DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED INFO: Loading module at fixed address %x, Status = %r\n", FixLoaddingAddress, Status));\r
-   return Status;\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+\r
+    Status = EFI_NOT_FOUND;\r
+\r
+    if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) {\r
+      //\r
+      // Build tool will save the address in PointerToRelocations & PointerToLineNumbers fields in the first section header\r
+      // that doesn't point to code section in image header.So there is an assumption that when the feature is enabled,\r
+      // if a module with a loading address assigned by tools, the PointerToRelocations & PointerToLineNumbers fields\r
+      // should not be Zero, or else, these 2 fields should be set to Zero\r
+      //\r
+      ValueInSectionHeader = ReadUnaligned64((UINT64*)&SectionHeader.PointerToRelocations);\r
+      if (ValueInSectionHeader != 0) {\r
+        //\r
+        // Found first section header that doesn't point to code section in which build tool saves the\r
+        // offset to SMRAM base as image base in PointerToRelocations & PointerToLineNumbers fields\r
+        //\r
+        FixLoadingAddress = (EFI_PHYSICAL_ADDRESS)(gLoadModuleAtFixAddressSmramBase + (INT64)ValueInSectionHeader);\r
+        //\r
+        // Check if the memory range is available.\r
+        //\r
+        Status = CheckAndMarkFixLoadingMemoryUsageBitMap (FixLoadingAddress, (UINTN)(ImageContext->ImageSize + ImageContext->SectionAlignment));\r
+        if (!EFI_ERROR(Status)) {\r
+          //\r
+          // The assigned address is valid. Return the specified loading address\r
+          //\r
+          ImageContext->ImageAddress = FixLoadingAddress;\r
+        }\r
+      }\r
+      break;\r
+    }\r
+    SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);\r
+  }\r
+  DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED INFO: Loading module at fixed address %x, Status = %r\n", FixLoadingAddress, Status));\r
+  return Status;\r
 }\r
 /**\r
   Loads an EFI image into SMRAM.\r
@@ -322,13 +315,9 @@ SmmLoadImage (
   EFI_DEVICE_PATH_PROTOCOL       *HandleFilePath;\r
   EFI_FIRMWARE_VOLUME2_PROTOCOL  *Fv;\r
   PE_COFF_LOADER_IMAGE_CONTEXT   ImageContext;\r
-  UINT64                         Tick;\r
 \r
-  Tick = 0;\r
-  PERF_CODE (\r
-    Tick = GetPerformanceCounter ();\r
-  );\r
-   \r
+  PERF_LOAD_IMAGE_BEGIN (DriverEntry->ImageHandle);\r
+\r
   Buffer               = NULL;\r
   Size                 = 0;\r
   Fv                   = DriverEntry->Fv;\r
@@ -403,7 +392,7 @@ SmmLoadImage (
                   &AuthenticationStatus\r
                   );\r
   }\r
-  \r
+\r
   if (EFI_ERROR (Status)) {\r
     if (Buffer != NULL) {\r
       gBS->FreePool (Buffer);\r
@@ -427,7 +416,7 @@ SmmLoadImage (
   //\r
   // Verify the Authentication Status through the Security Architectural Protocol\r
   // Only on images that have been read using Firmware Volume protocol.\r
-  // All SMM images are from FV protocol. \r
+  // All SMM images are from FV protocol.\r
   //\r
   if (!EFI_ERROR (SecurityStatus) && (mSecurity != NULL)) {\r
     SecurityStatus = mSecurity->FileAuthenticationState (\r
@@ -441,7 +430,7 @@ SmmLoadImage (
     Status = SecurityStatus;\r
     return Status;\r
   }\r
-  \r
+\r
   //\r
   // Initialize ImageContext\r
   //\r
@@ -473,7 +462,7 @@ SmmLoadImage (
       // following statements is to bypass SmmFreePages\r
       //\r
       PageCount = 0;\r
-      DstBuffer = (UINTN)gLoadModuleAtFixAddressSmramBase;   \r
+      DstBuffer = (UINTN)gLoadModuleAtFixAddressSmramBase;\r
     } else {\r
        DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED ERROR: Failed to load module at fixed address. \n"));\r
        //\r
@@ -481,7 +470,7 @@ SmmLoadImage (
        //\r
        PageCount = (UINTN)EFI_SIZE_TO_PAGES((UINTN)ImageContext.ImageSize + ImageContext.SectionAlignment);\r
        DstBuffer = (UINTN)(-1);\r
-     \r
+\r
        Status = SmmAllocatePages (\r
                    AllocateMaxAddress,\r
                    EfiRuntimeServicesCode,\r
@@ -491,15 +480,15 @@ SmmLoadImage (
        if (EFI_ERROR (Status)) {\r
          if (Buffer != NULL) {\r
            gBS->FreePool (Buffer);\r
-         } \r
+         }\r
          return Status;\r
-       }     \r
+       }\r
       ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)DstBuffer;\r
     }\r
   } else {\r
      PageCount = (UINTN)EFI_SIZE_TO_PAGES((UINTN)ImageContext.ImageSize + ImageContext.SectionAlignment);\r
      DstBuffer = (UINTN)(-1);\r
-     \r
+\r
      Status = SmmAllocatePages (\r
                   AllocateMaxAddress,\r
                   EfiRuntimeServicesCode,\r
@@ -512,14 +501,14 @@ SmmLoadImage (
        }\r
        return Status;\r
      }\r
-     \r
+\r
      ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)DstBuffer;\r
   }\r
   //\r
-  // Align buffer on section boundry\r
+  // Align buffer on section boundary\r
   //\r
   ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;\r
-  ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS)(ImageContext.SectionAlignment - 1));\r
+  ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS)ImageContext.SectionAlignment - 1);\r
 \r
   //\r
   // Load the image to our new buffer\r
@@ -554,7 +543,7 @@ SmmLoadImage (
   // Save Image EntryPoint in DriverEntry\r
   //\r
   DriverEntry->ImageEntryPoint  = ImageContext.EntryPoint;\r
-  DriverEntry->ImageBuffer      = DstBuffer; \r
+  DriverEntry->ImageBuffer      = DstBuffer;\r
   DriverEntry->NumberOfPage     = PageCount;\r
 \r
   //\r
@@ -579,6 +568,11 @@ SmmLoadImage (
   DriverEntry->LoadedImage->SystemTable   = gST;\r
   DriverEntry->LoadedImage->DeviceHandle  = DeviceHandle;\r
 \r
+  DriverEntry->SmmLoadedImage.Revision     = EFI_LOADED_IMAGE_PROTOCOL_REVISION;\r
+  DriverEntry->SmmLoadedImage.ParentHandle = gSmmCorePrivate->SmmIplImageHandle;\r
+  DriverEntry->SmmLoadedImage.SystemTable  = gST;\r
+  DriverEntry->SmmLoadedImage.DeviceHandle = DeviceHandle;\r
+\r
   //\r
   // Make an EfiBootServicesData buffer copy of FilePath\r
   //\r
@@ -592,11 +586,30 @@ SmmLoadImage (
   }\r
   CopyMem (DriverEntry->LoadedImage->FilePath, FilePath, GetDevicePathSize (FilePath));\r
 \r
-  DriverEntry->LoadedImage->ImageBase     = (VOID *)(UINTN)DriverEntry->ImageBuffer;\r
+  DriverEntry->LoadedImage->ImageBase     = (VOID *)(UINTN) ImageContext.ImageAddress;\r
   DriverEntry->LoadedImage->ImageSize     = ImageContext.ImageSize;\r
   DriverEntry->LoadedImage->ImageCodeType = EfiRuntimeServicesCode;\r
   DriverEntry->LoadedImage->ImageDataType = EfiRuntimeServicesData;\r
 \r
+  //\r
+  // Make a buffer copy of FilePath\r
+  //\r
+  Status = SmmAllocatePool (EfiRuntimeServicesData, GetDevicePathSize(FilePath), (VOID **)&DriverEntry->SmmLoadedImage.FilePath);\r
+  if (EFI_ERROR (Status)) {\r
+    if (Buffer != NULL) {\r
+      gBS->FreePool (Buffer);\r
+    }\r
+    gBS->FreePool (DriverEntry->LoadedImage->FilePath);\r
+    SmmFreePages (DstBuffer, PageCount);\r
+    return Status;\r
+  }\r
+  CopyMem (DriverEntry->SmmLoadedImage.FilePath, FilePath, GetDevicePathSize(FilePath));\r
+\r
+  DriverEntry->SmmLoadedImage.ImageBase = (VOID *)(UINTN) ImageContext.ImageAddress;\r
+  DriverEntry->SmmLoadedImage.ImageSize = ImageContext.ImageSize;\r
+  DriverEntry->SmmLoadedImage.ImageCodeType = EfiRuntimeServicesCode;\r
+  DriverEntry->SmmLoadedImage.ImageDataType = EfiRuntimeServicesData;\r
+\r
   //\r
   // Create a new image handle in the UEFI handle database for the SMM Driver\r
   //\r
@@ -607,8 +620,18 @@ SmmLoadImage (
                   NULL\r
                   );\r
 \r
-  PERF_START (DriverEntry->ImageHandle, "LoadImage:", NULL, Tick);\r
-  PERF_END (DriverEntry->ImageHandle, "LoadImage:", NULL, 0);\r
+  //\r
+  // Create a new image handle in the SMM handle database for the SMM Driver\r
+  //\r
+  DriverEntry->SmmImageHandle = NULL;\r
+  Status = SmmInstallProtocolInterface (\r
+             &DriverEntry->SmmImageHandle,\r
+             &gEfiLoadedImageProtocolGuid,\r
+             EFI_NATIVE_INTERFACE,\r
+             &DriverEntry->SmmLoadedImage\r
+             );\r
+\r
+  PERF_LOAD_IMAGE_END (DriverEntry->ImageHandle);\r
 \r
   //\r
   // Print the load address and the PDB file name if it is available\r
@@ -669,20 +692,20 @@ SmmLoadImage (
   //\r
   // Free buffer allocated by Fv->ReadSection.\r
   //\r
-  // The UEFI Boot Services FreePool() function must be used because Fv->ReadSection \r
+  // The UEFI Boot Services FreePool() function must be used because Fv->ReadSection\r
   // used the UEFI Boot Services AllocatePool() function\r
   //\r
   Status = gBS->FreePool(Buffer);\r
   if (!EFI_ERROR (Status) && EFI_ERROR (SecurityStatus)) {\r
     Status = SecurityStatus;\r
   }\r
-  return Status;  \r
+  return Status;\r
 }\r
 \r
 /**\r
   Preprocess dependency expression and update DriverEntry to reflect the\r
   state of  Before and After dependencies. If DriverEntry->Before\r
-  or DriverEntry->After is set it will never be cleared. \r
+  or DriverEntry->After is set it will never be cleared.\r
 \r
   @param  DriverEntry           DriverEntry element to update .\r
 \r
@@ -781,7 +804,7 @@ SmmGetDepexSectionAndPreProccess (
   drivers to run. Drain the mScheduledQueue and load and start a PE\r
   image for each driver. Search the mDiscoveredList to see if any driver can\r
   be placed on the mScheduledQueue. If no drivers are placed on the\r
-  mScheduledQueue exit the function. \r
+  mScheduledQueue exit the function.\r
 \r
   @retval EFI_SUCCESS           All of the SMM Drivers that could be dispatched\r
                                 have been run and the SMM Entry Point has been\r
@@ -875,9 +898,9 @@ SmmDispatcher (
       // For each SMM driver, pass NULL as ImageHandle\r
       //\r
       RegisterSmramProfileImage (DriverEntry, TRUE);\r
-      PERF_START (DriverEntry->ImageHandle, "StartImage:", NULL, 0);\r
+      PERF_START_IMAGE_BEGIN (DriverEntry->ImageHandle);\r
       Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)DriverEntry->ImageEntryPoint)(DriverEntry->ImageHandle, gST);\r
-      PERF_END (DriverEntry->ImageHandle, "StartImage:", NULL, 0);\r
+      PERF_START_IMAGE_END (DriverEntry->ImageHandle);\r
       if (EFI_ERROR(Status)){\r
         UnregisterSmramProfileImage (DriverEntry, TRUE);\r
         SmmFreePages(DriverEntry->ImageBuffer, DriverEntry->NumberOfPage);\r
@@ -895,6 +918,16 @@ SmmDispatcher (
           }\r
           gBS->FreePool (DriverEntry->LoadedImage);\r
         }\r
+        Status = SmmUninstallProtocolInterface (\r
+                   DriverEntry->SmmImageHandle,\r
+                   &gEfiLoadedImageProtocolGuid,\r
+                   &DriverEntry->SmmLoadedImage\r
+                   );\r
+        if (!EFI_ERROR(Status)) {\r
+          if (DriverEntry->SmmLoadedImage.FilePath != NULL) {\r
+            SmmFreePool (DriverEntry->SmmLoadedImage.FilePath);\r
+          }\r
+        }\r
       }\r
 \r
       REPORT_STATUS_CODE_WITH_EXTENDED_DATA (\r
@@ -906,11 +939,11 @@ SmmDispatcher (
 \r
       if (!PreviousSmmEntryPointRegistered && gSmmCorePrivate->SmmEntryPointRegistered) {\r
         //\r
-        // Return immediately if the SMM Entry Point was registered by the SMM \r
+        // Return immediately if the SMM Entry Point was registered by the SMM\r
         // Driver that was just dispatched.  The SMM IPL will reinvoke the SMM\r
-        // Core Dispatcher.  This is required so SMM Mode may be enabled as soon \r
-        // as all the dependent SMM Drivers for SMM Mode have been dispatched.  \r
-        // Once the SMM Entry Point has been registered, then SMM Mode will be \r
+        // Core Dispatcher.  This is required so SMM Mode may be enabled as soon\r
+        // as all the dependent SMM Drivers for SMM Mode have been dispatched.\r
+        // Once the SMM Entry Point has been registered, then SMM Mode will be\r
         // used.\r
         //\r
         gRequestDispatch = TRUE;\r
@@ -1283,6 +1316,7 @@ SmmDriverDispatchHandler (
     //\r
     // Discover Drivers in FV and add them to the Discovered Driver List.\r
     // Process EFI_FV_FILETYPE_SMM type and then EFI_FV_FILETYPE_COMBINED_SMM_DXE\r
+    //  EFI_FV_FILETYPE_SMM_CORE is processed to produce a Loaded Image protocol for the core\r
     //\r
     for (SmmTypeIndex = 0; SmmTypeIndex < sizeof (mSmmFileTypes)/sizeof (EFI_FV_FILETYPE); SmmTypeIndex++) {\r
       //\r
@@ -1300,7 +1334,55 @@ SmmDriverDispatchHandler (
                                   &Size\r
                                   );\r
         if (!EFI_ERROR (GetNextFileStatus)) {\r
-          SmmAddToDriverList (Fv, FvHandle, &NameGuid);\r
+          if (Type == EFI_FV_FILETYPE_SMM_CORE) {\r
+            //\r
+            // If this is the SMM core fill in it's DevicePath & DeviceHandle\r
+            //\r
+            if (mSmmCoreLoadedImage->FilePath == NULL) {\r
+              //\r
+              // Maybe one special FV contains only one SMM_CORE module, so its device path must\r
+              // be initialized completely.\r
+              //\r
+              EfiInitializeFwVolDevicepathNode (&mFvDevicePath.File, &NameGuid);\r
+              SetDevicePathEndNode (&mFvDevicePath.End);\r
+\r
+              //\r
+              // Make an EfiBootServicesData buffer copy of FilePath\r
+              //\r
+              Status = gBS->AllocatePool (\r
+                              EfiBootServicesData,\r
+                              GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath),\r
+                              (VOID **)&mSmmCoreLoadedImage->FilePath\r
+                              );\r
+              ASSERT_EFI_ERROR (Status);\r
+              CopyMem (mSmmCoreLoadedImage->FilePath, &mFvDevicePath, GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath));\r
+\r
+              mSmmCoreLoadedImage->DeviceHandle = FvHandle;\r
+            }\r
+            if (mSmmCoreDriverEntry->SmmLoadedImage.FilePath == NULL) {\r
+              //\r
+              // Maybe one special FV contains only one SMM_CORE module, so its device path must\r
+              // be initialized completely.\r
+              //\r
+              EfiInitializeFwVolDevicepathNode (&mFvDevicePath.File, &NameGuid);\r
+              SetDevicePathEndNode (&mFvDevicePath.End);\r
+\r
+              //\r
+              // Make a buffer copy FilePath\r
+              //\r
+              Status = SmmAllocatePool (\r
+                         EfiRuntimeServicesData,\r
+                         GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath),\r
+                         (VOID **)&mSmmCoreDriverEntry->SmmLoadedImage.FilePath\r
+                         );\r
+              ASSERT_EFI_ERROR (Status);\r
+              CopyMem (mSmmCoreDriverEntry->SmmLoadedImage.FilePath, &mFvDevicePath, GetDevicePathSize((EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath));\r
+\r
+              mSmmCoreDriverEntry->SmmLoadedImage.DeviceHandle = FvHandle;\r
+            }\r
+          } else {\r
+            SmmAddToDriverList (Fv, FvHandle, &NameGuid);\r
+          }\r
         }\r
       } while (!EFI_ERROR (GetNextFileStatus));\r
     }\r
@@ -1349,14 +1431,14 @@ SmmDriverDispatchHandler (
     //\r
     // Free data allocated by Fv->ReadSection ()\r
     //\r
-    // The UEFI Boot Services FreePool() function must be used because Fv->ReadSection \r
+    // The UEFI Boot Services FreePool() function must be used because Fv->ReadSection\r
     // used the UEFI Boot Services AllocatePool() function\r
     //\r
     gBS->FreePool (AprioriFile);\r
   }\r
 \r
   //\r
-  // Execute the SMM Dispatcher on any newly discovered FVs and previously \r
+  // Execute the SMM Dispatcher on any newly discovered FVs and previously\r
   // discovered SMM drivers that have been discovered but not dispatched.\r
   //\r
   Status = SmmDispatcher ();\r
@@ -1368,7 +1450,7 @@ SmmDriverDispatchHandler (
     if (*CommBufferSize > 0) {\r
       if (Status == EFI_NOT_READY) {\r
         //\r
-        // If a the SMM Core Entry Point was just registered, then set flag to \r
+        // If a the SMM Core Entry Point was just registered, then set flag to\r
         // request the SMM Dispatcher to be restarted.\r
         //\r
         *(UINT8 *)CommBuffer = COMM_BUFFER_SMM_DISPATCH_RESTART;\r