/** @file
  SMM Driver Dispatcher.

  Step #1 - When a FV protocol is added to the system every driver in the FV
            is added to the mDiscoveredList. The Before, and After Depex are
            pre-processed as drivers are added to the mDiscoveredList. If an Apriori
            file exists in the FV those drivers are addeded to the
            mScheduledQueue. The mFvHandleList is used to make sure a
            FV is only processed once.

  Step #2 - Dispatch. Remove driver from the mScheduledQueue and load and
            start it. After mScheduledQueue is drained check the
            mDiscoveredList to see if any item has a Depex that is ready to
            be placed on the mScheduledQueue.

  Step #3 - Adding to the mScheduledQueue requires that you process Before
            and After dependencies. This is done recursively as the call to add
            to the mScheduledQueue checks for Before and recursively adds
            all Befores. It then addes the item that was passed in and then
            processes the After dependencies by recursively calling the routine.

  Dispatcher Rules:
  The rules for the dispatcher are similar to the DXE dispatcher.

  The rules for DXE dispatcher are in chapter 10 of the DXE CIS. Figure 10-3
  is the state diagram for the DXE dispatcher

  Depex - Dependency Expression.

  Copyright (c) 2014, Hewlett-Packard Development Company, L.P.
  Copyright (c) 2009 - 2023, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "PiSmmCore.h"

//
// SMM Dispatcher Data structures
//
#define KNOWN_HANDLE_SIGNATURE  SIGNATURE_32('k','n','o','w')
typedef struct {
  UINTN         Signature;
  LIST_ENTRY    Link;           // mFvHandleList
  EFI_HANDLE    Handle;
} KNOWN_HANDLE;

//
// Function Prototypes
//

/**
  Insert InsertedDriverEntry onto the mScheduledQueue. To do this you
  must add any driver with a before dependency on InsertedDriverEntry first.
  You do this by recursively calling this routine. After all the Befores are
  processed you can add InsertedDriverEntry to the mScheduledQueue.
  Then you can add any driver with an After dependency on InsertedDriverEntry
  by recursively calling this routine.

  @param  InsertedDriverEntry   The driver to insert on the ScheduledLink Queue

**/
VOID
SmmInsertOnScheduledQueueWhileProcessingBeforeAndAfter (
  IN  EFI_SMM_DRIVER_ENTRY  *InsertedDriverEntry
  );

//
// The Driver List contains one copy of every driver that has been discovered.
// Items are never removed from the driver list. List of EFI_SMM_DRIVER_ENTRY
//
LIST_ENTRY  mDiscoveredList = INITIALIZE_LIST_HEAD_VARIABLE (mDiscoveredList);

//
// Queue of drivers that are ready to dispatch. This queue is a subset of the
// mDiscoveredList.list of EFI_SMM_DRIVER_ENTRY.
//
LIST_ENTRY  mScheduledQueue = INITIALIZE_LIST_HEAD_VARIABLE (mScheduledQueue);

//
// List of handles who's Fv's have been parsed and added to the mFwDriverList.
//
LIST_ENTRY  mFvHandleList = INITIALIZE_LIST_HEAD_VARIABLE (mFvHandleList);

//
// Flag for the SMM Dispatcher.  TRUE if dispatcher is executing.
//
BOOLEAN  gDispatcherRunning = FALSE;

//
// Flag for the SMM Dispatcher.  TRUE if there is one or more SMM drivers ready to be dispatched
//
BOOLEAN  gRequestDispatch = FALSE;

//
// List of file types supported by dispatcher
//
EFI_FV_FILETYPE  mSmmFileTypes[] = {
  EFI_FV_FILETYPE_SMM,
  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
  //
};

typedef struct {
  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH    File;
  EFI_DEVICE_PATH_PROTOCOL             End;
} FV_FILEPATH_DEVICE_PATH;

FV_FILEPATH_DEVICE_PATH  mFvDevicePath;

//
// DXE Architecture Protocols
//
EFI_SECURITY_ARCH_PROTOCOL   *mSecurity  = NULL;
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 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 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
**/
EFI_STATUS
CheckAndMarkFixLoadingMemoryUsageBitMap (
  IN  EFI_PHYSICAL_ADDRESS  ImageBase,
  IN  UINTN                 ImageSize
  )
{
  UINT32                SmmCodePageNumber;
  UINT64                SmmCodeSize;
  EFI_PHYSICAL_ADDRESS  SmmCodeBase;
  UINTN                 BaseOffsetPageNumber;
  UINTN                 TopOffsetPageNumber;
  UINTN                 Index;

  //
  // Build tool will calculate the smm code size and then patch the PcdLoadFixAddressSmmCodePageNumber
  //
  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
  // indicate the status of the corresponding memory page, available or not
  //
  if (mSmmCodeMemoryRangeUsageBitMap == NULL) {
    mSmmCodeMemoryRangeUsageBitMap = AllocateZeroPool (((SmmCodePageNumber / 64) + 1)*sizeof (UINT64));
  }

  //
  // If the Dxe code memory range is not allocated or the bit map array allocation failed, return EFI_NOT_FOUND
  //
  if (mSmmCodeMemoryRangeUsageBitMap == NULL) {
    return EFI_NOT_FOUND;
  }

  //
  // 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;
  }

  //
  // Test if the memory is available or not.
  //
  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;
    }
  }

  //
  // 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;
}

