Check in DxeCore for Nt32 platform. Currently, it does not follow PI/UEFI2.1.
authoryshang1 <yshang1@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 4 Jul 2007 10:51:54 +0000 (10:51 +0000)
committeryshang1 <yshang1@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 4 Jul 2007 10:51:54 +0000 (10:51 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3045 6f19259b-4bc3-4df7-8a09-765794883524

42 files changed:
MdeModulePkg/Core/Dxe/DebugImageInfo.h [new file with mode: 0644]
MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c [new file with mode: 0644]
MdeModulePkg/Core/Dxe/Dispatcher/dependency.c [new file with mode: 0644]
MdeModulePkg/Core/Dxe/DxeMain.h [new file with mode: 0644]
MdeModulePkg/Core/Dxe/DxeMain.inf [new file with mode: 0644]
MdeModulePkg/Core/Dxe/DxeMain.msa [new file with mode: 0644]
MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c [new file with mode: 0644]
MdeModulePkg/Core/Dxe/DxeMain/DxeProtocolNotify.c [new file with mode: 0644]
MdeModulePkg/Core/Dxe/Event/event.c [new file with mode: 0644]
MdeModulePkg/Core/Dxe/Event/execdata.c [new file with mode: 0644]
MdeModulePkg/Core/Dxe/Event/timer.c [new file with mode: 0644]
MdeModulePkg/Core/Dxe/Event/tpl.c [new file with mode: 0644]
MdeModulePkg/Core/Dxe/Exec.h [new file with mode: 0644]
MdeModulePkg/Core/Dxe/FwVol/Ffs.c [new file with mode: 0644]
MdeModulePkg/Core/Dxe/FwVol/FwVol.c [new file with mode: 0644]
MdeModulePkg/Core/Dxe/FwVol/FwVolAttrib.c [new file with mode: 0644]
MdeModulePkg/Core/Dxe/FwVol/FwVolRead.c [new file with mode: 0644]
MdeModulePkg/Core/Dxe/FwVol/FwVolWrite.c [new file with mode: 0644]
MdeModulePkg/Core/Dxe/FwVolBlock.h [new file with mode: 0644]
MdeModulePkg/Core/Dxe/FwVolBlock/FwVolBlock.c [new file with mode: 0644]
MdeModulePkg/Core/Dxe/FwVolDriver.h [new file with mode: 0644]
MdeModulePkg/Core/Dxe/Gcd/gcd.c [new file with mode: 0644]
MdeModulePkg/Core/Dxe/Hand/DriverSupport.c [new file with mode: 0644]
MdeModulePkg/Core/Dxe/Hand/Notify.c [new file with mode: 0644]
MdeModulePkg/Core/Dxe/Hand/handle.c [new file with mode: 0644]
MdeModulePkg/Core/Dxe/Hand/locate.c [new file with mode: 0644]
MdeModulePkg/Core/Dxe/Image.h [new file with mode: 0644]
MdeModulePkg/Core/Dxe/Image/Image.c [new file with mode: 0644]
MdeModulePkg/Core/Dxe/Image/ImageFile.c [new file with mode: 0644]
MdeModulePkg/Core/Dxe/Library.h [new file with mode: 0644]
MdeModulePkg/Core/Dxe/Library/Library.c [new file with mode: 0644]
MdeModulePkg/Core/Dxe/Mem/Page.c [new file with mode: 0644]
MdeModulePkg/Core/Dxe/Mem/memdata.c [new file with mode: 0644]
MdeModulePkg/Core/Dxe/Mem/pool.c [new file with mode: 0644]
MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c [new file with mode: 0644]
MdeModulePkg/Core/Dxe/Misc/InstallConfigurationTable.c [new file with mode: 0644]
MdeModulePkg/Core/Dxe/Misc/SetWatchdogTimer.c [new file with mode: 0644]
MdeModulePkg/Core/Dxe/Misc/Stall.c [new file with mode: 0644]
MdeModulePkg/Core/Dxe/SectionExtraction/CoreSectionExtraction.c [new file with mode: 0644]
MdeModulePkg/Core/Dxe/gcd.h [new file with mode: 0644]
MdeModulePkg/Core/Dxe/hand.h [new file with mode: 0644]
MdeModulePkg/Core/Dxe/imem.h [new file with mode: 0644]

diff --git a/MdeModulePkg/Core/Dxe/DebugImageInfo.h b/MdeModulePkg/Core/Dxe/DebugImageInfo.h
new file mode 100644 (file)
index 0000000..006f629
--- /dev/null
@@ -0,0 +1,126 @@
+/*++\r
+\r
+Copyright (c) 2006, 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
+\r
+Module Name:\r
+\r
+  DebugImageInfo.h\r
+    \r
+Abstract:\r
+\r
+  Support functions for managing debug image info table when loading and unloading\r
+  images.\r
+\r
+--*/\r
+\r
+#ifndef __DEBUG_IMAGE_INFO_H__\r
+#define __DEBUG_IMAGE_INFO_H__\r
+\r
+#define FOUR_MEG_PAGES  0x400  \r
+#define FOUR_MEG_MASK   ((FOUR_MEG_PAGES * EFI_PAGE_SIZE) - 1)\r
+\r
+#define EFI_DEBUG_TABLE_ENTRY_SIZE       (sizeof (VOID *))\r
+\r
+VOID\r
+CoreInitializeDebugImageInfoTable (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Creates and initializes the DebugImageInfo Table.  Also creates the configuration\r
+  table and registers it into the system table.\r
+\r
+Arguments:\r
+  None\r
+\r
+Returns:\r
+  NA\r
+\r
+Notes:\r
+  This function allocates memory, frees it, and then allocates memory at an\r
+  address within the initial allocation. Since this function is called early\r
+  in DXE core initialization (before drivers are dispatched), this should not\r
+  be a problem.\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+CoreUpdateDebugTableCrc32 (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Update the CRC32 in the Debug Table.\r
+  Since the CRC32 service is made available by the Runtime driver, we have to\r
+  wait for the Runtime Driver to be installed before the CRC32 can be computed.\r
+  This function is called elsewhere by the core when the runtime architectural\r
+  protocol is produced.\r
+\r
+Arguments:\r
+  None\r
+\r
+Returns:\r
+  NA\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+CoreNewDebugImageInfoEntry (\r
+  UINT32                    ImageInfoType,\r
+  EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,\r
+  EFI_HANDLE                ImageHandle\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Adds a new DebugImageInfo structure to the DebugImageInfo Table.  Re-Allocates\r
+  the table if it's not large enough to accomidate another entry.\r
+\r
+Arguments:\r
+\r
+  ImageInfoType     - type of debug image information\r
+  LoadedImage       - pointer to the loaded image protocol for the image being loaded\r
+  ImageHandle       - image handle for the image being loaded\r
+\r
+Returns:\r
+  NA\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+CoreRemoveDebugImageInfoEntry (\r
+  EFI_HANDLE ImageHandle\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Removes and frees an entry from the DebugImageInfo Table.\r
+\r
+Arguments:\r
+\r
+  ImageHandle       - image handle for the image being unloaded\r
+\r
+Returns:\r
+\r
+  NA\r
+\r
+--*/\r
+;\r
+\r
+#endif\r
diff --git a/MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c b/MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c
new file mode 100644 (file)
index 0000000..9792a16
--- /dev/null
@@ -0,0 +1,1170 @@
+/*++\r
+\r
+Copyright (c) 2006, 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
+\r
+Module Name:\r
+\r
+  Dispatcher.c\r
+\r
+Abstract:\r
+\r
+  Tiano 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
+            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
+            be placed on the mScheduledQueue.\r
+\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
+            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
+  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
+--*/\r
+\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
+\r
+//\r
+// Queue of drivers that are ready to dispatch. This queue is a subset of the\r
+// mDiscoveredList.list of EFI_CORE_DRIVER_ENTRY.\r
+//\r
+LIST_ENTRY  mScheduledQueue = INITIALIZE_LIST_HEAD_VARIABLE (mScheduledQueue);\r
+\r
+//\r
+// List of handles who's Fv's have been parsed and added to the mFwDriverList.\r
+//\r
+LIST_ENTRY  mFvHandleList = INITIALIZE_LIST_HEAD_VARIABLE (mFvHandleList);           // list of KNOWN_HANDLE\r
+\r
+//\r
+// Lock for mDiscoveredList, mScheduledQueue, gDispatcherRunning.\r
+//\r
+EFI_LOCK  mDispatcherLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_HIGH_LEVEL);\r
+\r
+\r
+//\r
+// Flag for the DXE Dispacher.  TRUE if dispatcher is execuing.\r
+//\r
+BOOLEAN  gDispatcherRunning = FALSE;\r
+\r
+//\r
+// Module globals to manage the FwVol registration notification event\r
+//\r
+EFI_EVENT       mFwVolEvent;\r
+VOID            *mFwVolEventRegistration;\r
+\r
+//\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_DXE_CORE,\r
+  EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE\r
+};\r
+\r
+typedef struct {\r
+  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH   File;\r
+  EFI_DEVICE_PATH_PROTOCOL            End;\r
+} FV_FILEPATH_DEVICE_PATH;\r
+\r
+FV_FILEPATH_DEVICE_PATH mFvDevicePath;\r
+\r
+\r
+//\r
+// Function Prototypes\r
+//\r
+STATIC\r
+VOID\r
+CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (\r
+  IN  EFI_CORE_DRIVER_ENTRY   *InsertedDriverEntry\r
+  );\r
\r
+STATIC\r
+VOID\r
+EFIAPI\r
+CoreFwVolEventProtocolNotify (\r
+  IN  EFI_EVENT       Event,\r
+  IN  VOID            *Context\r
+  );\r
+\r
+STATIC\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+CoreFvToDevicePath (\r
+  IN  EFI_FIRMWARE_VOLUME_PROTOCOL    *Fv,\r
+  IN  EFI_HANDLE                      FvHandle,\r
+  IN  EFI_GUID                        *DriverName\r
+  );\r
+\r
+STATIC \r
+EFI_STATUS\r
+CoreAddToDriverList (\r
+  IN  EFI_FIRMWARE_VOLUME_PROTOCOL  *Fv,\r
+  IN  EFI_HANDLE                    FvHandle,\r
+  IN  EFI_GUID                      *DriverName\r
+  );\r
+\r
+STATIC\r
+EFI_STATUS \r
+CoreProcessFvImageFile (\r
+  IN  EFI_FIRMWARE_VOLUME_PROTOCOL    *Fv,\r
+  IN  EFI_HANDLE                      FvHandle,\r
+  IN  EFI_GUID                        *DriverName\r
+  );\r
+\r
+STATIC\r
+VOID\r
+CoreAcquireDispatcherLock (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Enter critical section by gaining lock on mDispatcherLock\r
+\r
+Arguments:\r
+\r
+  None\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+\r
+{\r
+  CoreAcquireLock (&mDispatcherLock);\r
+}\r
+\r
+STATIC\r
+VOID\r
+CoreReleaseDispatcherLock (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Exit critical section by releasing lock on mDispatcherLock\r
+\r
+Arguments:\r
+\r
+  None\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+{\r
+  CoreReleaseLock (&mDispatcherLock);\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+CoreGetDepexSectionAndPreProccess (\r
+  IN  EFI_CORE_DRIVER_ENTRY   *DriverEntry\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  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
+Arguments:\r
+\r
+  DriverEntry - Driver to work on.\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS - Depex read and preprossesed \r
+\r
+  EFI_PROTOCOL_ERROR - The section extraction protocol returned an error and \r
+                        Depex reading needs to be retried.\r
+\r
+  Other Error - DEPEX not found.\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                    Status;\r
+  EFI_SECTION_TYPE              SectionType;\r
+  UINT32                        AuthenticationStatus;\r
+  EFI_FIRMWARE_VOLUME_PROTOCOL  *Fv;\r
+\r
+  \r
+  Fv = DriverEntry->Fv;\r
+\r
+  //\r
+  // Grab Depex info, it will never be free'ed.\r
+  //\r
+  SectionType         = EFI_SECTION_DXE_DEPEX;\r
+  Status = Fv->ReadSection (\r
+                DriverEntry->Fv, \r
+                &DriverEntry->FileName,\r
+                SectionType, \r
+                0, \r
+                &DriverEntry->Depex, \r
+                (UINTN *)&DriverEntry->DepexSize,\r
+                &AuthenticationStatus\r
+                );\r
+  if (EFI_ERROR (Status)) {\r
+    if (Status == EFI_PROTOCOL_ERROR) {\r
+      //\r
+      // The section extraction protocol failed so set protocol error flag\r
+      //\r
+      DriverEntry->DepexProtocolError = TRUE;\r
+    } else {\r
+      //\r
+      // If no Depex assume EFI 1.1 driver model\r
+      //\r
+      DriverEntry->Depex = NULL;\r
+      DriverEntry->Dependent = TRUE;\r
+      DriverEntry->DepexProtocolError = FALSE;\r
+    }\r
+  } else {\r
+    //\r
+    // Set Before, After, and Unrequested state information based on Depex\r
+    // Driver will be put in Dependent or Unrequested state\r
+    //\r
+    CorePreProcessDepex (DriverEntry);\r
+    DriverEntry->DepexProtocolError = FALSE;\r
+  }  \r
+\r
+  return Status;\r
+}\r
+\r
+EFI_DXESERVICE\r
+EFI_STATUS\r
+EFIAPI\r
+CoreSchedule (\r
+  IN  EFI_HANDLE  FirmwareVolumeHandle,\r
+  IN  EFI_GUID    *DriverName\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Check every driver and locate a matching one. If the driver is found, the Unrequested\r
+  state flag is cleared.\r
+\r
+Arguments:\r
+\r
+  FirmwareVolumeHandle - The handle of the Firmware Volume that contains the firmware \r
+                         file specified by DriverName.\r
+\r
+  DriverName           - The Driver name to put in the Dependent state.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS   - The DriverName was found and it's SOR bit was cleared\r
+\r
+  EFI_NOT_FOUND - The DriverName does not exist or it's SOR bit was not set.\r
+\r
+--*/\r
+{\r
+  LIST_ENTRY            *Link;\r
+  EFI_CORE_DRIVER_ENTRY *DriverEntry;\r
+\r
+  //\r
+  // Check every driver\r
+  //\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->FvHandle == FirmwareVolumeHandle &&\r
+        DriverEntry->Unrequested && \r
+        CompareGuid (DriverName, &DriverEntry->FileName)) {\r
+      //\r
+      // Move the driver from the Unrequested to the Dependent state\r
+      //\r
+      CoreAcquireDispatcherLock ();\r
+      DriverEntry->Unrequested  = FALSE;\r
+      DriverEntry->Dependent    = TRUE;\r
+      CoreReleaseDispatcherLock ();\r
+    \r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
+  return EFI_NOT_FOUND;  \r
+}\r
+\r
+\r
+EFI_DXESERVICE\r
+EFI_STATUS\r
+EFIAPI\r
+CoreTrust (\r
+  IN  EFI_HANDLE  FirmwareVolumeHandle,\r
+  IN  EFI_GUID    *DriverName\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Convert a driver from the Untrused back to the Scheduled state\r
+\r
+Arguments:\r
+\r
+  FirmwareVolumeHandle - The handle of the Firmware Volume that contains the firmware \r
+                         file specified by DriverName.\r
+\r
+  DriverName           - The Driver name to put in the Scheduled state\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS   - The file was found in the untrusted state, and it was promoted \r
+                  to the trusted state.\r
+\r
+  EFI_NOT_FOUND - The file was not found in the untrusted state.\r
+\r
+--*/\r
+{\r
+  LIST_ENTRY            *Link;\r
+  EFI_CORE_DRIVER_ENTRY *DriverEntry;\r
+\r
+  //\r
+  // Check every driver\r
+  //\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->FvHandle == FirmwareVolumeHandle &&\r
+        DriverEntry->Untrusted && \r
+        CompareGuid (DriverName, &DriverEntry->FileName)) {\r
+      //\r
+      // Transition driver from Untrusted to Scheduled state.\r
+      //\r
+      CoreAcquireDispatcherLock ();\r
+      DriverEntry->Untrusted = FALSE;\r
+      DriverEntry->Scheduled = TRUE;\r
+      InsertTailList (&mScheduledQueue, &DriverEntry->ScheduledLink);\r
+      CoreReleaseDispatcherLock ();\r
+    \r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
+  return EFI_NOT_FOUND;  \r
+}\r
+\r
+\r
+EFI_DXESERVICE\r
+EFI_STATUS\r
+EFIAPI\r
+CoreDispatcher (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\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
+  image for each driver. Search the mDiscoveredList to see if any driver can \r
+  be placed on the mScheduledQueue. If no drivers are placed on the\r
+  mScheduledQueue exit the function. On exit it is assumed the Bds()\r
+  will be called, and when the Bds() exits the Dispatcher will be called \r
+  again.\r
+\r
+Arguments:\r
+\r
+  NONE\r
+\r
+Returns:\r
+\r
+  EFI_ALREADY_STARTED - The DXE Dispatcher is already running\r
+\r
+  EFI_NOT_FOUND       - No DXE Drivers were dispatched\r
+\r
+  EFI_SUCCESS         - One or more DXE Drivers were dispatched\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                      Status;\r
+  EFI_STATUS                      ReturnStatus;\r
+  LIST_ENTRY                      *Link;\r
+  EFI_CORE_DRIVER_ENTRY           *DriverEntry;\r
+  BOOLEAN                         ReadyToRun;\r
+\r
+  if (gDispatcherRunning) {\r
+    //\r
+    // If the dispatcher is running don't let it be restarted.\r
+    //\r
+    return EFI_ALREADY_STARTED;\r
+  }\r
+\r
+  gDispatcherRunning = TRUE;\r
+\r
+\r
+  ReturnStatus = EFI_NOT_FOUND;\r
+  do {\r
+    //\r
+    // Drain the Scheduled Queue\r
+    //\r
+    while (!IsListEmpty (&mScheduledQueue)) {\r
+      DriverEntry = CR (\r
+                      mScheduledQueue.ForwardLink,\r
+                      EFI_CORE_DRIVER_ENTRY,\r
+                      ScheduledLink,\r
+                      EFI_CORE_DRIVER_ENTRY_SIGNATURE\r
+                      );\r
+\r
+      //\r
+      // Load the DXE Driver image into memory. If the Driver was transitioned from\r
+      // 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
+        Status = CoreLoadImage (\r
+                        FALSE, \r
+                        gDxeCoreImageHandle, \r
+                        DriverEntry->FvFileDevicePath,\r
+                        NULL, \r
+                        0, \r
+                        &DriverEntry->ImageHandle\r
+                        );\r
+\r
+        //\r
+        // Update the driver state to reflect that it's been loaded\r
+        //\r
+        if (EFI_ERROR (Status)) {\r
+          CoreAcquireDispatcherLock ();\r
+\r
+          if (Status == EFI_SECURITY_VIOLATION) {\r
+            //\r
+            // Take driver from Scheduled to Untrused state\r
+            //\r
+            DriverEntry->Untrusted = TRUE;\r
+          } 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
+            //\r
+            // This case include the Never Trusted state if EFI_ACCESS_DENIED is returned\r
+            //\r
+            DriverEntry->Initialized  = TRUE;\r
+          }\r
+\r
+          DriverEntry->Scheduled = FALSE;\r
+          RemoveEntryList (&DriverEntry->ScheduledLink);\r
+          \r
+          CoreReleaseDispatcherLock ();\r
+        \r
+          //\r
+          // If it's an error don't try the StartImage\r
+          //\r
+          continue;\r
+        }\r
+      }\r
+\r
+      CoreAcquireDispatcherLock ();\r
+\r
+      DriverEntry->Scheduled    = FALSE;\r
+      DriverEntry->Initialized  = TRUE;\r
+      RemoveEntryList (&DriverEntry->ScheduledLink);\r
+      \r
+      CoreReleaseDispatcherLock ();\r
+\r
+\r
+      CoreReportProgressCodeSpecific (EFI_SOFTWARE_DXE_CORE | EFI_SW_PC_INIT_BEGIN, DriverEntry->ImageHandle);\r
+      Status = CoreStartImage (DriverEntry->ImageHandle, NULL, NULL);\r
+      CoreReportProgressCodeSpecific (EFI_SOFTWARE_DXE_CORE | EFI_SW_PC_INIT_END, DriverEntry->ImageHandle);\r
+\r
+      ReturnStatus = EFI_SUCCESS;\r
+    }\r
+\r
+    //\r
+    // Search DriverList for items to place on Scheduled Queue\r
+    //\r
+    ReadyToRun = FALSE;\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
+\r
+      if (DriverEntry->DepexProtocolError){\r
+        //\r
+        // If Section Extraction Protocol did not let the Depex be read before retry the read\r
+        //\r
+        Status = CoreGetDepexSectionAndPreProccess (DriverEntry);\r
+      } \r
+\r
+      if (DriverEntry->Dependent) {\r
+        if (CoreIsSchedulable (DriverEntry)) {\r
+          CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (DriverEntry); \r
+          ReadyToRun = TRUE;\r
+        } \r
+      }\r
+    }\r
+  } while (ReadyToRun);\r
+\r
+  gDispatcherRunning = FALSE;\r
+\r
+  return ReturnStatus;\r
+}\r
+\r
+STATIC\r
+VOID\r
+CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (\r
+  IN  EFI_CORE_DRIVER_ENTRY   *InsertedDriverEntry\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Insert InsertedDriverEntry onto the mScheduledQueue. To do this you \r
+  must add any driver with a before dependency on InsertedDriverEntry first.\r
+  You do this by recursively calling this routine. After all the Befores are\r
+  processed you can add InsertedDriverEntry to the mScheduledQueue. \r
+  Then you can add any driver with an After dependency on InsertedDriverEntry \r
+  by recursively calling this routine.\r
+\r
+Arguments:\r
+\r
+  InsertedDriverEntry - The driver to insert on the ScheduledLink Queue\r
+\r
+Returns:\r
+\r
+  NONE \r
+\r
+--*/\r
+{\r
+  LIST_ENTRY            *Link;\r
+  EFI_CORE_DRIVER_ENTRY *DriverEntry;\r
+\r
+  //\r
+  // Process Before Dependency\r
+  //\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 (CompareGuid (&InsertedDriverEntry->FileName, &DriverEntry->BeforeAfterGuid)) {\r
+        //\r
+        // Recursively process BEFORE\r
+        //\r
+        CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (DriverEntry);\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  // Convert driver from Dependent to Scheduled state\r
+  //\r
+  CoreAcquireDispatcherLock ();\r
+\r
+  InsertedDriverEntry->Dependent = FALSE;\r
+  InsertedDriverEntry->Scheduled = TRUE;\r
+  InsertTailList (&mScheduledQueue, &InsertedDriverEntry->ScheduledLink);\r
+  \r
+  CoreReleaseDispatcherLock ();\r
+\r
+  //\r
+  // Process After Dependency\r
+  //\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 (CompareGuid (&InsertedDriverEntry->FileName, &DriverEntry->BeforeAfterGuid)) {\r
+        //\r
+        // Recursively process AFTER\r
+        //\r
+        CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (DriverEntry);\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
+STATIC\r
+BOOLEAN\r
+FvHasBeenProcessed (\r
+  IN  EFI_HANDLE      FvHandle\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Return TRUE if the Fv has been processed, FALSE if not.\r
+\r
+Arguments:\r
+\r
+  FvHandle - The handle of a FV that's being tested\r
+\r
+Returns:\r
+\r
+  TRUE  - Fv protocol on FvHandle has been processed\r
+\r
+  FALSE - Fv protocol on FvHandle has not yet been processed\r
+\r
+--*/\r
+{\r
+  LIST_ENTRY      *Link;\r
+  KNOWN_HANDLE    *KnownHandle;\r
+\r
+  for (Link = mFvHandleList.ForwardLink; Link != &mFvHandleList; Link = Link->ForwardLink) {\r
+    KnownHandle = CR(Link, KNOWN_HANDLE, Link, KNOWN_HANDLE_SIGNATURE);\r
+    if (KnownHandle->Handle == FvHandle) {\r
+      return TRUE;\r
+    }\r
+  }\r
+  return FALSE;\r
+}\r
+\r
+STATIC\r
+VOID\r
+FvIsBeingProcesssed (\r
+  IN  EFI_HANDLE    FvHandle\r
+  )\r
+/*++\r
+\r
+Routine Description:\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
+\r
+Arguments:\r
+\r
+  FvHandle - The handle of a FV that has been processed\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+{\r
+  KNOWN_HANDLE  *KnownHandle;\r
+\r
+  KnownHandle = CoreAllocateBootServicesPool (sizeof (KNOWN_HANDLE));\r
+  ASSERT (KnownHandle != NULL);\r
+\r
+  KnownHandle->Signature = KNOWN_HANDLE_SIGNATURE;\r
+  KnownHandle->Handle = FvHandle;\r
+  InsertTailList (&mFvHandleList, &KnownHandle->Link);\r
+}\r
+\r
+\r
+\r
+STATIC\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+CoreFvToDevicePath (\r
+  IN  EFI_FIRMWARE_VOLUME_PROTOCOL    *Fv,\r
+  IN  EFI_HANDLE                      FvHandle,\r
+  IN  EFI_GUID                        *DriverName\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Convert FvHandle and DriverName into an EFI device path\r
+\r
+Arguments:\r
+\r
+  Fv         - Fv protocol, needed to read Depex info out of FLASH.\r
+  \r
+  FvHandle   - Handle for Fv, needed in the EFI_CORE_DRIVER_ENTRY so that the\r
+               PE image can be read out of the FV at a later time.\r
+\r
+  DriverName - Name of driver to add to mDiscoveredList.\r
+\r
+Returns:\r
+\r
+  Pointer to device path constructed from FvHandle and DriverName\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                          Status;\r
+  EFI_DEVICE_PATH_PROTOCOL            *FvDevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL            *FileNameDevicePath;\r
+\r
+  //\r
+  // Remember the device path of the FV\r
+  //\r
+  Status = CoreHandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);\r
+  if (EFI_ERROR (Status)) {\r
+    FileNameDevicePath = NULL;\r
+  } else {\r
+    //\r
+    // 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
+\r
+    FileNameDevicePath = CoreAppendDevicePath (\r
+                            FvDevicePath, \r
+                            (EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath\r
+                            );\r
+  }\r
+\r
+  return FileNameDevicePath;\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+CoreAddToDriverList (\r
+  IN  EFI_FIRMWARE_VOLUME_PROTOCOL    *Fv,\r
+  IN  EFI_HANDLE                      FvHandle,\r
+  IN  EFI_GUID                        *DriverName\r
+  )\r
+/*++\r
+\r
+Routine Description:\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
+  in DriverEntry. Pre-process the Depex to set the SOR, Before and After state.\r
+  The Discovered list is never free'ed and contains booleans that represent the\r
+  other possible DXE driver states.\r
+\r
+Arguments:\r
+\r
+  Fv         - Fv protocol, needed to read Depex info out of FLASH.\r
+  \r
+  FvHandle   - Handle for Fv, needed in the EFI_CORE_DRIVER_ENTRY so that the\r
+               PE image can be read out of the FV at a later time.\r
+\r
+  DriverName - Name of driver to add to mDiscoveredList.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS - If driver was added to the mDiscoveredList.\r
+\r
+  EFI_ALREADY_STARTED - The driver has already been started. Only one DriverName\r
+                        may be active in the system at any one time.\r
+\r
+--*/\r
+{\r
+  EFI_CORE_DRIVER_ENTRY               *DriverEntry;\r
+\r
\r
+  //\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
+  ASSERT (DriverEntry != NULL);\r
+\r
+  DriverEntry->Signature        = EFI_CORE_DRIVER_ENTRY_SIGNATURE;\r
+  CopyMem (&DriverEntry->FileName, DriverName, sizeof (EFI_GUID));\r
+  DriverEntry->FvHandle         = FvHandle;\r
+  DriverEntry->Fv               = Fv;\r
+  DriverEntry->FvFileDevicePath = CoreFvToDevicePath (Fv, FvHandle, DriverName);\r
+\r
+  CoreGetDepexSectionAndPreProccess (DriverEntry);\r
+  \r
+  CoreAcquireDispatcherLock ();\r
+  \r
+  InsertTailList (&mDiscoveredList, &DriverEntry->Link);\r
+\r
+  CoreReleaseDispatcherLock ();\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+\r
+EFI_STATUS \r
+CoreProcessFvImageFile (\r
+  IN  EFI_FIRMWARE_VOLUME_PROTOCOL    *Fv,\r
+  IN  EFI_HANDLE                      FvHandle,\r
+  IN  EFI_GUID                        *DriverName\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get the driver from the FV through driver name, and produce a FVB protocol on FvHandle.\r
+\r
+Arguments:\r
+\r
+  Fv          - The FIRMWARE_VOLUME protocol installed on the FV.\r
+  FvHandle    - The handle which FVB protocol installed on.\r
+  DriverName  - The driver guid specified.\r
+\r
+Returns:\r
+\r
+  EFI_OUT_OF_RESOURCES    - No enough memory or other resource.\r
+  \r
+  EFI_VOLUME_CORRUPTED    - Corrupted volume.\r
+  \r
+  EFI_SUCCESS             - Function successfully returned.\r
+  \r
+\r
+--*/\r
+{\r
+  EFI_STATUS                          Status;\r
+  EFI_SECTION_TYPE                    SectionType;\r
+  UINT32                              AuthenticationStatus;\r
+  VOID                                *Buffer;\r
+  UINTN                               BufferSize;\r
+\r
+  //\r
+  // Read the first (and only the first) firmware volume section\r
+  //\r
+  SectionType = EFI_SECTION_FIRMWARE_VOLUME_IMAGE;\r
+  Buffer      = NULL;\r
+  BufferSize  = 0;\r
+  Status = Fv->ReadSection (\r
+                Fv, \r
+                DriverName, \r
+                SectionType, \r
+                0, \r
+                &Buffer, \r
+                &BufferSize,\r
+                &AuthenticationStatus\r
+                );\r
+  if (!EFI_ERROR (Status)) {\r
+    //\r
+    // Produce a FVB protocol for the file\r
+    //\r
+    Status = ProduceFVBProtocolOnBuffer (\r
+              (EFI_PHYSICAL_ADDRESS) (UINTN) Buffer,\r
+              (UINT64)BufferSize,\r
+              FvHandle,\r
+              NULL\r
+              );\r
+  }\r
+\r
+  if (EFI_ERROR (Status) && (Buffer != NULL)) {    \r
+  //\r
+  // ReadSection or Produce FVB failed, Free data buffer\r
+  //\r
+  CoreFreePool (Buffer); \r
+\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+STATIC\r
+VOID\r
+EFIAPI\r
+CoreFwVolEventProtocolNotify (\r
+  IN  EFI_EVENT       Event,\r
+  IN  VOID            *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\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
+  must loop on CoreLocateHandle () to see how many protocols were added and\r
+  do the following to each FV:\r
+\r
+  If the Fv has already been processed, skip it. If the Fv has not been \r
+  processed then mark it as being processed, as we are about to process it.\r
+\r
+  Read the Fv and add any driver in the Fv to the mDiscoveredList.The \r
+  mDiscoveredList is never free'ed and contains variables that define\r
+  the other states the DXE driver transitions to.. \r
+  \r
+  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
+Arguments:\r
+\r
+  Event   - The Event that is being processed, not used.\r
+  \r
+  Context - Event Context, not used.\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                    Status;\r
+  EFI_STATUS                    GetNextFileStatus;\r
+  EFI_STATUS                    SecurityStatus;\r
+  EFI_FIRMWARE_VOLUME_PROTOCOL  *Fv;\r
+  EFI_DEVICE_PATH_PROTOCOL      *FvDevicePath;\r
+  EFI_HANDLE                    FvHandle;\r
+  UINTN                         BufferSize;\r
+  EFI_GUID                      NameGuid;\r
+  UINTN                         Key;\r
+  EFI_FV_FILETYPE               Type;\r
+  EFI_FV_FILE_ATTRIBUTES        Attributes;\r
+  UINTN                         Size;\r
+  EFI_CORE_DRIVER_ENTRY         *DriverEntry;\r
+  EFI_GUID                      *AprioriFile;\r
+  UINTN                         AprioriEntryCount;\r
+  UINTN                         Index;\r
+  LIST_ENTRY                    *Link;\r
+  UINT32                        AuthenticationStatus;\r
+  UINTN                         SizeOfBuffer;\r
+\r
+\r
+  while (TRUE) {\r
+    BufferSize = sizeof (EFI_HANDLE);\r
+    Status = CoreLocateHandle (\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
+      //\r
+      return;\r
+    }\r
+\r
+    if (FvHasBeenProcessed (FvHandle)) {\r
+      //\r
+      // This Fv has already been processed so lets skip it!\r
+      //\r
+      continue;\r
+    }\r
+\r
+    Status = CoreHandleProtocol (FvHandle, &gEfiFirmwareVolumeDispatchProtocolGuid, (VOID **)&Fv);\r
+    if (EFI_ERROR (Status)) {\r
+      //\r
+      // If no dispatch protocol then skip, but do not marked as being processed as it\r
+      // may show up later.\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, &gEfiFirmwareVolumeProtocolGuid, (VOID **)&Fv);\r
+    if (EFI_ERROR (Status)) {\r
+      //\r
+      // The Handle has a FirmwareVolumeDispatch protocol and should also contiain\r
+      // a FirmwareVolume protocol thus we should never get here.\r
+      //\r
+      ASSERT (FALSE);\r
+      continue;\r
+    }\r
+    \r
+    Status = CoreHandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);\r
+    if (EFI_ERROR (Status)) {\r
+      //\r
+      // The Firmware volume doesn't have device path, can't be dispatched.\r
+      //\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
+    // 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
+      //\r
+      // Initialize the search key\r
+      //\r
+      Key = 0;\r
+      do {\r
+        Type = mDxeFileTypes[Index];\r
+        GetNextFileStatus = Fv->GetNextFile (\r
+                                  Fv, \r
+                                  &Key,\r
+                                  &Type,  \r
+                                  &NameGuid, \r
+                                  &Attributes, \r
+                                  &Size\r
+                                  );\r
+        if (!EFI_ERROR (GetNextFileStatus)) {\r
+          if (Type == EFI_FV_FILETYPE_DXE_CORE) {\r
+            //\r
+            // If this is the DXE core fill in it's DevicePath & DeviceHandle\r
+            //\r
+            if (gDxeCoreLoadedImage->FilePath == NULL) {\r
+              if (CompareGuid (&NameGuid, gDxeCoreFileName)) {\r
+                //\r
+                // Maybe One specail Fv cantains only one DXE_CORE module, so its device path must\r
+                // 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
+\r
+                gDxeCoreLoadedImage->FilePath = CoreDuplicateDevicePath (\r
+                                                  (EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath\r
+                                                  );\r
+                gDxeCoreLoadedImage->DeviceHandle = FvHandle;\r
+              }\r
+            }\r
+          } else if (Type == EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) {\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
+            //\r
+            CoreProcessFvImageFile (Fv, FvHandle, &NameGuid);\r
+          } else {\r
+            //\r
+            // Transition driver from Undiscovered to Discovered state\r
+            //\r
+            CoreAddToDriverList (Fv, FvHandle, &NameGuid);\r
+          }\r
+        }\r
+      } while (!EFI_ERROR (GetNextFileStatus));\r
+    }\r
+    \r
+    //\r
+    // Read the array of GUIDs from the Apriori file if it is present in the firmware volume\r
+    //\r
+    AprioriFile = NULL;\r
+    Status = Fv->ReadSection (\r
+                  Fv,\r
+                  &gAprioriGuid,\r
+                  EFI_SECTION_RAW,\r
+                  0,\r
+                  (VOID **)&AprioriFile,\r
+                  &SizeOfBuffer,\r
+                  &AuthenticationStatus\r
+                  );\r
+    if (!EFI_ERROR (Status)) {\r
+      AprioriEntryCount = SizeOfBuffer / sizeof (EFI_GUID);\r
+    } else {\r
+      AprioriEntryCount = 0;\r
+    }\r
+\r
+    //\r
+    // Put drivers on Apriori List on the Scheduled queue. The Discovered List includes\r
+    // 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
+    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
+          DriverEntry->Dependent = FALSE;\r
+          DriverEntry->Scheduled = TRUE;\r
+          InsertTailList (&mScheduledQueue, &DriverEntry->ScheduledLink);\r
+          break;\r
+        }\r
+      }\r
+    }\r
+\r
+    CoreReleaseDispatcherLock ();\r
+\r
+    //\r
+    // Free data allocated by Fv->ReadSection () \r
+    //\r
+    CoreFreePool (AprioriFile);  \r
+  }\r
+}\r
+\r
+\r
+VOID\r
+CoreInitializeDispatcher (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Initialize the dispatcher. Initialize the notification function that runs when\r
+  a FV protocol is added to the system.\r
+\r
+Arguments:\r
+\r
+  NONE\r
+\r
+Returns:\r
+\r
+  NONE \r
+\r
+--*/\r
+{\r
+  mFwVolEvent = CoreCreateProtocolNotifyEvent (\r
+                  &gEfiFirmwareVolumeProtocolGuid, \r
+                  TPL_CALLBACK,\r
+                  CoreFwVolEventProtocolNotify,\r
+                  NULL,\r
+                  &mFwVolEventRegistration,\r
+                  TRUE\r
+                  );\r
+}\r
+\r
+//\r
+// Function only used in debug builds\r
+//\r
+VOID\r
+CoreDisplayDiscoveredNotDispatched (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Traverse the discovered list for any drivers that were discovered but not loaded \r
+  because the dependency experessions evaluated to false\r
+\r
+Arguments:\r
+\r
+  NONE\r
+\r
+Returns:\r
+\r
+  NONE \r
+\r
+--*/\r
+{\r
+  LIST_ENTRY                    *Link;\r
+  EFI_CORE_DRIVER_ENTRY         *DriverEntry;\r
+\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->Dependent) {\r
+      DEBUG ((EFI_D_LOAD, "Driver %g was discovered but not loaded!!\n", &DriverEntry->FileName));\r
+    }\r
+  }\r
+}\r
diff --git a/MdeModulePkg/Core/Dxe/Dispatcher/dependency.c b/MdeModulePkg/Core/Dxe/Dispatcher/dependency.c
new file mode 100644 (file)
index 0000000..7c2093b
--- /dev/null
@@ -0,0 +1,452 @@
+/*++ \r
+\r
+Copyright (c) 2006, 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
+\r
+Module Name:\r
+\r
+  dependency.c\r
+\r
+Abstract:\r
+\r
+  DXE Dispatcher Dependency Evaluator\r
+\r
+  This routine evaluates a dependency expression (DEPENDENCY_EXPRESSION) to determine\r
+  if a driver can be scheduled for execution.  The criteria for\r
+  schedulability is that the dependency expression is satisfied.\r
+\r
+--*/\r
+\r
+#include <DxeMain.h>\r
+\r
+//\r
+// Global stack used to evaluate dependency expressions\r
+//\r
+BOOLEAN *mDepexEvaluationStack        = NULL;\r
+BOOLEAN *mDepexEvaluationStackEnd     = NULL;\r
+BOOLEAN *mDepexEvaluationStackPointer = NULL;\r
+\r
+//\r
+// Worker functions\r
+//\r
+\r
+STATIC\r
+EFI_STATUS\r
+GrowDepexStack (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Grow size of the Depex stack\r
+\r
+Arguments:\r
+\r
+  Stack     - Old stack on the way in and new stack on the way out\r
+\r
+  StackSize - New size of the stack\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS          - Stack successfully growed.\r
+  \r
+  EFI_OUT_OF_RESOURCES - There is not enough system memory to grow the stack.\r
+  \r
+  \r
+\r
+--*/\r
+{\r
+  BOOLEAN     *NewStack;\r
+  UINTN       Size;\r
+\r
+  Size = DEPEX_STACK_SIZE_INCREMENT;\r
+  if (mDepexEvaluationStack != NULL) {\r
+    Size = Size + (mDepexEvaluationStackEnd - mDepexEvaluationStack);\r
+  }\r
+\r
+  NewStack = CoreAllocateBootServicesPool (Size * sizeof (BOOLEAN));\r
+  if (NewStack == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  if (mDepexEvaluationStack != NULL) {\r
+    //\r
+    // Copy to Old Stack to the New Stack\r
+    //\r
+    CopyMem (\r
+      NewStack, \r
+      mDepexEvaluationStack, \r
+      (mDepexEvaluationStackEnd - mDepexEvaluationStack) * sizeof (BOOLEAN)\r
+      );\r
+\r
+    //\r
+    // Free The Old Stack\r
+    //\r
+    CoreFreePool (mDepexEvaluationStack);\r
+  }\r
+\r
+  //\r
+  // Make the Stack pointer point to the old data in the new stack\r
+  //\r
+  mDepexEvaluationStackPointer = NewStack + (mDepexEvaluationStackPointer - mDepexEvaluationStack);\r
+  mDepexEvaluationStack        = NewStack;\r
+  mDepexEvaluationStackEnd     = NewStack + Size;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+STATIC\r
+EFI_STATUS\r
+PushBool (\r
+  IN BOOLEAN  Value\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Push an element onto the Boolean Stack\r
+\r
+Arguments:\r
+\r
+  Value - BOOLEAN to push.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS          - The value was pushed onto the stack.\r
+\r
+  EFI_OUT_OF_RESOURCES - There is not enough system memory to grow the stack.\r
+\r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  //\r
+  // Check for a stack overflow condition\r
+  //\r
+  if (mDepexEvaluationStackPointer == mDepexEvaluationStackEnd) {\r
+    //\r
+    // Grow the stack\r
+    //\r
+    Status = GrowDepexStack ();\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Push the item onto the stack\r
+  //\r
+  *mDepexEvaluationStackPointer = Value;\r
+  mDepexEvaluationStackPointer++;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+STATIC\r
+EFI_STATUS \r
+PopBool (\r
+  OUT BOOLEAN  *Value\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Pop an element from the Boolean stack.\r
+\r
+Arguments:\r
+\r
+  Value - BOOLEAN to pop.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS       - The value was popped onto the stack.\r
+\r
+  EFI_ACCESS_DENIED - The pop operation underflowed the stack\r
+\r
+--*/\r
+{\r
+  //\r
+  // Check for a stack underflow condition\r
+  //\r
+  if (mDepexEvaluationStackPointer == mDepexEvaluationStack) {\r
+    return EFI_ACCESS_DENIED;\r
+  }\r
+\r
+  //\r
+  // Pop the item off the stack\r
+  //\r
+  mDepexEvaluationStackPointer--;\r
+  *Value = *mDepexEvaluationStackPointer;\r
+  return EFI_SUCCESS;  \r
+}\r
+\r
+\r
+EFI_STATUS\r
+CorePreProcessDepex (\r
+  IN  EFI_CORE_DRIVER_ENTRY   *DriverEntry  \r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Preprocess dependency expression and update DriverEntry to reflect the\r
+  state of  Before, After, and SOR dependencies. If DriverEntry->Before\r
+  or DriverEntry->After is set it will never be cleared. If SOR is set\r
+  it will be cleared by CoreSchedule(), and then the driver can be \r
+  dispatched.\r
+\r
+Arguments:\r
+\r
+  DriverEntry - DriverEntry element to update\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS - It always works.\r
+\r
+--*/\r
+{\r
+  UINT8  *Iterator;\r
+    \r
+  Iterator = DriverEntry->Depex;\r
+  if (*Iterator == EFI_DEP_SOR) {\r
+    DriverEntry->Unrequested = TRUE;\r
+  } else {\r
+    DriverEntry->Dependent = TRUE;\r
+  }\r
+    \r
+  if (*Iterator == EFI_DEP_BEFORE) {\r
+    DriverEntry->Before = TRUE;\r
+  } else if (*Iterator == EFI_DEP_AFTER) {\r
+    DriverEntry->After = TRUE;\r
+  } \r
+\r
+  if (DriverEntry->Before || DriverEntry->After) {\r
+    CopyMem (&DriverEntry->BeforeAfterGuid, Iterator + 1, sizeof (EFI_GUID));\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+BOOLEAN\r
+CoreIsSchedulable (\r
+  IN  EFI_CORE_DRIVER_ENTRY   *DriverEntry  \r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This is the POSTFIX version of the dependency evaluator.  This code does \r
+  not need to handle Before or After, as it is not valid to call this \r
+  routine in this case. The SOR is just ignored and is a nop in the grammer.\r
+\r
+  POSTFIX means all the math is done on top of the stack.\r
+\r
+Arguments:\r
+\r
+  DriverEntry - DriverEntry element to update\r
+  \r
+Returns:\r
+\r
+  TRUE - If driver is ready to run.\r
+\r
+  FALSE - If driver is not ready to run or some fatal error was found.\r
+\r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+  UINT8       *Iterator;\r
+  BOOLEAN     Operator;\r
+  BOOLEAN     Operator2;\r
+  EFI_GUID    DriverGuid;\r
+  VOID        *Interface;\r
+\r
+  if (DriverEntry->After || DriverEntry->Before) {\r
+    //\r
+    // If Before or After Depex skip as CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter ()\r
+    // processes them.\r
+    //\r
+    return FALSE;\r
+  }\r
+\r
+  if (DriverEntry->Depex == NULL) {\r
+    //\r
+    // A NULL Depex means treat the driver like an EFI 1.0 thing.\r
+    //\r
+    Status = CoreAllEfiServicesAvailable ();\r
+    if (EFI_ERROR (Status)) {\r
+      return FALSE;\r
+    }\r
+    return TRUE;\r
+  }\r
+\r
+  //\r
+  // Clean out memory leaks in Depex Boolean stack. Leaks are only caused by\r
+  //  incorrectly formed DEPEX expressions\r
+  //\r
+  mDepexEvaluationStackPointer = mDepexEvaluationStack;\r
+\r
+\r
+  Iterator = DriverEntry->Depex;\r
+  \r
+  while (TRUE) {\r
+    //\r
+    // Check to see if we are attempting to fetch dependency expression instructions\r
+    // past the end of the dependency expression.\r
+    //\r
+    if (((UINTN)Iterator - (UINTN)DriverEntry->Depex) >= DriverEntry->DepexSize) {\r
+      return FALSE;\r
+    }\r
+\r
+    //\r
+    // Look at the opcode of the dependency expression instruction.\r
+    //\r
+    switch (*Iterator) {\r
+    case EFI_DEP_BEFORE:\r
+    case EFI_DEP_AFTER:\r
+      //\r
+      // For a well-formed Dependency Expression, the code should never get here.\r
+      // The BEFORE and AFTER are processed prior to this routine's invocation.\r
+      // If the code flow arrives at this point, there was a BEFORE or AFTER\r
+      // that were not the first opcodes.\r
+      //\r
+      ASSERT (FALSE);\r
+    case EFI_DEP_SOR:\r
+      //\r
+      // These opcodes can only appear once as the first opcode.  If it is found \r
+      // at any other location, then the dependency expression evaluates to FALSE\r
+      //\r
+      if (Iterator != DriverEntry->Depex) {\r
+        return FALSE;\r
+      }\r
+      //\r
+      // Otherwise, it is the first opcode and should be treated as a NOP.\r
+      //\r
+      break;\r
+\r
+    case EFI_DEP_PUSH:  \r
+      //\r
+      // Push operator is followed by a GUID. Test to see if the GUID protocol\r
+      // is installed and push the boolean result on the stack.\r
+      //\r
+      CopyMem (&DriverGuid, Iterator + 1, sizeof (EFI_GUID));\r
+\r
+      Status = CoreLocateProtocol (&DriverGuid, NULL, &Interface);\r
+\r
+      if (EFI_ERROR (Status)) {\r
+        Status = PushBool (FALSE);\r
+      } else {\r
+        *Iterator = EFI_DEP_REPLACE_TRUE;\r
+        Status = PushBool (TRUE);\r
+      }\r
+      if (EFI_ERROR (Status)) {\r
+        return FALSE;\r
+      }\r
+\r
+      Iterator += sizeof (EFI_GUID);\r
+      break;\r
+\r
+    case EFI_DEP_AND:    \r
+      Status = PopBool (&Operator);\r
+      if (EFI_ERROR (Status)) {\r
+        return FALSE;\r
+      }\r
+\r
+      Status = PopBool (&Operator2);\r
+      if (EFI_ERROR (Status)) {\r
+        return FALSE;\r
+      }\r
+\r
+      Status = PushBool ((BOOLEAN)(Operator && Operator2));\r
+      if (EFI_ERROR (Status)) {\r
+        return FALSE;\r
+      }\r
+      break;\r
+\r
+    case EFI_DEP_OR:     \r
+      Status = PopBool (&Operator);\r
+      if (EFI_ERROR (Status)) {\r
+        return FALSE;\r
+      }\r
+\r
+      Status = PopBool (&Operator2);\r
+      if (EFI_ERROR (Status)) {\r
+        return FALSE;\r
+      }\r
+\r
+      Status = PushBool ((BOOLEAN)(Operator || Operator2));\r
+      if (EFI_ERROR (Status)) {\r
+        return FALSE;\r
+      }\r
+      break;\r
+\r
+    case EFI_DEP_NOT:    \r
+      Status = PopBool (&Operator);\r
+      if (EFI_ERROR (Status)) {\r
+        return FALSE;\r
+      }\r
+\r
+      Status = PushBool ((BOOLEAN)(!Operator));\r
+      if (EFI_ERROR (Status)) {\r
+        return FALSE;\r
+      }\r
+      break;\r
+\r
+    case EFI_DEP_TRUE:   \r
+      Status = PushBool (TRUE);\r
+      if (EFI_ERROR (Status)) {\r
+        return FALSE;\r
+      }\r
+      break;\r
+\r
+    case EFI_DEP_FALSE: \r
+      Status = PushBool (FALSE);\r
+      if (EFI_ERROR (Status)) {\r
+        return FALSE;\r
+      }\r
+      break;\r
+\r
+    case EFI_DEP_END:    \r
+      Status = PopBool (&Operator);\r
+      if (EFI_ERROR (Status)) {\r
+        return FALSE;\r
+      }\r
+      return Operator;\r
+\r
+    case EFI_DEP_REPLACE_TRUE:\r
+      Status = PushBool (TRUE);\r
+      if (EFI_ERROR (Status)) {\r
+        return FALSE;\r
+      }\r
+\r
+      Iterator += sizeof (EFI_GUID);\r
+      break;\r
+\r
+    default:      \r
+      goto Done;\r
+    }\r
+    \r
+    //\r
+    // Skip over the Dependency Op Code we just processed in the switch.\r
+    // The math is done out of order, but it should not matter. That is\r
+    // we may add in the sizeof (EFI_GUID) before we account for the OP Code.\r
+    // This is not an issue, since we just need the correct end result. You\r
+    // need to be careful using Iterator in the loop as it's intermediate value\r
+    // may be strange.\r
+    //\r
+    Iterator++;\r
+  }\r
+\r
+Done:\r
+  return FALSE;\r
+}\r
+\r
diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h
new file mode 100644 (file)
index 0000000..fb7c82f
--- /dev/null
@@ -0,0 +1,2847 @@
+/*++\r
+\r
+Copyright (c) 2006 - 2007, 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
+\r
+Module Name:\r
+\r
+  DxeMain.h\r
+\r
+Abstract:\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#ifndef _DXE_MAIN_H_\r
+#define _DXE_MAIN_H_\r
+\r
+\r
+//\r
+// The package level header files this module uses\r
+//\r
+#include <PiDxe.h>\r
+#include <FrameworkPei.h>\r
+//\r
+// The protocols, PPI and GUID defintions for this module\r
+//\r
+#include <Protocol/LoadedImage.h>\r
+#include <Protocol/GuidedSectionExtraction.h>\r
+#include <Protocol/SectionExtraction.h>\r
+#include <Guid/DebugImageInfoTable.h>\r
+#include <Protocol/DevicePath.h>\r
+#include <Protocol/Runtime.h>\r
+#include <Protocol/LoadFile.h>\r
+#include <Protocol/DriverBinding.h>\r
+#include <Protocol/VariableWrite.h>\r
+#include <Protocol/PlatformDriverOverride.h>\r
+#include <Protocol/Variable.h>\r
+#include <Guid/MemoryTypeInformation.h>\r
+#include <Guid/FirmwareFileSystem2.h>\r
+#include <Guid/HobList.h>\r
+#include <Protocol/Timer.h>\r
+#include <Protocol/SimpleFileSystem.h>\r
+#include <Protocol/Bds.h>\r
+#include <Guid/FileInfo.h>\r
+#include <Protocol/RealTimeClock.h>\r
+#include <Guid/Apriori.h>\r
+#include <Protocol/WatchdogTimer.h>\r
+#include <Protocol/FirmwareVolume.h>\r
+#include <Protocol/MonotonicCounter.h>\r
+#include <Guid/DxeServices.h>\r
+#include <Guid/MemoryAllocationHob.h>\r
+#include <Protocol/StatusCode.h>\r
+#include <Protocol/CustomizedDecompress.h>\r
+#include <Protocol/Decompress.h>\r
+#include <Protocol/LoadPe32Image.h>\r
+#include <Protocol/FirmwareVolumeDispatch.h>\r
+#include <Protocol/Security.h>\r
+#include <Protocol/Ebc.h>\r
+#include <Guid/EventLegacyBios.h>\r
+#include <Protocol/Reset.h>\r
+#include <Protocol/EdkDecompress.h>\r
+#include <Protocol/Cpu.h>\r
+#include <Guid/EventGroup.h>\r
+#include <Protocol/Metronome.h>\r
+#include <Protocol/FirmwareVolumeBlock.h>\r
+#include <Protocol/Capsule.h>\r
+#include <Protocol/BusSpecificDriverOverride.h>\r
+#include <Protocol/Performance.h>\r
+#include <Guid/StatusCodeDataTypeId.h>\r
+//\r
+// The Library classes this module consumes\r
+//\r
+#include <Library/DxeCoreEntryPoint.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/HobLib.h>\r
+#include <Library/PerformanceLib.h>\r
+#include <Library/UefiDecompressLib.h>\r
+#include <Library/CustomDecompressLib.h>\r
+#include <Library/PeCoffLoaderLib.h>\r
+#include <Library/CacheMaintenanceLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+\r
+#include "DebugImageInfo.h"\r
+#include "Library.h"\r
+#include "FwVolBlock.h"\r
+#include "FwVolDriver.h"\r
+#include "gcd.h"\r
+#include "imem.h"\r
+#include "Image.h"\r
+#include "Exec.h"\r
+#include "hand.h"\r
+\r
+\r
+//\r
+// Modifier for EFI DXE Services\r
+//\r
+#define EFI_DXESERVICE\r
+\r
+//\r
+// attributes for reserved memory before it is promoted to system memory\r
+//\r
+#define EFI_MEMORY_PRESENT      0x0100000000000000ULL\r
+#define EFI_MEMORY_INITIALIZED  0x0200000000000000ULL\r
+#define EFI_MEMORY_TESTED       0x0400000000000000ULL\r
+\r
+//\r
+// range for memory mapped port I/O on IPF\r
+//\r
+#define EFI_MEMORY_PORT_IO  0x4000000000000000ULL\r
+\r
+\r
+///\r
+/// EFI_DEP_REPLACE_TRUE - Used to dynamically patch the dependecy expression\r
+///                        to save time.  A EFI_DEP_PUSH is evauated one an\r
+///                        replaced with EFI_DEP_REPLACE_TRUE\r
+///\r
+#define EFI_DEP_REPLACE_TRUE  0xff\r
+\r
+///\r
+/// Define the initial size of the dependency expression evaluation stack\r
+///\r
+#define DEPEX_STACK_SIZE_INCREMENT  0x1000\r
+\r
+typedef struct {\r
+  EFI_GUID                    *ProtocolGuid;\r
+  VOID                        **Protocol;\r
+  EFI_EVENT                   Event;\r
+  VOID                        *Registration;\r
+  BOOLEAN                     Present;\r
+} ARCHITECTURAL_PROTOCOL_ENTRY;\r
+\r
+\r
+//\r
+// DXE Dispatcher Data structures\r
+//\r
+\r
+#define KNOWN_HANDLE_SIGNATURE  EFI_SIGNATURE_32('k','n','o','w')\r
+typedef struct {\r
+  UINTN           Signature;\r
+  LIST_ENTRY      Link;         // mFvHandleList           \r
+  EFI_HANDLE      Handle;\r
+} KNOWN_HANDLE;\r
+\r
+\r
+#define EFI_CORE_DRIVER_ENTRY_SIGNATURE EFI_SIGNATURE_32('d','r','v','r')\r
+typedef struct {\r
+  UINTN                           Signature;\r
+  LIST_ENTRY                      Link;             // mDriverList\r
+\r
+  LIST_ENTRY                      ScheduledLink;    // mScheduledQueue\r
+\r
+  EFI_HANDLE                      FvHandle;\r
+  EFI_GUID                        FileName;\r
+  EFI_DEVICE_PATH_PROTOCOL        *FvFileDevicePath;\r
+  EFI_FIRMWARE_VOLUME_PROTOCOL    *Fv;\r
+\r
+  VOID                            *Depex;\r
+  UINTN                           DepexSize;\r
+\r
+  BOOLEAN                         Before;\r
+  BOOLEAN                         After;\r
+  EFI_GUID                        BeforeAfterGuid;\r
+\r
+  BOOLEAN                         Dependent;\r
+  BOOLEAN                         Unrequested;\r
+  BOOLEAN                         Scheduled;\r
+  BOOLEAN                         Untrusted;\r
+  BOOLEAN                         Initialized;\r
+  BOOLEAN                         DepexProtocolError;\r
+\r
+  EFI_HANDLE                      ImageHandle;\r
+\r
+} EFI_CORE_DRIVER_ENTRY;\r
+\r
+//\r
+//The data structure of GCD memory map entry\r
+//\r
+#define EFI_GCD_MAP_SIGNATURE  EFI_SIGNATURE_32('g','c','d','m')\r
+typedef struct {\r
+  UINTN                 Signature;\r
+  LIST_ENTRY            Link;\r
+  EFI_PHYSICAL_ADDRESS  BaseAddress;\r
+  UINT64                EndAddress;\r
+  UINT64                Capabilities;\r
+  UINT64                Attributes;\r
+  EFI_GCD_MEMORY_TYPE   GcdMemoryType;\r
+  EFI_GCD_IO_TYPE       GcdIoType;\r
+  EFI_HANDLE            ImageHandle;\r
+  EFI_HANDLE            DeviceHandle;\r
+} EFI_GCD_MAP_ENTRY;\r
+\r
+//\r
+// DXE Core Global Variables\r
+//\r
+extern EFI_SYSTEM_TABLE                         *gDxeCoreST;\r
+extern EFI_BOOT_SERVICES                        *gDxeCoreBS;\r
+extern EFI_RUNTIME_SERVICES                     *gDxeCoreRT;\r
+extern EFI_DXE_SERVICES                         *gDxeCoreDS;\r
+extern EFI_HANDLE                               gDxeCoreImageHandle;\r
+\r
+extern EFI_DECOMPRESS_PROTOCOL                  gEfiDecompress;\r
+extern EFI_PEI_PE_COFF_LOADER_PROTOCOL          *gEfiPeiPeCoffLoader;\r
+\r
+extern EFI_RUNTIME_ARCH_PROTOCOL                *gRuntime;\r
+extern EFI_CPU_ARCH_PROTOCOL                    *gCpu;\r
+extern EFI_WATCHDOG_TIMER_ARCH_PROTOCOL         *gWatchdogTimer;\r
+extern EFI_METRONOME_ARCH_PROTOCOL              *gMetronome;\r
+extern EFI_TIMER_ARCH_PROTOCOL                  *gTimer;\r
+extern EFI_SECURITY_ARCH_PROTOCOL               *gSecurity;\r
+extern EFI_BDS_ARCH_PROTOCOL                    *gBds;\r
+extern EFI_STATUS_CODE_PROTOCOL                 *gStatusCode;\r
+\r
+extern EFI_TPL                                  gEfiCurrentTpl;\r
+\r
+extern EFI_GUID                                 *gDxeCoreFileName;\r
+extern EFI_LOADED_IMAGE_PROTOCOL                *gDxeCoreLoadedImage;\r
+\r
+extern EFI_MEMORY_TYPE_INFORMATION              gMemoryTypeInformation[EfiMaxMemoryType + 1];\r
+\r
+extern BOOLEAN                                  gDispatcherRunning;\r
+extern EFI_RUNTIME_ARCH_PROTOCOL                gRuntimeTemplate;\r
+\r
+//\r
+// Service Initialization Functions\r
+//\r
+\r
+\r
+VOID\r
+CoreInitializePool (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Called to initialize the pool.\r
+\r
+Arguments:\r
+\r
+  None\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+CoreAddMemoryDescriptor (\r
+  IN EFI_MEMORY_TYPE       Type,\r
+  IN EFI_PHYSICAL_ADDRESS  Start,\r
+  IN UINT64                NumberOfPages,\r
+  IN UINT64                Attribute\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Called to initialize the memory map and add descriptors to\r
+  the current descriptor list.\r
+\r
+       The first descriptor that is added must be general usable\r
+  memory as the addition allocates heap.\r
+\r
+Arguments:\r
+\r
+  Type          - The type of memory to add\r
+\r
+  Start         - The starting address in the memory range\r
+                  Must be page aligned\r
+\r
+  NumberOfPages - The number of pages in the range\r
+\r
+  Attribute     - Attributes of the memory to add\r
+\r
+Returns:\r
+\r
+  None.  The range is added to the memory map\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+CoreReleaseGcdMemoryLock (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+    Release memory lock on mGcdMemorySpaceLock\r
+\r
+Arguments:\r
+    None\r
+\r
+Returns:\r
+    None\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+CoreAcquireGcdMemoryLock (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+    Acquire memory lock on mGcdMemorySpaceLock\r
+\r
+Arguments:\r
+    None\r
+\r
+Returns:\r
+    None\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CoreInitializeMemoryServices (\r
+  IN VOID                  **HobStart,\r
+  IN EFI_PHYSICAL_ADDRESS  *MemoryBaseAddress,\r
+  IN UINT64                *MemoryLength\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  External function. Initializes the GCD and memory services based on the memory \r
+  descriptor HOBs.  This function is responsible for priming the GCD map and the\r
+  memory map, so memory allocations and resource allocations can be made.  The first\r
+  part of this function can not depend on any memory services until at least one\r
+  memory descriptor is provided to the memory services.  Then the memory services\r
+  can be used to intialize the GCD map.\r
+\r
+Arguments:\r
+\r
+  HobStart - The start address of the HOB.\r
+  \r
+  MemoryBaseAddress   - Start address of memory region found to init DXE core.\r
+  \r
+  MemoryLength        - Length of memory region found to init DXE core.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS         - Memory services successfully initialized.\r
+\r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+CoreInitializeGcdServices (\r
+  IN VOID                  **HobStart,\r
+  IN EFI_PHYSICAL_ADDRESS  MemoryBaseAddress,\r
+  IN UINT64                MemoryLength\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  External function. Initializes the GCD and memory services based on the memory \r
+  descriptor HOBs.  This function is responsible for priming the GCD map and the\r
+  memory map, so memory allocations and resource allocations can be made.  The first\r
+  part of this function can not depend on any memory services until at least one\r
+  memory descriptor is provided to the memory services.  Then the memory services\r
+  can be used to intialize the GCD map.\r
+\r
+Arguments:\r
+\r
+  HobStart - The start address of the HOB\r
+  \r
+  MemoryBaseAddress   - Start address of memory region found to init DXE core.\r
+  \r
+  MemoryLength        - Length of memory region found to init DXE core.\r
+\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS         - GCD services successfully initialized.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CoreInitializeEventServices (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Initializes "event" support and populates parts of the System and Runtime Table.\r
+\r
+Arguments:\r
+\r
+  None\r
+    \r
+Returns:\r
+\r
+  EFI_SUCCESS - Always return success\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CoreInitializeImageServices (\r
+  IN  VOID *HobStart\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Add the Image Services to EFI Boot Services Table and install the protocol\r
+  interfaces for this image.\r
+\r
+Arguments:\r
+\r
+  HobStart        - The HOB to initialize\r
+\r
+Returns:\r
+\r
+  Status code.\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+CoreNotifyOnArchProtocolInstallation (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Creates an event that is fired everytime a Protocol of a specific type is installed\r
+\r
+Arguments:\r
+  NONE\r
+\r
+Returns:\r
+  NONE\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CoreAllEfiServicesAvailable (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Return TRUE if all AP services are availible.\r
+\r
+Arguments:\r
+  NONE\r
+\r
+Returns:\r
+  EFI_SUCCESS   - All AP services are available\r
+  EFI_NOT_FOUND - At least one AP service is not available \r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+CalculateEfiHdrCrc (\r
+  IN  OUT EFI_TABLE_HEADER    *Hdr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Calcualte the 32-bit CRC in a EFI table using the service provided by the\r
+  gRuntime service.\r
+\r
+Arguments:\r
+\r
+  Hdr  - Pointer to an EFI standard header\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+EFIAPI\r
+CoreTimerTick (\r
+  IN UINT64     Duration\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Called by the platform code to process a tick.\r
+\r
+Arguments:\r
+\r
+  Duration    - The number of 100ns elasped since the last call to TimerTick\r
+    \r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+CoreInitializeDispatcher (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Initialize the dispatcher. Initialize the notification function that runs when\r
+  a FV protocol is added to the system.\r
+\r
+Arguments:\r
+\r
+  NONE\r
+\r
+Returns:\r
+\r
+  NONE \r
+\r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+CoreIsSchedulable (\r
+  IN  EFI_CORE_DRIVER_ENTRY   *DriverEntry  \r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This is the POSTFIX version of the dependency evaluator.  This code does \r
+  not need to handle Before or After, as it is not valid to call this \r
+  routine in this case. The SOR is just ignored and is a nop in the grammer.\r
+\r
+  POSTFIX means all the math is done on top of the stack.\r
+\r
+Arguments:\r
+\r
+  DriverEntry - DriverEntry element to update\r
+  \r
+Returns:\r
+\r
+  TRUE - If driver is ready to run.\r
+\r
+  FALSE - If driver is not ready to run or some fatal error was found.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CorePreProcessDepex (\r
+  IN  EFI_CORE_DRIVER_ENTRY   *DriverEntry  \r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Preprocess dependency expression and update DriverEntry to reflect the\r
+  state of  Before, After, and SOR dependencies. If DriverEntry->Before\r
+  or DriverEntry->After is set it will never be cleared. If SOR is set\r
+  it will be cleared by CoreSchedule(), and then the driver can be \r
+  dispatched.\r
+\r
+Arguments:\r
+\r
+  DriverEntry - DriverEntry element to update\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS - It always works.\r
+\r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreExitBootServices (\r
+  IN EFI_HANDLE   ImageHandle,\r
+  IN UINTN        MapKey\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  EFI 1.0 API to terminate Boot Services\r
+\r
+Arguments:\r
+\r
+  ImageHandle - Handle that represents the identity of the calling image\r
+\r
+  MapKey      -Key to the latest memory map.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS - Boot Services terminated\r
+  EFI_INVALID_PARAMETER - MapKey is incorrect.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CoreTerminateMemoryMap (\r
+  IN UINTN        MapKey\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Make sure the memory map is following all the construction rules, \r
+  it is the last time to check memory map error before exit boot services.\r
+\r
+Arguments:\r
+\r
+  MapKey        - Memory map key\r
+\r
+Returns:\r
+\r
+  EFI_INVALID_PARAMETER       - Memory map not consistent with construction rules.\r
+  \r
+  EFI_SUCCESS                 - Valid memory map.\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+CoreNotifySignalList (\r
+  IN EFI_GUID     *EventGroup\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Signals all events on the requested list\r
+\r
+Arguments:\r
+\r
+  SignalType      - The list to signal\r
+    \r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreInstallConfigurationTable (\r
+  IN EFI_GUID         *Guid,\r
+  IN VOID             *Table\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Boot Service called to add, modify, or remove a system configuration table from \r
+  the EFI System Table.\r
+\r
+Arguments:\r
+\r
+  Guid:   Pointer to the GUID for the entry to add, update, or remove\r
+  Table:  Pointer to the configuration table for the entry to add, update, or\r
+          remove, may be NULL.\r
+\r
+Returns:\r
+  \r
+  EFI_SUCCESS               Guid, Table pair added, updated, or removed.\r
+  EFI_INVALID_PARAMETER     Input GUID not valid.\r
+  EFI_NOT_FOUND             Attempted to delete non-existant entry\r
+  EFI_OUT_OF_RESOURCES      Not enough memory available\r
+\r
+--*/\r
+;\r
+\r
+\r
+EFI_TPL\r
+EFIAPI\r
+CoreRaiseTpl (\r
+  IN EFI_TPL  NewTpl\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Raise the task priority level to the new level.\r
+  High level is implemented by disabling processor interrupts.\r
+\r
+Arguments:\r
+\r
+  NewTpl  - New task priority level\r
+    \r
+Returns:\r
+\r
+  The previous task priority level\r
+\r
+--*/\r
+;\r
+\r
+\r
+VOID\r
+EFIAPI\r
+CoreRestoreTpl (\r
+  IN EFI_TPL  NewTpl\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Lowers the task priority to the previous value.   If the new \r
+  priority unmasks events at a higher priority, they are dispatched.\r
+\r
+Arguments:\r
+\r
+  NewTpl  - New, lower, task priority\r
+    \r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreStall (\r
+  IN UINTN            Microseconds\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Introduces a fine-grained stall.\r
+\r
+Arguments:\r
+\r
+  Microseconds      The number of microseconds to stall execution\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS            - Execution was stalled for at least the requested amount\r
+                           of microseconds.\r
+\r
+  EFI_NOT_AVAILABLE_YET  - gMetronome is not available yet\r
+\r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreSetWatchdogTimer (\r
+  IN UINTN            Timeout,\r
+  IN UINT64           WatchdogCode,\r
+  IN UINTN            DataSize,\r
+  IN CHAR16           *WatchdogData   OPTIONAL\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Sets the system's watchdog timer.\r
+\r
+Arguments:\r
+\r
+  Timeout         The number of seconds.  Zero disables the timer.\r
+\r
+  ///////following  three parameters are left for platform specific using  \r
+  \r
+  WatchdogCode    The numberic code to log.  0x0 to 0xffff are firmware\r
+  DataSize        Size of the optional data\r
+  WatchdogData    Optional Null terminated unicode string followed by binary \r
+                  data.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS               Timeout has been set\r
+  EFI_NOT_AVAILABLE_YET     WatchdogTimer is not available yet \r
+  EFI_UNSUPPORTED           System does not have a timer (currently not used)\r
+  EFI_DEVICE_ERROR          Could not complete due to hardware error\r
+\r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreInstallProtocolInterface (\r
+  IN OUT EFI_HANDLE     *UserHandle,\r
+  IN EFI_GUID           *Protocol,\r
+  IN EFI_INTERFACE_TYPE InterfaceType,\r
+  IN VOID               *Interface\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Wrapper function to CoreInstallProtocolInterfaceNotify.  This is the public API which\r
+  Calls the private one which contains a BOOLEAN parameter for notifications\r
+\r
+Arguments:\r
+\r
+  UserHandle     - The handle to install the protocol handler on,\r
+                    or NULL if a new handle is to be allocated\r
+\r
+  Protocol       - The protocol to add to the handle\r
+\r
+  InterfaceType  - Indicates whether Interface is supplied in native form.\r
+\r
+  Interface      - The interface for the protocol being added\r
+\r
+Returns:\r
+\r
+  Status code    \r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CoreInstallProtocolInterfaceNotify (\r
+  IN OUT EFI_HANDLE     *UserHandle,\r
+  IN EFI_GUID           *Protocol,\r
+  IN EFI_INTERFACE_TYPE InterfaceType,\r
+  IN VOID               *Interface,\r
+  IN BOOLEAN            Notify\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Installs a protocol interface into the boot services environment.\r
+\r
+Arguments:\r
+\r
+  UserHandle     - The handle to install the protocol handler on,\r
+                   or NULL if a new handle is to be allocated\r
+\r
+  Protocol       - The protocol to add to the handle\r
+\r
+  InterfaceType  - Indicates whether Interface is supplied in native form.\r
+\r
+  Interface      - The interface for the protocol being added\r
+  \r
+  Notify         - Whether to notify the notification list for this protocol \r
+\r
+Returns:\r
+\r
+  EFI_INVALID_PARAMETER     - Invalid parameter\r
+  \r
+  EFI_OUT_OF_RESOURCES       - No enough buffer to allocate\r
+  \r
+  EFI_SUCCESS               - Protocol interface successfully installed\r
+\r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreInstallMultipleProtocolInterfaces (\r
+  IN OUT EFI_HANDLE           *Handle,\r
+  ...\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Installs a list of protocol interface into the boot services environment.\r
+  This function calls InstallProtocolInterface() in a loop. If any error\r
+  occures all the protocols added by this function are removed. This is \r
+  basically a lib function to save space.\r
+\r
+Arguments:\r
+\r
+  Handle      - The handle to install the protocol handlers on,\r
+                or NULL if a new handle is to be allocated\r
+  ...         - EFI_GUID followed by protocol instance. A NULL terminates the \r
+                list. The pairs are the arguments to InstallProtocolInterface().\r
+                All the protocols are added to Handle.\r
+\r
+Returns:\r
+\r
+  EFI_INVALID_PARAMETER       - Handle is NULL.\r
+  \r
+  EFI_SUCCESS                 - Protocol interfaces successfully installed.\r
+\r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreUninstallMultipleProtocolInterfaces (\r
+  IN EFI_HANDLE           Handle,\r
+  ...\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Uninstalls a list of protocol interface in the boot services environment. \r
+  This function calls UnisatllProtocolInterface() in a loop. This is \r
+  basically a lib function to save space.\r
+\r
+Arguments:\r
+\r
+  Handle      - The handle to uninstall the protocol\r
+\r
+  ...         - EFI_GUID followed by protocol instance. A NULL terminates the \r
+                list. The pairs are the arguments to UninstallProtocolInterface().\r
+                All the protocols are added to Handle.\r
+\r
+Returns:\r
+\r
+  Status code    \r
+\r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreReinstallProtocolInterface (\r
+  IN EFI_HANDLE     UserHandle,\r
+  IN EFI_GUID       *Protocol,\r
+  IN VOID           *OldInterface,\r
+  IN VOID           *NewInterface\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Reinstall a protocol interface on a device handle.  The OldInterface for Protocol is replaced by the NewInterface.\r
+\r
+Arguments:\r
+\r
+  UserHandle    - Handle on which the interface is to be reinstalled\r
+  Protocol      - The numeric ID of the interface\r
+  OldInterface  - A pointer to the old interface\r
+  NewInterface  - A pointer to the new interface \r
+\r
+\r
+Returns:\r
+\r
+  Status code.\r
+\r
+  On EFI_SUCCESS            The protocol interface was installed\r
+  On EFI_NOT_FOUND          The OldInterface on the handle was not found\r
+  On EFI_INVALID_PARAMETER  One of the parameters has an invalid value\r
+  \r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreUninstallProtocolInterface (\r
+  IN EFI_HANDLE       UserHandle,\r
+  IN EFI_GUID         *Protocol,\r
+  IN VOID             *Interface\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Uninstalls all instances of a protocol:interfacer from a handle. \r
+  If the last protocol interface is remove from the handle, the \r
+  handle is freed.\r
+\r
+Arguments:\r
+\r
+  UserHandle      - The handle to remove the protocol handler from\r
+\r
+  Protocol        - The protocol, of protocol:interface, to remove\r
+\r
+  Interface       - The interface, of protocol:interface, to remove\r
+\r
+Returns:\r
+\r
+  EFI_INVALID_PARAMETER       - Protocol is NULL.\r
+  \r
+  EFI_SUCCESS                 - Protocol interface successfully uninstalled.\r
+\r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreHandleProtocol (\r
+  IN  EFI_HANDLE       UserHandle,\r
+  IN  EFI_GUID         *Protocol,\r
+  OUT VOID             **Interface\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Queries a handle to determine if it supports a specified protocol.\r
+\r
+Arguments:\r
+\r
+  UserHandle  - The handle being queried.\r
+\r
+  Protocol    - The published unique identifier of the protocol.\r
+\r
+  Interface   - Supplies the address where a pointer to the corresponding Protocol\r
+               Interface is returned.\r
+\r
+Returns:\r
+\r
+  The requested protocol interface for the handle\r
+  \r
+--*/  \r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreOpenProtocol (\r
+  IN  EFI_HANDLE                UserHandle,\r
+  IN  EFI_GUID                  *Protocol,\r
+  OUT VOID                      **Interface OPTIONAL,\r
+  IN  EFI_HANDLE                ImageHandle,\r
+  IN  EFI_HANDLE                ControllerHandle,\r
+  IN  UINT32                    Attributes\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Locates the installed protocol handler for the handle, and\r
+  invokes it to obtain the protocol interface. Usage information\r
+  is registered in the protocol data base.\r
+\r
+Arguments:\r
+\r
+  UserHandle        - The handle to obtain the protocol interface on\r
+\r
+  Protocol          - The ID of the protocol \r
+\r
+  Interface         - The location to return the protocol interface\r
+\r
+  ImageHandle       - The handle of the Image that is opening the protocol interface\r
+                    specified by Protocol and Interface.\r
+  \r
+  ControllerHandle  - The controller handle that is requiring this interface.\r
+\r
+  Attributes     - The open mode of the protocol interface specified by Handle\r
+                    and Protocol.\r
+\r
+Returns:\r
+\r
+  EFI_INVALID_PARAMETER       - Protocol is NULL.\r
+  \r
+  EFI_SUCCESS                 - Get the protocol interface.\r
+  \r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreOpenProtocolInformation (\r
+  IN  EFI_HANDLE                          UserHandle,\r
+  IN  EFI_GUID                            *Protocol,\r
+  OUT EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer,\r
+  OUT UINTN                               *EntryCount\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Return information about Opened protocols in the system\r
+\r
+Arguments:\r
+\r
+  UserHandle  - The handle to close the protocol interface on\r
+\r
+  Protocol    - The ID of the protocol \r
+\r
+  EntryBuffer - A pointer to a buffer of open protocol information in the form of\r
+                EFI_OPEN_PROTOCOL_INFORMATION_ENTRY structures.\r
+\r
+  EntryCount  - Number of EntryBuffer entries\r
+\r
+Returns:\r
+\r
+  \r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreCloseProtocol (\r
+  IN  EFI_HANDLE                UserHandle,\r
+  IN  EFI_GUID                  *Protocol,\r
+  IN  EFI_HANDLE                ImageHandle,\r
+  IN  EFI_HANDLE                ControllerHandle\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Close Protocol\r
+\r
+Arguments:\r
+\r
+  UserHandle       - The handle to close the protocol interface on\r
+\r
+  Protocol         - The ID of the protocol \r
+\r
+  ImageHandle      - The user of the protocol to close\r
+\r
+  ControllerHandle - The user of the protocol to close\r
+\r
+Returns:\r
+\r
+  EFI_INVALID_PARAMETER     - Protocol is NULL.\r
+    \r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreProtocolsPerHandle (\r
+  IN  EFI_HANDLE       UserHandle,\r
+  OUT EFI_GUID         ***ProtocolBuffer,\r
+  OUT UINTN            *ProtocolBufferCount\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Retrieves the list of protocol interface GUIDs that are installed on a handle in a buffer allocated\r
+ from pool.\r
+\r
+Arguments:\r
+\r
+  UserHandle           - The handle from which to retrieve the list of protocol interface\r
+                          GUIDs.\r
+\r
+  ProtocolBuffer       - A pointer to the list of protocol interface GUID pointers that are\r
+                          installed on Handle.\r
+\r
+  ProtocolBufferCount  - A pointer to the number of GUID pointers present in\r
+                          ProtocolBuffer.\r
+\r
+Returns:\r
+  EFI_SUCCESS   -  The list of protocol interface GUIDs installed on Handle was returned in\r
+                   ProtocolBuffer. The number of protocol interface GUIDs was\r
+                   returned in ProtocolBufferCount.\r
+  EFI_INVALID_PARAMETER   -  Handle is NULL.\r
+  EFI_INVALID_PARAMETER   -  Handle is not a valid EFI_HANDLE.\r
+  EFI_INVALID_PARAMETER   -  ProtocolBuffer is NULL.\r
+  EFI_INVALID_PARAMETER   -  ProtocolBufferCount is NULL.\r
+  EFI_OUT_OF_RESOURCES    -  There is not enough pool memory to store the results.\r
+  \r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreRegisterProtocolNotify (\r
+  IN  EFI_GUID       *Protocol,\r
+  IN  EFI_EVENT      Event,\r
+  OUT VOID           **Registration\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Add a new protocol notification record for the request protocol.\r
+\r
+Arguments:\r
+\r
+  Protocol      - The requested protocol to add the notify registration\r
+\r
+  Event         - The event to signal \r
+\r
+  Registration  - Returns the registration record\r
+\r
+\r
+Returns:\r
+\r
+  EFI_INVALID_PARAMETER       - Invalid parameter\r
+\r
+  EFI_SUCCESS                 - Successfully returned the registration record that has been added\r
+  \r
+--*/\r
+;\r
+  \r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreLocateHandle (\r
+  IN     EFI_LOCATE_SEARCH_TYPE         SearchType,\r
+  IN     EFI_GUID                       *Protocol OPTIONAL,\r
+  IN     VOID                           *SearchKey OPTIONAL,\r
+  IN OUT UINTN                          *BufferSize,\r
+  OUT    EFI_HANDLE                     *Buffer\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Locates the requested handle(s) and returns them in Buffer.\r
+\r
+Arguments:\r
+\r
+  SearchType  - The type of search to perform to locate the handles\r
+\r
+  Protocol    - The protocol to search for\r
+  \r
+  SearchKey   - Dependant on SearchType\r
+\r
+  BufferSize  - On input the size of Buffer.  On output the \r
+                size of data returned.  \r
+\r
+  Buffer      - The buffer to return the results in\r
+\r
+\r
+Returns:\r
+\r
+  EFI_BUFFER_TOO_SMALL      - Buffer too small, required buffer size is returned in BufferSize.\r
+\r
+  EFI_INVALID_PARAMETER     - Invalid parameter\r
+  \r
+  EFI_SUCCESS               - Successfully found the requested handle(s) and returns them in Buffer.\r
+  \r
+--*/\r
+;\r
+  \r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreLocateDevicePath (\r
+  IN     EFI_GUID                       *Protocol,\r
+  IN OUT EFI_DEVICE_PATH_PROTOCOL       **FilePath,\r
+  OUT    EFI_HANDLE                     *Device\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Locates the handle to a device on the device path that supports the specified protocol.\r
+\r
+Arguments:\r
+\r
+  Protocol    - The protocol to search for.\r
+  FilePath    - On input, a pointer to a pointer to the device path. On output, the device\r
+                  path pointer is modified to point to the remaining part of the devicepath.\r
+  Device      - A pointer to the returned device handle.              \r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - The resulting handle was returned.\r
+  EFI_NOT_FOUND         - No handles matched the search.\r
+  EFI_INVALID_PARAMETER - One of the parameters has an invalid value.\r
+\r
+--*/\r
+;\r
+\r
\r
+EFI_STATUS\r
+EFIAPI\r
+CoreLocateHandleBuffer (\r
+  IN     EFI_LOCATE_SEARCH_TYPE         SearchType,\r
+  IN     EFI_GUID                       *Protocol OPTIONAL,\r
+  IN     VOID                           *SearchKey OPTIONAL,\r
+  IN OUT UINTN                          *NumberHandles,\r
+  OUT    EFI_HANDLE                     **Buffer\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Function returns an array of handles that support the requested protocol \r
+  in a buffer allocated from pool. This is a version of CoreLocateHandle()\r
+  that allocates a buffer for the caller.\r
+\r
+Arguments:\r
+\r
+  SearchType           - Specifies which handle(s) are to be returned.\r
+  Protocol             - Provides the protocol to search by.   \r
+                         This parameter is only valid for SearchType ByProtocol.\r
+  SearchKey            - Supplies the search key depending on the SearchType.\r
+  NumberHandles      - The number of handles returned in Buffer.\r
+  Buffer               - A pointer to the buffer to return the requested array of \r
+                         handles that support Protocol.\r
+\r
+Returns:\r
+  \r
+  EFI_SUCCESS             - The result array of handles was returned.\r
+  EFI_NOT_FOUND           - No handles match the search. \r
+  EFI_OUT_OF_RESOURCES    - There is not enough pool memory to store the matching results.\r
+  EFI_INVALID_PARAMETER   - Invalid parameter\r
+\r
+--*/\r
+;\r
+\r
\r
+EFI_STATUS\r
+EFIAPI\r
+CoreLocateProtocol (\r
+  IN    EFI_GUID  *Protocol,\r
+  IN    VOID      *Registration OPTIONAL,\r
+  OUT   VOID      **Interface\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Return the first Protocol Interface that matches the Protocol GUID. If\r
+  Registration is pasased in return a Protocol Instance that was just add\r
+  to the system. If Retistration is NULL return the first Protocol Interface\r
+  you find.\r
+\r
+Arguments:\r
+\r
+  Protocol     - The protocol to search for\r
+  \r
+  Registration - Optional Registration Key returned from RegisterProtocolNotify() \r
+\r
+  Interface    - Return the Protocol interface (instance).\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS                 - If a valid Interface is returned\r
+  \r
+  EFI_INVALID_PARAMETER       - Invalid parameter\r
+  \r
+  EFI_NOT_FOUND               - Protocol interface not found\r
+\r
+--*/\r
+;\r
+\r
+UINT64\r
+CoreGetHandleDatabaseKey (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  return handle database key.\r
+\r
+Arguments:\r
+\r
+  None\r
+  \r
+Returns:\r
+  \r
+  Handle database key.\r
+  \r
+--*/\r
+;\r
+\r
+VOID\r
+CoreConnectHandlesByKey (\r
+  UINT64  Key\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Go connect any handles that were created or modified while a image executed.\r
+\r
+Arguments:\r
+\r
+  Key  -  The Key to show that the handle has been created/modified\r
+\r
+Returns:\r
+  \r
+  None\r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS \r
+EFIAPI\r
+CoreConnectController (\r
+  IN  EFI_HANDLE                ControllerHandle,\r
+  IN  EFI_HANDLE                *DriverImageHandle    OPTIONAL,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL  *RemainingDevicePath  OPTIONAL,\r
+  IN  BOOLEAN                   Recursive\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Connects one or more drivers to a controller.\r
+\r
+Arguments:\r
+\r
+  ControllerHandle            - Handle of the controller to be connected.\r
+\r
+  DriverImageHandle           - DriverImageHandle A pointer to an ordered list of driver image handles.\r
+\r
+  RemainingDevicePath         - RemainingDevicePath A pointer to the device path that specifies a child of the\r
+                                controller specified by ControllerHandle.\r
+    \r
+  Recursive -                 - Whether the function would be called recursively or not.\r
+\r
+Returns:\r
+\r
+  Status code.\r
+\r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS \r
+EFIAPI\r
+CoreDisconnectController (\r
+  IN EFI_HANDLE  ControllerHandle,\r
+  IN EFI_HANDLE  DriverImageHandle  OPTIONAL,\r
+  IN EFI_HANDLE  ChildHandle        OPTIONAL\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Disonnects a controller from a driver\r
+\r
+Arguments:\r
+\r
+  ControllerHandle  - ControllerHandle The handle of the controller from which driver(s) \r
+                        are to be disconnected.\r
+  DriverImageHandle - DriverImageHandle The driver to disconnect from ControllerHandle.\r
+  ChildHandle       - ChildHandle The handle of the child to destroy.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           -  One or more drivers were disconnected from the controller.\r
+  EFI_SUCCESS           -  On entry, no drivers are managing ControllerHandle.\r
+  EFI_SUCCESS           -  DriverImageHandle is not NULL, and on entry DriverImageHandle is not managing ControllerHandle.\r
+  EFI_INVALID_PARAMETER -  ControllerHandle is not a valid EFI_HANDLE.\r
+  EFI_INVALID_PARAMETER -  DriverImageHandle is not NULL, and it is not a valid EFI_HANDLE.\r
+  EFI_INVALID_PARAMETER -  ChildHandle is not NULL, and it is not a valid EFI_HANDLE.\r
+  EFI_OUT_OF_RESOURCES  -  There are not enough resources available to disconnect any drivers from ControllerHandle.\r
+  EFI_DEVICE_ERROR      -  The controller could not be disconnected because of a device error.\r
+\r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreAllocatePages (\r
+  IN      EFI_ALLOCATE_TYPE       Type,\r
+  IN      EFI_MEMORY_TYPE         MemoryType,\r
+  IN      UINTN                   NumberOfPages,\r
+  IN OUT  EFI_PHYSICAL_ADDRESS    *Memory\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Allocates pages from the memory map.\r
+\r
+Arguments:\r
+\r
+  Type          - The type of allocation to perform\r
+\r
+  MemoryType    - The type of memory to turn the allocated pages into\r
+\r
+  NumberOfPages - The number of pages to allocate\r
+\r
+  Memory        - A pointer to receive the base allocated memory address\r
+\r
+Returns:\r
+\r
+  Status. On success, Memory is filled in with the base address allocated\r
+  \r
+  EFI_INVALID_PARAMETER     - Parameters violate checking rules defined in spec.\r
+  \r
+  EFI_NOT_FOUND             - Could not allocate pages match the requirement.\r
+  \r
+  EFI_OUT_OF_RESOURCES      - No enough pages to allocate.\r
+  \r
+  EFI_SUCCESS               - Pages successfully allocated.\r
+\r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS \r
+EFIAPI\r
+CoreFreePages (\r
+  IN EFI_PHYSICAL_ADDRESS   Memory,\r
+  IN UINTN                  NumberOfPages\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Frees previous allocated pages.\r
+\r
+Arguments:\r
+\r
+  Memory        - Base address of memory being freed\r
+\r
+  NumberOfPages - The number of pages to free\r
+\r
+Returns:\r
+\r
+  EFI_NOT_FOUND       - Could not find the entry that covers the range\r
+  \r
+  EFI_INVALID_PARAMETER   - Address not aligned\r
+  \r
+  EFI_SUCCESS         -Pages successfully freed.\r
+\r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreGetMemoryMap (\r
+  IN OUT UINTN                       *MemoryMapSize,\r
+  IN OUT EFI_MEMORY_DESCRIPTOR       *Desc,\r
+  OUT    UINTN                       *MapKey,\r
+  OUT    UINTN                       *DescriptorSize,\r
+  OUT    UINT32                      *DescriptorVersion\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Returns the current memory map.\r
+\r
+Arguments:\r
+\r
+  MemoryMapSize     - On input the buffer size of MemoryMap allocated by caller\r
+                      On output the required buffer size to contain the memory map \r
+                      \r
+  Desc              - The buffer to return the current memory map\r
+\r
+  MapKey            - The address to return the current map key\r
+\r
+  DescriptorSize    - The size in bytes for an individual EFI_MEMORY_DESCRIPTOR\r
+\r
+  DescriptorVersion - The version number associated with the EFI_MEMORY_DESCRIPTOR\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           The current memory map was returned successfully\r
+\r
+  EFI_BUFFER_TOO_SMALL  The MemoryMap buffer was too small\r
+\r
+  EFI_INVALID_PARAMETER One of the parameters has an invalid value\r
+\r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreAllocatePool (\r
+  IN   EFI_MEMORY_TYPE  PoolType,\r
+  IN   UINTN            Size,\r
+  OUT  VOID             **Buffer\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Allocate pool of a particular type.\r
+\r
+Arguments:\r
+\r
+  PoolType    - Type of pool to allocate\r
+\r
+  Size        - The amount of pool to allocate\r
+\r
+  Buffer      - The address to return a pointer to the allocated pool\r
+\r
+Returns:\r
+\r
+  EFI_INVALID_PARAMETER     - PoolType not valid\r
+  \r
+  EFI_OUT_OF_RESOURCES      - Size exceeds max pool size or allocation failed.  \r
+  \r
+  EFI_SUCCESS               - Pool successfully allocated.\r
+\r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreFreePool (\r
+  IN VOID      *Buffer\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Frees pool.\r
+\r
+Arguments:\r
+\r
+  Buffer      - The allocated pool entry to free\r
+\r
+Returns:\r
+\r
+  EFI_INVALID_PARAMETER   - Buffer is not a valid value.\r
+  \r
+  EFI_SUCCESS             - Pool successfully freed.\r
+\r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreLoadImage (\r
+  IN  BOOLEAN                    BootPolicy,\r
+  IN  EFI_HANDLE                 ParentImageHandle,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL   *FilePath,\r
+  IN  VOID                       *SourceBuffer   OPTIONAL,\r
+  IN  UINTN                      SourceSize,\r
+  OUT EFI_HANDLE                 *ImageHandle\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Loads an EFI image into memory and returns a handle to the image.\r
+\r
+Arguments:\r
+\r
+  BootPolicy          - If TRUE, indicates that the request originates from the boot manager,\r
+                        and that the boot manager is attempting to load FilePath as a boot selection.\r
+  ParentImageHandle   - The caller's image handle.\r
+  FilePath            - The specific file path from which the image is loaded.\r
+  SourceBuffer        - If not NULL, a pointer to the memory location containing a copy of \r
+                        the image to be loaded.\r
+  SourceSize          - The size in bytes of SourceBuffer.\r
+  ImageHandle         - Pointer to the returned image handle that is created when the image \r
+                        is successfully loaded.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS            - The image was loaded into memory.\r
+  EFI_NOT_FOUND          - The FilePath was not found.\r
+  EFI_INVALID_PARAMETER  - One of the parameters has an invalid value.\r
+  EFI_UNSUPPORTED        - The image type is not supported, or the device path cannot be \r
+                           parsed to locate the proper protocol for loading the file.\r
+  EFI_OUT_OF_RESOURCES   - Image was not loaded due to insufficient resources.\r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreUnloadImage (\r
+  IN EFI_HANDLE  ImageHandle\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Unload the specified image.\r
+\r
+Arguments:\r
+\r
+  ImageHandle       - The specified image handle.\r
+\r
+Returns:\r
+\r
+  EFI_INVALID_PARAMETER       - Image handle is NULL.\r
+  \r
+  EFI_UNSUPPORTED             - Attempt to unload an unsupported image.\r
+  \r
+  EFI_SUCCESS                 - Image successfully unloaded.\r
+\r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreStartImage (\r
+  IN  EFI_HANDLE  ImageHandle,\r
+  OUT UINTN       *ExitDataSize,\r
+  OUT CHAR16      **ExitData  OPTIONAL\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Transfer control to a loaded image's entry point.\r
+\r
+Arguments:\r
+\r
+  ImageHandle     - Handle of image to be started.\r
+  \r
+  ExitDataSize    - Pointer of the size to ExitData\r
+  \r
+  ExitData        - Pointer to a pointer to a data buffer that includes a Null-terminated\r
+                    Unicode string, optionally followed by additional binary data. The string\r
+                    is a description that the caller may use to further indicate the reason for\r
+                    the image's exit.\r
+\r
+Returns:\r
+\r
+  EFI_INVALID_PARAMETER     - Invalid parameter\r
+  \r
+  EFI_OUT_OF_RESOURCES       - No enough buffer to allocate\r
+  \r
+  EFI_SUCCESS               - Successfully transfer control to the image's entry point.\r
+\r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreExit (\r
+  IN EFI_HANDLE  ImageHandle,\r
+  IN EFI_STATUS  Status,\r
+  IN UINTN       ExitDataSize,\r
+  IN CHAR16      *ExitData  OPTIONAL\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Terminates the currently loaded EFI image and returns control to boot services.\r
+\r
+Arguments:\r
+\r
+  ImageHandle       - Handle that identifies the image. This parameter is passed to the image \r
+                      on entry.\r
+  Status            - The image's exit code.\r
+  ExitDataSize      - The size, in bytes, of ExitData. Ignored if ExitStatus is\r
+                      EFI_SUCCESS.\r
+  ExitData          - Pointer to a data buffer that includes a Null-terminated Unicode string,\r
+                      optionally followed by additional binary data. The string is a \r
+                      description that the caller may use to further indicate the reason for\r
+                      the image's exit.\r
+\r
+Returns:\r
+\r
+  EFI_INVALID_PARAMETER     - Image handle is NULL or it is not current image.\r
+  \r
+  EFI_SUCCESS               - Successfully terminates the currently loaded EFI image.\r
+  \r
+  EFI_ACCESS_DENIED         - Should never reach there.\r
+\r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreCreateEvent (\r
+  IN  UINT32               Type,\r
+  IN  EFI_TPL              NotifyTpl,\r
+  IN  EFI_EVENT_NOTIFY     NotifyFunction,\r
+  IN  VOID                 *NotifyContext,\r
+  OUT EFI_EVENT            *pEvent\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Creates a general-purpose event structure\r
+\r
+Arguments:\r
+\r
+  Type                - The type of event to create and its mode and attributes\r
+  NotifyTpl           - The task priority level of event notifications\r
+  NotifyFunction      - Pointer to the event's notification function\r
+  NotifyContext       - Pointer to the notification function's context; corresponds to\r
+                        parameter "Context" in the notification function\r
+  pEvent              - Pointer to the newly created event if the call succeeds; undefined otherwise\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - The event structure was created\r
+  EFI_INVALID_PARAMETER - One of the parameters has an invalid value\r
+  EFI_OUT_OF_RESOURCES  - The event could not be allocated\r
+\r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreCreateEventEx (\r
+  IN UINT32                   Type,\r
+  IN EFI_TPL                  NotifyTpl,\r
+  IN EFI_EVENT_NOTIFY         NotifyFunction, OPTIONAL\r
+  IN CONST VOID               *NotifyContext, OPTIONAL\r
+  IN CONST EFI_GUID           *EventGroup,    OPTIONAL\r
+  OUT EFI_EVENT               *Event\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Creates a general-purpose event structure\r
+\r
+Arguments:\r
+  Type                - The type of event to create and its mode and attributes\r
+  NotifyTpl           - The task priority level of event notifications\r
+  NotifyFunction      - Pointer to the events notification function\r
+  NotifyContext       - Pointer to the notification functions context; corresponds to\r
+                        parameter "Context" in the notification function\r
+  EventGrout          - GUID for EventGroup if NULL act the same as gBS->CreateEvent().\r
+  Event               - Pointer to the newly created event if the call succeeds; undefined otherwise\r
+\r
+Returns:\r
+  EFI_SUCCESS           - The event structure was created\r
+  EFI_INVALID_PARAMETER - One of the parameters has an invalid value\r
+  EFI_OUT_OF_RESOURCES  - The event could not be allocated\r
+\r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreSetTimer (\r
+  IN EFI_EVENT            Event,\r
+  IN EFI_TIMER_DELAY      Type,\r
+  IN UINT64               TriggerTime\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Sets the type of timer and the trigger time for a timer event.\r
+\r
+Arguments:\r
+\r
+  UserEvent   - The timer event that is to be signaled at the specified time\r
+  Type        - The type of time that is specified in TriggerTime\r
+  TriggerTime - The number of 100ns units until the timer expires\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS           - The event has been set to be signaled at the requested time\r
+  EFI_INVALID_PARAMETER - Event or Type is not valid\r
+\r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreSignalEvent (\r
+  IN EFI_EVENT            Event\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Signals the event.  Queues the event to be notified if needed\r
+    \r
+Arguments:\r
+\r
+  Event - The event to signal\r
+    \r
+Returns:\r
+\r
+  EFI_INVALID_PARAMETER - Parameters are not valid.\r
+  \r
+  EFI_SUCCESS - The event was signaled.\r
+\r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreWaitForEvent (\r
+  IN  UINTN        NumberOfEvents,\r
+  IN  EFI_EVENT    *UserEvents,\r
+  OUT UINTN        *UserIndex\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Stops execution until an event is signaled.\r
+    \r
+Arguments:\r
+\r
+  NumberOfEvents  - The number of events in the UserEvents array\r
+  UserEvents      - An array of EFI_EVENT\r
+  UserIndex       - Pointer to the index of the event which satisfied the wait condition\r
+    \r
+Returns:\r
+\r
+  EFI_SUCCESS           - The event indicated by Index was signaled.\r
+  EFI_INVALID_PARAMETER - The event indicated by Index has a notification function or \r
+                          Event was not a valid type\r
+  EFI_UNSUPPORTED       - The current TPL is not TPL_APPLICATION\r
+\r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreCloseEvent (\r
+  IN EFI_EVENT            Event\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Closes an event and frees the event structure.\r
+    \r
+Arguments:\r
+\r
+  UserEvent - Event to close\r
+    \r
+Returns:\r
+\r
+  EFI_INVALID_PARAMETER - Parameters are not valid.\r
+  \r
+  EFI_SUCCESS - The event has been closed\r
+\r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreCheckEvent (\r
+  IN EFI_EVENT            Event\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Check the status of an event\r
+    \r
+Arguments:\r
+\r
+  UserEvent - The event to check\r
+    \r
+Returns:\r
+\r
+  EFI_SUCCESS           - The event is in the signaled state\r
+  EFI_NOT_READY         - The event is not in the signaled state\r
+  EFI_INVALID_PARAMETER - Event is of type EVT_NOTIFY_SIGNAL\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CoreAddMemorySpace (\r
+  IN EFI_GCD_MEMORY_TYPE   GcdMemoryType,\r
+  IN EFI_PHYSICAL_ADDRESS  BaseAddress,\r
+  IN UINT64                Length,\r
+  IN UINT64                Capabilities\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Add a segment of memory space to GCD map and add all available pages in this segment \r
+  as memory descriptors.\r
+\r
+Arguments:\r
+    \r
+  GcdMemoryType     - Memory type of the segment.\r
+  \r
+  BaseAddress       - Base address of the segment.\r
+  \r
+  Length            - Length of the segment.\r
+  \r
+  Capabilities      - alterable attributes of the segment.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS       - Merged this segment into GCD map.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CoreAllocateMemorySpace (\r
+  IN     EFI_GCD_ALLOCATE_TYPE  GcdAllocateType,\r
+  IN     EFI_GCD_MEMORY_TYPE    GcdMemoryType,\r
+  IN     UINTN                  Alignment,\r
+  IN     UINT64                 Length,\r
+  IN OUT EFI_PHYSICAL_ADDRESS   *BaseAddress,\r
+  IN     EFI_HANDLE             ImageHandle,\r
+  IN     EFI_HANDLE             DeviceHandle OPTIONAL\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Allocate memory space on GCD map.\r
+\r
+Arguments:\r
+  \r
+  GcdAllocateType   - The type of allocate operation\r
+  \r
+  GcdMemoryType     - The desired memory type\r
+  \r
+  Alignment         - Align with 2^Alignment\r
+  \r
+  Length            - Length to allocate\r
+  \r
+  BaseAddress       - Base address to allocate\r
+  \r
+  ImageHandle       - The image handle consume the allocated space.\r
+  \r
+  DeviceHandle      - The device handle consume the allocated space.\r
+\r
+Returns:\r
+\r
+  EFI_INVALID_PARAMETER       - Invalid parameter.\r
+  \r
+  EFI_NOT_FOUND               - No descriptor contains the desired space.\r
+  \r
+  EFI_SUCCESS                 - Memory space successfully allocated.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CoreFreeMemorySpace (\r
+  IN EFI_PHYSICAL_ADDRESS  BaseAddress,\r
+  IN UINT64                Length\r
+  )\r
+/*++\r
+\r
+Routine Description:Routine Description:\r
+\r
+  Free a segment of memory space in GCD map.\r
+\r
+Arguments:\r
+    \r
+  BaseAddress       - Base address of the segment.\r
+  \r
+  Length            - Length of the segment.\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS       - Space successfully freed.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CoreRemoveMemorySpace (\r
+  IN EFI_PHYSICAL_ADDRESS  BaseAddress,\r
+  IN UINT64                Length\r
+  )\r
+/*++\r
+\r
+Routine Description:Routine Description:\r
+\r
+  Remove a segment of memory space in GCD map.\r
+\r
+Arguments:\r
+    \r
+  BaseAddress       - Base address of the segment.\r
+  \r
+  Length            - Length of the segment.\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS       - Successfully a segment of memory space.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CoreGetMemorySpaceDescriptor (\r
+  IN  EFI_PHYSICAL_ADDRESS             BaseAddress,\r
+  OUT EFI_GCD_MEMORY_SPACE_DESCRIPTOR  *Descriptor\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Search all entries in GCD map which contains specified segment and build it to a descriptor.\r
+\r
+Arguments:\r
+\r
+  BaseAddress       - Specified start address\r
+  \r
+  Descriptor        - Specified length\r
+\r
+Returns:\r
+\r
+  EFI_INVALID_PARAMETER       - Invalid parameter\r
+  \r
+  EFI_SUCCESS                 - Successfully get memory space descriptor.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CoreSetMemorySpaceAttributes (\r
+  IN EFI_PHYSICAL_ADDRESS  BaseAddress,\r
+  IN UINT64                Length,\r
+  IN UINT64                Attributes\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set memory space with specified attributes.\r
+\r
+Arguments:\r
+\r
+  BaseAddress       - Specified start address\r
+  \r
+  Length            - Specified length\r
+  \r
+  Attributes        - Specified attributes\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS       - Successfully set attribute of a segment of memory space.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CoreGetMemorySpaceMap (\r
+  OUT UINTN                            *NumberOfDescriptors,\r
+  OUT EFI_GCD_MEMORY_SPACE_DESCRIPTOR  **MemorySpaceMap\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Transer all entries of GCD memory map into memory descriptors and pass to caller.\r
+\r
+Arguments:\r
+\r
+  NumberOfDescriptors       - Number of descriptors.\r
+  \r
+  MemorySpaceMap            - Descriptor array\r
+\r
+Returns:\r
+\r
+  EFI_INVALID_PARAMETER     - Invalid parameter\r
+  \r
+  EFI_OUT_OF_RESOURCES      - No enough buffer to allocate\r
+  \r
+  EFI_SUCCESS               - Successfully get memory space map.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CoreAddIoSpace (\r
+  IN EFI_GCD_IO_TYPE       GcdIoType,\r
+  IN EFI_PHYSICAL_ADDRESS  BaseAddress,\r
+  IN UINT64                Length\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Add a segment of IO space to GCD map.\r
+\r
+Arguments:\r
+    \r
+  GcdIoType         - IO type of the segment.\r
+  \r
+  BaseAddress       - Base address of the segment.\r
+  \r
+  Length            - Length of the segment.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS       - Merged this segment into GCD map.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CoreAllocateIoSpace (\r
+  IN     EFI_GCD_ALLOCATE_TYPE  GcdAllocateType,\r
+  IN     EFI_GCD_IO_TYPE        GcdIoType,\r
+  IN     UINTN                  Alignment,\r
+  IN     UINT64                 Length,\r
+  IN OUT EFI_PHYSICAL_ADDRESS   *BaseAddress,\r
+  IN     EFI_HANDLE             ImageHandle,\r
+  IN     EFI_HANDLE             DeviceHandle OPTIONAL\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Allocate IO space on GCD map.\r
+\r
+Arguments:\r
+  \r
+  GcdAllocateType   - The type of allocate operation\r
+  \r
+  GcdIoType         - The desired IO type\r
+  \r
+  Alignment         - Align with 2^Alignment\r
+  \r
+  Length            - Length to allocate\r
+  \r
+  BaseAddress       - Base address to allocate\r
+  \r
+  ImageHandle       - The image handle consume the allocated space.\r
+  \r
+  DeviceHandle      - The device handle consume the allocated space.\r
+\r
+Returns:\r
+\r
+  EFI_INVALID_PARAMETER       - Invalid parameter.\r
+  \r
+  EFI_NOT_FOUND               - No descriptor contains the desired space.\r
+  \r
+  EFI_SUCCESS                 - IO space successfully allocated.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CoreFreeIoSpace (\r
+  IN EFI_PHYSICAL_ADDRESS  BaseAddress,\r
+  IN UINT64                Length\r
+  )\r
+/*++\r
+\r
+Routine Description:Routine Description:\r
+\r
+  Free a segment of IO space in GCD map.\r
+\r
+Arguments:\r
+    \r
+  BaseAddress       - Base address of the segment.\r
+  \r
+  Length            - Length of the segment.\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS       - Space successfully freed.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CoreRemoveIoSpace (\r
+  IN EFI_PHYSICAL_ADDRESS  BaseAddress,\r
+  IN UINT64                Length\r
+  )\r
+/*++\r
+\r
+Routine Description:Routine Description:\r
+\r
+  Remove a segment of IO space in GCD map.\r
+\r
+Arguments:\r
+    \r
+  BaseAddress       - Base address of the segment.\r
+  \r
+  Length            - Length of the segment.\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS       - Successfully removed a segment of IO space.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CoreGetIoSpaceDescriptor (\r
+  IN  EFI_PHYSICAL_ADDRESS         BaseAddress,\r
+  OUT EFI_GCD_IO_SPACE_DESCRIPTOR  *Descriptor\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Search all entries in GCD map which contains specified segment and build it to a descriptor.\r
+\r
+Arguments:\r
+\r
+  BaseAddress       - Specified start address\r
+  \r
+  Descriptor        - Specified length\r
+\r
+Returns:\r
+\r
+  EFI_INVALID_PARAMETER       - Descriptor is NULL.\r
+  \r
+  EFI_SUCCESS                 - Successfully get the IO space descriptor.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CoreGetIoSpaceMap (\r
+  OUT UINTN                        *NumberOfDescriptors,\r
+  OUT EFI_GCD_IO_SPACE_DESCRIPTOR  **IoSpaceMap\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Transer all entries of GCD IO map into IO descriptors and pass to caller.\r
+\r
+Arguments:\r
+\r
+  NumberOfDescriptors       - Number of descriptors.\r
+  \r
+  IoSpaceMap                - Descriptor array\r
+\r
+Returns:\r
+\r
+  EFI_INVALID_PARAMETER     - Invalid parameter\r
+  \r
+  EFI_OUT_OF_RESOURCES      - No enough buffer to allocate\r
+  \r
+  EFI_SUCCESS               - Successfully get IO space map.\r
+\r
+--*/\r
+;\r
+\r
+EFI_DXESERVICE\r
+EFI_STATUS\r
+EFIAPI\r
+CoreDispatcher (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\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
+  image for each driver. Search the mDiscoveredList to see if any driver can \r
+  be placed on the mScheduledQueue. If no drivers are placed on the\r
+  mScheduledQueue exit the function. On exit it is assumed the Bds()\r
+  will be called, and when the Bds() exits the Dispatcher will be called \r
+  again.\r
+\r
+Arguments:\r
+\r
+  NONE\r
+\r
+Returns:\r
+\r
+  EFI_ALREADY_STARTED - The DXE Dispatcher is already running\r
+\r
+  EFI_NOT_FOUND       - No DXE Drivers were dispatched\r
+\r
+  EFI_SUCCESS         - One or more DXE Drivers were dispatched\r
+\r
+--*/\r
+;\r
+EFI_DXESERVICE\r
+EFI_STATUS\r
+EFIAPI\r
+CoreSchedule (\r
+  IN  EFI_HANDLE  FirmwareVolumeHandle,\r
+  IN  EFI_GUID    *DriverName\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Check every driver and locate a matching one. If the driver is found, the Unrequested\r
+  state flag is cleared.\r
+\r
+Arguments:\r
+\r
+  FirmwareVolumeHandle - The handle of the Firmware Volume that contains the firmware \r
+                         file specified by DriverName.\r
+\r
+  DriverName           - The Driver name to put in the Dependent state.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS   - The DriverName was found and it's SOR bit was cleared\r
+\r
+  EFI_NOT_FOUND - The DriverName does not exist or it's SOR bit was not set.\r
+\r
+--*/\r
+;\r
+\r
+EFI_DXESERVICE\r
+EFI_STATUS\r
+EFIAPI\r
+CoreTrust (\r
+  IN  EFI_HANDLE  FirmwareVolumeHandle,\r
+  IN  EFI_GUID    *DriverName\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Convert a driver from the Untrused back to the Scheduled state\r
+\r
+Arguments:\r
+\r
+  FirmwareVolumeHandle - The handle of the Firmware Volume that contains the firmware \r
+                         file specified by DriverName.\r
+\r
+  DriverName           - The Driver name to put in the Scheduled state\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS   - The file was found in the untrusted state, and it was promoted \r
+                  to the trusted state.\r
+\r
+  EFI_NOT_FOUND - The file was not found in the untrusted state.\r
+\r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+CoreGrowBuffer (\r
+  IN OUT EFI_STATUS       *Status,\r
+  IN OUT VOID             **Buffer,\r
+  IN     UINTN            BufferSize\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+    Helper function called as part of the code needed\r
+    to allocate the proper sized buffer for various \r
+    EFI interfaces.\r
+\r
+Arguments:\r
+\r
+    Status      - Current status\r
+\r
+    Buffer      - Current allocated buffer, or NULL\r
+\r
+    BufferSize  - Current buffer size needed\r
+    \r
+Returns:\r
+    \r
+    TRUE - if the buffer was reallocated and the caller \r
+    should try the API again.\r
+\r
+    FALSE - buffer could not be allocated and the caller\r
+    should not try the API again.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+FwVolDriverInit (\r
+  IN EFI_HANDLE                   ImageHandle,\r
+  IN EFI_SYSTEM_TABLE             *SystemTable\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+    This routine is the driver initialization entry point.  It initializes the\r
+    libraries, and registers two notification functions.  These notification\r
+    functions are responsible for building the FV stack dynamically.\r
+    \r
+Arguments:\r
+    ImageHandle   - The image handle.\r
+    SystemTable   - The system table.\r
+    \r
+Returns:\r
+    EFI_SUCCESS   - Function successfully returned.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+InitializeSectionExtraction (\r
+  IN EFI_HANDLE                   ImageHandle,\r
+  IN EFI_SYSTEM_TABLE             *SystemTable\r
+  )\r
+/*++\r
+\r
+Routine Description: \r
+  Entry point of the section extraction code. Initializes an instance of the \r
+  section extraction interface and installs it on a new handle.\r
+\r
+Arguments:  \r
+  ImageHandle   EFI_HANDLE: A handle for the image that is initializing this driver\r
+  SystemTable   EFI_SYSTEM_TABLE: A pointer to the EFI system table        \r
+\r
+Returns:  \r
+  EFI_SUCCESS:  Driver initialized successfully\r
+  EFI_OUT_OF_RESOURCES:   Could not allocate needed resources\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CoreProcessFirmwareVolume (\r
+  IN  VOID                         *FvHeader,\r
+  IN  UINTN                        Size, \r
+  OUT EFI_HANDLE                   *FVProtocolHandle\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+    This DXE service routine is used to process a firmware volume. In\r
+    particular, it can be called by BDS to process a single firmware\r
+    volume found in a capsule. \r
+\r
+Arguments:\r
+    FvHeader              - pointer to a firmware volume header\r
+    Size                  - the size of the buffer pointed to by FvHeader\r
+    FVProtocolHandle      - the handle on which a firmware volume protocol\r
+                            was produced for the firmware volume passed in.\r
+\r
+Returns:\r
+    EFI_OUT_OF_RESOURCES  - if an FVB could not be produced due to lack of \r
+                            system resources\r
+    EFI_VOLUME_CORRUPTED  - if the volume was corrupted\r
+    EFI_SUCCESS           - a firmware volume protocol was produced for the\r
+                            firmware volume\r
+\r
+--*/\r
+;\r
+\r
+//\r
+//Functions used during debug buils\r
+//\r
+VOID\r
+CoreDisplayMissingArchProtocols (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+  Displays Architectural protocols that were not loaded and are required for DXE core to function\r
+  Only used in Debug Builds\r
+\r
+  Arguments:\r
+    NONE\r
+\r
+  Returns:\r
+    NONE\r
+\r
+--*/;\r
+  \r
+VOID\r
+CoreDisplayDiscoveredNotDispatched (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+\r
+    Traverse the discovered list for any drivers that were discovered but not loaded \r
+    because the dependency experessions evaluated to false\r
+\r
+  Arguments:\r
+\r
+    NONE\r
+\r
+  Returns:\r
+\r
+    NONE \r
+\r
+--*/;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreEfiNotAvailableYetArg0 (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Place holder function until all the Boot Services and Runtime Services are available\r
+\r
+Arguments:\r
+\r
+  None\r
+\r
+Returns:\r
+\r
+  EFI_NOT_AVAILABLE_YET\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreEfiNotAvailableYetArg1 (\r
+  UINTN Arg1\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Place holder function until all the Boot Services and Runtime Services are available\r
+\r
+Arguments:\r
+\r
+  Arg1        - Undefined\r
+\r
+Returns:\r
+\r
+  EFI_NOT_AVAILABLE_YET\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreEfiNotAvailableYetArg2 (\r
+  UINTN Arg1,\r
+  UINTN Arg2\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Place holder function until all the Boot Services and Runtime Services are available\r
+\r
+Arguments:\r
+\r
+  Arg1        - Undefined\r
+  \r
+  Arg2        - Undefined\r
+\r
+Returns:\r
+\r
+  EFI_NOT_AVAILABLE_YET\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreEfiNotAvailableYetArg3 (\r
+  UINTN Arg1,\r
+  UINTN Arg2,\r
+  UINTN Arg3\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Place holder function until all the Boot Services and Runtime Services are available\r
+\r
+Arguments:\r
+\r
+  Arg1        - Undefined\r
+  \r
+  Arg2        - Undefined\r
+  \r
+  Arg3        - Undefined\r
+\r
+Returns:\r
+\r
+  EFI_NOT_AVAILABLE_YET\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreEfiNotAvailableYetArg4 (\r
+  UINTN Arg1,\r
+  UINTN Arg2,\r
+  UINTN Arg3,\r
+  UINTN Arg4\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Place holder function until all the Boot Services and Runtime Services are available\r
+\r
+Arguments:\r
+\r
+  Arg1        - Undefined\r
+  \r
+  Arg2        - Undefined\r
+  \r
+  Arg3        - Undefined\r
+  \r
+  Arg4        - Undefined\r
+\r
+Returns:\r
+\r
+  EFI_NOT_AVAILABLE_YET\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreEfiNotAvailableYetArg5 (\r
+  UINTN Arg1,\r
+  UINTN Arg2,\r
+  UINTN Arg3,\r
+  UINTN Arg4,\r
+  UINTN Arg5\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Place holder function until all the Boot Services and Runtime Services are available\r
+\r
+Arguments:\r
+\r
+  Arg1        - Undefined\r
+  \r
+  Arg2        - Undefined\r
+  \r
+  Arg3        - Undefined\r
+  \r
+  Arg4        - Undefined\r
+  \r
+  Arg5        - Undefined\r
+\r
+Returns:\r
+\r
+  EFI_NOT_AVAILABLE_YET\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CoreGetPeiProtocol (\r
+  IN EFI_GUID  *ProtocolGuid,\r
+  IN VOID      **Interface\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Searches for a Protocol Interface passed from PEI through a HOB\r
+\r
+Arguments:\r
+\r
+  ProtocolGuid - The Protocol GUID to search for in the HOB List\r
+\r
+  Interface    - A pointer to the interface for the Protocol GUID\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS   - The Protocol GUID was found and its interface is returned in Interface\r
+\r
+  EFI_NOT_FOUND - The Protocol GUID was not found in the HOB List\r
+\r
+--*/\r
+;\r
+  \r
+EFI_STATUS\r
+DxeMainUefiDecompressGetInfo (\r
+  IN EFI_DECOMPRESS_PROTOCOL            *This,\r
+  IN   VOID                             *Source,\r
+  IN   UINT32                           SourceSize,\r
+  OUT  UINT32                           *DestinationSize,\r
+  OUT  UINT32                           *ScratchSize\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DxeMainUefiDecompress (\r
+  IN EFI_DECOMPRESS_PROTOCOL              *This,\r
+  IN     VOID                             *Source,\r
+  IN     UINT32                           SourceSize,\r
+  IN OUT VOID                             *Destination,\r
+  IN     UINT32                           DestinationSize,\r
+  IN OUT VOID                             *Scratch,\r
+  IN     UINT32                           ScratchSize\r
+  );\r
+\r
+EFI_STATUS\r
+DxeMainTianoDecompressGetInfo (\r
+  IN EFI_TIANO_DECOMPRESS_PROTOCOL      *This,\r
+  IN   VOID                             *Source,\r
+  IN   UINT32                           SourceSize,\r
+  OUT  UINT32                           *DestinationSize,\r
+  OUT  UINT32                           *ScratchSize\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DxeMainTianoDecompress (\r
+  IN EFI_TIANO_DECOMPRESS_PROTOCOL        *This,\r
+  IN     VOID                             *Source,\r
+  IN     UINT32                           SourceSize,\r
+  IN OUT VOID                             *Destination,\r
+  IN     UINT32                           DestinationSize,\r
+  IN OUT VOID                             *Scratch,\r
+  IN     UINT32                           ScratchSize\r
+  );\r
+\r
+EFI_STATUS\r
+DxeMainCustomDecompressGetInfo (\r
+  IN EFI_CUSTOMIZED_DECOMPRESS_PROTOCOL  *This,\r
+  IN   VOID                              *Source,\r
+  IN   UINT32                            SourceSize,\r
+  OUT  UINT32                            *DestinationSize,\r
+  OUT  UINT32                            *ScratchSize\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DxeMainCustomDecompress (\r
+  IN EFI_CUSTOMIZED_DECOMPRESS_PROTOCOL  *This,\r
+  IN     VOID                            *Source,\r
+  IN     UINT32                          SourceSize,\r
+  IN OUT VOID                            *Destination,\r
+  IN     UINT32                          DestinationSize,\r
+  IN OUT VOID                            *Scratch,\r
+  IN     UINT32                          ScratchSize\r
+  );\r
+\r
+#endif\r
diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf
new file mode 100644 (file)
index 0000000..79dccde
--- /dev/null
@@ -0,0 +1,175 @@
+#/** @file\r
+# Component description file for DxeMain module.\r
+#\r
+# This module provide an DXE CIS compliant implementation of DXE Core.\r
+# Copyright (c) 2006 - 2007, Intel Corporation\r
+#\r
+#  All rights reserved. This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#\r
+#**/\r
+\r
+################################################################################\r
+#\r
+# Defines Section - statements that will be processed to create a Makefile.\r
+#\r
+################################################################################\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = DxeMain\r
+  FILE_GUID                      = D6A2CB7F-6A18-4e2f-B43B-9920A733700A\r
+  MODULE_TYPE                    = DXE_CORE\r
+  VERSION_STRING                 = 1.0\r
+  EDK_RELEASE_VERSION            = 0x00020000\r
+  EFI_SPECIFICATION_VERSION      = 0x00020000\r
+\r
+  ENTRY_POINT                    = DxeMain\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+################################################################################\r
+#\r
+# Sources Section - list of files that are required for the build to succeed.\r
+#\r
+################################################################################\r
+\r
+[Sources.common]\r
+  Library.h\r
+  imem.h\r
+  Image.h\r
+  hand.h\r
+  gcd.h\r
+  FwVolDriver.h\r
+  FwVolBlock.h\r
+  Exec.h\r
+  DxeMain.h\r
+  DebugImageInfo.h\r
+  SectionExtraction/CoreSectionExtraction.c\r
+  Image/ImageFile.c\r
+  Image/Image.c\r
+  Misc/DebugImageInfo.c\r
+  Misc/Stall.c\r
+  Misc/SetWatchdogTimer.c\r
+  Misc/InstallConfigurationTable.c\r
+  Library/Library.c\r
+  Hand/DriverSupport.c\r
+  Hand/Notify.c\r
+  Hand/locate.c\r
+  Hand/handle.c\r
+  Gcd/gcd.c\r
+  Mem/pool.c\r
+  Mem/Page.c\r
+  Mem/memdata.c\r
+  FwVolBlock/FwVolBlock.c\r
+  FwVol/FwVolWrite.c\r
+  FwVol/FwVolRead.c\r
+  FwVol/FwVolAttrib.c\r
+  FwVol/Ffs.c\r
+  FwVol/FwVol.c\r
+  Event/tpl.c\r
+  Event/timer.c\r
+  Event/event.c\r
+  Event/execdata.c\r
+  Dispatcher/dependency.c\r
+  Dispatcher/Dispatcher.c\r
+  DxeMain/DxeProtocolNotify.c\r
+  DxeMain/DxeMain.c\r
+  CommonHeader.h\r
+\r
+\r
+################################################################################\r
+#\r
+# Package Dependency Section - list of Package files that are required for\r
+#                              this module.\r
+#\r
+################################################################################\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  IntelFrameworkPkg/IntelFrameworkPkg.dec\r
+\r
+\r
+################################################################################\r
+#\r
+# Library Class Section - list of Library Classes that are required for\r
+#                         this module.\r
+#\r
+################################################################################\r
+\r
+[LibraryClasses]\r
+  BaseMemoryLib\r
+  CacheMaintenanceLib\r
+  PeCoffLoaderLib\r
+  UefiDecompressLib\r
+  PerformanceLib\r
+  HobLib\r
+  BaseLib\r
+  UefiLib\r
+  DebugLib\r
+  DxeCoreEntryPoint\r
+\r
+\r
+################################################################################\r
+#\r
+# Guid C Name Section - list of Guids that this module uses or produces.\r
+#\r
+################################################################################\r
+\r
+[Guids]\r
+  gEfiEventLegacyBootGuid                       # ALWAYS_CONSUMED\r
+  gEfiEventReadyToBootGuid                      # ALWAYS_CONSUMED\r
+  gEfiEventMemoryMapChangeGuid                  # ALWAYS_CONSUMED\r
+  gEfiEventVirtualAddressChangeGuid             # ALWAYS_CONSUMED\r
+  gEfiEventExitBootServicesGuid                 # ALWAYS_CONSUMED\r
+  gEfiHobMemoryAllocModuleGuid                  # ALWAYS_CONSUMED\r
+  gEfiFileInfoGuid                              # ALWAYS_CONSUMED\r
+  gEfiFirmwareFileSystemGuid                    # ALWAYS_CONSUMED\r
+  gAprioriGuid                                  # ALWAYS_CONSUMED\r
+  gEfiDebugImageInfoTableGuid                   # ALWAYS_CONSUMED\r
+  gEfiHobListGuid                               # ALWAYS_CONSUMED\r
+  gEfiDxeServicesTableGuid                      # ALWAYS_CONSUMED\r
+  gEfiMemoryTypeInformationGuid                 # ALWAYS_CONSUMED\r
+\r
+\r
+################################################################################\r
+#\r
+# Protocol C Name Section - list of Protocol and Protocol Notify C Names\r
+#                           that this module uses or produces.\r
+#\r
+################################################################################\r
+\r
+[Protocols]\r
+  gEfiStatusCodeRuntimeProtocolGuid             # PROTOCOL SOMETIMES_CONSUMED\r
+  gEfiCapsuleArchProtocolGuid                   # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiTianoDecompressProtocolGuid               # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiCustomizedDecompressProtocolGuid          # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiDecompressProtocolGuid                    # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiLoadPeImageProtocolGuid                   # PROTOCOL ALWAYS_PRODUCED\r
+  gEfiSimpleFileSystemProtocolGuid              # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiLoadFileProtocolGuid                      # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiResetArchProtocolGuid                     # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiRealTimeClockArchProtocolGuid             # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiRuntimeArchProtocolGuid                   # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiWatchdogTimerArchProtocolGuid             # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiSecurityArchProtocolGuid                  # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiVariableArchProtocolGuid                  # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiBdsArchProtocolGuid                       # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiVariableWriteArchProtocolGuid             # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiMonotonicCounterArchProtocolGuid          # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiMetronomeArchProtocolGuid                 # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiTimerArchProtocolGuid                     # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiBusSpecificDriverOverrideProtocolGuid     # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiPlatformDriverOverrideProtocolGuid        # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiDriverBindingProtocolGuid                 # PROTOCOL SOMETIMES_CONSUMED\r
+  gEfiFirmwareVolumeBlockProtocolGuid           # PROTOCOL ALWAYS_PRODUCED\r
+  gEfiFirmwareVolumeDispatchProtocolGuid        # PROTOCOL ALWAYS_PRODUCED\r
+  gEfiFirmwareVolumeProtocolGuid                # PROTOCOL ALWAYS_PRODUCED\r
+  gEfiCpuArchProtocolGuid                       # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiDevicePathProtocolGuid                    # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiLoadedImageProtocolGuid                   # PROTOCOL ALWAYS_PRODUCED\r
+  gEfiEbcProtocolGuid                           # PROTOCOL SOMETIMES_CONSUMED\r
+  gEfiSectionExtractionProtocolGuid             # PROTOCOL ALWAYS_PRODUCED\r
diff --git a/MdeModulePkg/Core/Dxe/DxeMain.msa b/MdeModulePkg/Core/Dxe/DxeMain.msa
new file mode 100644 (file)
index 0000000..1ed9c09
--- /dev/null
@@ -0,0 +1,243 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r
+  <MsaHeader>\r
+    <ModuleName>DxeMain</ModuleName>\r
+    <ModuleType>DXE_CORE</ModuleType>\r
+    <GuidValue>D6A2CB7F-6A18-4e2f-B43B-9920A733700A</GuidValue>\r
+    <Version>1.0</Version>\r
+    <Abstract>Component description file for DxeMain module.</Abstract>\r
+    <Description>This module provide an DXE CIS compliant implementation of DXE Core.</Description>\r
+    <Copyright>Copyright (c) 2006 - 2007, Intel Corporation</Copyright>\r
+    <License>All rights reserved. This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.</License>\r
+    <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION   0x00000052</Specification>\r
+  </MsaHeader>\r
+  <ModuleDefinitions>\r
+    <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>\r
+    <BinaryModule>false</BinaryModule>\r
+    <OutputFileBasename>DxeMain</OutputFileBasename>\r
+  </ModuleDefinitions>\r
+  <LibraryClassDefinitions>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>DxeCoreEntryPoint</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>DebugLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>BaseLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>HobLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>PerformanceLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiDecompressLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>TianoDecompressLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>CustomDecompressLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>EdkPeCoffLoaderLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>CacheMaintenanceLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>BaseMemoryLib</Keyword>\r
+    </LibraryClass>\r
+  </LibraryClassDefinitions>\r
+  <SourceFiles>\r
+    <Filename>DxeMain/DxeMain.c</Filename>\r
+    <Filename>DxeMain/DxeProtocolNotify.c</Filename>\r
+    <Filename>Dispatcher/Dispatcher.c</Filename>\r
+    <Filename>Dispatcher/dependency.c</Filename>\r
+    <Filename>Event/execdata.c</Filename>\r
+    <Filename>Event/event.c</Filename>\r
+    <Filename>Event/timer.c</Filename>\r
+    <Filename>Event/tpl.c</Filename>\r
+    <Filename>FwVol/FwVol.c</Filename>\r
+    <Filename>FwVol/Ffs.c</Filename>\r
+    <Filename>FwVol/FwVolAttrib.c</Filename>\r
+    <Filename>FwVol/FwVolRead.c</Filename>\r
+    <Filename>FwVol/FwVolWrite.c</Filename>\r
+    <Filename>FwVolBlock/FwVolBlock.c</Filename>\r
+    <Filename>Mem/memdata.c</Filename>\r
+    <Filename>Mem/Page.c</Filename>\r
+    <Filename>Mem/pool.c</Filename>\r
+    <Filename>Gcd/gcd.c</Filename>\r
+    <Filename>Hand/handle.c</Filename>\r
+    <Filename>Hand/locate.c</Filename>\r
+    <Filename>Hand/Notify.c</Filename>\r
+    <Filename>Hand/DriverSupport.c</Filename>\r
+    <Filename>Library/Library.c</Filename>\r
+    <Filename>Misc/InstallConfigurationTable.c</Filename>\r
+    <Filename>Misc/SetWatchdogTimer.c</Filename>\r
+    <Filename>Misc/Stall.c</Filename>\r
+    <Filename>Misc/DebugImageInfo.c</Filename>\r
+    <Filename>Image/Image.c</Filename>\r
+    <Filename>Image/ImageFile.c</Filename>\r
+    <Filename>SectionExtraction/CoreSectionExtraction.c</Filename>\r
+    <Filename>DebugImageInfo.h</Filename>\r
+    <Filename>DxeMain.h</Filename>\r
+    <Filename>Exec.h</Filename>\r
+    <Filename>FwVolBlock.h</Filename>\r
+    <Filename>FwVolDriver.h</Filename>\r
+    <Filename>gcd.h</Filename>\r
+    <Filename>hand.h</Filename>\r
+    <Filename>Image.h</Filename>\r
+    <Filename>imem.h</Filename>\r
+    <Filename>Library.h</Filename>\r
+  </SourceFiles>\r
+  <PackageDependencies>\r
+    <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+    <Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>\r
+  </PackageDependencies>\r
+  <Protocols>\r
+    <Protocol Usage="SOMETIMES_CONSUMED">\r
+      <ProtocolCName>gEfiEbcProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_PRODUCED">\r
+      <ProtocolCName>gEfiLoadedImageProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiDevicePathProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiCpuArchProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_PRODUCED">\r
+      <ProtocolCName>gEfiFirmwareVolumeProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_PRODUCED">\r
+      <ProtocolCName>gEfiFirmwareVolumeDispatchProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_PRODUCED">\r
+      <ProtocolCName>gEfiFirmwareVolumeBlockProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_PRODUCED">\r
+      <ProtocolCName>gEfiSectionExtractionProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="SOMETIMES_CONSUMED">\r
+      <ProtocolCName>gEfiDriverBindingProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiPlatformDriverOverrideProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiBusSpecificDriverOverrideProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiTimerArchProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiMetronomeArchProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiMonotonicCounterArchProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiVariableWriteArchProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiBdsArchProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiVariableArchProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiSecurityArchProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiWatchdogTimerArchProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiRuntimeArchProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiRealTimeClockArchProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiResetArchProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiLoadFileProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiSimpleFileSystemProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_PRODUCED">\r
+      <ProtocolCName>gEfiLoadPeImageProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiDecompressProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiCustomizedDecompressProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiTianoDecompressProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiCapsuleArchProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="SOMETIMES_CONSUMED">\r
+      <ProtocolCName>gEfiStatusCodeRuntimeProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+  </Protocols>\r
+  <Guids>\r
+    <GuidCNames Usage="ALWAYS_CONSUMED">\r
+      <GuidCName>gEfiMemoryTypeInformationGuid</GuidCName>\r
+    </GuidCNames>\r
+    <GuidCNames Usage="ALWAYS_CONSUMED">\r
+      <GuidCName>gEfiDxeServicesTableGuid</GuidCName>\r
+    </GuidCNames>\r
+    <GuidCNames Usage="ALWAYS_CONSUMED">\r
+      <GuidCName>gEfiHobListGuid</GuidCName>\r
+    </GuidCNames>\r
+    <GuidCNames Usage="ALWAYS_CONSUMED">\r
+      <GuidCName>gEfiDebugImageInfoTableGuid</GuidCName>\r
+    </GuidCNames>\r
+    <GuidCNames Usage="ALWAYS_CONSUMED">\r
+      <GuidCName>gAprioriGuid</GuidCName>\r
+    </GuidCNames>\r
+    <GuidCNames Usage="ALWAYS_CONSUMED">\r
+      <GuidCName>gEfiFirmwareFileSystemGuid</GuidCName>\r
+    </GuidCNames>\r
+    <GuidCNames Usage="ALWAYS_CONSUMED">\r
+      <GuidCName>gEfiFileInfoGuid</GuidCName>\r
+    </GuidCNames>\r
+    <GuidCNames Usage="ALWAYS_CONSUMED">\r
+      <GuidCName>gEfiHobMemoryAllocModuleGuid</GuidCName>\r
+    </GuidCNames>\r
+    <GuidCNames Usage="ALWAYS_CONSUMED">\r
+      <GuidCName>gEfiEventExitBootServicesGuid</GuidCName>\r
+    </GuidCNames>\r
+    <GuidCNames Usage="ALWAYS_CONSUMED">\r
+      <GuidCName>gEfiEventVirtualAddressChangeGuid</GuidCName>\r
+    </GuidCNames>\r
+    <GuidCNames Usage="ALWAYS_CONSUMED">\r
+      <GuidCName>gEfiEventMemoryMapChangeGuid</GuidCName>\r
+    </GuidCNames>\r
+    <GuidCNames Usage="ALWAYS_CONSUMED">\r
+      <GuidCName>gEfiEventReadyToBootGuid</GuidCName>\r
+    </GuidCNames>\r
+    <GuidCNames Usage="ALWAYS_CONSUMED">\r
+      <GuidCName>gEfiEventLegacyBootGuid</GuidCName>\r
+    </GuidCNames>\r
+  </Guids>\r
+  <Externs>\r
+    <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>\r
+    <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>\r
+    <Extern>\r
+      <ModuleEntryPoint>DxeMain</ModuleEntryPoint>\r
+    </Extern>\r
+  </Externs>\r
+</ModuleSurfaceArea>\r
diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c
new file mode 100644 (file)
index 0000000..0324901
--- /dev/null
@@ -0,0 +1,874 @@
+/*++\r
+\r
+Copyright (c) 2006 - 2007, 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
+\r
+Module Name:\r
+\r
+  DxeMain.c\r
+\r
+Abstract:\r
+\r
+  DXE Core Main Entry Point\r
+\r
+--*/\r
+\r
+#include <DxeMain.h>\r
+\r
+//\r
+// DXE Core Global Variables for Protocols from PEI\r
+//\r
+EFI_HANDLE                                mDecompressHandle = NULL;\r
+EFI_PEI_PE_COFF_LOADER_PROTOCOL           *gEfiPeiPeCoffLoader          = NULL;\r
+\r
+//\r
+// DXE Core globals for Architecture Protocols\r
+//\r
+EFI_SECURITY_ARCH_PROTOCOL        *gSecurity      = NULL;\r
+EFI_CPU_ARCH_PROTOCOL             *gCpu           = NULL;\r
+EFI_METRONOME_ARCH_PROTOCOL       *gMetronome     = NULL;\r
+EFI_TIMER_ARCH_PROTOCOL           *gTimer         = NULL;\r
+EFI_BDS_ARCH_PROTOCOL             *gBds           = NULL;\r
+EFI_WATCHDOG_TIMER_ARCH_PROTOCOL  *gWatchdogTimer = NULL;\r
+\r
+\r
+//\r
+// BugBug: I'n not runtime, but is the PPI?\r
+//\r
+EFI_STATUS_CODE_PROTOCOL     gStatusCodeInstance = {\r
+  NULL\r
+};\r
+\r
+EFI_STATUS_CODE_PROTOCOL     *gStatusCode    = &gStatusCodeInstance;\r
+\r
+\r
+//\r
+// DXE Core Global used to update core loaded image protocol handle\r
+//\r
+EFI_GUID                           *gDxeCoreFileName;\r
+EFI_LOADED_IMAGE_PROTOCOL          *gDxeCoreLoadedImage;\r
+\r
+\r
+\r
+//\r
+// DXE Core Module Variables\r
+//\r
+\r
+EFI_BOOT_SERVICES mBootServices = {\r
+  {\r
+    EFI_BOOT_SERVICES_SIGNATURE,                                                          // Signature\r
+    EFI_BOOT_SERVICES_REVISION,                                                           // Revision\r
+    sizeof (EFI_BOOT_SERVICES),                                                           // HeaderSize\r
+    0,                                                                                    // CRC32\r
+    0                                                                                     // Reserved\r
+  },\r
+  (EFI_RAISE_TPL)                               CoreRaiseTpl,                             // RaiseTPL\r
+  (EFI_RESTORE_TPL)                             CoreRestoreTpl,                           // RestoreTPL\r
+  (EFI_ALLOCATE_PAGES)                          CoreAllocatePages,                        // AllocatePages\r
+  (EFI_FREE_PAGES)                              CoreFreePages,                            // FreePages\r
+  (EFI_GET_MEMORY_MAP)                          CoreGetMemoryMap,                         // GetMemoryMap\r
+  (EFI_ALLOCATE_POOL)                           CoreAllocatePool,                         // AllocatePool\r
+  (EFI_FREE_POOL)                               CoreFreePool,                             // FreePool\r
+  (EFI_CREATE_EVENT)                            CoreCreateEvent,                          // CreateEvent\r
+  (EFI_SET_TIMER)                               CoreSetTimer,                             // SetTimer\r
+  (EFI_WAIT_FOR_EVENT)                          CoreWaitForEvent,                         // WaitForEvent\r
+  (EFI_SIGNAL_EVENT)                            CoreSignalEvent,                          // SignalEvent\r
+  (EFI_CLOSE_EVENT)                             CoreCloseEvent,                           // CloseEvent\r
+  (EFI_CHECK_EVENT)                             CoreCheckEvent,                           // CheckEvent\r
+  (EFI_INSTALL_PROTOCOL_INTERFACE)              CoreInstallProtocolInterface,             // InstallProtocolInterface\r
+  (EFI_REINSTALL_PROTOCOL_INTERFACE)            CoreReinstallProtocolInterface,           // ReinstallProtocolInterface\r
+  (EFI_UNINSTALL_PROTOCOL_INTERFACE)            CoreUninstallProtocolInterface,           // UninstallProtocolInterface\r
+  (EFI_HANDLE_PROTOCOL)                         CoreHandleProtocol,                       // HandleProtocol\r
+  (VOID *)                                      NULL,                                     // Reserved\r
+  (EFI_REGISTER_PROTOCOL_NOTIFY)                CoreRegisterProtocolNotify,               // RegisterProtocolNotify\r
+  (EFI_LOCATE_HANDLE)                           CoreLocateHandle,                         // LocateHandle\r
+  (EFI_LOCATE_DEVICE_PATH)                      CoreLocateDevicePath,                     // LocateDevicePath\r
+  (EFI_INSTALL_CONFIGURATION_TABLE)             CoreInstallConfigurationTable,            // InstallConfigurationTable\r
+  (EFI_IMAGE_LOAD)                              CoreLoadImage,                            // LoadImage\r
+  (EFI_IMAGE_START)                             CoreStartImage,                           // StartImage\r
+  (EFI_EXIT)                                    CoreExit,                                 // Exit\r
+  (EFI_IMAGE_UNLOAD)                            CoreUnloadImage,                          // UnloadImage\r
+  (EFI_EXIT_BOOT_SERVICES)                      CoreExitBootServices,                     // ExitBootServices\r
+  (EFI_GET_NEXT_MONOTONIC_COUNT)                CoreEfiNotAvailableYetArg1,               // GetNextMonotonicCount\r
+  (EFI_STALL)                                   CoreStall,                                // Stall\r
+  (EFI_SET_WATCHDOG_TIMER)                      CoreSetWatchdogTimer,                     // SetWatchdogTimer\r
+  (EFI_CONNECT_CONTROLLER)                      CoreConnectController,                    // ConnectController\r
+  (EFI_DISCONNECT_CONTROLLER)                   CoreDisconnectController,                 // DisconnectController\r
+  (EFI_OPEN_PROTOCOL)                           CoreOpenProtocol,                         // OpenProtocol\r
+  (EFI_CLOSE_PROTOCOL)                          CoreCloseProtocol,                        // CloseProtocol\r
+  (EFI_OPEN_PROTOCOL_INFORMATION)               CoreOpenProtocolInformation,              // OpenProtocolInformation\r
+  (EFI_PROTOCOLS_PER_HANDLE)                    CoreProtocolsPerHandle,                   // ProtocolsPerHandle\r
+  (EFI_LOCATE_HANDLE_BUFFER)                    CoreLocateHandleBuffer,                   // LocateHandleBuffer\r
+  (EFI_LOCATE_PROTOCOL)                         CoreLocateProtocol,                       // LocateProtocol\r
+  (EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES)    CoreInstallMultipleProtocolInterfaces,    // InstallMultipleProtocolInterfaces\r
+  (EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES)  CoreUninstallMultipleProtocolInterfaces,  // UninstallMultipleProtocolInterfaces\r
+  (EFI_CALCULATE_CRC32)                         CoreEfiNotAvailableYetArg3,               // CalculateCrc32\r
+  (EFI_COPY_MEM)                                CopyMem,                                  // CopyMem\r
+  (EFI_SET_MEM)                                 SetMem,                                   // SetMem\r
+  (EFI_CREATE_EVENT_EX)                         CoreCreateEventEx                         // CreateEventEx\r
+};\r
+\r
+EFI_DXE_SERVICES mDxeServices = {\r
+  {\r
+    DXE_SERVICES_SIGNATURE,                                           // Signature\r
+    DXE_SERVICES_REVISION,                                            // Revision\r
+    sizeof (DXE_SERVICES),                                            // HeaderSize\r
+    0,                                                                    // CRC32\r
+    0                                                                     // Reserved\r
+  },\r
+  (EFI_ADD_MEMORY_SPACE)             CoreAddMemorySpace,                  // AddMemorySpace\r
+  (EFI_ALLOCATE_MEMORY_SPACE)        CoreAllocateMemorySpace,             // AllocateMemorySpace\r
+  (EFI_FREE_MEMORY_SPACE)            CoreFreeMemorySpace,                 // FreeMemorySpace\r
+  (EFI_REMOVE_MEMORY_SPACE)          CoreRemoveMemorySpace,               // RemoveMemorySpace\r
+  (EFI_GET_MEMORY_SPACE_DESCRIPTOR)  CoreGetMemorySpaceDescriptor,        // GetMemorySpaceDescriptor\r
+  (EFI_SET_MEMORY_SPACE_ATTRIBUTES)  CoreSetMemorySpaceAttributes,        // SetMemorySpaceAttributes\r
+  (EFI_GET_MEMORY_SPACE_MAP)         CoreGetMemorySpaceMap,               // GetMemorySpaceMap\r
+  (EFI_ADD_IO_SPACE)                 CoreAddIoSpace,                      // AddIoSpace\r
+  (EFI_ALLOCATE_IO_SPACE)            CoreAllocateIoSpace,                 // AllocateIoSpace\r
+  (EFI_FREE_IO_SPACE)                CoreFreeIoSpace,                     // FreeIoSpace\r
+  (EFI_REMOVE_IO_SPACE)              CoreRemoveIoSpace,                   // RemoveIoSpace\r
+  (EFI_GET_IO_SPACE_DESCRIPTOR)      CoreGetIoSpaceDescriptor,            // GetIoSpaceDescriptor\r
+  (EFI_GET_IO_SPACE_MAP)             CoreGetIoSpaceMap,                   // GetIoSpaceMap\r
+  (EFI_DISPATCH)                     CoreDispatcher,                      // Dispatch\r
+  (EFI_SCHEDULE)                     CoreSchedule,                        // Schedule\r
+  (EFI_TRUST)                        CoreTrust,                           // Trust\r
+  (EFI_PROCESS_FIRMWARE_VOLUME)      CoreProcessFirmwareVolume,           // ProcessFirmwareVolume\r
+};\r
+\r
+EFI_SYSTEM_TABLE mEfiSystemTableTemplate = {\r
+  {\r
+    EFI_SYSTEM_TABLE_SIGNATURE,                                           // Signature\r
+    EFI_SYSTEM_TABLE_REVISION,                                            // Revision\r
+    sizeof (EFI_SYSTEM_TABLE),                                            // HeaderSize\r
+    0,                                                                    // CRC32\r
+    0                                                                     // Reserved\r
+  },\r
+  NULL,                                                                   // FirmwareVendor\r
+  0,                                                                      // FirmwareRevision\r
+  NULL,                                                                   // ConsoleInHandle\r
+  NULL,                                                                   // ConIn\r
+  NULL,                                                                   // ConsoleOutHandle\r
+  NULL,                                                                   // ConOut\r
+  NULL,                                                                   // StandardErrorHandle\r
+  NULL,                                                                   // StdErr\r
+  NULL,                                                                   // RuntimeServices\r
+  &mBootServices,                                                         // BootServices\r
+  0,                                                                      // NumberOfConfigurationTableEntries\r
+  NULL                                                                    // ConfigurationTable\r
+};\r
+\r
+EFI_RUNTIME_SERVICES mEfiRuntimeServicesTableTemplate = {\r
+  {\r
+    EFI_RUNTIME_SERVICES_SIGNATURE,                               // Signature\r
+    EFI_RUNTIME_SERVICES_REVISION,                                // Revision\r
+    sizeof (EFI_RUNTIME_SERVICES),                                // HeaderSize\r
+    0,                                                            // CRC32\r
+    0                                                             // Reserved\r
+  },\r
+  (EFI_GET_TIME)                    CoreEfiNotAvailableYetArg2,   // GetTime\r
+  (EFI_SET_TIME)                    CoreEfiNotAvailableYetArg1,   // SetTime\r
+  (EFI_GET_WAKEUP_TIME)             CoreEfiNotAvailableYetArg3,   // GetWakeupTime\r
+  (EFI_SET_WAKEUP_TIME)             CoreEfiNotAvailableYetArg2,   // SetWakeupTime\r
+  (EFI_SET_VIRTUAL_ADDRESS_MAP)     CoreEfiNotAvailableYetArg4,   // SetVirtualAddressMap\r
+  (EFI_CONVERT_POINTER)             CoreEfiNotAvailableYetArg2,   // ConvertPointer\r
+  (EFI_GET_VARIABLE)                CoreEfiNotAvailableYetArg5,   // GetVariable\r
+  (EFI_GET_NEXT_VARIABLE_NAME)      CoreEfiNotAvailableYetArg3,   // GetNextVariableName\r
+  (EFI_SET_VARIABLE)                CoreEfiNotAvailableYetArg5,   // SetVariable\r
+  (EFI_GET_NEXT_HIGH_MONO_COUNT)    CoreEfiNotAvailableYetArg1,   // GetNextHighMonotonicCount\r
+  (EFI_RESET_SYSTEM)                CoreEfiNotAvailableYetArg4,   // ResetSystem\r
+  (EFI_UPDATE_CAPSULE)              CoreEfiNotAvailableYetArg3,   // UpdateCapsule\r
+  (EFI_QUERY_CAPSULE_CAPABILITIES)  CoreEfiNotAvailableYetArg4,   // QueryCapsuleCapabilities\r
+  (EFI_QUERY_VARIABLE_INFO)         CoreEfiNotAvailableYetArg4    // QueryVariableInfo\r
+};\r
+\r
+EFI_RUNTIME_ARCH_PROTOCOL gRuntimeTemplate = {\r
+  INITIALIZE_LIST_HEAD_VARIABLE (gRuntimeTemplate.ImageHead),\r
+  INITIALIZE_LIST_HEAD_VARIABLE (gRuntimeTemplate.EventHead),\r
+\r
+  //\r
+  // Make sure Size != sizeof (EFI_MEMORY_DESCRIPTOR). This will\r
+  // prevent people from having pointer math bugs in their code.\r
+  // now you have to use *DescriptorSize to make things work.\r
+  //\r
+  sizeof (EFI_MEMORY_DESCRIPTOR) + sizeof (UINT64) - (sizeof (EFI_MEMORY_DESCRIPTOR) % sizeof (UINT64)),\r
+  EFI_MEMORY_DESCRIPTOR_VERSION,\r
+  0,\r
+  NULL,\r
+  NULL,\r
+  FALSE,\r
+  FALSE\r
+};\r
+\r
+EFI_RUNTIME_ARCH_PROTOCOL *gRuntime = &gRuntimeTemplate;\r
+\r
+//\r
+// DXE Core Global Variables for the EFI System Table, Boot Services Table,\r
+// DXE Services Table, and Runtime Services Table\r
+//\r
+EFI_BOOT_SERVICES     *gDxeCoreBS = &mBootServices;\r
+EFI_DXE_SERVICES      *gDxeCoreDS = &mDxeServices;\r
+EFI_SYSTEM_TABLE      *gDxeCoreST = NULL;\r
+\r
+//\r
+// For debug initialize gDxeCoreRT to template. gDxeCoreRT must be allocated from RT memory\r
+//  but gDxeCoreRT is used for ASSERT () and DEBUG () type macros so lets give it\r
+//  a value that will not cause debug infrastructure to crash early on.\r
+//\r
+EFI_RUNTIME_SERVICES  *gDxeCoreRT = &mEfiRuntimeServicesTableTemplate;\r
+EFI_HANDLE            gDxeCoreImageHandle = NULL;\r
+\r
+VOID  *mHobStart;\r
+\r
+//\r
+// EFI Decompress Protocol\r
+//\r
+EFI_DECOMPRESS_PROTOCOL  gEfiDecompress = {\r
+  DxeMainUefiDecompressGetInfo,\r
+  DxeMainUefiDecompress\r
+};\r
+\r
+//\r
+// Main entry point to the DXE Core\r
+//\r
+VOID\r
+EFIAPI\r
+DxeMain (\r
+  IN  VOID *HobStart\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Main entry point to DXE Core.\r
+\r
+Arguments:\r
+\r
+  HobStart - Pointer to the beginning of the HOB List from PEI\r
+\r
+Returns:\r
+\r
+  This function should never return\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                         Status;\r
+  EFI_PHYSICAL_ADDRESS               MemoryBaseAddress;\r
+  UINT64                             MemoryLength;\r
+\r
+  mHobStart = HobStart;\r
+\r
+  //\r
+  // Initialize Memory Services\r
+  //\r
+  CoreInitializeMemoryServices (&HobStart, &MemoryBaseAddress, &MemoryLength);\r
+\r
+  //\r
+  // Allocate the EFI System Table and EFI Runtime Service Table from EfiRuntimeServicesData\r
+  // Use the templates to initialize the contents of the EFI System Table and EFI Runtime Services Table\r
+  //\r
+  gDxeCoreST = CoreAllocateRuntimeCopyPool (sizeof (EFI_SYSTEM_TABLE), &mEfiSystemTableTemplate);\r
+  ASSERT (gDxeCoreST != NULL);\r
+\r
+  gDxeCoreRT = CoreAllocateRuntimeCopyPool (sizeof (EFI_RUNTIME_SERVICES), &mEfiRuntimeServicesTableTemplate);\r
+  ASSERT (gDxeCoreRT != NULL);\r
+\r
+  gDxeCoreST->RuntimeServices = gDxeCoreRT;\r
+\r
+  //\r
+  // Start the Image Services.\r
+  //\r
+  Status = CoreInitializeImageServices (HobStart);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Call constructor for all libraries\r
+  //\r
+  ProcessLibraryConstructorList (gDxeCoreImageHandle, gDxeCoreST);\r
+  PERF_END   (0,PEI_TOK, NULL, 0) ;\r
+  PERF_START (0,DXE_TOK, NULL, 0) ;\r
+\r
+  //\r
+  // Initialize the Global Coherency Domain Services\r
+  //\r
+  Status = CoreInitializeGcdServices (&HobStart, MemoryBaseAddress, MemoryLength);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Install the DXE Services Table into the EFI System Tables's Configuration Table\r
+  //\r
+  Status = CoreInstallConfigurationTable (&gEfiDxeServicesTableGuid, gDxeCoreDS);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Install the HOB List into the EFI System Tables's Configuration Table\r
+  //\r
+  Status = CoreInstallConfigurationTable (&gEfiHobListGuid, HobStart);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Install Memory Type Information Table into the EFI System Tables's Configuration Table\r
+  //\r
+  Status = CoreInstallConfigurationTable (&gEfiMemoryTypeInformationGuid, &gMemoryTypeInformation);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Initialize the ReportStatusCode with PEI version, if available\r
+  //\r
+  CoreGetPeiProtocol (&gEfiStatusCodeRuntimeProtocolGuid, (VOID **)&gStatusCode->ReportStatusCode);\r
+\r
+  //\r
+  // Report Status Code here for DXE_ENTRY_POINT once it is available\r
+  //\r
+  CoreReportProgressCode ((EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_ENTRY_POINT));\r
+\r
+  //\r
+  // Create the aligned system table pointer structure that is used by external\r
+  // debuggers to locate the system table...  Also, install debug image info\r
+  // configuration table.\r
+  //\r
+  CoreInitializeDebugImageInfoTable ();\r
+  CoreNewDebugImageInfoEntry (\r
+    EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL,\r
+    gDxeCoreLoadedImage,\r
+    gDxeCoreImageHandle\r
+    );\r
+\r
+  DEBUG ((EFI_D_INFO | EFI_D_LOAD, "HOBLIST address in DXE = 0x%08x\n", HobStart));\r
+\r
+  //\r
+  // Initialize the Event Services\r
+  //\r
+  Status = CoreInitializeEventServices ();\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+\r
+  //\r
+  // Get the Protocols that were passed in from PEI to DXE through GUIDed HOBs\r
+  //\r
+  // These Protocols are not architectural. This implementation is sharing code between\r
+  // PEI and DXE in order to save FLASH space. These Protocols could also be implemented\r
+  // as part of the DXE Core. However, that would also require the DXE Core to be ported\r
+  // each time a different CPU is used, a different Decompression algorithm is used, or a\r
+  // different Image type is used. By placing these Protocols in PEI, the DXE Core remains\r
+  // generic, and only PEI and the Arch Protocols need to be ported from Platform to Platform,\r
+  // and from CPU to CPU.\r
+  //\r
+\r
+  //\r
+  // Publish the EFI, Tiano, and Custom Decompress protocols for use by other DXE components\r
+  //\r
+  Status = CoreInstallMultipleProtocolInterfaces (\r
+              &mDecompressHandle,\r
+              &gEfiDecompressProtocolGuid,           &gEfiDecompress,\r
+              NULL\r
+              );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  gEfiPeiPeCoffLoader = GetPeCoffLoaderProtocol ();\r
+  ASSERT (gEfiPeiPeCoffLoader != NULL);\r
+\r
+  //\r
+  // Register for the GUIDs of the Architectural Protocols, so the rest of the\r
+  // EFI Boot Services and EFI Runtime Services tables can be filled in.\r
+  //\r
+  CoreNotifyOnArchProtocolInstallation ();\r
+\r
+  //\r
+  // Produce Firmware Volume Protocols, one for each FV in the HOB list.\r
+  //\r
+  Status = FwVolBlockDriverInit (gDxeCoreImageHandle, gDxeCoreST);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  Status = FwVolDriverInit (gDxeCoreImageHandle, gDxeCoreST);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Produce the Section Extraction Protocol\r
+  //\r
+  Status = InitializeSectionExtraction (gDxeCoreImageHandle, gDxeCoreST);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Initialize the DXE Dispatcher\r
+  //\r
+  PERF_START (0,"CoreInitializeDispatcher", "DxeMain", 0) ;\r
+  CoreInitializeDispatcher ();\r
+  PERF_END (0,"CoreInitializeDispatcher", "DxeMain", 0) ;\r
+\r
+  //\r
+  // Invoke the DXE Dispatcher\r
+  //\r
+  PERF_START (0, "CoreDispatcher", "DxeMain", 0);\r
+  CoreDispatcher ();\r
+  PERF_END (0, "CoreDispatcher", "DxeMain", 0);\r
+\r
+  //\r
+  // Display Architectural protocols that were not loaded if this is DEBUG build\r
+  //\r
+  DEBUG_CODE_BEGIN ();\r
+    CoreDisplayMissingArchProtocols ();\r
+  DEBUG_CODE_END ();\r
+\r
+  //\r
+  // Assert if the Architectural Protocols are not present.\r
+  //\r
+  ASSERT_EFI_ERROR (CoreAllEfiServicesAvailable ());\r
+\r
+  //\r
+  // Report Status code before transfer control to BDS\r
+  //\r
+  CoreReportProgressCode ((EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_HANDOFF_TO_NEXT));\r
+  //\r
+  // Display any drivers that were not dispatched because dependency expression\r
+  // evaluated to false if this is a debug build\r
+  //\r
+  DEBUG_CODE_BEGIN ();\r
+    CoreDisplayDiscoveredNotDispatched ();\r
+  DEBUG_CODE_END ();\r
+\r
+  //\r
+  // Transfer control to the BDS Architectural Protocol\r
+  //\r
+  gBds->Entry (gBds);\r
+\r
+  //\r
+  // BDS should never return\r
+  //\r
+  ASSERT (FALSE);\r
+  CpuDeadLoop ();\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreEfiNotAvailableYetArg0 (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Place holder function until all the Boot Services and Runtime Services are available\r
+\r
+Arguments:\r
+\r
+  None\r
+\r
+Returns:\r
+\r
+  EFI_NOT_AVAILABLE_YET\r
+\r
+--*/\r
+{\r
+  //\r
+  // This function should never be executed.  If it does, then the architectural protocols\r
+  // have not been designed correctly.  The CpuBreakpoint () is commented out for now until the\r
+  // DXE Core and all the Architectural Protocols are complete.\r
+  //\r
+\r
+  return EFI_NOT_AVAILABLE_YET;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreEfiNotAvailableYetArg1 (\r
+  UINTN Arg1\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Place holder function until all the Boot Services and Runtime Services are available\r
+\r
+Arguments:\r
+\r
+  Arg1        - Undefined\r
+\r
+Returns:\r
+\r
+  EFI_NOT_AVAILABLE_YET\r
+\r
+--*/\r
+{\r
+  //\r
+  // This function should never be executed.  If it does, then the architectural protocols\r
+  // have not been designed correctly.  The CpuBreakpoint () is commented out for now until the\r
+  // DXE Core and all the Architectural Protocols are complete.\r
+  //\r
+\r
+  return EFI_NOT_AVAILABLE_YET;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreEfiNotAvailableYetArg2 (\r
+  UINTN Arg1,\r
+  UINTN Arg2\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Place holder function until all the Boot Services and Runtime Services are available\r
+\r
+Arguments:\r
+\r
+  Arg1        - Undefined\r
+\r
+  Arg2        - Undefined\r
+\r
+Returns:\r
+\r
+  EFI_NOT_AVAILABLE_YET\r
+\r
+--*/\r
+{\r
+  //\r
+  // This function should never be executed.  If it does, then the architectural protocols\r
+  // have not been designed correctly.  The CpuBreakpoint () is commented out for now until the\r
+  // DXE Core and all the Architectural Protocols are complete.\r
+  //\r
+\r
+  return EFI_NOT_AVAILABLE_YET;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreEfiNotAvailableYetArg3 (\r
+  UINTN Arg1,\r
+  UINTN Arg2,\r
+  UINTN Arg3\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Place holder function until all the Boot Services and Runtime Services are available\r
+\r
+Arguments:\r
+\r
+  Arg1        - Undefined\r
+\r
+  Arg2        - Undefined\r
+\r
+  Arg3        - Undefined\r
+\r
+Returns:\r
+\r
+  EFI_NOT_AVAILABLE_YET\r
+\r
+--*/\r
+{\r
+  //\r
+  // This function should never be executed.  If it does, then the architectural protocols\r
+  // have not been designed correctly.  The CpuBreakpoint () is commented out for now until the\r
+  // DXE Core and all the Architectural Protocols are complete.\r
+  //\r
+\r
+  return EFI_NOT_AVAILABLE_YET;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreEfiNotAvailableYetArg4 (\r
+  UINTN Arg1,\r
+  UINTN Arg2,\r
+  UINTN Arg3,\r
+  UINTN Arg4\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Place holder function until all the Boot Services and Runtime Services are available\r
+\r
+Arguments:\r
+\r
+  Arg1        - Undefined\r
+\r
+  Arg2        - Undefined\r
+\r
+  Arg3        - Undefined\r
+\r
+  Arg4        - Undefined\r
+\r
+Returns:\r
+\r
+  EFI_NOT_AVAILABLE_YET\r
+\r
+--*/\r
+{\r
+  //\r
+  // This function should never be executed.  If it does, then the architectural protocols\r
+  // have not been designed correctly.  The CpuBreakpoint () is commented out for now until the\r
+  // DXE Core and all the Architectural Protocols are complete.\r
+  //\r
+\r
+  return EFI_NOT_AVAILABLE_YET;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreEfiNotAvailableYetArg5 (\r
+  UINTN Arg1,\r
+  UINTN Arg2,\r
+  UINTN Arg3,\r
+  UINTN Arg4,\r
+  UINTN Arg5\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Place holder function until all the Boot Services and Runtime Services are available\r
+\r
+Arguments:\r
+\r
+  Arg1        - Undefined\r
+\r
+  Arg2        - Undefined\r
+\r
+  Arg3        - Undefined\r
+\r
+  Arg4        - Undefined\r
+\r
+  Arg5        - Undefined\r
+\r
+Returns:\r
+\r
+  EFI_NOT_AVAILABLE_YET\r
+\r
+--*/\r
+{\r
+  //\r
+  // This function should never be executed.  If it does, then the architectural protocols\r
+  // have not been designed correctly.  The CpuBreakpoint () is commented out for now until the\r
+  // DXE Core and all the Architectural Protocols are complete.\r
+  //\r
+\r
+  return EFI_NOT_AVAILABLE_YET;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+CoreGetPeiProtocol (\r
+  IN EFI_GUID  *ProtocolGuid,\r
+  IN VOID      **Interface\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Searches for a Protocol Interface passed from PEI through a HOB\r
+\r
+Arguments:\r
+\r
+  ProtocolGuid - The Protocol GUID to search for in the HOB List\r
+\r
+  Interface    - A pointer to the interface for the Protocol GUID\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS   - The Protocol GUID was found and its interface is returned in Interface\r
+\r
+  EFI_NOT_FOUND - The Protocol GUID was not found in the HOB List\r
+\r
+--*/\r
+{\r
+  EFI_HOB_GUID_TYPE   *GuidHob;\r
+  VOID                *Buffer;\r
+\r
+  GuidHob = GetNextGuidHob (ProtocolGuid, mHobStart);\r
+  if (GuidHob == NULL) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  Buffer = GET_GUID_HOB_DATA (GuidHob);\r
+  ASSERT (Buffer != NULL);\r
+\r
+  *Interface = (VOID *)(*(UINTN *)(Buffer));\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+VOID\r
+CalculateEfiHdrCrc (\r
+  IN  OUT EFI_TABLE_HEADER    *Hdr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Calcualte the 32-bit CRC in a EFI table using the service provided by the\r
+  gRuntime service.\r
+\r
+Arguments:\r
+\r
+  Hdr  - Pointer to an EFI standard header\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+{\r
+  UINT32 Crc;\r
+\r
+  Hdr->CRC32 = 0;\r
+\r
+  //\r
+  // If gDxeCoreBS->CalculateCrce32 () == CoreEfiNotAvailableYet () then\r
+  //  Crc will come back as zero if we set it to zero here\r
+  //\r
+  Crc = 0;\r
+  gDxeCoreBS->CalculateCrc32 ((UINT8 *)Hdr, Hdr->HeaderSize, &Crc);\r
+  Hdr->CRC32 = Crc;\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreExitBootServices (\r
+  IN EFI_HANDLE   ImageHandle,\r
+  IN UINTN        MapKey\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Terminates all boot services.\r
+\r
+Arguments:\r
+\r
+  ImageHandle   - Handle that identifies the exiting image.\r
+\r
+  MapKey -Key to the latest memory map.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS - Boot Services terminated\r
+  EFI_INVALID_PARAMETER - MapKey is incorrect.\r
+\r
+--*/\r
+{\r
+  EFI_STATUS    Status;\r
+\r
+  //\r
+  // Terminate memory services if the MapKey matches\r
+  //\r
+  Status = CoreTerminateMemoryMap (MapKey);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Notify other drivers that we are exiting boot services.\r
+  //\r
+  CoreNotifySignalList (&gEfiEventExitBootServicesGuid);\r
+\r
+  //\r
+  // Disable Timer\r
+  //\r
+  gTimer->SetTimerPeriod (gTimer, 0);\r
+\r
+  //\r
+  // Disable CPU Interrupts\r
+  //\r
+  gCpu->DisableInterrupt (gCpu);\r
+\r
+  //\r
+  // Report that ExitBootServices() has been called\r
+  //\r
+  // We are using gEfiDxeServicesTableGuid as the caller ID for Dxe Core\r
+  //\r
+  CoreReportProgressCode ((EFI_SOFTWARE_EFI_BOOT_SERVICE | EFI_SW_BS_PC_EXIT_BOOT_SERVICES));\r
+\r
+  //\r
+  // Clear the non-runtime values of the EFI System Table\r
+  //\r
+  gDxeCoreST->BootServices        = NULL;\r
+  gDxeCoreST->ConIn               = NULL;\r
+  gDxeCoreST->ConsoleInHandle     = NULL;\r
+  gDxeCoreST->ConOut              = NULL;\r
+  gDxeCoreST->ConsoleOutHandle    = NULL;\r
+  gDxeCoreST->StdErr              = NULL;\r
+  gDxeCoreST->StandardErrorHandle = NULL;\r
+\r
+  //\r
+  // Recompute the 32-bit CRC of the EFI System Table\r
+  //\r
+  CalculateEfiHdrCrc (&gDxeCoreST->Hdr);\r
+\r
+  //\r
+  // Zero out the Boot Service Table\r
+  //\r
+  SetMem (gDxeCoreBS, sizeof (EFI_BOOT_SERVICES), 0);\r
+  gDxeCoreBS = NULL;\r
+\r
+  //\r
+  // Update the AtRuntime field in Runtiem AP.\r
+  //\r
+  gRuntime->AtRuntime = TRUE;\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+DxeMainUefiDecompressGetInfo (\r
+  IN EFI_DECOMPRESS_PROTOCOL            *This,\r
+  IN   VOID                             *Source,\r
+  IN   UINT32                           SourceSize,\r
+  OUT  UINT32                           *DestinationSize,\r
+  OUT  UINT32                           *ScratchSize\r
+  )\r
+{\r
+  if (Source == NULL \r
+        || DestinationSize == NULL \r
+        || ScratchSize == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  return UefiDecompressGetInfo (Source, SourceSize, DestinationSize, ScratchSize);\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DxeMainUefiDecompress (\r
+  IN EFI_DECOMPRESS_PROTOCOL              *This,\r
+  IN     VOID                             *Source,\r
+  IN     UINT32                           SourceSize,\r
+  IN OUT VOID                             *Destination,\r
+  IN     UINT32                           DestinationSize,\r
+  IN OUT VOID                             *Scratch,\r
+  IN     UINT32                           ScratchSize\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  UINT32      TestDestinationSize;\r
+  UINT32      TestScratchSize;\r
+  \r
+  if (Source == NULL \r
+        || Destination== NULL \r
+        || Scratch == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  \r
+  Status = UefiDecompressGetInfo (Source, SourceSize, &TestDestinationSize, &TestScratchSize);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  if (ScratchSize < TestScratchSize || DestinationSize < TestDestinationSize) {\r
+    return RETURN_INVALID_PARAMETER;\r
+  }\r
+\r
+  return UefiDecompress (Source, Destination, Scratch);\r
+}\r
+\r
diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeProtocolNotify.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeProtocolNotify.c
new file mode 100644 (file)
index 0000000..5c9a5b8
--- /dev/null
@@ -0,0 +1,297 @@
+/*++\r
+\r
+Copyright (c) 2006 - 2007, 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
+\r
+Module Name:\r
+\r
+  DxeProtocolNotify.c\r
+\r
+Abstract:\r
+\r
+  This file deals with Architecture Protocol (AP) registration in\r
+  the Dxe Core. The mArchProtocols[] array represents a list of\r
+  events that represent the Architectural Protocols.\r
+\r
+--*/\r
+\r
+#include <DxeMain.h>\r
+\r
+\r
+//\r
+// DXE Core Global Variables for all of the Architectural Protocols.\r
+// If a protocol is installed mArchProtocols[].Present will be TRUE.\r
+//\r
+// CoreNotifyOnArchProtocolInstallation () fills in mArchProtocols[].Event\r
+// and mArchProtocols[].Registration as it creates events for every array\r
+// entry.\r
+//\r
+\r
+ARCHITECTURAL_PROTOCOL_ENTRY  mArchProtocols[] = {\r
+  { &gEfiSecurityArchProtocolGuid,         (VOID **)&gSecurity,      NULL, NULL, FALSE },\r
+  { &gEfiCpuArchProtocolGuid,              (VOID **)&gCpu,           NULL, NULL, FALSE },\r
+  { &gEfiMetronomeArchProtocolGuid,        (VOID **)&gMetronome,     NULL, NULL, FALSE },\r
+  { &gEfiTimerArchProtocolGuid,            (VOID **)&gTimer,         NULL, NULL, FALSE },\r
+  { &gEfiBdsArchProtocolGuid,              (VOID **)&gBds,           NULL, NULL, FALSE },\r
+  { &gEfiWatchdogTimerArchProtocolGuid,    (VOID **)&gWatchdogTimer, NULL, NULL, FALSE },\r
+  { &gEfiRuntimeArchProtocolGuid,          (VOID **)&gRuntime,       NULL, NULL, FALSE },\r
+  { &gEfiVariableArchProtocolGuid,         (VOID **)NULL,            NULL, NULL, FALSE },\r
+  { &gEfiVariableWriteArchProtocolGuid,    (VOID **)NULL,            NULL, NULL, FALSE },\r
+  { &gEfiCapsuleArchProtocolGuid,          (VOID **)NULL,            NULL, NULL, FALSE},\r
+  { &gEfiMonotonicCounterArchProtocolGuid, (VOID **)NULL,            NULL, NULL, FALSE },\r
+  { &gEfiResetArchProtocolGuid,            (VOID **)NULL,            NULL, NULL, FALSE },\r
+  { &gEfiRealTimeClockArchProtocolGuid,    (VOID **)NULL,            NULL, NULL, FALSE },\r
+  { NULL,                                  (VOID **)NULL,            NULL, NULL, FALSE }\r
+};\r
+\r
+\r
+EFI_STATUS\r
+CoreAllEfiServicesAvailable (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Return TRUE if all AP services are availible.\r
+\r
+Arguments:\r
+  NONE\r
+\r
+Returns:\r
+  EFI_SUCCESS   - All AP services are available\r
+  EFI_NOT_FOUND - At least one AP service is not available\r
+\r
+--*/\r
+{\r
+  ARCHITECTURAL_PROTOCOL_ENTRY  *Entry;\r
+\r
+  for (Entry = mArchProtocols; Entry->ProtocolGuid != NULL; Entry++) {\r
+    if (!Entry->Present) {\r
+      return EFI_NOT_FOUND;\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+STATIC\r
+VOID\r
+EFIAPI\r
+GenericArchProtocolNotify (\r
+  IN   EFI_EVENT       Event,\r
+  IN   VOID            *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Notification event handler registered by CoreNotifyOnArchProtocolInstallation ().\r
+  This notify function is registered for every architectural protocol. This handler\r
+  updates mArchProtocol[] array entry with protocol instance data and sets it's\r
+  present flag to TRUE. If any constructor is required it is executed. The EFI\r
+  System Table headers are updated.\r
+\r
+Arguments:\r
+\r
+  Event   - The Event that is being processed, not used.\r
+\r
+  Context - Event Context, not used.\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                      Status;\r
+  ARCHITECTURAL_PROTOCOL_ENTRY    *Entry;\r
+  VOID                            *Protocol;\r
+  BOOLEAN                         Found;\r
+  LIST_ENTRY                      *Link;\r
+  LIST_ENTRY                      TempLinkNode;\r
+\r
+  Found = FALSE;\r
+  for (Entry = mArchProtocols; Entry->ProtocolGuid != NULL; Entry++) {\r
+\r
+    Status = CoreLocateProtocol (Entry->ProtocolGuid, Entry->Registration, &Protocol);\r
+    if (EFI_ERROR (Status)) {\r
+      continue;\r
+    }\r
+\r
+    Found = TRUE;\r
+    Entry->Present = TRUE;\r
+\r
+    //\r
+    // Update protocol global variable if one exists. Entry->Protocol points to a global variable\r
+    // if one exists in the DXE core for this Architectural Protocol\r
+    //\r
+    if (Entry->Protocol != NULL) {\r
+      *(Entry->Protocol) = Protocol;\r
+    }\r
+\r
+    if (CompareGuid (Entry->ProtocolGuid, &gEfiTimerArchProtocolGuid)) {\r
+      //\r
+      // Register the Core timer tick handler with the Timer AP\r
+      //\r
+      gTimer->RegisterHandler (gTimer, CoreTimerTick);\r
+    }\r
+\r
+    if (CompareGuid (Entry->ProtocolGuid, &gEfiRuntimeArchProtocolGuid)) {\r
+      //\r
+      // When runtime architectural protocol is available, updates CRC32 in the Debug Table\r
+      //\r
+      CoreUpdateDebugTableCrc32 ();\r
+\r
+      //\r
+      // Update the Runtime Architectural protocol with the template that the core was\r
+      // using so there would not need to be a dependency on the Runtime AP\r
+      //\r
+\r
+      //\r
+      // Copy all the registered Image to new gRuntime protocol\r
+      //\r
+      for (Link = gRuntimeTemplate.ImageHead.ForwardLink; Link != &gRuntimeTemplate.ImageHead; Link = TempLinkNode.ForwardLink) {\r
+        CopyMem (&TempLinkNode, Link, sizeof(LIST_ENTRY));\r
+        InsertTailList (&gRuntime->ImageHead, Link);\r
+      }\r
+      //\r
+      // Copy all the registered Event to new gRuntime protocol\r
+      //\r
+      for (Link = gRuntimeTemplate.EventHead.ForwardLink; Link != &gRuntimeTemplate.EventHead; Link = TempLinkNode.ForwardLink) {\r
+        CopyMem (&TempLinkNode, Link, sizeof(LIST_ENTRY));\r
+        InsertTailList (&gRuntime->EventHead, Link);\r
+      }\r
+\r
+      //\r
+      // Clean up gRuntimeTemplate\r
+      //\r
+      gRuntimeTemplate.ImageHead.ForwardLink = &gRuntimeTemplate.ImageHead;\r
+      gRuntimeTemplate.ImageHead.BackLink    = &gRuntimeTemplate.ImageHead;\r
+      gRuntimeTemplate.EventHead.ForwardLink = &gRuntimeTemplate.EventHead;\r
+      gRuntimeTemplate.EventHead.BackLink    = &gRuntimeTemplate.EventHead;\r
+    }\r
+  }\r
+\r
+  //\r
+  // It's over kill to do them all every time, but it saves a lot of code.\r
+  //\r
+  if (Found) {\r
+    CalculateEfiHdrCrc (&gDxeCoreRT->Hdr);\r
+    CalculateEfiHdrCrc (&gDxeCoreBS->Hdr);\r
+    CalculateEfiHdrCrc (&gDxeCoreST->Hdr);\r
+    CalculateEfiHdrCrc (&gDxeCoreDS->Hdr);\r
+  }\r
+}\r
+\r
+\r
+\r
+VOID\r
+CoreNotifyOnArchProtocolInstallation (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Creates an event that is fired everytime a Protocol of a specific type is installed\r
+\r
+Arguments:\r
+  NONE\r
+\r
+Returns:\r
+  NONE\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                      Status;\r
+  ARCHITECTURAL_PROTOCOL_ENTRY    *Entry;\r
+\r
+  for (Entry = mArchProtocols; Entry->ProtocolGuid != NULL; Entry++) {\r
+\r
+    //\r
+    // Create the event\r
+    //\r
+    Status = CoreCreateEvent (\r
+              EVT_NOTIFY_SIGNAL,\r
+              TPL_CALLBACK,\r
+              GenericArchProtocolNotify,\r
+              NULL,\r
+              &Entry->Event\r
+              );\r
+    ASSERT_EFI_ERROR(Status);\r
+\r
+    //\r
+    // Register for protocol notifactions on this event\r
+    //\r
+    Status = CoreRegisterProtocolNotify (\r
+              Entry->ProtocolGuid,\r
+              Entry->Event,\r
+              &Entry->Registration\r
+              );\r
+    ASSERT_EFI_ERROR(Status);\r
+\r
+  }\r
+}\r
+\r
+//\r
+// Following is needed to display missing architectural protocols in debug builds\r
+//\r
+typedef struct {\r
+  EFI_GUID                    *ProtocolGuid;\r
+  CHAR16                       *GuidString;\r
+} GUID_TO_STRING_PROTOCOL_ENTRY;\r
+\r
+static const GUID_TO_STRING_PROTOCOL_ENTRY MissingProtocols[] = {\r
+  { &gEfiSecurityArchProtocolGuid,         (CHAR16 *)L"Security"           },\r
+  { &gEfiCpuArchProtocolGuid,              (CHAR16 *)L"CPU"                },\r
+  { &gEfiMetronomeArchProtocolGuid,        (CHAR16 *)L"Metronome"          },\r
+  { &gEfiTimerArchProtocolGuid,            (CHAR16 *)L"Timer"              },\r
+  { &gEfiBdsArchProtocolGuid,              (CHAR16 *)L"Bds"                },\r
+  { &gEfiWatchdogTimerArchProtocolGuid,    (CHAR16 *)L"Watchdog Timer"     },\r
+  { &gEfiRuntimeArchProtocolGuid,          (CHAR16 *)L"Runtime"            },\r
+  { &gEfiVariableArchProtocolGuid,         (CHAR16 *)L"Variable"           },\r
+  { &gEfiVariableWriteArchProtocolGuid,    (CHAR16 *)L"Variable Write"     },\r
+  { &gEfiCapsuleArchProtocolGuid,          (CHAR16 *)L"Capsule"            },\r
+  { &gEfiMonotonicCounterArchProtocolGuid, (CHAR16 *)L"Monotonic Counter"  },\r
+  { &gEfiResetArchProtocolGuid,            (CHAR16 *)L"Reset"              },\r
+//  { &gEfiStatusCodeRuntimeProtocolGuid,       (CHAR16 *)L"Status Code"        },\r
+  { &gEfiRealTimeClockArchProtocolGuid,    (CHAR16 *)L"Real Time Clock"    }\r
+};\r
+\r
+VOID\r
+CoreDisplayMissingArchProtocols (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Displays Architectural protocols that were not loaded and are required for DXE core to function\r
+  Only used in Debug Builds\r
+\r
+Arguments:\r
+  NONE\r
+\r
+Returns:\r
+  NONE\r
+\r
+--*/\r
+{\r
+  const GUID_TO_STRING_PROTOCOL_ENTRY  *MissingEntry;\r
+  ARCHITECTURAL_PROTOCOL_ENTRY         *Entry;\r
+\r
+  for (Entry = mArchProtocols; Entry->ProtocolGuid != NULL; Entry++) {\r
+    if (!Entry->Present) {\r
+      MissingEntry = MissingProtocols;\r
+      for (MissingEntry = MissingProtocols; TRUE ; MissingEntry++) {\r
+        if (CompareGuid (Entry->ProtocolGuid, MissingEntry->ProtocolGuid)) {\r
+          DEBUG ((EFI_D_ERROR, "\n%s Arch Protocol not present!!\n", MissingEntry->GuidString));\r
+          break;\r
+        }\r
+      }\r
+    }\r
+  }\r
+}\r
diff --git a/MdeModulePkg/Core/Dxe/Event/event.c b/MdeModulePkg/Core/Dxe/Event/event.c
new file mode 100644 (file)
index 0000000..b3ba71d
--- /dev/null
@@ -0,0 +1,757 @@
+/*++\r
+\r
+Copyright (c) 2006 - 2007, 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
+\r
+Module Name:\r
+\r
+    event.c\r
+\r
+Abstract:\r
+\r
+    EFI Event support\r
+\r
+--*/\r
+\r
+\r
+#include <DxeMain.h>\r
+\r
+//\r
+// Enumerate the valid types\r
+//\r
+UINT32 mEventTable[] = {\r
+  //\r
+  // 0x80000200       Timer event with a notification function that is\r
+  // queue when the event is signaled with SignalEvent()\r
+  //\r
+  EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
+  //\r
+  // 0x80000000       Timer event without a notification function. It can be\r
+  // signaled with SignalEvent() and checked with CheckEvent() or WaitForEvent().\r
+  //\r
+  EVT_TIMER,\r
+  //\r
+  // 0x00000100       Generic event with a notification function that\r
+  // can be waited on with CheckEvent() or WaitForEvent()\r
+  //\r
+  EVT_NOTIFY_WAIT,\r
+  //\r
+  // 0x00000200       Generic event with a notification function that\r
+  // is queue when the event is signaled with SignalEvent()\r
+  //\r
+  EVT_NOTIFY_SIGNAL,\r
+  //\r
+  // 0x00000201       ExitBootServicesEvent.\r
+  //\r
+  EVT_SIGNAL_EXIT_BOOT_SERVICES,\r
+  //\r
+  // 0x60000202       SetVirtualAddressMapEvent.\r
+  //\r
+  EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,\r
+\r
+  //\r
+  // 0x00000000       Generic event without a notification function.\r
+  // It can be signaled with SignalEvent() and checked with CheckEvent()\r
+  // or WaitForEvent().\r
+  //\r
+  0x00000000,\r
+  //\r
+  // 0x80000100       Timer event with a notification function that can be\r
+  // waited on with CheckEvent() or WaitForEvent()\r
+  //\r
+  EVT_TIMER | EVT_NOTIFY_WAIT,\r
+};\r
+\r
+STATIC\r
+VOID\r
+CoreAcquireEventLock (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Enter critical section by acquiring the lock on gEventQueueLock.\r
+\r
+Arguments:\r
+\r
+  None\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+{\r
+  CoreAcquireLock (&gEventQueueLock);\r
+}\r
+\r
+STATIC\r
+VOID\r
+CoreReleaseEventLock (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Exit critical section by releasing the lock on gEventQueueLock.\r
+\r
+Arguments:\r
+\r
+  None\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+{\r
+  CoreReleaseLock (&gEventQueueLock);\r
+}\r
+\r
+\r
+EFI_STATUS\r
+CoreInitializeEventServices (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Initializes "event" support and populates parts of the System and Runtime Table.\r
+\r
+Arguments:\r
+\r
+  None\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS - Always return success\r
+\r
+--*/\r
+{\r
+  UINTN        Index;\r
+\r
+  for (Index=0; Index <= TPL_HIGH_LEVEL; Index++) {\r
+    InitializeListHead (&gEventQueue[Index]);\r
+  }\r
+\r
+  CoreInitializeTimer ();\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+VOID\r
+CoreDispatchEventNotifies (\r
+  IN EFI_TPL      Priority\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Dispatches all pending events.\r
+\r
+Arguments:\r
+\r
+  Priority - The task priority level of event notifications to dispatch\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+{\r
+  IEVENT          *Event;\r
+  LIST_ENTRY      *Head;\r
+\r
+  CoreAcquireEventLock ();\r
+  ASSERT (gEventQueueLock.OwnerTpl == Priority);\r
+  Head = &gEventQueue[Priority];\r
+\r
+  //\r
+  // Dispatch all the pending notifications\r
+  //\r
+  while (!IsListEmpty (Head)) {\r
+\r
+    Event = CR (Head->ForwardLink, IEVENT, NotifyLink, EVENT_SIGNATURE);\r
+    RemoveEntryList (&Event->NotifyLink);\r
+\r
+    Event->NotifyLink.ForwardLink = NULL;\r
+\r
+    //\r
+    // Only clear the SIGNAL status if it is a SIGNAL type event.\r
+    // WAIT type events are only cleared in CheckEvent()\r
+    //\r
+    if (Event->Type & EVT_NOTIFY_SIGNAL) {\r
+      Event->SignalCount = 0;\r
+    }\r
+\r
+    CoreReleaseEventLock ();\r
+\r
+    //\r
+    // Notify this event\r
+    //\r
+    ASSERT (Event->NotifyFunction != NULL);\r
+    Event->NotifyFunction (Event, Event->NotifyContext);\r
+\r
+    //\r
+    // Check for next pending event\r
+    //\r
+    CoreAcquireEventLock ();\r
+  }\r
+\r
+  gEventPending &= ~(1 << Priority);\r
+  CoreReleaseEventLock ();\r
+}\r
+\r
+\r
+STATIC\r
+VOID\r
+CoreNotifyEvent (\r
+  IN  IEVENT      *Event\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Queues the event's notification function to fire\r
+\r
+Arguments:\r
+\r
+  Event       - The Event to notify\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+{\r
+\r
+  //\r
+  // Event database must be locked\r
+  //\r
+  ASSERT_LOCKED (&gEventQueueLock);\r
+\r
+  //\r
+  // If the event is queued somewhere, remove it\r
+  //\r
+\r
+  if (Event->NotifyLink.ForwardLink != NULL) {\r
+    RemoveEntryList (&Event->NotifyLink);\r
+    Event->NotifyLink.ForwardLink = NULL;\r
+  }\r
+\r
+  //\r
+  // Queue the event to the pending notification list\r
+  //\r
+\r
+  InsertTailList (&gEventQueue[Event->NotifyTpl], &Event->NotifyLink);\r
+  gEventPending |= (UINTN)(1 << Event->NotifyTpl);\r
+}\r
+\r
+\r
+\r
+VOID\r
+CoreNotifySignalList (\r
+  IN EFI_GUID     *EventGroup\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Signals all events in the EventGroup\r
+\r
+Arguments:\r
+  EventGroup - The list to signal\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+{\r
+  LIST_ENTRY              *Link;\r
+  LIST_ENTRY              *Head;\r
+  IEVENT                  *Event;\r
+\r
+  CoreAcquireEventLock ();\r
+\r
+  Head = &gEventSignalQueue;\r
+  for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {\r
+    Event = CR (Link, IEVENT, SignalLink, EVENT_SIGNATURE);\r
+    if (CompareGuid (&Event->EventGroup, EventGroup)) {\r
+      CoreNotifyEvent (Event);\r
+    }\r
+  }\r
+\r
+  CoreReleaseEventLock ();\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreCreateEvent (\r
+  IN UINT32                   Type,\r
+  IN EFI_TPL                  NotifyTpl,\r
+  IN EFI_EVENT_NOTIFY         NotifyFunction, OPTIONAL\r
+  IN VOID                     *NotifyContext, OPTIONAL\r
+  OUT EFI_EVENT               *Event\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Creates a general-purpose event structure\r
+\r
+Arguments:\r
+  Type                - The type of event to create and its mode and attributes\r
+  NotifyTpl           - The task priority level of event notifications\r
+  NotifyFunction      - Pointer to the events notification function\r
+  NotifyContext       - Pointer to the notification functions context; corresponds to\r
+                        parameter "Context" in the notification function\r
+  Event               - Pointer to the newly created event if the call succeeds; undefined otherwise\r
+\r
+Returns:\r
+  EFI_SUCCESS           - The event structure was created\r
+  EFI_INVALID_PARAMETER - One of the parameters has an invalid value\r
+  EFI_OUT_OF_RESOURCES  - The event could not be allocated\r
+\r
+--*/\r
+{\r
+  EFI_GUID            *GuidPtr;\r
+  EFI_EVENT_NOTIFY    Function;\r
+\r
+  GuidPtr = NULL;\r
+  Function = NotifyFunction;\r
+\r
+  //\r
+  // Convert EFI 1.10 Events to thier UEFI 2.0 CreateEventEx mapping\r
+  //\r
+  if (Type == EVT_SIGNAL_EXIT_BOOT_SERVICES) {\r
+    GuidPtr = &gEfiEventExitBootServicesGuid;\r
+  } else if (Type == EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE) {\r
+    GuidPtr = &gEfiEventVirtualAddressChangeGuid;\r
+  }\r
+\r
+  return CoreCreateEventEx (Type, NotifyTpl, Function, NotifyContext, GuidPtr, Event);\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreCreateEventEx (\r
+  IN UINT32                   Type,\r
+  IN EFI_TPL                  NotifyTpl,\r
+  IN EFI_EVENT_NOTIFY         NotifyFunction, OPTIONAL\r
+  IN CONST VOID               *NotifyContext, OPTIONAL\r
+  IN CONST EFI_GUID           *EventGroup,    OPTIONAL\r
+  OUT EFI_EVENT               *Event\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Creates a general-purpose event structure\r
+\r
+Arguments:\r
+  Type                - The type of event to create and its mode and attributes\r
+  NotifyTpl           - The task priority level of event notifications\r
+  NotifyFunction      - Pointer to the events notification function\r
+  NotifyContext       - Pointer to the notification functions context; corresponds to\r
+                        parameter "Context" in the notification function\r
+  EventGrout          - GUID for EventGroup if NULL act the same as gBS->CreateEvent().\r
+  Event               - Pointer to the newly created event if the call succeeds; undefined otherwise\r
+\r
+Returns:\r
+  EFI_SUCCESS           - The event structure was created\r
+  EFI_INVALID_PARAMETER - One of the parameters has an invalid value\r
+  EFI_OUT_OF_RESOURCES  - The event could not be allocated\r
+\r
+--*/\r
+{\r
+  EFI_STATUS      Status;\r
+  IEVENT          *IEvent;\r
+  INTN            Index;\r
+\r
+\r
+  if ((Event == NULL) || (NotifyTpl == TPL_APPLICATION)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Check to make sure no reserved flags are set\r
+  //\r
+  Status = EFI_INVALID_PARAMETER;\r
+  for (Index = 0; Index < (sizeof (mEventTable) / sizeof (UINT32)); Index++) {\r
+     if (Type == mEventTable[Index]) {\r
+       Status = EFI_SUCCESS;\r
+       break;\r
+     }\r
+  }\r
+  if(EFI_ERROR (Status)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // If it's a notify type of event, check its parameters\r
+  //\r
+  if ((Type & (EVT_NOTIFY_WAIT | EVT_NOTIFY_SIGNAL))) {\r
+    //\r
+    // Check for an invalid NotifyFunction or NotifyTpl\r
+    //\r
+    if ((NotifyFunction == NULL) ||\r
+        (NotifyTpl < TPL_APPLICATION) ||\r
+       (NotifyTpl >= TPL_HIGH_LEVEL)) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+  } else {\r
+    //\r
+    // No notification needed, zero ignored values\r
+    //\r
+    NotifyTpl = 0;\r
+    NotifyFunction = NULL;\r
+    NotifyContext = NULL;\r
+  }\r
+\r
+  //\r
+  // Allcoate and initialize a new event structure.\r
+  //\r
+  Status = CoreAllocatePool (\r
+             (Type & EVT_RUNTIME) ? EfiRuntimeServicesData: EfiBootServicesData,\r
+             sizeof (IEVENT),\r
+             (VOID **)&IEvent\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  SetMem (IEvent, sizeof (IEVENT), 0);\r
+\r
+  IEvent->Signature = EVENT_SIGNATURE;\r
+  IEvent->Type = Type;\r
+\r
+  IEvent->NotifyTpl      = NotifyTpl;\r
+  IEvent->NotifyFunction = NotifyFunction;\r
+  IEvent->NotifyContext  = (VOID *)NotifyContext;\r
+  if (EventGroup != NULL) {\r
+    CopyGuid (&IEvent->EventGroup, EventGroup);\r
+    IEvent->ExFlag = TRUE;\r
+  }\r
+\r
+  *Event = IEvent;\r
+\r
+  if (Type & EVT_RUNTIME) {\r
+    //\r
+    // Keep a list of all RT events so we can tell the RT AP.\r
+    //\r
+    IEvent->RuntimeData.Type           = Type;\r
+    IEvent->RuntimeData.NotifyTpl      = NotifyTpl;\r
+    IEvent->RuntimeData.NotifyFunction = NotifyFunction;\r
+    IEvent->RuntimeData.NotifyContext  = (VOID *) NotifyContext;\r
+    IEvent->RuntimeData.Event          = (EFI_EVENT *) IEvent;\r
+    InsertTailList (&gRuntime->EventHead, &IEvent->RuntimeData.Link);\r
+  }\r
+\r
+  CoreAcquireEventLock ();\r
+\r
+  if ((Type & EVT_NOTIFY_SIGNAL) != 0x00000000) {\r
+    //\r
+    // The Event's NotifyFunction must be queued whenever the event is signaled\r
+    //\r
+    InsertHeadList (&gEventSignalQueue, &IEvent->SignalLink);\r
+  }\r
+\r
+  CoreReleaseEventLock ();\r
+\r
+  //\r
+  // Done\r
+  //\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreSignalEvent (\r
+  IN EFI_EVENT    UserEvent\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Signals the event.  Queues the event to be notified if needed\r
+\r
+Arguments:\r
+\r
+  UserEvent - The event to signal\r
+\r
+Returns:\r
+\r
+  EFI_INVALID_PARAMETER - Parameters are not valid.\r
+\r
+  EFI_SUCCESS - The event was signaled.\r
+\r
+--*/\r
+{\r
+  IEVENT          *Event;\r
+\r
+  Event = UserEvent;\r
+\r
+  if (Event == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Event->Signature != EVENT_SIGNATURE) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  CoreAcquireEventLock ();\r
+\r
+  //\r
+  // If the event is not already signalled, do so\r
+  //\r
+\r
+  if (Event->SignalCount == 0x00000000) {\r
+    Event->SignalCount++;\r
+\r
+    //\r
+    // If signalling type is a notify function, queue it\r
+    //\r
+    if (Event->Type & EVT_NOTIFY_SIGNAL) {\r
+      if (Event->ExFlag) {\r
+        //\r
+        // The CreateEventEx() style requires all members of the Event Group\r
+        //  to be signaled.\r
+        //\r
+        CoreReleaseEventLock ();\r
+        CoreNotifySignalList (&Event->EventGroup);\r
+        CoreAcquireEventLock ();\r
+       } else {\r
+        CoreNotifyEvent (Event);\r
+      }\r
+    }\r
+  }\r
+\r
+  CoreReleaseEventLock ();\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreCheckEvent (\r
+  IN EFI_EVENT        UserEvent\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Check the status of an event\r
+\r
+Arguments:\r
+\r
+  UserEvent - The event to check\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - The event is in the signaled state\r
+  EFI_NOT_READY         - The event is not in the signaled state\r
+  EFI_INVALID_PARAMETER - Event is of type EVT_NOTIFY_SIGNAL\r
+\r
+--*/\r
+\r
+{\r
+  IEVENT      *Event;\r
+  EFI_STATUS  Status;\r
+\r
+  Event = UserEvent;\r
+\r
+  if (Event == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Event->Signature != EVENT_SIGNATURE) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Event->Type & EVT_NOTIFY_SIGNAL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status = EFI_NOT_READY;\r
+\r
+  if (!Event->SignalCount && (Event->Type & EVT_NOTIFY_WAIT)) {\r
+\r
+    //\r
+    // Queue the wait notify function\r
+    //\r
+\r
+    CoreAcquireEventLock ();\r
+    if (!Event->SignalCount) {\r
+      CoreNotifyEvent (Event);\r
+    }\r
+    CoreReleaseEventLock ();\r
+  }\r
+\r
+  //\r
+  // If the even looks signalled, get the lock and clear it\r
+  //\r
+\r
+  if (Event->SignalCount) {\r
+    CoreAcquireEventLock ();\r
+\r
+    if (Event->SignalCount) {\r
+      Event->SignalCount = 0;\r
+      Status = EFI_SUCCESS;\r
+    }\r
+\r
+    CoreReleaseEventLock ();\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreWaitForEvent (\r
+  IN UINTN        NumberOfEvents,\r
+  IN EFI_EVENT    *UserEvents,\r
+  OUT UINTN       *UserIndex\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Stops execution until an event is signaled.\r
+\r
+Arguments:\r
+\r
+  NumberOfEvents  - The number of events in the UserEvents array\r
+  UserEvents      - An array of EFI_EVENT\r
+  UserIndex       - Pointer to the index of the event which satisfied the wait condition\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - The event indicated by Index was signaled.\r
+  EFI_INVALID_PARAMETER - The event indicated by Index has a notification function or\r
+                          Event was not a valid type\r
+  EFI_UNSUPPORTED       - The current TPL is not TPL_APPLICATION\r
+\r
+--*/\r
+\r
+{\r
+  EFI_STATUS      Status;\r
+  UINTN           Index;\r
+\r
+  //\r
+  // Can only WaitForEvent at TPL_APPLICATION\r
+  //\r
+  if (gEfiCurrentTpl != TPL_APPLICATION) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  for(;;) {\r
+\r
+    for(Index = 0; Index < NumberOfEvents; Index++) {\r
+\r
+      Status = CoreCheckEvent (UserEvents[Index]);\r
+\r
+      //\r
+      // provide index of event that caused problem\r
+      //\r
+      if (Status != EFI_NOT_READY) {\r
+        *UserIndex = Index;\r
+        return Status;\r
+      }\r
+    }\r
+\r
+    //\r
+    // This was the location of the Idle loop callback in EFI 1.x reference\r
+    // code. We don't have that concept in this base at this point.\r
+    //\r
+  }\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreCloseEvent (\r
+  IN EFI_EVENT    UserEvent\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Closes an event and frees the event structure.\r
+\r
+Arguments:\r
+\r
+  UserEvent - Event to close\r
+\r
+Returns:\r
+\r
+  EFI_INVALID_PARAMETER - Parameters are not valid.\r
+\r
+  EFI_SUCCESS - The event has been closed\r
+\r
+--*/\r
+\r
+{\r
+  EFI_STATUS  Status;\r
+  IEVENT      *Event;\r
+\r
+  Event = UserEvent;\r
+\r
+  if (Event == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Event->Signature != EVENT_SIGNATURE) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // If it's a timer event, make sure it's not pending\r
+  //\r
+  if (Event->Type & EVT_TIMER) {\r
+    CoreSetTimer (Event, TimerCancel, 0);\r
+  }\r
+\r
+  CoreAcquireEventLock ();\r
+\r
+  //\r
+  // If the event is queued somewhere, remove it\r
+  //\r
+\r
+  if (Event->RuntimeData.Link.ForwardLink != NULL) {\r
+    RemoveEntryList (&Event->RuntimeData.Link);\r
+  }\r
+\r
+  if (Event->NotifyLink.ForwardLink != NULL) {\r
+    RemoveEntryList (&Event->NotifyLink);\r
+  }\r
+\r
+  if (Event->SignalLink.ForwardLink != NULL) {\r
+    RemoveEntryList (&Event->SignalLink);\r
+  }\r
+\r
+  CoreReleaseEventLock ();\r
+\r
+  //\r
+  // If the event is registered on a protocol notify, then remove it from the protocol database\r
+  //\r
+  CoreUnregisterProtocolNotify (Event);\r
+\r
+  Status = CoreFreePool (Event);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return Status;\r
+}\r
diff --git a/MdeModulePkg/Core/Dxe/Event/execdata.c b/MdeModulePkg/Core/Dxe/Event/execdata.c
new file mode 100644 (file)
index 0000000..a6d388a
--- /dev/null
@@ -0,0 +1,51 @@
+/*++\r
+\r
+Copyright (c) 2006, 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
+\r
+Module Name:\r
+  \r
+  execdata.c\r
+\r
+Abstract:\r
+\r
+\r
+\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#include <DxeMain.h>\r
+\r
+\r
+//\r
+// gTpl - Task priority level\r
+//\r
+EFI_TPL  gEfiCurrentTpl = TPL_APPLICATION;\r
+\r
+\r
+//\r
+// gEventQueueLock - Protects the event queus\r
+//\r
+EFI_LOCK gEventQueueLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_HIGH_LEVEL);\r
+\r
+//\r
+// gEventQueue - A list of event's to notify for each priority level\r
+// gEventPending - A bitmask of the EventQueues that are pending\r
+//\r
+LIST_ENTRY      gEventQueue[TPL_HIGH_LEVEL + 1];\r
+UINTN           gEventPending = 0;\r
+\r
+\r
+//\r
+// gEventSignalQueue - A list of events to signal based on EventGroup type\r
+//\r
+LIST_ENTRY      gEventSignalQueue = INITIALIZE_LIST_HEAD_VARIABLE (gEventSignalQueue);\r
+\r
diff --git a/MdeModulePkg/Core/Dxe/Event/timer.c b/MdeModulePkg/Core/Dxe/Event/timer.c
new file mode 100644 (file)
index 0000000..0f886f9
--- /dev/null
@@ -0,0 +1,388 @@
+/*++\r
+\r
+Copyright (c) 2006, 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
+\r
+Module Name:\r
+\r
+  timer.c\r
+\r
+Abstract:\r
+\r
+  EFI Event support\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+\r
+#include <DxeMain.h>\r
+\r
+//\r
+// Internal prototypes\r
+//\r
+STATIC\r
+UINT64\r
+CoreCurrentSystemTime (\r
+  VOID\r
+  );\r
+\r
+STATIC\r
+VOID\r
+EFIAPI\r
+CoreCheckTimers (\r
+  IN EFI_EVENT    Event,\r
+  IN VOID         *Context\r
+  );\r
+\r
+STATIC\r
+VOID\r
+CoreInsertEventTimer (\r
+  IN IEVENT       *Event\r
+  );\r
+\r
+//\r
+// Internal data\r
+//\r
+\r
+static LIST_ENTRY       mEfiTimerList = INITIALIZE_LIST_HEAD_VARIABLE (mEfiTimerList);\r
+static EFI_LOCK         mEfiTimerLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_HIGH_LEVEL - 1);\r
+static EFI_EVENT        mEfiCheckTimerEvent;\r
+\r
+static EFI_LOCK         mEfiSystemTimeLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_HIGH_LEVEL);\r
+static UINT64           mEfiSystemTime = 0;\r
+\r
+//\r
+// Timer functions\r
+//\r
+\r
+VOID\r
+CoreInitializeTimer (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Initializes timer support\r
+\r
+Arguments:\r
+\r
+  None\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  Status = CoreCreateEvent (\r
+              EVT_NOTIFY_SIGNAL,\r
+              TPL_HIGH_LEVEL - 1,\r
+              CoreCheckTimers,\r
+              NULL,\r
+              &mEfiCheckTimerEvent\r
+              );\r
+  ASSERT_EFI_ERROR (Status);\r
+}\r
+\r
+STATIC\r
+UINT64\r
+CoreCurrentSystemTime (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Returns the current system time\r
+\r
+Arguments:\r
+\r
+  None\r
+\r
+Returns:\r
+\r
+  Returns the current system time\r
+\r
+--*/\r
+{\r
+  UINT64          SystemTime;\r
+\r
+  CoreAcquireLock (&mEfiSystemTimeLock);\r
+  SystemTime = mEfiSystemTime;\r
+  CoreReleaseLock (&mEfiSystemTimeLock);\r
+  return SystemTime;\r
+}\r
+\r
+VOID\r
+EFIAPI\r
+CoreTimerTick (\r
+  IN UINT64   Duration\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Called by the platform code to process a tick.\r
+\r
+Arguments:\r
+\r
+  Duration    - The number of 100ns elasped since the last call to TimerTick\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+{\r
+  IEVENT          *Event;\r
+\r
+  //\r
+  // Check runtiem flag in case there are ticks while exiting boot services\r
+  //\r
+\r
+  CoreAcquireLock (&mEfiSystemTimeLock);\r
+\r
+  //\r
+  // Update the system time\r
+  //\r
+\r
+  mEfiSystemTime += Duration;\r
+\r
+  //\r
+  // If the head of the list is expired, fire the timer event\r
+  // to process it\r
+  //\r
+\r
+  if (!IsListEmpty (&mEfiTimerList)) {\r
+    Event = CR (mEfiTimerList.ForwardLink, IEVENT, u.Timer.Link, EVENT_SIGNATURE);\r
+\r
+    if (Event->u.Timer.TriggerTime <= mEfiSystemTime) {\r
+      CoreSignalEvent (mEfiCheckTimerEvent);\r
+    }\r
+  }\r
+\r
+  CoreReleaseLock (&mEfiSystemTimeLock);\r
+}\r
+\r
+STATIC\r
+VOID\r
+EFIAPI\r
+CoreCheckTimers (\r
+  IN EFI_EVENT            CheckEvent,\r
+  IN VOID                 *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Checks the sorted timer list against the current system time.\r
+  Signals any expired event timer.\r
+\r
+Arguments:\r
+\r
+  CheckEvent  - Not used\r
+\r
+  Context     - Not used\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+{\r
+  UINT64                  SystemTime;\r
+  IEVENT                  *Event;\r
+\r
+  //\r
+  // Check the timer database for expired timers\r
+  //\r
+\r
+  CoreAcquireLock (&mEfiTimerLock);\r
+  SystemTime = CoreCurrentSystemTime ();\r
+\r
+  while (!IsListEmpty (&mEfiTimerList)) {\r
+    Event = CR (mEfiTimerList.ForwardLink, IEVENT, u.Timer.Link, EVENT_SIGNATURE);\r
+\r
+    //\r
+    // If this timer is not expired, then we're done\r
+    //\r
+\r
+    if (Event->u.Timer.TriggerTime > SystemTime) {\r
+      break;\r
+    }\r
+\r
+    //\r
+    // Remove this timer from the timer queue\r
+    //\r
+\r
+    RemoveEntryList (&Event->u.Timer.Link);\r
+    Event->u.Timer.Link.ForwardLink = NULL;\r
+\r
+    //\r
+    // Signal it\r
+    //\r
+    CoreSignalEvent (Event);\r
+\r
+    //\r
+    // If this is a periodic timer, set it\r
+    //\r
+    if (Event->u.Timer.Period) {\r
+\r
+      //\r
+      // Compute the timers new trigger time\r
+      //\r
+\r
+      Event->u.Timer.TriggerTime = Event->u.Timer.TriggerTime + Event->u.Timer.Period;\r
+\r
+      //\r
+      // If that's before now, then reset the timer to start from now\r
+      //\r
+      if (Event->u.Timer.TriggerTime <= SystemTime) {\r
+        Event->u.Timer.TriggerTime = SystemTime;\r
+        CoreSignalEvent (mEfiCheckTimerEvent);\r
+      }\r
+\r
+      //\r
+      // Add the timer\r
+      //\r
+\r
+      CoreInsertEventTimer (Event);\r
+    }\r
+  }\r
+\r
+  CoreReleaseLock (&mEfiTimerLock);\r
+}\r
+\r
+STATIC\r
+VOID\r
+CoreInsertEventTimer (\r
+  IN IEVENT   *Event\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Inserts the timer event\r
+\r
+Arguments:\r
+\r
+  Event - Points to the internal structure of timer event to be installed\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+{\r
+  UINT64          TriggerTime;\r
+  LIST_ENTRY      *Link;\r
+  IEVENT          *Event2;\r
+\r
+  ASSERT_LOCKED (&mEfiTimerLock);\r
+\r
+  //\r
+  // Get the timer's trigger time\r
+  //\r
+\r
+  TriggerTime = Event->u.Timer.TriggerTime;\r
+\r
+  //\r
+  // Insert the timer into the timer database in assending sorted order\r
+  //\r
+\r
+  for (Link = mEfiTimerList.ForwardLink; Link  != &mEfiTimerList; Link = Link->ForwardLink) {\r
+    Event2 = CR (Link, IEVENT, u.Timer.Link, EVENT_SIGNATURE);\r
+\r
+    if (Event2->u.Timer.TriggerTime > TriggerTime) {\r
+      break;\r
+    }\r
+  }\r
+\r
+  InsertTailList (Link, &Event->u.Timer.Link);\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CoreSetTimer (\r
+  IN EFI_EVENT            UserEvent,\r
+  IN EFI_TIMER_DELAY      Type,\r
+  IN UINT64               TriggerTime\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Sets the type of timer and the trigger time for a timer event.\r
+\r
+Arguments:\r
+\r
+  UserEvent   - The timer event that is to be signaled at the specified time\r
+  Type        - The type of time that is specified in TriggerTime\r
+  TriggerTime - The number of 100ns units until the timer expires\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - The event has been set to be signaled at the requested time\r
+  EFI_INVALID_PARAMETER - Event or Type is not valid\r
+\r
+--*/\r
+{\r
+  IEVENT      *Event;\r
+\r
+  Event = UserEvent;\r
+\r
+  if (Event == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Event->Signature != EVENT_SIGNATURE) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Type < 0 || Type > TimerRelative  || !(Event->Type & EVT_TIMER)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  CoreAcquireLock (&mEfiTimerLock);\r
+\r
+  //\r
+  // If the timer is queued to the timer database, remove it\r
+  //\r
+\r
+  if (Event->u.Timer.Link.ForwardLink != NULL) {\r
+    RemoveEntryList (&Event->u.Timer.Link);\r
+    Event->u.Timer.Link.ForwardLink = NULL;\r
+  }\r
+\r
+  Event->u.Timer.TriggerTime = 0;\r
+  Event->u.Timer.Period = 0;\r
+\r
+  if (Type != TimerCancel) {\r
+\r
+    if (Type == TimerPeriodic) {\r
+      Event->u.Timer.Period = TriggerTime;\r
+    }\r
+\r
+    Event->u.Timer.TriggerTime = CoreCurrentSystemTime () + TriggerTime;\r
+    CoreInsertEventTimer (Event);\r
+\r
+    if (TriggerTime == 0) {\r
+      CoreSignalEvent (mEfiCheckTimerEvent);\r
+    }\r
+  }\r
+\r
+  CoreReleaseLock (&mEfiTimerLock);\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/MdeModulePkg/Core/Dxe/Event/tpl.c b/MdeModulePkg/Core/Dxe/Event/tpl.c
new file mode 100644 (file)
index 0000000..437665f
--- /dev/null
@@ -0,0 +1,198 @@
+/*++\r
+\r
+Copyright (c) 2006, 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
+\r
+Module Name:\r
+\r
+    tpl.c\r
+\r
+Abstract:\r
+\r
+    Task priority function    \r
+\r
+--*/\r
+\r
+#include <DxeMain.h>\r
+\r
+STATIC\r
+VOID\r
+CoreSetInterruptState (\r
+  IN BOOLEAN      Enable\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  \r
+  Set Interrupt State\r
+  \r
+Arguments:\r
+  \r
+  Enable - The state of enable or disable interrupt\r
+  \r
+Returns:\r
+  \r
+  None\r
+\r
+--*/\r
+\r
+{\r
+  if (gCpu != NULL) {\r
+    if (Enable) {\r
+      gCpu->EnableInterrupt(gCpu);\r
+    } else {\r
+      gCpu->DisableInterrupt(gCpu);\r
+    }\r
+  }\r
+}\r
+\r
+//\r
+// Return the highest set bit\r
+//\r
+UINTN\r
+CoreHighestSetBit (\r
+  IN UINTN     Number\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  \r
+  Return the highest set bit\r
+  \r
+Arguments:\r
+  \r
+  Number - The value to check\r
+  \r
+Returns:\r
+  \r
+  Bit position of the highest set bit\r
+\r
+--*/\r
+{\r
+  UINTN   msb;\r
+  \r
+  msb = 31;\r
+  while ((msb > 0) && ((Number & (UINTN)(1 << msb)) == 0)) {\r
+    msb--;\r
+  }\r
+\r
+  return msb;\r
+}\r
+\r
+\r
+\r
+EFI_TPL\r
+EFIAPI\r
+CoreRaiseTpl (\r
+  IN EFI_TPL      NewTpl\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Raise the task priority level to the new level.\r
+  High level is implemented by disabling processor interrupts.\r
+\r
+Arguments:\r
+\r
+  NewTpl  - New task priority level\r
+    \r
+Returns:\r
+\r
+  The previous task priority level\r
+\r
+--*/\r
+{\r
+  EFI_TPL     OldTpl;\r
+\r
+  OldTpl = gEfiCurrentTpl;\r
+  ASSERT (OldTpl <= NewTpl);\r
+  ASSERT (VALID_TPL (NewTpl));\r
+\r
+  //\r
+  // If raising to high level, disable interrupts\r
+  //\r
+  if (NewTpl >= TPL_HIGH_LEVEL  &&  OldTpl < TPL_HIGH_LEVEL) {\r
+    CoreSetInterruptState (FALSE);\r
+  }\r
+\r
+  //\r
+  // Set the new value\r
+  //\r
+  gEfiCurrentTpl = NewTpl;\r
+\r
+  return OldTpl;\r
+}\r
+\r
+\r
+\r
+VOID\r
+EFIAPI\r
+CoreRestoreTpl (\r
+  IN EFI_TPL NewTpl\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Lowers the task priority to the previous value.   If the new \r
+  priority unmasks events at a higher priority, they are dispatched.\r
+\r
+Arguments:\r
+\r
+  NewTpl  - New, lower, task priority\r
+    \r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+{\r
+  EFI_TPL     OldTpl;\r
+\r
+  OldTpl = gEfiCurrentTpl;\r
+  ASSERT (NewTpl <= OldTpl);\r
+  ASSERT (VALID_TPL (NewTpl));\r
+\r
+  //\r
+  // If lowering below HIGH_LEVEL, make sure\r
+  // interrupts are enabled\r
+  //\r
+\r
+  if (OldTpl >= TPL_HIGH_LEVEL  &&  NewTpl < TPL_HIGH_LEVEL) {\r
+    gEfiCurrentTpl = TPL_HIGH_LEVEL;  \r
+  }\r
+\r
+  //\r
+  // Dispatch any pending events\r
+  //\r
+\r
+  while ((-2 << NewTpl) & gEventPending) {\r
+    gEfiCurrentTpl = CoreHighestSetBit (gEventPending);\r
+    if (gEfiCurrentTpl < TPL_HIGH_LEVEL) {\r
+      CoreSetInterruptState (TRUE);\r
+    }\r
+    CoreDispatchEventNotifies (gEfiCurrentTpl);\r
+  }\r
+\r
+  //\r
+  // Set the new value\r
+  //\r
+\r
+  gEfiCurrentTpl = NewTpl;\r
+\r
+  //\r
+  // If lowering below HIGH_LEVEL, make sure\r
+  // interrupts are enabled\r
+  //\r
+  if (gEfiCurrentTpl < TPL_HIGH_LEVEL) {\r
+    CoreSetInterruptState (TRUE);\r
+  }\r
+\r
+}\r
diff --git a/MdeModulePkg/Core/Dxe/Exec.h b/MdeModulePkg/Core/Dxe/Exec.h
new file mode 100644 (file)
index 0000000..5df7001
--- /dev/null
@@ -0,0 +1,208 @@
+/*++\r
+\r
+Copyright (c) 2006, 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
+\r
+Module Name:\r
+  \r
+  exec.h\r
+\r
+Abstract:\r
+    \r
+  EFI Event support\r
+\r
+--*/\r
+\r
+#ifndef _EXEC_H_\r
+#define _EXEC_H_\r
+\r
+#define VALID_TPL(a)            ((a) <= TPL_HIGH_LEVEL)\r
+\r
+//\r
+// EFI_EVENT\r
+//\r
+\r
+\r
+\r
+#define EVENT_SIGNATURE         EFI_SIGNATURE_32('e','v','n','t')\r
+typedef struct {\r
+  UINTN                   Signature;\r
+  UINT32                  Type;\r
+  UINT32                  SignalCount;\r
+\r
+  //\r
+  // Entry if the event is registered to be signalled\r
+  //\r
+\r
+  LIST_ENTRY              SignalLink;\r
+\r
+  //\r
+  // Notification information for this event\r
+  //\r
+\r
+  EFI_TPL                 NotifyTpl;\r
+  EFI_EVENT_NOTIFY        NotifyFunction;\r
+  VOID                    *NotifyContext;\r
+  EFI_GUID                EventGroup;\r
+  LIST_ENTRY              NotifyLink; \r
+  BOOLEAN                 ExFlag;\r
+  \r
+  //\r
+  // A list of all runtime events\r
+  //\r
+  EFI_RUNTIME_EVENT_ENTRY   RuntimeData;\r
+\r
+  //\r
+  // Information by event type\r
+  //\r
+\r
+  union {\r
+    //\r
+    // For timer events\r
+    //\r
+    struct {\r
+      LIST_ENTRY      Link;\r
+      UINT64          TriggerTime;\r
+      UINT64          Period;\r
+    } Timer;\r
+  } u;\r
+\r
+} IEVENT;    \r
+\r
+//\r
+// Internal prototypes\r
+//\r
+\r
+VOID\r
+CoreDispatchEventNotifies (\r
+  IN EFI_TPL      Priority\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Dispatches all pending events. \r
+\r
+Arguments:\r
+\r
+  Priority - The task priority level of event notifications to dispatch\r
+    \r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+;\r
+\r
+\r
+UINTN\r
+CoreHighestSetBit (\r
+  IN UINTN         Number\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  \r
+  Return the highest set bit\r
+  \r
+Arguments:\r
+  \r
+  Number - The value to check\r
+  \r
+Returns:\r
+  \r
+  Bit position of the highest set bit\r
+\r
+--*/\r
+;\r
+\r
+\r
+BOOLEAN\r
+GetInterruptState (\r
+  VOID               \r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Disables CPU interrupts.\r
+\r
+Arguments:\r
+\r
+  This                - Protocol instance structure\r
+\r
+  State               - Pointer to the CPU's current interrupt state\r
+\r
+Returns: \r
+\r
+  EFI_SUCCESS           - If interrupts were disabled in the CPU.\r
+\r
+  EFI_INVALID_PARAMETER - State is NULL.\r
+  \r
+--*/\r
+;\r
+\r
+//\r
+// Exported functions\r
+//\r
+\r
+VOID\r
+CoreEventVirtualAddressFixup (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  A function out of date, should be removed.\r
+\r
+Arguments:\r
+\r
+  None\r
+    \r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+;\r
+\r
+\r
+VOID\r
+CoreInitializeTimer (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Initializes timer support\r
+\r
+Arguments:\r
+\r
+  None\r
+    \r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+;\r
+\r
+//\r
+// extern data declarations\r
+//\r
+\r
+extern EFI_LOCK       gEventQueueLock;\r
+extern UINTN          gEventPending;\r
+extern LIST_ENTRY     gEventQueue[];\r
+extern LIST_ENTRY     gEventSignalQueue;\r
+extern UINT8          gHSB[];\r
+\r
+#endif\r
diff --git a/MdeModulePkg/Core/Dxe/FwVol/Ffs.c b/MdeModulePkg/Core/Dxe/FwVol/Ffs.c
new file mode 100644 (file)
index 0000000..23c84b3
--- /dev/null
@@ -0,0 +1,266 @@
+/*++\r
+\r
+Copyright (c) 2006, 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
+\r
+Module Name:\r
+\r
+  Ffs.c\r
+\r
+Abstract:\r
+\r
+  FFS file access utilities.\r
+\r
+--*/\r
+\r
+\r
+#include <DxeMain.h>\r
+\r
+#define PHYSICAL_ADDRESS_TO_POINTER(Address) ((VOID *)((UINTN)(Address)))\r
+\r
+\r
+EFI_FFS_FILE_STATE\r
+GetFileState (\r
+  IN UINT8                ErasePolarity,\r
+  IN EFI_FFS_FILE_HEADER  *FfsHeader\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Get the FFS file state by checking the highest bit set in the header's state field\r
+\r
+Arguments:\r
+  ErasePolarity -  Erase polarity attribute of the firmware volume\r
+  FfsHeader     -  Points to the FFS file header\r
+    \r
+Returns:\r
+  FFS File state \r
+    \r
+--*/\r
+{\r
+  EFI_FFS_FILE_STATE      FileState;\r
+  UINT8                   HighestBit;\r
+\r
+  FileState = FfsHeader->State;\r
+\r
+  if (ErasePolarity != 0) {\r
+    FileState = (EFI_FFS_FILE_STATE)~FileState;\r
+  }\r
+\r
+  HighestBit = 0x80;\r
+  while (HighestBit != 0 && ((HighestBit & FileState) == 0)) {\r
+    HighestBit >>= 1;\r
+  }\r
+\r
+  return (EFI_FFS_FILE_STATE)HighestBit;\r
+}\r
+\r
+\r
+BOOLEAN\r
+IsBufferErased (\r
+  IN UINT8    ErasePolarity,\r
+  IN VOID     *InBuffer,\r
+  IN UINTN    BufferSize\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Check if a block of buffer is erased\r
+\r
+Arguments:\r
+  ErasePolarity -  Erase polarity attribute of the firmware volume\r
+  InBuffer      -  The buffer to be checked\r
+  BufferSize    -  Size of the buffer in bytes\r
+    \r
+Returns:\r
+  TRUE  -  The block of buffer is erased\r
+  FALSE -  The block of buffer is not erased\r
+    \r
+--*/\r
+{\r
+  UINTN   Count;\r
+  UINT8   EraseByte;\r
+  UINT8   *Buffer;\r
+\r
+  if(ErasePolarity == 1) {\r
+    EraseByte = 0xFF;\r
+  } else {\r
+    EraseByte = 0;\r
+  }\r
+\r
+  Buffer = InBuffer;\r
+  for (Count = 0; Count < BufferSize; Count++) {\r
+    if (Buffer[Count] != EraseByte) {\r
+      return FALSE;\r
+    }\r
+  }\r
+\r
+  return TRUE;\r
+}\r
+\r
+\r
+BOOLEAN\r
+VerifyFvHeaderChecksum (\r
+  IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Verify checksum of the firmware volume header \r
+\r
+Arguments:\r
+  FvHeader  -  Points to the firmware volume header to be checked\r
+    \r
+Returns:\r
+  TRUE  -  Checksum verification passed\r
+  FALSE -  Checksum verification failed\r
+    \r
+--*/\r
+{\r
+  UINT32  Index;\r
+  UINT32  HeaderLength;\r
+  UINT16  Checksum;\r
+  UINT16  *ptr;\r
+\r
+  HeaderLength = FvHeader->HeaderLength;\r
+  ptr = (UINT16 *)FvHeader;\r
+  Checksum = 0;\r
+\r
+  for (Index = 0; Index < HeaderLength / sizeof (UINT16); Index++) {\r
+    Checksum = (UINT16)(Checksum + ptr[Index]);\r
+  }\r
+\r
+  if (Checksum == 0) {\r
+    return TRUE;\r
+  } else {\r
+    return FALSE;\r
+  }\r
+}\r
+\r
+STATIC\r
+BOOLEAN\r
+VerifyHeaderChecksum (\r
+  IN EFI_FFS_FILE_HEADER  *FfsHeader\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Verify checksum of the FFS file header \r
+\r
+Arguments:\r
+  FfsHeader  -  Points to the FFS file header to be checked\r
+    \r
+Returns:\r
+  TRUE  -  Checksum verification passed\r
+  FALSE -  Checksum verification failed\r
+    \r
+--*/\r
+{\r
+  UINT32            Index;\r
+  UINT8             *ptr;\r
+  UINT8             HeaderChecksum;\r
+\r
+  ptr = (UINT8 *)FfsHeader;\r
+  HeaderChecksum = 0;\r
+  for (Index = 0; Index < sizeof(EFI_FFS_FILE_HEADER); Index++) {\r
+    HeaderChecksum = (UINT8)(HeaderChecksum + ptr[Index]);\r
+  }\r
+\r
+  HeaderChecksum = (UINT8) (HeaderChecksum - FfsHeader->State - FfsHeader->IntegrityCheck.Checksum.File);\r
+\r
+  if (HeaderChecksum == 0) {\r
+    return TRUE;\r
+  } else {\r
+    return FALSE;\r
+  }\r
+}\r
+\r
+\r
+BOOLEAN\r
+IsValidFfsHeader (\r
+  IN UINT8                ErasePolarity,\r
+  IN EFI_FFS_FILE_HEADER  *FfsHeader,\r
+  OUT EFI_FFS_FILE_STATE  *FileState\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Check if it's a valid FFS file header\r
+\r
+Arguments:\r
+  ErasePolarity -  Erase polarity attribute of the firmware volume\r
+  FfsHeader     -  Points to the FFS file header to be checked\r
+  FileState     -  FFS file state to be returned\r
+    \r
+Returns:\r
+  TRUE  -  Valid FFS file header\r
+  FALSE -  Invalid FFS file header\r
+    \r
+--*/\r
+{\r
+  *FileState = GetFileState (ErasePolarity, FfsHeader);\r
+\r
+  switch (*FileState) {\r
+    case EFI_FILE_HEADER_VALID:\r
+    case EFI_FILE_DATA_VALID:\r
+    case EFI_FILE_MARKED_FOR_UPDATE:\r
+    case EFI_FILE_DELETED:\r
+      //\r
+      // Here we need to verify header checksum\r
+      //\r
+      return VerifyHeaderChecksum (FfsHeader);\r
+    \r
+    case EFI_FILE_HEADER_CONSTRUCTION:\r
+    case EFI_FILE_HEADER_INVALID:\r
+    default:\r
+      return FALSE;\r
+  }\r
+}\r
+\r
+\r
+BOOLEAN\r
+IsValidFfsFile (\r
+  IN UINT8                ErasePolarity,\r
+  IN EFI_FFS_FILE_HEADER  *FfsHeader\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Check if it's a valid FFS file. \r
+  Here we are sure that it has a valid FFS file header since we must call IsValidFfsHeader() first.\r
+\r
+Arguments:\r
+  ErasePolarity -  Erase polarity attribute of the firmware volume\r
+  FfsHeader     -  Points to the FFS file to be checked\r
+    \r
+Returns:\r
+  TRUE  -  Valid FFS file\r
+  FALSE -  Invalid FFS file\r
+    \r
+--*/\r
+{\r
+  EFI_FFS_FILE_STATE  FileState;\r
+\r
+  FileState = GetFileState (ErasePolarity, FfsHeader);\r
+  switch (FileState) {\r
+\r
+    case EFI_FILE_DELETED:\r
+    case EFI_FILE_DATA_VALID:\r
+    case EFI_FILE_MARKED_FOR_UPDATE:\r
+      //\r
+      // Some other vliadation like file content checksum might be done here.\r
+      // For performance issue, Tiano only do FileState check.\r
+      //\r
+      return TRUE;\r
+\r
+    default:\r
+      return FALSE;\r
+  }\r
+}\r
+\r
diff --git a/MdeModulePkg/Core/Dxe/FwVol/FwVol.c b/MdeModulePkg/Core/Dxe/FwVol/FwVol.c
new file mode 100644 (file)
index 0000000..7fa346c
--- /dev/null
@@ -0,0 +1,547 @@
+/**@file\r
+  Firmware File System driver that produce Firmware Volume protocol.\r
+  Layers on top of Firmware Block protocol to produce a file abstraction \r
+  of FV based files.\r
+  \r
+Copyright (c) 2006 - 2007 Intel Corporation. <BR>\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
+\r
+**/\r
+\r
+#include <DxeMain.h>\r
+\r
+#define KEYSIZE       sizeof (UINTN)\r
+\r
+//\r
+// Protocol notify related globals\r
+//\r
+VOID          *gEfiFwVolBlockNotifyReg;\r
+EFI_EVENT     gEfiFwVolBlockEvent;\r
+\r
+FV_DEVICE mFvDevice = {\r
+  FV_DEVICE_SIGNATURE,\r
+  NULL,\r
+  NULL,\r
+  {\r
+    FvGetVolumeAttributes,\r
+    FvSetVolumeAttributes,\r
+    FvReadFile,\r
+    FvReadFileSection,\r
+    FvWriteFile,\r
+    FvGetNextFile,\r
+    KEYSIZE\r
+  },\r
+  NULL,\r
+  NULL,\r
+  NULL,\r
+  NULL,\r
+  { NULL, NULL },\r
+  0\r
+};\r
+\r
+\r
+//\r
+// FFS helper functions\r
+//\r
+\r
+EFI_STATUS\r
+GetFwVolHeader (\r
+  IN     EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL     *Fvb,\r
+  OUT    EFI_FIRMWARE_VOLUME_HEADER             **FwVolHeader\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  given the supplied FW_VOL_BLOCK_PROTOCOL, allocate a buffer for output and\r
+  copy the volume header into it.\r
+\r
+Arguments:\r
+  Fvb - The FW_VOL_BLOCK_PROTOCOL instance from which to read the volume\r
+          header\r
+  FwVolHeader - Pointer to pointer to allocated buffer in which the volume\r
+                  header is returned.\r
+\r
+Returns:\r
+  EFI_OUT_OF_RESOURCES    - No enough buffer could be allocated.\r
+  EFI_SUCCESS             - Successfully read volume header to the allocated buffer.\r
+\r
+--*/\r
+\r
+{\r
+  EFI_STATUS                  Status;\r
+  EFI_FIRMWARE_VOLUME_HEADER  TempFvh;\r
+  UINTN                       FvhLength;\r
+  UINT8                       *Buffer;\r
+\r
+\r
+  //\r
+  //Determine the real length of FV header\r
+  //\r
+  FvhLength = sizeof (EFI_FIRMWARE_VOLUME_HEADER);\r
+  Status = Fvb->Read (Fvb, 0, 0, &FvhLength, (UINT8 *)&TempFvh);\r
+\r
+  //\r
+  // Allocate a buffer for the caller\r
+  //\r
+  *FwVolHeader = CoreAllocateBootServicesPool (TempFvh.HeaderLength);\r
+  if (*FwVolHeader == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  //\r
+  // Copy the standard header into the buffer\r
+  //\r
+  CopyMem (*FwVolHeader, &TempFvh, sizeof (EFI_FIRMWARE_VOLUME_HEADER));\r
+\r
+  //\r
+  // Read the rest of the header\r
+  //\r
+  FvhLength = TempFvh.HeaderLength - sizeof (EFI_FIRMWARE_VOLUME_HEADER);\r
+  Buffer = (UINT8 *)*FwVolHeader + sizeof (EFI_FIRMWARE_VOLUME_HEADER);\r
+  Status = Fvb->Read (Fvb, 0, sizeof (EFI_FIRMWARE_VOLUME_HEADER), &FvhLength, Buffer);\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // Read failed so free buffer\r
+    //\r
+    CoreFreePool (*FwVolHeader);\r
+  }\r
\r
+  return Status;\r
+}\r
+\r
+\r
+STATIC\r
+VOID\r
+FreeFvDeviceResource (\r
+  IN FV_DEVICE  *FvDevice\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Free FvDevice resource when error happens\r
+\r
+Arguments:\r
+  FvDevice - pointer to the FvDevice to be freed.\r
+\r
+Returns:\r
+  None.\r
+\r
+--*/\r
+{\r
+  FFS_FILE_LIST_ENTRY         *FfsFileEntry;\r
+  LIST_ENTRY                  *NextEntry;\r
+\r
+  //\r
+  // Free File List Entry\r
+  //\r
+  FfsFileEntry = (FFS_FILE_LIST_ENTRY *)FvDevice->FfsFileListHeader.ForwardLink;\r
+  while (&FfsFileEntry->Link != &FvDevice->FfsFileListHeader) {\r
+    NextEntry = (&FfsFileEntry->Link)->ForwardLink;\r
+    \r
+    if (FfsFileEntry->StreamHandle != 0) {\r
+      //\r
+      // Close stream and free resources from SEP\r
+      //\r
+      FfsFileEntry->Sep->CloseSectionStream (FfsFileEntry->Sep, FfsFileEntry->StreamHandle);\r
+    }\r
+\r
+    CoreFreePool (FfsFileEntry);\r
+\r
+    FfsFileEntry = (FFS_FILE_LIST_ENTRY *)NextEntry;\r
+  }\r
+\r
+\r
+  //\r
+  // Free the cache\r
+  //\r
+  CoreFreePool (FvDevice->CachedFv);\r
+\r
+  //\r
+  // Free Volume Header\r
+  //\r
+  CoreFreePool (FvDevice->FwVolHeader);\r
+\r
+  return;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+FvCheck (\r
+  IN OUT FV_DEVICE  *FvDevice\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Check if a FV is consistent and allocate cache\r
+\r
+Arguments:\r
+  FvDevice - pointer to the FvDevice to be checked.\r
+\r
+Returns:\r
+  EFI_OUT_OF_RESOURCES    - No enough buffer could be allocated.\r
+  EFI_SUCCESS             - FV is consistent and cache is allocated.\r
+  EFI_VOLUME_CORRUPTED    - File system is corrupted.\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                            Status;\r
+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL    *Fvb;\r
+  EFI_FIRMWARE_VOLUME_HEADER            *FwVolHeader;\r
+  EFI_FVB_ATTRIBUTES                    FvbAttributes;\r
+  EFI_FV_BLOCK_MAP_ENTRY                *BlockMap;\r
+  FFS_FILE_LIST_ENTRY                   *FfsFileEntry;\r
+  EFI_FFS_FILE_HEADER                   *FfsHeader;\r
+  UINT8                                 *CacheLocation;\r
+  UINTN                                 LbaOffset;\r
+  UINTN                                 Index;\r
+  EFI_LBA                               LbaIndex;\r
+  UINTN                                 Size;\r
+  UINTN                                 FileLength;\r
+  EFI_FFS_FILE_STATE                    FileState;\r
+  UINT8                                 *TopFvAddress;\r
+  UINTN                                 TestLength;\r
+\r
+\r
+  Fvb = FvDevice->Fvb;\r
+  FwVolHeader = FvDevice->FwVolHeader;\r
\r
+  Status = Fvb->GetAttributes (Fvb, &FvbAttributes);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Size is the size of the FV minus the head. We have already allocated\r
+  // the header to check to make sure the volume is valid\r
+  //\r
+  Size = (UINTN)(FwVolHeader->FvLength - FwVolHeader->HeaderLength);\r
+  FvDevice->CachedFv = CoreAllocateBootServicesPool (Size);\r
+\r
+  if (FvDevice->CachedFv == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  //\r
+  // Remember a pointer to the end fo the CachedFv\r
+  //\r
+  FvDevice->EndOfCachedFv = FvDevice->CachedFv + Size;\r
+\r
+  //\r
+  // Copy FV minus header into memory using the block map we have all ready\r
+  // read into memory.\r
+  //\r
+  BlockMap = FwVolHeader->BlockMap;\r
+  CacheLocation = FvDevice->CachedFv;\r
+  LbaIndex = 0;\r
+  LbaOffset = FwVolHeader->HeaderLength;\r
+  while ((BlockMap->NumBlocks != 0) || (BlockMap->Length != 0)) {\r
+    \r
+    for (Index = 0; Index < BlockMap->NumBlocks; Index ++) {\r
+\r
+      Size = BlockMap->Length;\r
+      if (Index == 0) {\r
+        //\r
+        // Cache does not include FV Header\r
+        //\r
+        Size -= LbaOffset;\r
+      }\r
+      Status = Fvb->Read (Fvb,\r
+                          LbaIndex,\r
+                          LbaOffset,\r
+                          &Size,\r
+                          CacheLocation\r
+                          );\r
+      //\r
+      // Not check EFI_BAD_BUFFER_SIZE, for Size = BlockMap->Length\r
+      //\r
+      if (EFI_ERROR (Status)) {\r
+        goto Done;\r
+      }\r
+      \r
+      //\r
+      // After we skip Fv Header always read from start of block\r
+      //\r
+      LbaOffset = 0;\r
+\r
+      LbaIndex++;\r
+      CacheLocation += Size;\r
+    }\r
+    BlockMap++;\r
+  }\r
+\r
+  //\r
+  // Scan to check the free space & File list\r
+  //\r
+  if (FvbAttributes & EFI_FVB_ERASE_POLARITY) {\r
+    FvDevice->ErasePolarity = 1;\r
+  } else {\r
+    FvDevice->ErasePolarity = 0;\r
+  } \r
+\r
+\r
+  //\r
+  // go through the whole FV cache, check the consistence of the FV.\r
+  // Make a linked list off all the Ffs file headers\r
+  //\r
+  Status = EFI_SUCCESS;\r
+  InitializeListHead (&FvDevice->FfsFileListHeader);\r
+\r
+  //\r
+  // Build FFS list\r
+  //\r
+  FfsHeader = (EFI_FFS_FILE_HEADER *)FvDevice->CachedFv;\r
+  TopFvAddress = FvDevice->EndOfCachedFv;\r
+  while ((UINT8 *)FfsHeader < TopFvAddress) {\r
+\r
+    TestLength = TopFvAddress - ((UINT8 *)FfsHeader);\r
+    if (TestLength > sizeof (EFI_FFS_FILE_HEADER)) {\r
+      TestLength = sizeof (EFI_FFS_FILE_HEADER);\r
+    }\r
+\r
+    if (IsBufferErased (FvDevice->ErasePolarity, FfsHeader, TestLength)) {\r
+      //\r
+      // We have found the free space so we are done!\r
+      //\r
+      goto Done;\r
+    }\r
+\r
+    if (!IsValidFfsHeader (FvDevice->ErasePolarity, FfsHeader, &FileState)) {\r
+      if ((FileState == EFI_FILE_HEADER_INVALID) || \r
+          (FileState == EFI_FILE_HEADER_CONSTRUCTION)) {\r
+        FfsHeader++;\r
+      \r
+        continue;\r
+      \r
+      } else {\r
+        //\r
+        // File system is corrputed\r
+        //\r
+        Status = EFI_VOLUME_CORRUPTED;\r
+        goto Done;\r
+      }\r
+    }\r
+\r
+    if (!IsValidFfsFile (FvDevice->ErasePolarity, FfsHeader)) {\r
+      //\r
+      // File system is corrupted\r
+      //\r
+      Status = EFI_VOLUME_CORRUPTED;\r
+      goto Done;\r
+    }\r
+\r
+    //\r
+    // Size[3] is a three byte array, read 4 bytes and throw one away\r
+    //\r
+    FileLength = *(UINT32 *)&FfsHeader->Size[0] & 0x00FFFFFF;\r
+\r
+    FileState = GetFileState (FvDevice->ErasePolarity, FfsHeader);\r
+    \r
+    //\r
+    // check for non-deleted file\r
+    //\r
+    if (FileState != EFI_FILE_DELETED) {\r
+      //\r
+      // Create a FFS list entry for each non-deleted file\r
+      //\r
+      FfsFileEntry = CoreAllocateZeroBootServicesPool (sizeof (FFS_FILE_LIST_ENTRY));\r
+      if (FfsFileEntry == NULL) {\r
+        Status = EFI_OUT_OF_RESOURCES;\r
+        goto Done;\r
+      }\r
+    \r
+      FfsFileEntry->FfsHeader = FfsHeader;\r
+      InsertTailList (&FvDevice->FfsFileListHeader, &FfsFileEntry->Link);\r
+    }\r
+\r
+    FfsHeader =  (EFI_FFS_FILE_HEADER *)(((UINT8 *)FfsHeader) + FileLength);\r
+    \r
+    //\r
+    // Adjust pointer to the next 8-byte aligned boundry.\r
+    //\r
+    FfsHeader = (EFI_FFS_FILE_HEADER *)(((UINTN)FfsHeader + 7) & ~0x07);\r
+    \r
+  }\r
+\r
+Done:\r
+  if (EFI_ERROR (Status)) {\r
+    FreeFvDeviceResource (FvDevice);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+STATIC\r
+VOID\r
+EFIAPI\r
+NotifyFwVolBlock (\r
+  IN  EFI_EVENT Event,\r
+  IN  VOID      *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+    This notification function is invoked when an instance of the\r
+    EFI_FW_VOLUME_BLOCK_PROTOCOL is produced.  It layers an instance of the\r
+    EFI_FIRMWARE_VOLUME_PROTOCOL on the same handle.  This is the function where\r
+    the actual initialization of the EFI_FIRMWARE_VOLUME_PROTOCOL is done.\r
+\r
+Arguments:\r
+    Event - The event that occured\r
+    Context - For EFI compatiblity.  Not used.\r
+\r
+Returns:\r
+\r
+    None.\r
+\r
+--*/\r
+{\r
+  EFI_HANDLE                            Handle;\r
+  EFI_STATUS                            Status;\r
+  UINTN                                 BufferSize;\r
+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL    *Fvb;\r
+  EFI_FIRMWARE_VOLUME_PROTOCOL          *Fv;\r
+  FV_DEVICE                             *FvDevice;\r
+  EFI_FIRMWARE_VOLUME_HEADER            *FwVolHeader;\r
+  //\r
+  // Examine all new handles\r
+  //\r
+  for (;;) {\r
+    //\r
+    // Get the next handle\r
+    //\r
+    BufferSize = sizeof (Handle);\r
+    Status = CoreLocateHandle (\r
+              ByRegisterNotify,\r
+              NULL,\r
+              gEfiFwVolBlockNotifyReg,\r
+              &BufferSize,\r
+              &Handle\r
+              );\r
+\r
+    //\r
+    // If not found, we're done\r
+    //\r
+    if (EFI_NOT_FOUND == Status) {\r
+      break;\r
+    }\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      continue;\r
+    }\r
+    \r
+    //\r
+    // Get the FirmwareVolumeBlock protocol on that handle\r
+    //\r
+    Status = CoreHandleProtocol (Handle, &gEfiFirmwareVolumeBlockProtocolGuid, (VOID **)&Fvb); \r
+    ASSERT_EFI_ERROR (Status);\r
+    \r
+\r
+    //\r
+    // Make sure the Fv Header is O.K.\r
+    //\r
+    Status = GetFwVolHeader (Fvb, &FwVolHeader);\r
+    if (EFI_ERROR (Status)) {\r
+      return;\r
+    }\r
+\r
+    if (!VerifyFvHeaderChecksum (FwVolHeader)) {\r
+      CoreFreePool (FwVolHeader);\r
+      continue;\r
+    }\r
+\r
+\r
+    //\r
+    // Check to see that the file system is indeed formatted in a way we can\r
+    // understand it...\r
+    //\r
+    if (!CompareGuid (&FwVolHeader->FileSystemGuid, &gEfiFirmwareFileSystemGuid)) {\r
+      continue;\r
+    }\r
+\r
+    //\r
+    // Check if there is an FV protocol already installed in that handle\r
+    //\r
+    Status = CoreHandleProtocol (Handle, &gEfiFirmwareVolumeProtocolGuid, (VOID **)&Fv);\r
+    if (!EFI_ERROR (Status)) {\r
+      //\r
+      // Update Fv to use a new Fvb\r
+      //\r
+      FvDevice = _CR (Fv, FV_DEVICE, Fv);\r
+      if (FvDevice->Signature == FV_DEVICE_SIGNATURE) {\r
+        //\r
+        // Only write into our device structure if it's our device structure\r
+        //\r
+        FvDevice->Fvb = Fvb;\r
+      }\r
+\r
+    } else {\r
+      //\r
+      // No FwVol protocol on the handle so create a new one\r
+      //\r
+      FvDevice = CoreAllocateCopyPool (sizeof (FV_DEVICE), &mFvDevice);\r
+      if (FvDevice == NULL) {\r
+        return;\r
+      }\r
+      \r
+      FvDevice->Fvb         = Fvb;\r
+      FvDevice->Handle      = Handle;\r
+      FvDevice->FwVolHeader = FwVolHeader;\r
+      FvDevice->Fv.ParentHandle = Fvb->ParentHandle;\r
+      \r
+      //\r
+      // Install an New FV protocol on the existing handle\r
+      //\r
+      Status = CoreInstallProtocolInterface (\r
+                  &Handle,\r
+                  &gEfiFirmwareVolumeProtocolGuid,\r
+                  EFI_NATIVE_INTERFACE,\r
+                  &FvDevice->Fv\r
+                  );\r
+      ASSERT_EFI_ERROR (Status);\r
+    }\r
+  }\r
+  \r
+  return;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+FwVolDriverInit (\r
+  IN EFI_HANDLE                   ImageHandle,\r
+  IN EFI_SYSTEM_TABLE             *SystemTable\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+    This routine is the driver initialization entry point.  It initializes the\r
+    libraries, and registers two notification functions.  These notification\r
+    functions are responsible for building the FV stack dynamically.\r
+    \r
+Arguments:\r
+    ImageHandle   - The image handle.\r
+    SystemTable   - The system table.\r
+    \r
+Returns:\r
+    EFI_SUCCESS   - Function successfully returned.\r
+\r
+--*/\r
+{\r
+  gEfiFwVolBlockEvent = CoreCreateProtocolNotifyEvent (\r
+                          &gEfiFirmwareVolumeBlockProtocolGuid,\r
+                          TPL_CALLBACK,\r
+                          NotifyFwVolBlock,\r
+                          NULL,\r
+                          &gEfiFwVolBlockNotifyReg,\r
+                          TRUE\r
+                          );\r
+  return EFI_SUCCESS;\r
+}\r
+\r
diff --git a/MdeModulePkg/Core/Dxe/FwVol/FwVolAttrib.c b/MdeModulePkg/Core/Dxe/FwVol/FwVolAttrib.c
new file mode 100644 (file)
index 0000000..4a31a8d
--- /dev/null
@@ -0,0 +1,99 @@
+/*++\r
+\r
+Copyright (c) 2006, 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
+\r
+Module Name:\r
+\r
+  FwVolAttrib.c\r
+\r
+Abstract:\r
+\r
+  Implements get/set firmware volume attributes\r
+\r
+--*/\r
+\r
+#include <DxeMain.h>\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+FvGetVolumeAttributes (\r
+  IN  EFI_FIRMWARE_VOLUME_PROTOCOL  *This,\r
+  OUT EFI_FV_ATTRIBUTES             *Attributes\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+    Retrieves attributes, insures positive polarity of attribute bits, returns\r
+    resulting attributes in output parameter\r
+\r
+Arguments:\r
+    This        - Calling context\r
+    Attributes  - output buffer which contains attributes\r
+\r
+Returns:\r
+    EFI_SUCCESS         - Successfully got volume attributes\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                                Status;\r
+  FV_DEVICE                                 *FvDevice;\r
+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL        *Fvb;\r
+  EFI_FVB_ATTRIBUTES                        FvbAttributes;\r
+\r
+  FvDevice = FV_DEVICE_FROM_THIS (This);\r
+  Fvb = FvDevice->Fvb;\r
+\r
+  if (FvDevice->CachedFv == NULL) {\r
+    Status = FvCheck (FvDevice);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+  }\r
+\r
+  //\r
+  // First get the Firmware Volume Block Attributes\r
+  //\r
+  Status = Fvb->GetAttributes (Fvb, &FvbAttributes);\r
+\r
+  //\r
+  // Mask out Fvb bits that are not defined in FV \r
+  //\r
+  FvbAttributes &= 0xfffff0ff;\r
+  \r
+  *Attributes = (EFI_FV_ATTRIBUTES)FvbAttributes; \r
+  \r
+  return Status;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+FvSetVolumeAttributes (\r
+  IN EFI_FIRMWARE_VOLUME_PROTOCOL   *This,\r
+  IN OUT EFI_FV_ATTRIBUTES          *Attributes\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+    Sets current attributes for volume\r
+\r
+Arguments:\r
+    This       - Calling context\r
+    Attributes - At input, contains attributes to be set.  At output contains\r
+      new value of FV\r
+\r
+Returns:\r
+    EFI_UNSUPPORTED   - Could not be set.\r
+\r
+--*/\r
+{\r
+  return EFI_UNSUPPORTED;\r
+}\r
+\r
diff --git a/MdeModulePkg/Core/Dxe/FwVol/FwVolRead.c b/MdeModulePkg/Core/Dxe/FwVol/FwVolRead.c
new file mode 100644 (file)
index 0000000..ff2fcb8
--- /dev/null
@@ -0,0 +1,516 @@
+/*++\r
+\r
+Copyright (c) 2006, 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
+\r
+Module Name:\r
+\r
+  FwVolRead.c\r
+\r
+Abstract:\r
+\r
+  Implements read firmware file\r
+\r
+--*/\r
+\r
+#include <DxeMain.h>\r
+\r
+/*++\r
+\r
+Required Alignment    Alignment Value in FFS       Alignment Value in\r
+(bytes)                        Attributes Field               Firmware Volume Interfaces\r
+1                                    0                                     0\r
+2                                    0