]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c
MdeModulePkg DxeCore: Fix issue to print GUID value %g without pointer
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / Dispatcher / Dispatcher.c
index 5a0efad1b79b05e1bd8a53c4b0b0eedf41e20111..5eee71bb2cd33ce6fd10dd72c183d76db9239b4d 100644 (file)
@@ -2,48 +2,48 @@
   DXE Dispatcher.\r
 \r
   Step #1 - When a FV protocol is added to the system every driver in the FV\r
-            is added to the mDiscoveredList. The SOR, Before, and After Depex are \r
-            pre-processed as drivers are added to the mDiscoveredList. If an Apriori \r
-            file exists in the FV those drivers are addeded to the \r
-            mScheduledQueue. The mFvHandleList is used to make sure a \r
+            is added to the mDiscoveredList. The SOR, Before, and After Depex are\r
+            pre-processed as drivers are added to the mDiscoveredList. If an Apriori\r
+            file exists in the FV those drivers are addeded to the\r
+            mScheduledQueue. The mFvHandleList is used to make sure a\r
             FV is only processed once.\r
 \r
   Step #2 - Dispatch. Remove driver from the mScheduledQueue and load and\r
-            start it. After mScheduledQueue is drained check the \r
-            mDiscoveredList to see if any item has a Depex that is ready to \r
+            start it. After mScheduledQueue is drained check the\r
+            mDiscoveredList to see if any item has a Depex that is ready to\r
             be placed on the mScheduledQueue.\r
 \r
-  Step #3 - Adding to the mScheduledQueue requires that you process Before \r
+  Step #3 - Adding to the mScheduledQueue requires that you process Before\r
             and After dependencies. This is done recursively as the call to add\r
-            to the mScheduledQueue checks for Before and recursively adds \r
-            all Befores. It then addes the item that was passed in and then \r
+            to the mScheduledQueue checks for Before and recursively adds\r
+            all Befores. It then addes the item that was passed in and then\r
             processess the After dependecies by recursively calling the routine.\r
 \r
   Dispatcher Rules:\r
-  The rules for the dispatcher are in chapter 10 of the DXE CIS. Figure 10-3 \r
+  The rules for the dispatcher are in chapter 10 of the DXE CIS. Figure 10-3\r
   is the state diagram for the DXE dispatcher\r
 \r
   Depex - Dependency Expresion.\r
   SOR   - Schedule On Request - Don't schedule if this bit is set.\r
 \r
-Copyright (c) 2006 - 2008, Intel Corporation                                                         \r
-All rights reserved. This program and the accompanying materials                          \r
-are licensed and made available under the terms and conditions of the BSD License         \r
-which accompanies this 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) 2006 - 2017, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this 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
 \r
 **/\r
 \r
-#include <DxeMain.h>\r
+#include "DxeMain.h"\r
 \r
 //\r
 // The Driver List contains one copy of every driver that has been discovered.\r
 // Items are never removed from the driver list. List of EFI_CORE_DRIVER_ENTRY\r
 //\r
-LIST_ENTRY  mDiscoveredList = INITIALIZE_LIST_HEAD_VARIABLE (mDiscoveredList);  \r
+LIST_ENTRY  mDiscoveredList = INITIALIZE_LIST_HEAD_VARIABLE (mDiscoveredList);\r
 \r
 //\r
 // Queue of drivers that are ready to dispatch. This queue is a subset of the\r
@@ -76,9 +76,10 @@ VOID            *mFwVolEventRegistration;
 //\r
 // List of file types supported by dispatcher\r
 //\r