/**
  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 loading address.

**/
EFI_STATUS
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             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 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 ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED INFO: Loading module at fixed address %x, Status = %r\n", FixLoadingAddress, Status));
  return Status;
}

/**
  Loads an EFI image into SMRAM.

  @param  DriverEntry             EFI_SMM_DRIVER_ENTRY instance

  @return EFI_STATUS

**/
EFI_STATUS
EFIAPI
SmmLoadImage (
  IN OUT EFI_SMM_DRIVER_ENTRY  *DriverEntry
  )
{
  UINT32                         AuthenticationStatus;
  UINTN                          FilePathSize;
  VOID                           *Buffer;
  UINTN                          Size;
  UINTN                          PageCount;
  EFI_GUID                       *NameGuid;
  EFI_STATUS                     Status;
  EFI_STATUS                     SecurityStatus;
  EFI_HANDLE                     DeviceHandle;
  EFI_PHYSICAL_ADDRESS           DstBuffer;
  EFI_DEVICE_PATH_PROTOCOL       *FilePath;
  EFI_DEVICE_PATH_PROTOCOL       *OriginalFilePath;
  EFI_DEVICE_PATH_PROTOCOL       *HandleFilePath;
  EFI_FIRMWARE_VOLUME2_PROTOCOL  *Fv;
  PE_COFF_LOADER_IMAGE_CONTEXT   ImageContext;
  UINTN                          Index;
  UINTN                          StartIndex;
  CHAR8                          EfiFileName[512];

  PERF_LOAD_IMAGE_BEGIN (DriverEntry->ImageHandle);

  Buffer   = NULL;
  Size     = 0;
  Fv       = DriverEntry->Fv;
  NameGuid = &DriverEntry->FileName;
  FilePath = DriverEntry->FvFileDevicePath;

  OriginalFilePath     = FilePath;
  HandleFilePath       = FilePath;
  DeviceHandle         = NULL;
  SecurityStatus       = EFI_SUCCESS;
  Status               = EFI_SUCCESS;
  AuthenticationStatus = 0;

  //
  // Try to get the image device handle by checking the match protocol.
  //
  Status = gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, &HandleFilePath, &DeviceHandle);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // If the Security2 and Security Architectural Protocol has not been located yet, then attempt to locate it
  //
  if (mSecurity2 == NULL) {
    gBS->LocateProtocol (&gEfiSecurity2ArchProtocolGuid, NULL, (VOID **)&mSecurity2);
  }

  if (mSecurity == NULL) {
    gBS->LocateProtocol (&gEfiSecurityArchProtocolGuid, NULL, (VOID **)&mSecurity);
  }

  //
  // When Security2 is installed, Security Architectural Protocol must be published.
  //
  ASSERT (mSecurity2 == NULL || mSecurity != NULL);

  //
  // Pull out just the file portion of the DevicePath for the LoadedImage FilePath
  //
  FilePath = OriginalFilePath;
  Status   = gBS->HandleProtocol (DeviceHandle, &gEfiDevicePathProtocolGuid, (VOID **)&HandleFilePath);
  if (!EFI_ERROR (Status)) {
    FilePathSize = GetDevicePathSize (HandleFilePath) - sizeof (EFI_DEVICE_PATH_PROTOCOL);
    FilePath     = (EFI_DEVICE_PATH_PROTOCOL *)(((UINT8 *)FilePath) + FilePathSize);
  }

  //
  // Try reading PE32 section firstly
  //
  Status = Fv->ReadSection (
                 Fv,
                 NameGuid,
                 EFI_SECTION_PE32,
                 0,
                 &Buffer,
                 &Size,
                 &AuthenticationStatus
                 );

  if (EFI_ERROR (Status)) {
    //
    // Try reading TE section secondly
    //
    Buffer = NULL;
    Size   = 0;
    Status = Fv->ReadSection (
                   Fv,
                   NameGuid,
                   EFI_SECTION_TE,
                   0,
                   &Buffer,
                   &Size,
                   &AuthenticationStatus
                   );
  }

  if (EFI_ERROR (Status)) {
    if (Buffer != NULL) {
      gBS->FreePool (Buffer);
    }

    return Status;
  }

  //
  // Verify File Authentication through the Security2 Architectural Protocol
  //
  if (mSecurity2 != NULL) {
    SecurityStatus = mSecurity2->FileAuthentication (
                                   mSecurity2,
                                   OriginalFilePath,
                                   Buffer,
                                   Size,
                                   FALSE
                                   );
  }

  //
  // 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.
  //
  if (!EFI_ERROR (SecurityStatus) && (mSecurity != NULL)) {
    SecurityStatus = mSecurity->FileAuthenticationState (
                                  mSecurity,
                                  AuthenticationStatus,
                                  OriginalFilePath
                                  );
  }

  if (EFI_ERROR (SecurityStatus) && (SecurityStatus != EFI_SECURITY_VIOLATION)) {
    Status = SecurityStatus;
    return Status;
  }

  //
  // Initialize ImageContext
  //
  ImageContext.Handle    = Buffer;
  ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;

  //
  // Get information about the image being loaded
  //
  Status = PeCoffLoaderGetImageInfo (&ImageContext);
  if (EFI_ERROR (Status)) {
    if (Buffer != NULL) {
      gBS->FreePool (Buffer);
    }

    return Status;
  }

  //
  // if Loading module at Fixed Address feature is enabled, then  cut out a memory range started from TESG BASE
  // to hold the Smm driver code
  //
  if (PcdGet64 (PcdLoadModuleAtFixAddressEnable) != 0) {
    //
    // Get the fixed loading address assigned by Build tool
    //
    Status = GetPeCoffImageFixLoadingAssignedAddress (&ImageContext);
    if (!EFI_ERROR (Status)) {
      //
      // Since the memory range to load Smm core already been cut out, so no need to allocate and free this range
      // following statements is to bypass SmmFreePages
      //
      PageCount = 0;
      DstBuffer = (UINTN)gLoadModuleAtFixAddressSmramBase;
    } else {
      DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED ERROR: Failed to load module at fixed address. \n"));
      //
      // allocate the memory to load the SMM driver
      //
      PageCount = (UINTN)EFI_SIZE_TO_PAGES ((UINTN)ImageContext.ImageSize + ImageContext.SectionAlignment);
      DstBuffer = (UINTN)(-1);

      Status = SmmAllocatePages (
                 AllocateMaxAddress,
                 EfiRuntimeServicesCode,
                 PageCount,
                 &DstBuffer
                 );
      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,
               PageCount,
               &DstBuffer
               );
    if (EFI_ERROR (Status)) {
      if (Buffer != NULL) {
        gBS->FreePool (Buffer);
      }

      return Status;
    }

    ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)DstBuffer;
  }

  //
  // Align buffer on section boundary
  //
  ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;
  ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS)ImageContext.SectionAlignment - 1);

  //
  // Load the image to our new buffer
  //
  Status = PeCoffLoaderLoadImage (&ImageContext);
  if (EFI_ERROR (Status)) {
    if (Buffer != NULL) {
      gBS->FreePool (Buffer);
    }

    SmmFreePages (DstBuffer, PageCount);
    return Status;
  }

  //
  // Relocate the image in our new buffer
  //
  Status = PeCoffLoaderRelocateImage (&ImageContext);
  if (EFI_ERROR (Status)) {
    if (Buffer != NULL) {
      gBS->FreePool (Buffer);
    }

    SmmFreePages (DstBuffer, PageCount);
    return Status;
  }

  //
  // Flush the instruction cache so the image data are written before we execute it
  //
  InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);

  //
  // Save Image EntryPoint in DriverEntry
  //
  DriverEntry->ImageEntryPoint = ImageContext.EntryPoint;
  DriverEntry->ImageBuffer     = DstBuffer;
  DriverEntry->NumberOfPage    = PageCount;

  //
  // Allocate a Loaded Image Protocol in EfiBootServicesData
  //
  Status = gBS->AllocatePool (EfiBootServicesData, sizeof (EFI_LOADED_IMAGE_PROTOCOL), (VOID **)&DriverEntry->LoadedImage);
  if (EFI_ERROR (Status)) {
    if (Buffer != NULL) {
      gBS->FreePool (Buffer);
    }

    SmmFreePages (DstBuffer, PageCount);
    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.
  //
  DriverEntry->LoadedImage->Revision     = EFI_LOADED_IMAGE_PROTOCOL_REVISION;
  DriverEntry->LoadedImage->ParentHandle = gSmmCorePrivate->SmmIplImageHandle;
  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
  //
  Status = gBS->AllocatePool (EfiBootServicesData, GetDevicePathSize (FilePath), (VOID **)&DriverEntry->LoadedImage->FilePath);
  if (EFI_ERROR (Status)) {
    if (Buffer != NULL) {
      gBS->FreePool (Buffer);
    }

    SmmFreePages (DstBuffer, PageCount);
    return Status;
  }

  CopyMem (DriverEntry->LoadedImage->FilePath, FilePath, GetDevicePathSize (FilePath));

  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
  //
  DriverEntry->ImageHandle = NULL;
  Status                   = gBS->InstallMultipleProtocolInterfaces (
                                    &DriverEntry->ImageHandle,
                                    &gEfiLoadedImageProtocolGuid,
                                    DriverEntry->LoadedImage,
                                    NULL
                                    );

  //
  // 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
  //

  DEBUG ((
    DEBUG_INFO | DEBUG_LOAD,
    "Loading SMM driver at 0x%11p EntryPoint=0x%11p ",
    (VOID *)(UINTN)ImageContext.ImageAddress,
    FUNCTION_ENTRY_POINT (ImageContext.EntryPoint)
    ));

  //
  // Print Module Name by Pdb file path.
  // Windows and Unix style file path are all trimmed correctly.
  //
  if (ImageContext.PdbPointer != NULL) {
    StartIndex = 0;
    for (Index = 0; ImageContext.PdbPointer[Index] != 0; Index++) {
      if ((ImageContext.PdbPointer[Index] == '\\') || (ImageContext.PdbPointer[Index] == '/')) {
        StartIndex = Index + 1;
      }
    }

    //
    // Copy the PDB file name to our temporary string, and replace .pdb with .efi
    // The PDB file name is limited in the range of 0~255.
    // If the length is bigger than 255, trim the redundant characters to avoid overflow in array boundary.
    //
    for (Index = 0; Index < sizeof (EfiFileName) - 4; Index++) {
      EfiFileName[Index] = ImageContext.PdbPointer[Index + StartIndex];
      if (EfiFileName[Index] == 0) {
        EfiFileName[Index] = '.';
      }

      if (EfiFileName[Index] == '.') {
        EfiFileName[Index + 1] = 'e';
        EfiFileName[Index + 2] = 'f';
        EfiFileName[Index + 3] = 'i';
        EfiFileName[Index + 4] = 0;
        break;
      }
    }

    if (Index == sizeof (EfiFileName) - 4) {
      EfiFileName[Index] = 0;
    }

    DEBUG ((DEBUG_INFO | DEBUG_LOAD, "%a", EfiFileName));   // &Image->ImageContext.PdbPointer[StartIndex]));
  }

  DEBUG ((DEBUG_INFO | DEBUG_LOAD, "\n"));

  //
  // Free buffer allocated by 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;
}

/**
  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.

  @param  DriverEntry           DriverEntry element to update .

  @retval EFI_SUCCESS           It always works.

**/
EFI_STATUS
SmmPreProcessDepex (
  IN EFI_SMM_DRIVER_ENTRY  *DriverEntry
  )
{
  UINT8  *Iterator;

  Iterator               = DriverEntry->Depex;
  DriverEntry->Dependent = TRUE;

  if (*Iterator == EFI_DEP_BEFORE) {
    DriverEntry->Before = TRUE;
  } else if (*Iterator == EFI_DEP_AFTER) {
    DriverEntry->After = TRUE;
  }

  if (DriverEntry->Before || DriverEntry->After) {
    CopyMem (&DriverEntry->BeforeAfterGuid, Iterator + 1, sizeof (EFI_GUID));
  }

  return EFI_SUCCESS;
}

/**
  Read Depex and pre-process the Depex for Before and After. If Section Extraction
  protocol returns an error via ReadSection defer the reading of the Depex.

  @param  DriverEntry           Driver to work on.

  @retval EFI_SUCCESS           Depex read and preprocessed
  @retval EFI_PROTOCOL_ERROR    The section extraction protocol returned an error
                                and  Depex reading needs to be retried.
  @retval Error                 DEPEX not found.

**/
EFI_STATUS
SmmGetDepexSectionAndPreProccess (
  IN EFI_SMM_DRIVER_ENTRY  *DriverEntry
  )
{
  EFI_STATUS                     Status;
  EFI_SECTION_TYPE               SectionType;
  UINT32                         AuthenticationStatus;
  EFI_FIRMWARE_VOLUME2_PROTOCOL  *Fv;

  Fv = DriverEntry->Fv;

  //
  // Grab Depex info, it will never be free'ed.
  // (Note: DriverEntry->Depex is in DXE memory)
  //
  SectionType = EFI_SECTION_SMM_DEPEX;
  Status      = Fv->ReadSection (
                      DriverEntry->Fv,
                      &DriverEntry->FileName,
                      SectionType,
                      0,
                      &DriverEntry->Depex,
                      (UINTN *)&DriverEntry->DepexSize,
                      &AuthenticationStatus
                      );
  if (EFI_ERROR (Status)) {
    if (Status == EFI_PROTOCOL_ERROR) {
      //
      // The section extraction protocol failed so set protocol error flag
      //
      DriverEntry->DepexProtocolError = TRUE;
    } else {
      //
      // If no Depex assume depend on all architectural protocols
      //
      DriverEntry->Depex              = NULL;
      DriverEntry->Dependent          = TRUE;
      DriverEntry->DepexProtocolError = FALSE;
    }
  } else {
    //
    // Set Before and After state information based on Depex
    // Driver will be put in Dependent state
    //
    SmmPreProcessDepex (DriverEntry);
    DriverEntry->DepexProtocolError = FALSE;
  }

  return Status;
}