-STATIC EFI_FV_FILETYPE mDxeFileTypes[] = { \r
-  EFI_FV_FILETYPE_DRIVER, \r
-  EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER, \r
+EFI_FV_FILETYPE mDxeFileTypes[] = {\r
+  EFI_FV_FILETYPE_DRIVER,\r
+  EFI_FV_FILETYPE_COMBINED_SMM_DXE,\r
+  EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER,\r
   EFI_FV_FILETYPE_DXE_CORE,\r
   EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE\r
 };\r
@@ -90,7 +91,6 @@ typedef struct {
 \r
 FV_FILEPATH_DEVICE_PATH mFvDevicePath;\r
 \r
-\r
 //\r
 // Function Prototypes\r
 //\r
@@ -105,12 +105,11 @@ FV_FILEPATH_DEVICE_PATH mFvDevicePath;
   @param  InsertedDriverEntry   The driver to insert on the ScheduledLink Queue\r
 \r
 **/\r
-STATIC\r
 VOID\r
 CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (\r
   IN  EFI_CORE_DRIVER_ENTRY   *InsertedDriverEntry\r
   );\r
\r
+\r
 /**\r
   Event notification that is fired every time a FV dispatch protocol is added.\r
   More than one protocol may have been added when this event is fired, so you\r
@@ -124,11 +123,10 @@ CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (
   While you are at it read the A Priori file into memory.\r
   Place drivers in the A Priori list onto the mScheduledQueue.\r
 \r
-  @param  Event                 The Event that is being processed, not used. \r
+  @param  Event                 The Event that is being processed, not used.\r
   @param  Context               Event Context, not used.\r
 \r
 **/\r
-STATIC\r
 VOID\r
 EFIAPI\r
 CoreFwVolEventProtocolNotify (\r
@@ -139,17 +137,16 @@ CoreFwVolEventProtocolNotify (
 /**\r
   Convert FvHandle and DriverName into an EFI device path\r
 \r
-  @param  Fv                    Fv protocol, needed to read Depex info out of \r
-                                FLASH. \r
-  @param  FvHandle              Handle for Fv, needed in the \r
-                                EFI_CORE_DRIVER_ENTRY so that the PE image can be \r
-                                read out of the FV at a later time. \r
-  @param  DriverName            Name of driver to add to mDiscoveredList. \r
+  @param  Fv                    Fv protocol, needed to read Depex info out of\r
+                                FLASH.\r
+  @param  FvHandle              Handle for Fv, needed in the\r
+                                EFI_CORE_DRIVER_ENTRY so that the PE image can be\r
+                                read out of the FV at a later time.\r
+  @param  DriverName            Name of driver to add to mDiscoveredList.\r
 \r
   @return Pointer to device path constructed from FvHandle and DriverName\r
 \r
 **/\r
-STATIC\r
 EFI_DEVICE_PATH_PROTOCOL *\r
 CoreFvToDevicePath (\r
   IN  EFI_FIRMWARE_VOLUME2_PROTOCOL   *Fv,\r
@@ -164,41 +161,41 @@ CoreFvToDevicePath (
   The Discovered list is never free'ed and contains booleans that represent the\r
   other possible DXE driver states.\r
 \r
-  @param  Fv                    Fv protocol, needed to read Depex info out of \r
-                                FLASH. \r
-  @param  FvHandle              Handle for Fv, needed in the \r
-                                EFI_CORE_DRIVER_ENTRY so that the PE image can be \r
-                                read out of the FV at a later time. \r
-  @param  DriverName            Name of driver to add to mDiscoveredList. \r
-\r
-  @retval EFI_SUCCESS           If driver was added to the mDiscoveredList. \r
-  @retval EFI_ALREADY_STARTED   The driver has already been started. Only one \r
-                                DriverName may be active in the system at any one \r
+  @param  Fv                    Fv protocol, needed to read Depex info out of\r
+                                FLASH.\r
+  @param  FvHandle              Handle for Fv, needed in the\r
+                                EFI_CORE_DRIVER_ENTRY so that the PE image can be\r
+                                read out of the FV at a later time.\r
+  @param  DriverName            Name of driver to add to mDiscoveredList.\r
+  @param  Type                  Fv File Type of file to add to mDiscoveredList.\r
+\r
+  @retval EFI_SUCCESS           If driver was added to the mDiscoveredList.\r
+  @retval EFI_ALREADY_STARTED   The driver has already been started. Only one\r
+                                DriverName may be active in the system at any one\r
                                 time.\r
 \r
 **/\r
-STATIC \r
 EFI_STATUS\r
 CoreAddToDriverList (\r
-  IN  EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv,\r
-  IN  EFI_HANDLE                    FvHandle,\r
-  IN  EFI_GUID                      *DriverName\r
+  IN  EFI_FIRMWARE_VOLUME2_PROTOCOL   *Fv,\r
+  IN  EFI_HANDLE                      FvHandle,\r
+  IN  EFI_GUID                        *DriverName,\r
+  IN  EFI_FV_FILETYPE                 Type\r
   );\r
 \r
 /**\r
   Get the driver from the FV through driver name, and produce a FVB protocol on FvHandle.\r
 \r
-  @param  Fv                    The FIRMWARE_VOLUME protocol installed on the FV. \r
-  @param  FvHandle              The handle which FVB protocol installed on. \r
-  @param  DriverName            The driver guid specified. \r
+  @param  Fv                    The FIRMWARE_VOLUME protocol installed on the FV.\r
+  @param  FvHandle              The handle which FVB protocol installed on.\r
+  @param  DriverName            The driver guid specified.\r
 \r
-  @retval EFI_OUT_OF_RESOURCES  No enough memory or other resource. \r
-  @retval EFI_VOLUME_CORRUPTED  Corrupted volume. \r
+  @retval EFI_OUT_OF_RESOURCES  No enough memory or other resource.\r
+  @retval EFI_VOLUME_CORRUPTED  Corrupted volume.\r
   @retval EFI_SUCCESS           Function successfully returned.\r
 \r
 **/\r
-STATIC\r
-EFI_STATUS \r
+EFI_STATUS\r
 CoreProcessFvImageFile (\r
   IN  EFI_FIRMWARE_VOLUME2_PROTOCOL   *Fv,\r
   IN  EFI_HANDLE                      FvHandle,\r
@@ -210,7 +207,6 @@ CoreProcessFvImageFile (
   Enter critical section by gaining lock on mDispatcherLock.\r
 \r
 **/\r
-STATIC\r
 VOID\r
 CoreAcquireDispatcherLock (\r
   VOID\r
@@ -224,7 +220,6 @@ CoreAcquireDispatcherLock (
   Exit critical section by releasing lock on mDispatcherLock.\r
 \r
 **/\r
-STATIC\r
 VOID\r
 CoreReleaseDispatcherLock (\r
   VOID\r
@@ -238,15 +233,14 @@ CoreReleaseDispatcherLock (
   Read Depex and pre-process the Depex for Before and After. If Section Extraction\r
   protocol returns an error via ReadSection defer the reading of the Depex.\r
 \r
-  @param  DriverEntry           Driver to work on. \r
+  @param  DriverEntry           Driver to work on.\r
 \r
-  @retval EFI_SUCCESS           Depex read and preprossesed \r
-  @retval EFI_PROTOCOL_ERROR    The section extraction protocol returned an error \r
-                                and  Depex reading needs to be retried. \r
+  @retval EFI_SUCCESS           Depex read and preprossesed\r
+  @retval EFI_PROTOCOL_ERROR    The section extraction protocol returned an error\r
+                                and  Depex reading needs to be retried.\r
   @retval Error                 DEPEX not found.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 CoreGetDepexSectionAndPreProccess (\r
   IN  EFI_CORE_DRIVER_ENTRY   *DriverEntry\r
@@ -257,7 +251,7 @@ CoreGetDepexSectionAndPreProccess (
   UINT32                        AuthenticationStatus;\r
   EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;\r
 \r
-  \r
+\r
   Fv = DriverEntry->Fv;\r
 \r
   //\r
@@ -265,11 +259,11 @@ CoreGetDepexSectionAndPreProccess (
   //\r
   SectionType         = EFI_SECTION_DXE_DEPEX;\r
   Status = Fv->ReadSection (\r
-                DriverEntry->Fv, \r
+                DriverEntry->Fv,\r
                 &DriverEntry->FileName,\r
-                SectionType, \r
-                0, \r
-                &DriverEntry->Depex, \r
+                SectionType,\r
+                0,\r
+                &DriverEntry->Depex,\r
                 (UINTN *)&DriverEntry->DepexSize,\r
                 &AuthenticationStatus\r
                 );\r
@@ -294,7 +288,7 @@ CoreGetDepexSectionAndPreProccess (
     //\r
     CorePreProcessDepex (DriverEntry);\r
     DriverEntry->DepexProtocolError = FALSE;\r
-  }  \r
+  }\r
 \r
   return Status;\r
 }\r
@@ -304,17 +298,16 @@ CoreGetDepexSectionAndPreProccess (
   Check every driver and locate a matching one. If the driver is found, the Unrequested\r
   state flag is cleared.\r
 \r
-  @param  FirmwareVolumeHandle  The handle of the Firmware Volume that contains \r
-                                the firmware  file specified by DriverName. \r
-  @param  DriverName            The Driver name to put in the Dependent state. \r
+  @param  FirmwareVolumeHandle  The handle of the Firmware Volume that contains\r
+                                the firmware  file specified by DriverName.\r
+  @param  DriverName            The Driver name to put in the Dependent state.\r
 \r
-  @retval EFI_SUCCESS           The DriverName was found and it's SOR bit was \r
-                                cleared \r
-  @retval EFI_NOT_FOUND         The DriverName does not exist or it's SOR bit was \r
-                                not set. \r
+  @retval EFI_SUCCESS           The DriverName was found and it's SOR bit was\r
+                                cleared\r
+  @retval EFI_NOT_FOUND         The DriverName does not exist or it's SOR bit was\r
+                                not set.\r
 \r
 **/\r
-EFI_DXESERVICE\r
 EFI_STATUS\r
 EFIAPI\r
 CoreSchedule (\r
@@ -331,7 +324,7 @@ CoreSchedule (
   for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {\r
     DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);\r
     if (DriverEntry->FvHandle == FirmwareVolumeHandle &&\r
-        DriverEntry->Unrequested && \r
+        DriverEntry->Unrequested &&\r
         CompareGuid (DriverName, &DriverEntry->FileName)) {\r
       //\r
       // Move the driver from the Unrequested to the Dependent state\r
@@ -340,28 +333,32 @@ CoreSchedule (
       DriverEntry->Unrequested  = FALSE;\r
       DriverEntry->Dependent    = TRUE;\r
       CoreReleaseDispatcherLock ();\r
-    \r
+\r
+      DEBUG ((DEBUG_DISPATCH, "Schedule FFS(%g) - EFI_SUCCESS\n", DriverName));\r
+      \r
       return EFI_SUCCESS;\r
     }\r
   }\r
-  return EFI_NOT_FOUND;  \r
+  \r
+  DEBUG ((DEBUG_DISPATCH, "Schedule FFS(%g) - EFI_NOT_FOUND\n", DriverName));\r
+  \r
+  return EFI_NOT_FOUND;\r
 }\r
 \r
 \r
 \r
 /**\r
-  Convert a driver from the Untrused back to the Scheduled state\r
+  Convert a driver from the Untrused back to the Scheduled state.\r
 \r
-  @param  FirmwareVolumeHandle  The handle of the Firmware Volume that contains \r
-                                the firmware  file specified by DriverName. \r
-  @param  DriverName            The Driver name to put in the Scheduled state \r
+  @param  FirmwareVolumeHandle  The handle of the Firmware Volume that contains\r
+                                the firmware  file specified by DriverName.\r
+  @param  DriverName            The Driver name to put in the Scheduled state\r
 \r
-  @retval EFI_SUCCESS           The file was found in the untrusted state, and it \r
-                                was promoted  to the trusted state. \r
-  @retval EFI_NOT_FOUND         The file was not found in the untrusted state. \r
+  @retval EFI_SUCCESS           The file was found in the untrusted state, and it\r
+                                was promoted  to the trusted state.\r
+  @retval EFI_NOT_FOUND         The file was not found in the untrusted state.\r
 \r
 **/\r
-EFI_DXESERVICE\r
 EFI_STATUS\r
 EFIAPI\r
 CoreTrust (\r
@@ -378,7 +375,7 @@ CoreTrust (
   for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {\r
     DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);\r
     if (DriverEntry->FvHandle == FirmwareVolumeHandle &&\r
-        DriverEntry->Untrusted && \r
+        DriverEntry->Untrusted &&\r
         CompareGuid (DriverName, &DriverEntry->FileName)) {\r
       //\r
       // Transition driver from Untrusted to Scheduled state.\r
@@ -388,15 +385,13 @@ CoreTrust (
       DriverEntry->Scheduled = TRUE;\r
       InsertTailList (&mScheduledQueue, &DriverEntry->ScheduledLink);\r
       CoreReleaseDispatcherLock ();\r
-    \r
+\r
       return EFI_SUCCESS;\r
     }\r
   }\r
-  return EFI_NOT_FOUND;  \r
+  return EFI_NOT_FOUND;\r
 }\r
 \r
-\r
-\r
 /**\r
   This is the main Dispatcher for DXE and it exits when there are no more\r
   drivers to run. Drain the mScheduledQueue and load and start a PE\r
@@ -406,14 +401,11 @@ CoreTrust (
   will be called, and when the Bds() exits the Dispatcher will be called\r
   again.\r
 \r
-  NONE\r
-\r
-  @retval EFI_ALREADY_STARTED   The DXE Dispatcher is already running \r
-  @retval EFI_NOT_FOUND         No DXE Drivers were dispatched \r
-  @retval EFI_SUCCESS           One or more DXE Drivers were dispatched \r
+  @retval EFI_ALREADY_STARTED   The DXE Dispatcher is already running\r
+  @retval EFI_NOT_FOUND         No DXE Drivers were dispatched\r
+  @retval EFI_SUCCESS           One or more DXE Drivers were dispatched\r
 \r
 **/\r
-EFI_DXESERVICE\r
 EFI_STATUS\r
 EFIAPI\r
 CoreDispatcher (\r
@@ -425,6 +417,8 @@ CoreDispatcher (
   LIST_ENTRY                      *Link;\r
   EFI_CORE_DRIVER_ENTRY           *DriverEntry;\r
   BOOLEAN                         ReadyToRun;\r
+  EFI_EVENT                       DxeDispatchEvent;\r
+  \r
 \r
   if (gDispatcherRunning) {\r
     //\r
@@ -435,6 +429,17 @@ CoreDispatcher (
 \r
   gDispatcherRunning = TRUE;\r
 \r
+  Status = CoreCreateEventEx (\r
+             EVT_NOTIFY_SIGNAL,\r
+             TPL_NOTIFY,\r
+             EfiEventEmptyFunction,\r
+             NULL,\r
+             &gEfiEventDxeDispatchGuid,\r
+             &DxeDispatchEvent\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
 \r
   ReturnStatus = EFI_NOT_FOUND;\r
   do {\r
@@ -454,13 +459,14 @@ CoreDispatcher (
       // Untrused to Scheduled it would have already been loaded so we may need to\r
       // skip the LoadImage\r
       //\r
-      if (DriverEntry->ImageHandle == NULL) {\r
+      if (DriverEntry->ImageHandle == NULL && !DriverEntry->IsFvImage) {\r
+        DEBUG ((DEBUG_INFO, "Loading driver %g\n", &DriverEntry->FileName));\r
         Status = CoreLoadImage (\r
-                        FALSE, \r
-                        gDxeCoreImageHandle, \r
+                        FALSE,\r
+                        gDxeCoreImageHandle,\r
                         DriverEntry->FvFileDevicePath,\r
-                        NULL, \r
-                        0, \r
+                        NULL,\r
+                        0,\r
                         &DriverEntry->ImageHandle\r
                         );\r
 \r
@@ -478,7 +484,7 @@ CoreDispatcher (
           } else {\r
             //\r
             // The DXE Driver could not be loaded, and do not attempt to load or start it again.\r
-            // Take driver from Scheduled to Initialized. \r
+            // Take driver from Scheduled to Initialized.\r
             //\r
             // This case include the Never Trusted state if EFI_ACCESS_DENIED is returned\r
             //\r
@@ -487,9 +493,9 @@ CoreDispatcher (
 \r
           DriverEntry->Scheduled = FALSE;\r
           RemoveEntryList (&DriverEntry->ScheduledLink);\r
-          \r
+\r
           CoreReleaseDispatcherLock ();\r
-        \r
+\r
           //\r
           // If it's an error don't try the StartImage\r
           //\r
@@ -502,22 +508,46 @@ CoreDispatcher (
       DriverEntry->Scheduled    = FALSE;\r
       DriverEntry->Initialized  = TRUE;\r
       RemoveEntryList (&DriverEntry->ScheduledLink);\r
-      \r
+\r
       CoreReleaseDispatcherLock ();\r
 \r
-      CoreReportProgressCodeSpecific (\r
-        FixedPcdGet32(PcdStatusCodeValueDxeDriverBegin), \r
-        DriverEntry->ImageHandle\r
-        );\r
-      Status = CoreStartImage (DriverEntry->ImageHandle, NULL, NULL);\r
-      CoreReportProgressCodeSpecific (\r
-        FixedPcdGet32(PcdStatusCodeValueDxeDriverEnd), \r
-        DriverEntry->ImageHandle\r
-        );\r
\r
+      if (DriverEntry->IsFvImage) {\r
+        //\r
+        // Produce a firmware volume block protocol for FvImage so it gets dispatched from. \r
+        //\r
+        Status = CoreProcessFvImageFile (DriverEntry->Fv, DriverEntry->FvHandle, &DriverEntry->FileName);\r
+      } else {\r
+        REPORT_STATUS_CODE_WITH_EXTENDED_DATA (\r
+          EFI_PROGRESS_CODE,\r
+          (EFI_SOFTWARE_DXE_CORE | EFI_SW_PC_INIT_BEGIN),\r
+          &DriverEntry->ImageHandle,\r
+          sizeof (DriverEntry->ImageHandle)\r
+          );\r
+        ASSERT (DriverEntry->ImageHandle != NULL);\r
+  \r
+        Status = CoreStartImage (DriverEntry->ImageHandle, NULL, NULL);\r
+  \r
+        REPORT_STATUS_CODE_WITH_EXTENDED_DATA (\r
+          EFI_PROGRESS_CODE,\r
+          (EFI_SOFTWARE_DXE_CORE | EFI_SW_PC_INIT_END),\r
+          &DriverEntry->ImageHandle,\r
+          sizeof (DriverEntry->ImageHandle)\r
+          );\r
+      }\r
 \r
       ReturnStatus = EFI_SUCCESS;\r
     }\r
 \r
+    //\r
+    // Now DXE Dispatcher finished one round of dispatch, signal an event group\r
+    // so that SMM Dispatcher get chance to dispatch SMM Drivers which depend\r
+    // on UEFI protocols\r
+    //\r
+    if (!EFI_ERROR (ReturnStatus)) {\r
+      CoreSignalEvent (DxeDispatchEvent);\r
+    }\r
+\r
     //\r
     // Search DriverList for items to place on Scheduled Queue\r
     //\r
@@ -530,17 +560,28 @@ CoreDispatcher (
         // If Section Extraction Protocol did not let the Depex be read before retry the read\r
         //\r
         Status = CoreGetDepexSectionAndPreProccess (DriverEntry);\r
-      } \r
+      }\r
 \r
       if (DriverEntry->Dependent) {\r
         if (CoreIsSchedulable (DriverEntry)) {\r
-          CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (DriverEntry); \r
+          CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (DriverEntry);\r
           ReadyToRun = TRUE;\r
-        } \r
+        }\r
+      } else {\r
+        if (DriverEntry->Unrequested) {\r
+          DEBUG ((DEBUG_DISPATCH, "Evaluate DXE DEPEX for FFS(%g)\n", &DriverEntry->FileName));\r
+          DEBUG ((DEBUG_DISPATCH, "  SOR                                             = Not Requested\n"));\r
+          DEBUG ((DEBUG_DISPATCH, "  RESULT = FALSE\n"));\r
+        }\r
       }\r
     }\r
   } while (ReadyToRun);\r
 \r
+  //\r
+  // Close DXE dispatch Event\r
+  //\r
+  CoreCloseEvent (DxeDispatchEvent);\r
+\r
   gDispatcherRunning = FALSE;\r
 \r
   return ReturnStatus;\r
@@ -558,7 +599,6 @@ CoreDispatcher (
   @param  InsertedDriverEntry   The driver to insert on the ScheduledLink Queue\r
 \r
 **/\r
-STATIC\r
 VOID\r
 CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (\r
   IN  EFI_CORE_DRIVER_ENTRY   *InsertedDriverEntry\r
@@ -572,12 +612,17 @@ CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (
   //\r
   for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {\r
     DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);\r
-    if (DriverEntry->Before && DriverEntry->Dependent) {\r
+    if (DriverEntry->Before && DriverEntry->Dependent && DriverEntry != InsertedDriverEntry) {\r
+      DEBUG ((DEBUG_DISPATCH, "Evaluate DXE DEPEX for FFS(%g)\n", &DriverEntry->FileName));\r
+      DEBUG ((DEBUG_DISPATCH, "  BEFORE FFS(%g) = ", &DriverEntry->BeforeAfterGuid));\r
       if (CompareGuid (&InsertedDriverEntry->FileName, &DriverEntry->BeforeAfterGuid)) {\r
         //\r
         // Recursively process BEFORE\r
         //\r
+        DEBUG ((DEBUG_DISPATCH, "TRUE\n  END\n  RESULT = TRUE\n"));\r
         CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (DriverEntry);\r
+      } else {\r
+        DEBUG ((DEBUG_DISPATCH, "FALSE\n  END\n  RESULT = FALSE\n"));\r
       }\r
     }\r
   }\r
@@ -590,7 +635,7 @@ CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (
   InsertedDriverEntry->Dependent = FALSE;\r
   InsertedDriverEntry->Scheduled = TRUE;\r
   InsertTailList (&mScheduledQueue, &InsertedDriverEntry->ScheduledLink);\r
-  \r
+\r
   CoreReleaseDispatcherLock ();\r
 \r
   //\r
@@ -598,12 +643,17 @@ CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (
   //\r
   for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {\r
     DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);\r
-    if (DriverEntry->After && DriverEntry->Dependent) {\r
+    if (DriverEntry->After && DriverEntry->Dependent && DriverEntry != InsertedDriverEntry) {\r
+      DEBUG ((DEBUG_DISPATCH, "Evaluate DXE DEPEX for FFS(%g)\n", &DriverEntry->FileName));\r
+      DEBUG ((DEBUG_DISPATCH, "  AFTER FFS(%g) = ", &DriverEntry->BeforeAfterGuid));\r
       if (CompareGuid (&InsertedDriverEntry->FileName, &DriverEntry->BeforeAfterGuid)) {\r
         //\r
         // Recursively process AFTER\r
         //\r
+        DEBUG ((DEBUG_DISPATCH, "TRUE\n  END\n  RESULT = TRUE\n"));\r
         CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (DriverEntry);\r
+      } else {\r
+        DEBUG ((DEBUG_DISPATCH, "FALSE\n  END\n  RESULT = FALSE\n"));\r
       }\r
     }\r
   }\r
@@ -613,14 +663,12 @@ CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (
 /**\r
   Return TRUE if the Fv has been processed, FALSE if not.\r
 \r
-  @param  FvHandle              The handle of a FV that's being tested \r
+  @param  FvHandle              The handle of a FV that's being tested\r
 \r
-  @retval TRUE                  Fv protocol on FvHandle has been processed \r
-  @retval FALSE                 Fv protocol on FvHandle has not yet been \r
-                                processed\r
+  @retval TRUE                  Fv protocol on FvHandle has been processed\r
+  @retval FALSE                 Fv protocol on FvHandle has not yet been processed\r
 \r
 **/\r
-STATIC\r
 BOOLEAN\r
 FvHasBeenProcessed (\r
   IN  EFI_HANDLE      FvHandle\r
@@ -641,26 +689,106 @@ FvHasBeenProcessed (
 \r
 /**\r
   Remember that Fv protocol on FvHandle has had it's drivers placed on the\r
-  mDiscoveredList. This fucntion adds entries on the mFvHandleList. Items are\r
-  never removed/freed from the mFvHandleList.\r
+  mDiscoveredList. This fucntion adds entries on the mFvHandleList if new \r
+  entry is different from one in mFvHandleList by checking FvImage Guid.\r
+  Items are never removed/freed from the mFvHandleList.\r
 \r
   @param  FvHandle              The handle of a FV that has been processed\r
 \r
+  @return A point to new added FvHandle entry. If FvHandle with the same FvImage guid\r
+          has been added, NULL will return. \r
+\r
 **/\r
-STATIC\r
-VOID\r
+KNOWN_HANDLE * \r
 FvIsBeingProcesssed (\r
   IN  EFI_HANDLE    FvHandle\r
   )\r
 {\r
-  KNOWN_HANDLE  *KnownHandle;\r
+  EFI_STATUS                            Status;\r
+  EFI_GUID                              FvNameGuid;\r
+  BOOLEAN                               FvNameGuidIsFound;\r
+  UINT32                                ExtHeaderOffset;\r
+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL    *Fvb;\r
+  EFI_FIRMWARE_VOLUME_HEADER            *FwVolHeader;\r
+  EFI_FV_BLOCK_MAP_ENTRY                *BlockMap;\r
+  UINTN                                 LbaOffset;\r
+  UINTN                                 Index;\r
+  EFI_LBA                               LbaIndex;\r
+  LIST_ENTRY                            *Link;\r
+  KNOWN_HANDLE                          *KnownHandle;\r
+\r
+  FwVolHeader = NULL;\r
+\r
+  //\r
+  // Get the FirmwareVolumeBlock protocol on that handle\r
+  //\r
+  FvNameGuidIsFound = FALSE;\r
+  Status = CoreHandleProtocol (FvHandle, &gEfiFirmwareVolumeBlockProtocolGuid, (VOID **)&Fvb);\r
+  if (!EFI_ERROR (Status)) {\r
+    //\r
+    // Get the full FV header based on FVB protocol.\r
+    //\r
+    ASSERT (Fvb != NULL);\r
+    Status = GetFwVolHeader (Fvb, &FwVolHeader);\r
+    if (!EFI_ERROR (Status)) {\r
+      ASSERT (FwVolHeader != NULL);\r
+      if (VerifyFvHeaderChecksum (FwVolHeader) && FwVolHeader->ExtHeaderOffset != 0) {\r
+        ExtHeaderOffset = (UINT32) FwVolHeader->ExtHeaderOffset;\r
+        BlockMap  = FwVolHeader->BlockMap;\r
+        LbaIndex  = 0;\r
+        LbaOffset = 0;\r
+        //\r
+        // Find LbaIndex and LbaOffset for FV extension header based on BlockMap.\r
+        //\r
+        while ((BlockMap->NumBlocks != 0) || (BlockMap->Length != 0)) {\r
+          for (Index = 0; Index < BlockMap->NumBlocks && ExtHeaderOffset >= BlockMap->Length; Index ++) {\r
+            ExtHeaderOffset -= BlockMap->Length;\r
+            LbaIndex ++;\r
+          }\r
+          //\r
+          // Check whether FvExtHeader is crossing the multi block range.\r
+          //\r
+          if (Index < BlockMap->NumBlocks) {\r
+            LbaOffset = ExtHeaderOffset;\r
+            break;\r
+          }\r
+          BlockMap++;\r
+        }\r
+        //\r
+        // Read FvNameGuid from FV extension header.\r
+        //\r
+        Status = ReadFvbData (Fvb, &LbaIndex, &LbaOffset, sizeof (FvNameGuid), (UINT8 *) &FvNameGuid);\r
+        if (!EFI_ERROR (Status)) {\r
+          FvNameGuidIsFound = TRUE;\r
+        }\r
+      }\r
+      CoreFreePool (FwVolHeader);\r
+    }\r
+  }\r
 \r
-  KnownHandle = CoreAllocateBootServicesPool (sizeof (KNOWN_HANDLE));\r
+  if (FvNameGuidIsFound) {\r
+    //\r
+    // Check whether the FV image with the found FvNameGuid has been processed.\r
+    //\r
+    for (Link = mFvHandleList.ForwardLink; Link != &mFvHandleList; Link = Link->ForwardLink) {\r
+      KnownHandle = CR(Link, KNOWN_HANDLE, Link, KNOWN_HANDLE_SIGNATURE);\r
+      if (CompareGuid (&FvNameGuid, &KnownHandle->FvNameGuid)) {\r
+        DEBUG ((EFI_D_ERROR, "FvImage on FvHandle %p and %p has the same FvNameGuid %g.\n", FvHandle, KnownHandle->Handle, &FvNameGuid));\r
+        return NULL;\r
+      }\r
+    }\r
+  }\r
+\r
+  KnownHandle = AllocateZeroPool (sizeof (KNOWN_HANDLE));\r
   ASSERT (KnownHandle != NULL);\r
 \r
   KnownHandle->Signature = KNOWN_HANDLE_SIGNATURE;\r
   KnownHandle->Handle = FvHandle;\r
+  if (FvNameGuidIsFound) {\r
+    CopyGuid (&KnownHandle->FvNameGuid, &FvNameGuid);\r
+  }\r
   InsertTailList (&mFvHandleList, &KnownHandle->Link);\r
+  return KnownHandle;\r
 }\r
 \r
 \r
@@ -669,17 +797,16 @@ FvIsBeingProcesssed (
 /**\r
   Convert FvHandle and DriverName into an EFI device path\r
 \r
-  @param  Fv                    Fv protocol, needed to read Depex info out of \r
-                                FLASH. \r
-  @param  FvHandle              Handle for Fv, needed in the \r
-                                EFI_CORE_DRIVER_ENTRY so that the PE image can be \r
-                                read out of the FV at a later time. \r
-  @param  DriverName            Name of driver to add to mDiscoveredList. \r
+  @param  Fv                    Fv protocol, needed to read Depex info out of\r
+                                FLASH.\r
+  @param  FvHandle              Handle for Fv, needed in the\r
+                                EFI_CORE_DRIVER_ENTRY so that the PE image can be\r
+                                read out of the FV at a later time.\r
+  @param  DriverName            Name of driver to add to mDiscoveredList.\r
 \r
   @return Pointer to device path constructed from FvHandle and DriverName\r
 \r
 **/\r
-STATIC\r
 EFI_DEVICE_PATH_PROTOCOL *\r
 CoreFvToDevicePath (\r
   IN  EFI_FIRMWARE_VOLUME2_PROTOCOL   *Fv,\r
@@ -702,12 +829,10 @@ CoreFvToDevicePath (
     // Build a device path to the file in the FV to pass into gBS->LoadImage\r
     //\r
     EfiInitializeFwVolDevicepathNode (&mFvDevicePath.File, DriverName);\r
-    mFvDevicePath.End.Type = EFI_END_ENTIRE_DEVICE_PATH;\r
-    mFvDevicePath.End.SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;\r
-    SetDevicePathNodeLength (&mFvDevicePath.End, sizeof (EFI_DEVICE_PATH_PROTOCOL));\r
+    SetDevicePathEndNode (&mFvDevicePath.End);\r
 \r
-    FileNameDevicePath = CoreAppendDevicePath (\r
-                            FvDevicePath, \r
+    FileNameDevicePath = AppendDevicePath (\r
+                            FvDevicePath,\r
                             (EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath\r
                             );\r
   }\r
@@ -717,7 +842,6 @@ CoreFvToDevicePath (
 \r
 \r
 \r
-\r
 /**\r
   Add an entry to the mDiscoveredList. Allocate memory to store the DriverEntry,\r
   and initilize any state variables. Read the Depex from the FV and store it\r
@@ -725,16 +849,17 @@ CoreFvToDevicePath (
   The Discovered list is never free'ed and contains booleans that represent the\r
   other possible DXE driver states.\r
 \r
-  @param  Fv                    Fv protocol, needed to read Depex info out of \r
-                                FLASH. \r
-  @param  FvHandle              Handle for Fv, needed in the \r
-                                EFI_CORE_DRIVER_ENTRY so that the PE image can be \r
-                                read out of the FV at a later time. \r
-  @param  DriverName            Name of driver to add to mDiscoveredList. \r
-\r
-  @retval EFI_SUCCESS           If driver was added to the mDiscoveredList. \r
-  @retval EFI_ALREADY_STARTED   The driver has already been started. Only one \r
-                                DriverName may be active in the system at any one \r
+  @param  Fv                    Fv protocol, needed to read Depex info out of\r
+                                FLASH.\r
+  @param  FvHandle              Handle for Fv, needed in the\r
+                                EFI_CORE_DRIVER_ENTRY so that the PE image can be\r
+                                read out of the FV at a later time.\r
+  @param  DriverName            Name of driver to add to mDiscoveredList.\r
+  @param  Type                  Fv File Type of file to add to mDiscoveredList.\r
+\r
+  @retval EFI_SUCCESS           If driver was added to the mDiscoveredList.\r
+  @retval EFI_ALREADY_STARTED   The driver has already been started. Only one\r
+                                DriverName may be active in the system at any one\r
                                 time.\r
 \r
 **/\r
@@ -742,29 +867,33 @@ EFI_STATUS
 CoreAddToDriverList (\r
   IN  EFI_FIRMWARE_VOLUME2_PROTOCOL   *Fv,\r
   IN  EFI_HANDLE                      FvHandle,\r
-  IN  EFI_GUID                        *DriverName\r
+  IN  EFI_GUID                        *DriverName,\r
+  IN  EFI_FV_FILETYPE                 Type\r
   )\r
 {\r
   EFI_CORE_DRIVER_ENTRY               *DriverEntry;\r
 \r
\r
+\r
   //\r
-  // Create the Driver Entry for the list. ZeroPool initializes lots of variables to \r
+  // Create the Driver Entry for the list. ZeroPool initializes lots of variables to\r
   // NULL or FALSE.\r
   //\r
-  DriverEntry = CoreAllocateZeroBootServicesPool (sizeof (EFI_CORE_DRIVER_ENTRY));\r
+  DriverEntry = AllocateZeroPool (sizeof (EFI_CORE_DRIVER_ENTRY));\r
   ASSERT (DriverEntry != NULL);\r
+  if (Type == EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) {\r
+    DriverEntry->IsFvImage = TRUE;\r
+  }\r
 \r
   DriverEntry->Signature        = EFI_CORE_DRIVER_ENTRY_SIGNATURE;\r
-  CopyMem (&DriverEntry->FileName, DriverName, sizeof (EFI_GUID));\r
+  CopyGuid (&DriverEntry->FileName, DriverName);\r
   DriverEntry->FvHandle         = FvHandle;\r
   DriverEntry->Fv               = Fv;\r
   DriverEntry->FvFileDevicePath = CoreFvToDevicePath (Fv, FvHandle, DriverName);\r
 \r
   CoreGetDepexSectionAndPreProccess (DriverEntry);\r
-  \r
+\r
   CoreAcquireDispatcherLock ();\r
-  \r
+\r
   InsertTailList (&mDiscoveredList, &DriverEntry->Link);\r
 \r
   CoreReleaseDispatcherLock ();\r
@@ -777,27 +906,30 @@ CoreAddToDriverList (
   Check if a FV Image type file (EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) is\r
   described by a EFI_HOB_FIRMWARE_VOLUME2 Hob.\r
 \r
-  @param  FvHandle              The handle which FVB protocol installed on. \r
-  @param  DriverName            The driver guid specified. \r
+  @param  FvNameGuid            The FV image guid specified.\r
+  @param  DriverName            The driver guid specified.\r
 \r
-  @retval TRUE                  This file is found in a EFI_HOB_FIRMWARE_VOLUME2 \r
-                                Hob. \r
+  @retval TRUE                  This file is found in a EFI_HOB_FIRMWARE_VOLUME2\r
+                                Hob.\r
   @retval FALSE                 Not found.\r
 \r
 **/\r
-STATIC\r
 BOOLEAN\r
 FvFoundInHobFv2 (\r
-  IN  EFI_HANDLE                      FvHandle,\r
+  IN  CONST EFI_GUID                  *FvNameGuid,\r
   IN  CONST EFI_GUID                  *DriverName\r
   )\r
 {\r
   EFI_PEI_HOB_POINTERS                HobFv2;\r
-  \r
+\r
   HobFv2.Raw = GetHobList ();\r
-  \r
+\r
   while ((HobFv2.Raw = GetNextHob (EFI_HOB_TYPE_FV2, HobFv2.Raw)) != NULL) {\r
-    if (CompareGuid (DriverName, &HobFv2.FirmwareVolume2->FileName)) {\r
+    //\r
+    // Compare parent FvNameGuid and FileGuid both.\r
+    //\r
+    if (CompareGuid (DriverName, &HobFv2.FirmwareVolume2->FileName) &&\r
+        CompareGuid (FvNameGuid, &HobFv2.FirmwareVolume2->FvName)) {\r
       return TRUE;\r
     }\r
     HobFv2.Raw = GET_NEXT_HOB (HobFv2);\r
@@ -811,16 +943,16 @@ FvFoundInHobFv2 (
 /**\r
   Get the driver from the FV through driver name, and produce a FVB protocol on FvHandle.\r
 \r
-  @param  Fv                    The FIRMWARE_VOLUME protocol installed on the FV. \r
-  @param  FvHandle              The handle which FVB protocol installed on. \r
-  @param  DriverName            The driver guid specified. \r
+  @param  Fv                    The FIRMWARE_VOLUME protocol installed on the FV.\r
+  @param  FvHandle              The handle which FVB protocol installed on.\r
+  @param  DriverName            The driver guid specified.\r
 \r
-  @retval EFI_OUT_OF_RESOURCES  No enough memory or other resource. \r
-  @retval EFI_VOLUME_CORRUPTED  Corrupted volume. \r
+  @retval EFI_OUT_OF_RESOURCES  No enough memory or other resource.\r
+  @retval EFI_VOLUME_CORRUPTED  Corrupted volume.\r
   @retval EFI_SUCCESS           Function successfully returned.\r
 \r
 **/\r
-EFI_STATUS \r
+EFI_STATUS\r
 CoreProcessFvImageFile (\r
   IN  EFI_FIRMWARE_VOLUME2_PROTOCOL   *Fv,\r
   IN  EFI_HANDLE                      FvHandle,\r
@@ -834,68 +966,111 @@ CoreProcessFvImageFile (
   VOID                                *AlignedBuffer;\r
   UINTN                               BufferSize;\r
   EFI_FIRMWARE_VOLUME_HEADER          *FvHeader;\r
-  UINT32                              FvAlignment;  \r
+  UINT32                              FvAlignment;\r
+  EFI_DEVICE_PATH_PROTOCOL            *FvFileDevicePath;\r
 \r
   //\r
   // Read the first (and only the first) firmware volume section\r
   //\r
-  SectionType = EFI_SECTION_FIRMWARE_VOLUME_IMAGE;\r
-  FvHeader    = NULL;\r
-  FvAlignment = 0;\r
-  Buffer      = NULL;\r
-  BufferSize  = 0;\r
+  SectionType   = EFI_SECTION_FIRMWARE_VOLUME_IMAGE;\r
+  FvHeader      = NULL;\r
+  FvAlignment   = 0;\r
+  Buffer        = NULL;\r
+  BufferSize    = 0;\r
   AlignedBuffer = NULL;\r
   Status = Fv->ReadSection (\r
-                Fv, \r
-                DriverName, \r
-                SectionType, \r
-                0, \r
-                &Buffer, \r
-                &BufferSize,\r
-                &AuthenticationStatus\r
-                );\r
+                 Fv,\r
+                 DriverName,\r
+                 SectionType,\r
+                 0,\r
+                 &Buffer,\r
+                 &BufferSize,\r
+                 &AuthenticationStatus\r
+                 );\r
   if (!EFI_ERROR (Status)) {\r
+     //\r
+    // Evaluate the authentication status of the Firmware Volume through\r
+    // Security Architectural Protocol\r
+    //\r
+    if (gSecurity != NULL) {\r
+      FvFileDevicePath = CoreFvToDevicePath (Fv, FvHandle, DriverName);\r
+      Status = gSecurity->FileAuthenticationState (\r
+                            gSecurity,\r
+                            AuthenticationStatus,\r
+                            FvFileDevicePath\r
+                            );\r
+      if (FvFileDevicePath != NULL) {\r
+        FreePool (FvFileDevicePath);\r
+      }\r
+\r
+      if (Status != EFI_SUCCESS) {\r
+        //\r
+        // Security check failed. The firmware volume should not be used for any purpose.\r
+        //\r
+        if (Buffer != NULL) {\r
+          FreePool (Buffer);\r
+        }\r
+        return Status;\r
+      }\r
+    }\r
+\r
     //\r
     // FvImage should be at its required alignment.\r
     //\r
     FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) Buffer;\r
-    FvAlignment = 1 << ((FvHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16);\r
     //\r
-    // FvAlignment must be more than 8 bytes required by FvHeader structure.\r
-    // \r
-    if (FvAlignment < 8) {\r
-      FvAlignment = 8;\r
-    }\r
-    AlignedBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES (BufferSize), (UINTN) FvAlignment);\r
-    if (AlignedBuffer == NULL) {\r
-      Status = EFI_OUT_OF_RESOURCES;\r
-    } else {\r
+    // If EFI_FVB2_WEAK_ALIGNMENT is set in the volume header then the first byte of the volume\r
+    // can be aligned on any power-of-two boundary. A weakly aligned volume can not be moved from\r
+    // its initial linked location and maintain its alignment.\r
+    //\r
+    if ((FvHeader->Attributes & EFI_FVB2_WEAK_ALIGNMENT) != EFI_FVB2_WEAK_ALIGNMENT) {\r
       //\r
-      // Move FvImage into the aligned buffer and release the original buffer.\r
+      // Get FvHeader alignment\r
       //\r
-      CopyMem (AlignedBuffer, Buffer, BufferSize);\r
-      CoreFreePool (Buffer);\r
-      Buffer = NULL;\r
+      FvAlignment = 1 << ((FvHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16);\r
       //\r
-      // Produce a FVB protocol for the file\r
+      // FvAlignment must be greater than or equal to 8 bytes of the minimum FFS alignment value.\r
       //\r
-      Status = ProduceFVBProtocolOnBuffer (\r
-                (EFI_PHYSICAL_ADDRESS) (UINTN) AlignedBuffer,\r
-                (UINT64)BufferSize,\r
-                FvHandle,\r
-                NULL\r
-                );\r
+      if (FvAlignment < 8) {\r
+        FvAlignment = 8;\r
+      }\r
+      //\r
+      // Allocate the aligned buffer for the FvImage.\r
+      //\r
+      AlignedBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES (BufferSize), (UINTN) FvAlignment);\r
+      if (AlignedBuffer == NULL) {\r
+        FreePool (Buffer);\r
+        return EFI_OUT_OF_RESOURCES;\r
+      } else {\r
+        //\r
+        // Move FvImage into the aligned buffer and release the original buffer.\r
+        //\r
+        CopyMem (AlignedBuffer, Buffer, BufferSize);\r
+        FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) AlignedBuffer;\r
+        CoreFreePool (Buffer);\r
+        Buffer = NULL;\r
+      }\r
     }\r
+    //\r
+    // Produce a FVB protocol for the file\r
+    //\r
+    Status = ProduceFVBProtocolOnBuffer (\r
+              (EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader,\r
+              (UINT64)BufferSize,\r
+              FvHandle,\r
+              AuthenticationStatus,\r
+              NULL\r
+              );\r
   }\r
 \r
-  if (EFI_ERROR (Status)) {    \r
+  if (EFI_ERROR (Status)) {\r
     //\r
     // ReadSection or Produce FVB failed, Free data buffer\r
     //\r
     if (Buffer != NULL) {\r
-      CoreFreePool (Buffer); \r
+      FreePool (Buffer);\r
     }\r
-    \r
+\r
     if (AlignedBuffer != NULL) {\r
       FreeAlignedPages (AlignedBuffer, EFI_SIZE_TO_PAGES (BufferSize));\r
     }\r
@@ -918,11 +1093,10 @@ CoreProcessFvImageFile (
   While you are at it read the A Priori file into memory.\r
   Place drivers in the A Priori list onto the mScheduledQueue.\r
 \r
-  @param  Event                 The Event that is being processed, not used. \r
+  @param  Event                 The Event that is being processed, not used.\r
   @param  Context               Event Context, not used.\r
 \r
 **/\r
-STATIC\r
 VOID\r
 EFIAPI\r
 CoreFwVolEventProtocolNotify (\r
@@ -932,7 +1106,6 @@ CoreFwVolEventProtocolNotify (
 {\r
   EFI_STATUS                    Status;\r
   EFI_STATUS                    GetNextFileStatus;\r
-  EFI_STATUS                    SecurityStatus;\r
   EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;\r
   EFI_DEVICE_PATH_PROTOCOL      *FvDevicePath;\r
   EFI_HANDLE                    FvHandle;\r
@@ -949,17 +1122,20 @@ CoreFwVolEventProtocolNotify (
   LIST_ENTRY                    *Link;\r
   UINT32                        AuthenticationStatus;\r
   UINTN                         SizeOfBuffer;\r
+  VOID                          *DepexBuffer;\r
+  KNOWN_HANDLE                  *KnownHandle;\r
 \r
+  FvHandle = NULL;\r
 \r
   while (TRUE) {\r
     BufferSize = sizeof (EFI_HANDLE);\r
     Status = CoreLocateHandle (\r
-                    ByRegisterNotify,\r
-                    NULL,\r
-                    mFwVolEventRegistration,\r
-                    &BufferSize,\r
-                    &FvHandle\r
-                    );\r
+               ByRegisterNotify,\r
+               NULL,\r
+               mFwVolEventRegistration,\r
+               &BufferSize,\r
+               &FvHandle\r
+               );\r
     if (EFI_ERROR (Status)) {\r
       //\r
       // If no more notification events exit\r
@@ -974,31 +1150,27 @@ CoreFwVolEventProtocolNotify (
       continue;\r
     }\r
 \r
-    Status = CoreHandleProtocol (FvHandle, &gEfiFirmwareVolumeDispatchProtocolGuid, (VOID **)&Fv);\r
-    if (EFI_ERROR (Status)) {\r
+    //\r
+    // Since we are about to process this Fv mark it as processed.\r
+    //\r
+    KnownHandle = FvIsBeingProcesssed (FvHandle);\r
+    if (KnownHandle == NULL) {\r
       //\r
-      // If no dispatch protocol then skip, but do not marked as being processed as it\r
-      // may show up later.\r
+      // The FV with the same FV name guid has already been processed. \r
+      // So lets skip it!\r
       //\r
       continue;\r
     }\r
 \r
-    //\r
-    // Since we are about to process this Fv mark it as processed.\r
-    //\r
-    FvIsBeingProcesssed (FvHandle);\r
-\r
-\r
     Status = CoreHandleProtocol (FvHandle, &gEfiFirmwareVolume2ProtocolGuid, (VOID **)&Fv);\r
-    if (EFI_ERROR (Status)) {\r
+    if (EFI_ERROR (Status) || Fv == NULL) {\r
       //\r
-      // The Handle has a FirmwareVolumeDispatch protocol and should also contiain\r
-      // a FirmwareVolume protocol thus we should never get here.\r
+      // FvHandle must have Firmware Volume2 protocol thus we should never get here.\r
       //\r
       ASSERT (FALSE);\r
       continue;\r
     }\r
-    \r
+\r
     Status = CoreHandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);\r
     if (EFI_ERROR (Status)) {\r
       //\r
@@ -1006,32 +1178,14 @@ CoreFwVolEventProtocolNotify (
       //\r
       continue;\r
     }\r
-    \r
-    //\r
-    // Evaluate the authentication status of the Firmware Volume through \r
-    // Security Architectural Protocol\r
-    //\r
-    if (gSecurity != NULL) {\r
-      SecurityStatus = gSecurity->FileAuthenticationState (\r
-                                    gSecurity, \r
-                                    0, \r
-                                    FvDevicePath\r
-                                    );\r
-      if (SecurityStatus != EFI_SUCCESS) {\r
-        //\r
-        // Security check failed. The firmware volume should not be used for any purpose.\r
-        //\r
-        continue;\r
-      }\r
-    }   \r
-    \r
+\r
     //\r
-    // Discover Drivers in FV and add them to the Discovered Driver List. \r
-    // Process EFI_FV_FILETYPE_DRIVER type and then EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER \r
+    // Discover Drivers in FV and add them to the Discovered Driver List.\r
+    // Process EFI_FV_FILETYPE_DRIVER type and then EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER\r
     //  EFI_FV_FILETYPE_DXE_CORE is processed to produce a Loaded Image protocol for the core\r
     //  EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE is processed to create a Fvb\r
     //\r
-    for (Index = 0; Index < sizeof (mDxeFileTypes)/sizeof (EFI_FV_FILETYPE); Index++) {\r
+    for (Index = 0; Index < sizeof (mDxeFileTypes) / sizeof (EFI_FV_FILETYPE); Index++) {\r
       //\r
       // Initialize the search key\r
       //\r
@@ -1039,11 +1193,11 @@ CoreFwVolEventProtocolNotify (
       do {\r
         Type = mDxeFileTypes[Index];\r
         GetNextFileStatus = Fv->GetNextFile (\r
-                                  Fv, \r
+                                  Fv,\r
                                   &Key,\r
-                                  &Type,  \r
-                                  &NameGuid, \r
-                                  &Attributes, \r
+                                  &Type,\r
+                                  &NameGuid,\r
+                                  &Attributes,\r
                                   &Size\r
                                   );\r
         if (!EFI_ERROR (GetNextFileStatus)) {\r
@@ -1058,11 +1212,9 @@ CoreFwVolEventProtocolNotify (
                 // be initialized completely.\r
                 //\r
                 EfiInitializeFwVolDevicepathNode (&mFvDevicePath.File, &NameGuid);\r
-                mFvDevicePath.End.Type = EFI_END_ENTIRE_DEVICE_PATH;\r
-                mFvDevicePath.End.SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;\r
-                SetDevicePathNodeLength (&mFvDevicePath.End, sizeof (EFI_DEVICE_PATH_PROTOCOL));\r
+                SetDevicePathEndNode (&mFvDevicePath.End);\r
 \r
-                gDxeCoreLoadedImage->FilePath = CoreDuplicateDevicePath (\r
+                gDxeCoreLoadedImage->FilePath = DuplicateDevicePath (\r
                                                   (EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath\r
                                                   );\r
                 gDxeCoreLoadedImage->DeviceHandle = FvHandle;\r
@@ -1070,28 +1222,72 @@ CoreFwVolEventProtocolNotify (
             }\r
           } else if (Type == EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) {\r
             //\r
-            // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already \r
+            // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already\r
             // been extracted.\r
             //\r
-            if (FvFoundInHobFv2 (FvHandle, &NameGuid)) {\r
+            if (FvFoundInHobFv2 (&KnownHandle->FvNameGuid, &NameGuid)) {\r
               continue;\r
             }\r
+\r
+            //\r
+            // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has SMM depex section.\r
+            //\r
+            DepexBuffer  = NULL;\r
+            SizeOfBuffer = 0;\r
+            Status = Fv->ReadSection (\r
+                           Fv,\r
+                           &NameGuid,\r
+                           EFI_SECTION_SMM_DEPEX,\r
+                           0,\r
+                           &DepexBuffer,\r
+                           &SizeOfBuffer,\r
+                           &AuthenticationStatus\r
+                           );\r
+            if (!EFI_ERROR (Status)) {\r
+              //\r
+              // If SMM depex section is found, this FV image is invalid to be supported.\r
+              // ASSERT FALSE to report this FV image.  \r
+              //\r
+              FreePool (DepexBuffer);\r
+              ASSERT (FALSE);\r
+            }\r
+\r
             //\r
-            // Found a firmware volume image. Produce a firmware volume block\r
-            // protocol for it so it gets dispatched from. This is usually a \r
-            // capsule.\r
+            // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has DXE depex section.\r
             //\r
-            CoreProcessFvImageFile (Fv, FvHandle, &NameGuid);\r
+            DepexBuffer  = NULL;\r
+            SizeOfBuffer = 0;\r
+            Status = Fv->ReadSection (\r
+                           Fv,\r
+                           &NameGuid,\r
+                           EFI_SECTION_DXE_DEPEX,\r
+                           0,\r
+                           &DepexBuffer,\r
+                           &SizeOfBuffer,\r
+                           &AuthenticationStatus\r
+                           );\r
+            if (EFI_ERROR (Status)) {\r
+              //\r
+              // If no depex section, produce a firmware volume block protocol for it so it gets dispatched from. \r
+              //\r
+              CoreProcessFvImageFile (Fv, FvHandle, &NameGuid);\r
+            } else {\r
+              //\r
+              // If depex section is found, this FV image will be dispatched until its depex is evaluated to TRUE.\r
+              //\r
+              FreePool (DepexBuffer);\r
+              CoreAddToDriverList (Fv, FvHandle, &NameGuid, Type);\r
+            }\r
           } else {\r
             //\r
             // Transition driver from Undiscovered to Discovered state\r
             //\r
-            CoreAddToDriverList (Fv, FvHandle, &NameGuid);\r
+            CoreAddToDriverList (Fv, FvHandle, &NameGuid, Type);\r
           }\r
         }\r
       } while (!EFI_ERROR (GetNextFileStatus));\r
     }\r
-    \r
+\r
     //\r
     // Read the array of GUIDs from the Apriori file if it is present in the firmware volume\r
     //\r
@@ -1116,27 +1312,28 @@ CoreFwVolEventProtocolNotify (
     // drivers not in the current FV and these must be skipped since the a priori list\r
     // is only valid for the FV that it resided in.\r
     //\r
-    CoreAcquireDispatcherLock ();\r
-    \r
+\r
     for (Index = 0; Index < AprioriEntryCount; Index++) {\r
       for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {\r
         DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);\r
         if (CompareGuid (&DriverEntry->FileName, &AprioriFile[Index]) &&\r
             (FvHandle == DriverEntry->FvHandle)) {\r
+          CoreAcquireDispatcherLock ();\r
           DriverEntry->Dependent = FALSE;\r
           DriverEntry->Scheduled = TRUE;\r
           InsertTailList (&mScheduledQueue, &DriverEntry->ScheduledLink);\r
+          CoreReleaseDispatcherLock ();\r
+          DEBUG ((DEBUG_DISPATCH, "Evaluate DXE DEPEX for FFS(%g)\n", &DriverEntry->FileName));\r
+          DEBUG ((DEBUG_DISPATCH, "  RESULT = TRUE (Apriori)\n"));\r
           break;\r
         }\r
       }\r
     }\r
 \r
-    CoreReleaseDispatcherLock ();\r
-\r
     //\r
-    // Free data allocated by Fv->ReadSection () \r
+    // Free data allocated by Fv->ReadSection ()\r
     //\r
-    CoreFreePool (AprioriFile);  \r
+    CoreFreePool (AprioriFile);\r
   }\r
 }\r
 \r
@@ -1144,7 +1341,7 @@ CoreFwVolEventProtocolNotify (
 \r
 /**\r
   Initialize the dispatcher. Initialize the notification function that runs when\r
-  a FV protocol is added to the system.\r
+  an FV2 protocol is added to the system.\r
 \r
 **/\r
 VOID\r
@@ -1152,13 +1349,12 @@ CoreInitializeDispatcher (
   VOID\r
   )\r
 {\r
-  mFwVolEvent = CoreCreateProtocolNotifyEvent (\r
-                  &gEfiFirmwareVolume2ProtocolGuid, \r
+  mFwVolEvent = EfiCreateProtocolNotifyEvent (\r
+                  &gEfiFirmwareVolume2ProtocolGuid,\r
                   TPL_CALLBACK,\r
                   CoreFwVolEventProtocolNotify,\r
                   NULL,\r
-                  &mFwVolEventRegistration,\r
-                  TRUE\r
+                  &mFwVolEventRegistration\r
                   );\r
 }\r
 \r