/**
  This is the main Dispatcher for SMM and it exits when there are no more
  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.

  @retval EFI_SUCCESS           All of the SMM Drivers that could be dispatched
                                have been run and the SMM Entry Point has been
                                registered.
  @retval EFI_NOT_READY         The SMM Driver that registered the SMM Entry Point
                                was just dispatched.
  @retval EFI_NOT_FOUND         There are no SMM Drivers available to be dispatched.
  @retval EFI_ALREADY_STARTED   The SMM Dispatcher is already running

**/
EFI_STATUS
SmmDispatcher (
  VOID
  )
{
  EFI_STATUS            Status;
  LIST_ENTRY            *Link;
  EFI_SMM_DRIVER_ENTRY  *DriverEntry;
  BOOLEAN               ReadyToRun;
  BOOLEAN               PreviousSmmEntryPointRegistered;

  if (!gRequestDispatch) {
    return EFI_NOT_FOUND;
  }

  if (gDispatcherRunning) {
    //
    // If the dispatcher is running don't let it be restarted.
    //
    return EFI_ALREADY_STARTED;
  }

  gDispatcherRunning = TRUE;

  do {
    //
    // Drain the Scheduled Queue
    //
    while (!IsListEmpty (&mScheduledQueue)) {
      DriverEntry = CR (
                      mScheduledQueue.ForwardLink,
                      EFI_SMM_DRIVER_ENTRY,
                      ScheduledLink,
                      EFI_SMM_DRIVER_ENTRY_SIGNATURE
                      );

      //
      // Load the SMM Driver image into memory. If the Driver was transitioned from
      // Untrused to Scheduled it would have already been loaded so we may need to
      // skip the LoadImage
      //
      if (DriverEntry->ImageHandle == NULL) {
        Status = SmmLoadImage (DriverEntry);

        //
        // Update the driver state to reflect that it's been loaded
        //
        if (EFI_ERROR (Status)) {
          //
          // The SMM Driver could not be loaded, and do not attempt to load or start it again.
          // Take driver from Scheduled to Initialized.
          //
          DriverEntry->Initialized = TRUE;
          DriverEntry->Scheduled   = FALSE;
          RemoveEntryList (&DriverEntry->ScheduledLink);

          //
          // If it's an error don't try the StartImage
          //
          continue;
        }
      }

      DriverEntry->Scheduled   = FALSE;
      DriverEntry->Initialized = TRUE;
      RemoveEntryList (&DriverEntry->ScheduledLink);

      REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
        EFI_PROGRESS_CODE,
        EFI_SOFTWARE_SMM_DRIVER | EFI_SW_PC_INIT_BEGIN,
        &DriverEntry->ImageHandle,
        sizeof (DriverEntry->ImageHandle)
        );

      //
      // Cache state of SmmEntryPointRegistered before calling entry point
      //
      PreviousSmmEntryPointRegistered = gSmmCorePrivate->SmmEntryPointRegistered;

      //
      // For each SMM driver, pass NULL as ImageHandle
      //
      RegisterSmramProfileImage (DriverEntry, TRUE);
      PERF_START_IMAGE_BEGIN (DriverEntry->ImageHandle);
      Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)DriverEntry->ImageEntryPoint)(DriverEntry->ImageHandle, gST);
      PERF_START_IMAGE_END (DriverEntry->ImageHandle);
      if (EFI_ERROR (Status)) {
        DEBUG ((
          DEBUG_ERROR,
          "Error: SMM image at %11p start failed: %r\n",
          DriverEntry->SmmLoadedImage.ImageBase,
          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 (
        EFI_PROGRESS_CODE,
        EFI_SOFTWARE_SMM_DRIVER | EFI_SW_PC_INIT_END,
        &DriverEntry->ImageHandle,
        sizeof (DriverEntry->ImageHandle)
        );

      if (!PreviousSmmEntryPointRegistered && gSmmCorePrivate->SmmEntryPointRegistered) {
        //
        // 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
        // used.
        //
        gRequestDispatch   = TRUE;
        gDispatcherRunning = FALSE;
        return EFI_NOT_READY;
      }
    }

    //
    // Search DriverList for items to place on Scheduled Queue
    //
    ReadyToRun = FALSE;
    for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
      DriverEntry = CR (Link, EFI_SMM_DRIVER_ENTRY, Link, EFI_SMM_DRIVER_ENTRY_SIGNATURE);

      if (DriverEntry->DepexProtocolError) {
        //
        // If Section Extraction Protocol did not let the Depex be read before retry the read
        //
        Status = SmmGetDepexSectionAndPreProccess (DriverEntry);
      }

      if (DriverEntry->Dependent) {
        if (SmmIsSchedulable (DriverEntry)) {
          SmmInsertOnScheduledQueueWhileProcessingBeforeAndAfter (DriverEntry);
          ReadyToRun = TRUE;
        }
      }
    }
  } while (ReadyToRun);

  //
  // If there is no more SMM driver to dispatch, stop the dispatch request
  //
  gRequestDispatch = FALSE;
  for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
    DriverEntry = CR (Link, EFI_SMM_DRIVER_ENTRY, Link, EFI_SMM_DRIVER_ENTRY_SIGNATURE);

    if (!DriverEntry->Initialized) {
      //
      // We have SMM driver pending to dispatch
      //
      gRequestDispatch = TRUE;
      break;
    }
  }

  gDispatcherRunning = FALSE;

  return EFI_SUCCESS;
}

/**
  Insert InsertedDriverEntry onto the mScheduledQueue. To do this you
  must add any driver with a before dependency on InsertedDriverEntry first.
  You do this by recursively calling this routine. After all the Befores are
  processed you can add InsertedDriverEntry to the mScheduledQueue.
  Then you can add any driver with an After dependency on InsertedDriverEntry
  by recursively calling this routine.

  @param  InsertedDriverEntry   The driver to insert on the ScheduledLink Queue

**/
VOID
SmmInsertOnScheduledQueueWhileProcessingBeforeAndAfter (
  IN  EFI_SMM_DRIVER_ENTRY  *InsertedDriverEntry
  )
{
  LIST_ENTRY            *Link;
  EFI_SMM_DRIVER_ENTRY  *DriverEntry;

  //
  // Process Before Dependency
  //
  for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
    DriverEntry = CR (Link, EFI_SMM_DRIVER_ENTRY, Link, EFI_SMM_DRIVER_ENTRY_SIGNATURE);
    if (DriverEntry->Before && DriverEntry->Dependent && (DriverEntry != InsertedDriverEntry)) {
      DEBUG ((DEBUG_DISPATCH, "Evaluate SMM DEPEX for FFS(%g)\n", &DriverEntry->FileName));
      DEBUG ((DEBUG_DISPATCH, "  BEFORE FFS(%g) = ", &DriverEntry->BeforeAfterGuid));
      if (CompareGuid (&InsertedDriverEntry->FileName, &DriverEntry->BeforeAfterGuid)) {
        //
        // Recursively process BEFORE
        //
        DEBUG ((DEBUG_DISPATCH, "TRUE\n  END\n  RESULT = TRUE\n"));
        SmmInsertOnScheduledQueueWhileProcessingBeforeAndAfter (DriverEntry);
      } else {
        DEBUG ((DEBUG_DISPATCH, "FALSE\n  END\n  RESULT = FALSE\n"));
      }
    }
  }

  //
  // Convert driver from Dependent to Scheduled state
  //

  InsertedDriverEntry->Dependent = FALSE;
  InsertedDriverEntry->Scheduled = TRUE;
  InsertTailList (&mScheduledQueue, &InsertedDriverEntry->ScheduledLink);

  //
  // Process After Dependency
  //
  for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
    DriverEntry = CR (Link, EFI_SMM_DRIVER_ENTRY, Link, EFI_SMM_DRIVER_ENTRY_SIGNATURE);
    if (DriverEntry->After && DriverEntry->Dependent && (DriverEntry != InsertedDriverEntry)) {
      DEBUG ((DEBUG_DISPATCH, "Evaluate SMM DEPEX for FFS(%g)\n", &DriverEntry->FileName));
      DEBUG ((DEBUG_DISPATCH, "  AFTER FFS(%g) = ", &DriverEntry->BeforeAfterGuid));
      if (CompareGuid (&InsertedDriverEntry->FileName, &DriverEntry->BeforeAfterGuid)) {
        //
        // Recursively process AFTER
        //
        DEBUG ((DEBUG_DISPATCH, "TRUE\n  END\n  RESULT = TRUE\n"));
        SmmInsertOnScheduledQueueWhileProcessingBeforeAndAfter (DriverEntry);
      } else {
        DEBUG ((DEBUG_DISPATCH, "FALSE\n  END\n  RESULT = FALSE\n"));
      }
    }
  }
}

/**
  Return TRUE if the Fv has been processed, FALSE if not.

  @param  FvHandle              The handle of a FV that's being tested

  @retval TRUE                  Fv protocol on FvHandle has been processed
  @retval FALSE                 Fv protocol on FvHandle has not yet been
                                processed

**/
BOOLEAN
FvHasBeenProcessed (
  IN EFI_HANDLE  FvHandle
  )
{
  LIST_ENTRY    *Link;
  KNOWN_HANDLE  *KnownHandle;

  for (Link = mFvHandleList.ForwardLink; Link != &mFvHandleList; Link = Link->ForwardLink) {
    KnownHandle = CR (Link, KNOWN_HANDLE, Link, KNOWN_HANDLE_SIGNATURE);
    if (KnownHandle->Handle == FvHandle) {
      return TRUE;
    }
  }

  return FALSE;
}

/**
  Remember that Fv protocol on FvHandle has had its drivers placed on the
  mDiscoveredList. This function adds entries on the mFvHandleList. Items are
  never removed/freed from the mFvHandleList.

  @param  FvHandle              The handle of a FV that has been processed

**/
VOID
FvIsBeingProcessed (
  IN EFI_HANDLE  FvHandle
  )
{
  KNOWN_HANDLE  *KnownHandle;

  KnownHandle = AllocatePool (sizeof (KNOWN_HANDLE));
  ASSERT (KnownHandle != NULL);

  KnownHandle->Signature = KNOWN_HANDLE_SIGNATURE;
  KnownHandle->Handle    = FvHandle;
  InsertTailList (&mFvHandleList, &KnownHandle->Link);
}

/**
  Convert FvHandle and DriverName into an EFI device path

  @param  Fv                    Fv protocol, needed to read Depex info out of
                                FLASH.
  @param  FvHandle              Handle for Fv, needed in the
                                EFI_SMM_DRIVER_ENTRY so that the PE image can be
                                read out of the FV at a later time.
  @param  DriverName            Name of driver to add to mDiscoveredList.

  @return Pointer to device path constructed from FvHandle and DriverName

**/
EFI_DEVICE_PATH_PROTOCOL *
SmmFvToDevicePath (
  IN  EFI_FIRMWARE_VOLUME2_PROTOCOL  *Fv,
  IN  EFI_HANDLE                     FvHandle,
  IN  EFI_GUID                       *DriverName
  )
{
  EFI_STATUS                Status;
  EFI_DEVICE_PATH_PROTOCOL  *FvDevicePath;
  EFI_DEVICE_PATH_PROTOCOL  *FileNameDevicePath;

  //
  // Remember the device path of the FV
  //
  Status = gBS->HandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);
  if (EFI_ERROR (Status)) {
    FileNameDevicePath = NULL;
  } else {
    //
    // Build a device path to the file in the FV to pass into gBS->LoadImage
    //
    EfiInitializeFwVolDevicepathNode (&mFvDevicePath.File, DriverName);
    SetDevicePathEndNode (&mFvDevicePath.End);

    //
    // Note: FileNameDevicePath is in DXE memory
    //
    FileNameDevicePath = AppendDevicePath (
                           FvDevicePath,
                           (EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath
                           );
  }

  return FileNameDevicePath;
}

/**
  Add an entry to the mDiscoveredList. Allocate memory to store the DriverEntry,
  and initialize any state variables. Read the Depex from the FV and store it
  in DriverEntry. Pre-process the Depex to set the Before and After state.
  The Discovered list is never free'ed and contains booleans that represent the
  other possible SMM driver states.

  @param  Fv                    Fv protocol, needed to read Depex info out of
                                FLASH.
  @param  FvHandle              Handle for Fv, needed in the
                                EFI_SMM_DRIVER_ENTRY so that the PE image can be
                                read out of the FV at a later time.
  @param  DriverName            Name of driver to add to mDiscoveredList.

  @retval EFI_SUCCESS           If driver was added to the mDiscoveredList.
  @retval EFI_ALREADY_STARTED   The driver has already been started. Only one
                                DriverName may be active in the system at any one
                                time.

**/
EFI_STATUS
SmmAddToDriverList (
  IN EFI_FIRMWARE_VOLUME2_PROTOCOL  *Fv,
  IN EFI_HANDLE                     FvHandle,
  IN EFI_GUID                       *DriverName
  )
{
  EFI_SMM_DRIVER_ENTRY  *DriverEntry;

  //
  // Create the Driver Entry for the list. ZeroPool initializes lots of variables to
  // NULL or FALSE.
  //
  DriverEntry = AllocateZeroPool (sizeof (EFI_SMM_DRIVER_ENTRY));
  ASSERT (DriverEntry != NULL);

  DriverEntry->Signature = EFI_SMM_DRIVER_ENTRY_SIGNATURE;
  CopyGuid (&DriverEntry->FileName, DriverName);
  DriverEntry->FvHandle         = FvHandle;
  DriverEntry->Fv               = Fv;
  DriverEntry->FvFileDevicePath = SmmFvToDevicePath (Fv, FvHandle, DriverName);

  SmmGetDepexSectionAndPreProccess (DriverEntry);

  InsertTailList (&mDiscoveredList, &DriverEntry->Link);
  gRequestDispatch = TRUE;

  return EFI_SUCCESS;
}

/**
  This function is the main entry point for an SMM handler dispatch
  or communicate-based callback.

  Event notification that is fired every time a FV dispatch protocol is added.
  More than one protocol may have been added when this event is fired, so you
  must loop on SmmLocateHandle () to see how many protocols were added and
  do the following to each FV:
  If the Fv has already been processed, skip it. If the Fv has not been
  processed then mark it as being processed, as we are about to process it.
  Read the Fv and add any driver in the Fv to the mDiscoveredList.The
  mDiscoveredList is never free'ed and contains variables that define
  the other states the SMM driver transitions to..
  While you are at it read the A Priori file into memory.
  Place drivers in the A Priori list onto the mScheduledQueue.

  @param  DispatchHandle  The unique handle assigned to this handler by SmiHandlerRegister().
  @param  Context         Points to an optional handler context which was specified when the handler was registered.
  @param  CommBuffer      A pointer to a collection of data in memory that will
                          be conveyed from a non-SMM environment into an SMM environment.
  @param  CommBufferSize  The size of the CommBuffer.

  @return Status Code

**/
EFI_STATUS
EFIAPI
SmmDriverDispatchHandler (
  IN     EFI_HANDLE  DispatchHandle,
  IN     CONST VOID  *Context         OPTIONAL,
  IN OUT VOID        *CommBuffer      OPTIONAL,
  IN OUT UINTN       *CommBufferSize  OPTIONAL
  )
{
  EFI_STATUS                     Status;
  UINTN                          HandleCount;
  EFI_HANDLE                     *HandleBuffer;
  EFI_STATUS                     GetNextFileStatus;
  EFI_FIRMWARE_VOLUME2_PROTOCOL  *Fv;
  EFI_DEVICE_PATH_PROTOCOL       *FvDevicePath;
  EFI_HANDLE                     FvHandle;
  EFI_GUID                       NameGuid;
  UINTN                          Key;
  EFI_FV_FILETYPE                Type;
  EFI_FV_FILE_ATTRIBUTES         Attributes;
  UINTN                          Size;
  EFI_SMM_DRIVER_ENTRY           *DriverEntry;
  EFI_GUID                       *AprioriFile;
  UINTN                          AprioriEntryCount;
  UINTN                          HandleIndex;
  UINTN                          SmmTypeIndex;
  UINTN                          AprioriIndex;
  LIST_ENTRY                     *Link;
  UINT32                         AuthenticationStatus;
  UINTN                          SizeOfBuffer;

  HandleBuffer = NULL;
  Status       = gBS->LocateHandleBuffer (
                        ByProtocol,
                        &gEfiFirmwareVolume2ProtocolGuid,
                        NULL,
                        &HandleCount,
                        &HandleBuffer
                        );
  if (EFI_ERROR (Status)) {
    return EFI_NOT_FOUND;
  }

  PERF_CALLBACK_BEGIN (&gEfiEventDxeDispatchGuid);

  for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
    FvHandle = HandleBuffer[HandleIndex];

    if (FvHasBeenProcessed (FvHandle)) {
      //
      // This Fv has already been processed so lets skip it!
      //
      continue;
    }

    //
    // Since we are about to process this Fv mark it as processed.
    //
    FvIsBeingProcessed (FvHandle);

    Status = gBS->HandleProtocol (FvHandle, &gEfiFirmwareVolume2ProtocolGuid, (VOID **)&Fv);
    if (EFI_ERROR (Status)) {
      //
      // FvHandle must have a Firmware Volume2 Protocol thus we should never get here.
      //
      ASSERT (FALSE);
      continue;
    }

    Status = gBS->HandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);
    if (EFI_ERROR (Status)) {
      //
      // The Firmware volume doesn't have device path, can't be dispatched.
      //
      continue;
    }

    //
    // 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++) {
      //
      // Initialize the search key
      //
      Key = 0;
      do {
        Type              = mSmmFileTypes[SmmTypeIndex];
        GetNextFileStatus = Fv->GetNextFile (
                                  Fv,
                                  &Key,
                                  &Type,
                                  &NameGuid,
                                  &Attributes,
                                  &Size
                                  );
        if (!EFI_ERROR (GetNextFileStatus)) {
          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));
    }

    //
    // Read the array of GUIDs from the Apriori file if it is present in the firmware volume
    // (Note: AprioriFile is in DXE memory)
    //
    AprioriFile = NULL;
    Status      = Fv->ReadSection (
                        Fv,
                        &gAprioriGuid,
                        EFI_SECTION_RAW,
                        0,
                        (VOID **)&AprioriFile,
                        &SizeOfBuffer,
                        &AuthenticationStatus
                        );
    if (!EFI_ERROR (Status)) {
      AprioriEntryCount = SizeOfBuffer / sizeof (EFI_GUID);
    } else {
      AprioriEntryCount = 0;
    }

    //
    // Put drivers on Apriori List on the Scheduled queue. The Discovered List includes
    // drivers not in the current FV and these must be skipped since the a priori list
    // is only valid for the FV that it resided in.
    //

    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[AprioriIndex]) &&
            (FvHandle == DriverEntry->FvHandle))
        {
          DriverEntry->Dependent = FALSE;
          DriverEntry->Scheduled = TRUE;
          InsertTailList (&mScheduledQueue, &DriverEntry->ScheduledLink);
          DEBUG ((DEBUG_DISPATCH, "Evaluate SMM DEPEX for FFS(%g)\n", &DriverEntry->FileName));
          DEBUG ((DEBUG_DISPATCH, "  RESULT = TRUE (Apriori)\n"));
          break;
        }
      }
    }

    //
    // Free data allocated by 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
  // discovered SMM drivers that have been discovered but not dispatched.
  //
  Status = SmmDispatcher ();

  //
  // Check to see if CommBuffer and CommBufferSize are valid
  //
  if ((CommBuffer != NULL) && (CommBufferSize != NULL)) {
    if (*CommBufferSize > 0) {
      if (Status == EFI_NOT_READY) {
        //
        // 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;
      } else if (!EFI_ERROR (Status)) {
        //
        // Set the flag to show that the SMM Dispatcher executed without errors
        //
        *(UINT8 *)CommBuffer = COMM_BUFFER_SMM_DISPATCH_SUCCESS;
      } else {
        //
        // Set the flag to show that the SMM Dispatcher encountered an error
        //
        *(UINT8 *)CommBuffer = COMM_BUFFER_SMM_DISPATCH_ERROR;
      }
    }
  }

  PERF_CALLBACK_END (&gEfiEventDxeDispatchGuid);
  return EFI_SUCCESS;
}

/**
  Traverse the discovered list for any drivers that were discovered but not loaded
  because the dependency expressions evaluated to false.

**/
VOID
SmmDisplayDiscoveredNotDispatched (
  VOID
  )
{
  LIST_ENTRY            *Link;
  EFI_SMM_DRIVER_ENTRY  *DriverEntry;

  for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
    DriverEntry = CR (Link, EFI_SMM_DRIVER_ENTRY, Link, EFI_SMM_DRIVER_ENTRY_SIGNATURE);
    if (DriverEntry->Dependent) {
      DEBUG ((DEBUG_LOAD, "SMM Driver %g was discovered but not loaded!!\n", &DriverEntry->FileName));
    }
  }
}
