]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Merge branch of PI tree to main trunk
authorklu2 <klu2@6f19259b-4bc3-4df7-8a09-765794883524>
Mon, 24 Sep 2007 11:38:43 +0000 (11:38 +0000)
committerklu2 <klu2@6f19259b-4bc3-4df7-8a09-765794883524>
Mon, 24 Sep 2007 11:38:43 +0000 (11:38 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3918 6f19259b-4bc3-4df7-8a09-765794883524

34 files changed:
MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c
MdeModulePkg/Core/DxeIplPeim/DxeIpl.h
MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
MdeModulePkg/Core/DxeIplPeim/DxeLoad.c
MdeModulePkg/Core/Pei/Dependency/dependency.c
MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
MdeModulePkg/Core/Pei/FwVol/FwVol.c
MdeModulePkg/Core/Pei/Image/Image.c
MdeModulePkg/Core/Pei/Memory/MemoryServices.c
MdeModulePkg/Core/Pei/PeiMain.h
MdeModulePkg/Core/Pei/PeiMain.inf
MdeModulePkg/Core/Pei/PeiMain.msa
MdeModulePkg/Core/Pei/PeiMain/PeiMain.c
MdeModulePkg/Core/Pei/Ppi/Ppi.c
MdeModulePkg/Core/Pei/Reset/Reset.c
MdeModulePkg/Core/Pei/Security/Security.c
MdeModulePkg/MdeModulePkg.dec
MdeModulePkg/MdeModulePkg.dsc
MdePkg/Include/Library/HobLib.h
MdePkg/Include/Library/PeiPiLib.h [new file with mode: 0644]
MdePkg/Include/Library/PeiServicesLib.h
MdePkg/Include/Library/PeiServicesTablePointerLib.h
MdePkg/Include/Library/PiLib.h
MdePkg/Include/Pi/PiPeiCis.h
MdePkg/Library/DxePiLib/DxePiLib.c
MdePkg/Library/PeiPiLib/PeiPiLib.c [new file with mode: 0644]
MdePkg/Library/PeiPiLib/PeiPiLib.inf [new file with mode: 0644]
MdePkg/Library/PeiServicesLib/PeiServicesLib.c
MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointer.c
MdePkg/Library/PeiServicesTablePointerLibMm7/PeiServicesTablePointer.c
MdePkg/MdePkg.dsc
Nt32Pkg/Library/Nt32PeCoffLoaderLib/Nt32PeCoffLoader.c
Nt32Pkg/Library/Nt32PeCoffLoaderLib/Nt32PeCoffLoaderLib.inf
Nt32Pkg/Nt32Pkg.dsc

index c7b4cc3e12a9a0f1f4e7d225acb18f7b9ed4a4da..da0555d8f938259f0c3c3f72aaa9dfd15d9bc75b 100644 (file)
@@ -490,7 +490,6 @@ Returns:
       \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
@@ -814,25 +813,12 @@ Returns:
 --*/\r
 {\r
   EFI_PEI_HOB_POINTERS                HobFv2;\r
-  EFI_STATUS                          Status;\r
-  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *Fvb;\r
-  EFI_FIRMWARE_VOLUME_HEADER          *FvHeader;\r
-  EFI_PHYSICAL_ADDRESS                FvHeaderAddr;\r
   \r
   HobFv2.Raw = GetHobList ();\r
   \r
   while ((HobFv2.Raw = GetNextHob (EFI_HOB_TYPE_FV2, HobFv2.Raw)) != NULL) {\r
     if (CompareGuid (DriverName, &HobFv2.FirmwareVolume2->FileName)) {\r
-      Status = CoreHandleProtocol (FvHandle, &gEfiFirmwareVolumeBlockProtocolGuid, (VOID **) &Fvb);\r
-      if (!EFI_ERROR (Status)) {\r
-        Status = Fvb->GetPhysicalAddress (Fvb, &FvHeaderAddr);\r
-        if (!EFI_ERROR (Status)) {\r
-          FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) FvHeaderAddr;\r
-          if (CompareGuid (&FvHeader->FileSystemGuid, &HobFv2.FirmwareVolume2->FvName)) {\r
-            return TRUE;\r
-          }\r
-        }\r
-      }\r
+      return TRUE;\r
     }\r
     HobFv2.Raw = GET_NEXT_HOB (HobFv2);\r
   }\r
index 1907077ef2188f867639ab127390186f4f6b1690..3cd9ebac4ca6cf5d309c00b4054a37c8f66bba09 100644 (file)
@@ -32,6 +32,11 @@ Abstract:
 #include <Ppi/FvLoadFile.h>\r
 #include <Ppi/RecoveryModule.h>\r
 #include <Ppi/MemoryDiscovered.h>\r
+#include <Ppi/Decompress.h>\r
+#include <Ppi/FirmwareVolumeInfo.h>\r
+\r
+#include <Guid/FirmwareFileSystem2.h>\r
+\r
 #include <Library/DebugLib.h>\r
 #include <Library/PeimEntryPoint.h>\r
 #include <Library/BaseLib.h>\r
@@ -67,14 +72,27 @@ PeiFindFile (
 \r
 EFI_STATUS\r
 PeiLoadFile (\r
-  IN  EFI_PEI_PE_COFF_LOADER_PROTOCOL           *PeiEfiPeiPeCoffLoader,\r
-  IN  VOID                                      *Pe32Data,\r
+  IN  EFI_PEI_FILE_HANDLE                       FileHandle,\r
   OUT EFI_PHYSICAL_ADDRESS                      *ImageAddress,\r
   OUT UINT64                                    *ImageSize,\r
   OUT EFI_PHYSICAL_ADDRESS                      *EntryPoint\r
   )\r
 ;\r
 \r
+EFI_STATUS\r
+DxeIplAddEncapsulatedFirmwareVolumes (\r
+  VOID\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+DxeIplFindFirmwareVolumeInstance (\r
+  IN OUT UINTN              *Instance,\r
+  IN  EFI_FV_FILETYPE       SeachType,\r
+  OUT EFI_PEI_FV_HANDLE     *VolumeHandle,\r
+  OUT EFI_PEI_FILE_HANDLE   *FileHandle\r
+  )\r
+;\r
 \r
 EFI_STATUS\r
 GetImageReadFunction (\r
@@ -133,9 +151,10 @@ PeiProcessFile (
 EFI_STATUS\r
 EFIAPI\r
 PeimInitializeDxeIpl (\r
-  IN EFI_FFS_FILE_HEADER       *FfsHeader,\r
+  IN EFI_PEI_FILE_HANDLE       FfsHandle,\r
   IN EFI_PEI_SERVICES          **PeiServices\r
-  );\r
+  )\r
+;\r
 \r
 \r
 #endif\r
index d76e904b8d7eb157f93ad92959be22a23eb44dac..ff003e114b14fd73148541d9dffd4569a46cd356 100644 (file)
@@ -58,8 +58,6 @@
   MdePkg/MdePkg.dec\r
   MdeModulePkg/MdeModulePkg.dec\r
   IntelFrameworkPkg/IntelFrameworkPkg.dec\r
-  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec\r
-\r
 \r
 [LibraryClasses]\r
   PeCoffLib\r
   gEfiPeiS3ResumePpiGuid                        # PPI SOMETIMES_CONSUMED\r
   gEfiPeiRecoveryModulePpiGuid                  # PPI SOMETIMES_CONSUMED\r
   gEfiEndOfPeiSignalPpiGuid                     # PPI SOMETIMES_PRODUCED\r
-  gEfiPeiFvFileLoaderPpiGuid                    # PPI SOMETIMES_PRODUCED\r
   gEfiDxeIplPpiGuid                             # PPI SOMETIMES_PRODUCED\r
   gEfiPeiPeCoffLoaderGuid                       \r
-\r
+  gEfiPeiDecompressPpiGuid\r
+  gEfiPeiFirmwareVolumeInfoPpiGuid\r
 \r
 [FeaturePcd.common]\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSupportCustomDecompress\r
index 32486a2e75d77327d37b11466e53c315b9331015..089e3bff66be44538ec8b53f1ee443ac03f0dcb7 100644 (file)
@@ -1,6 +1,8 @@
-/*++\r
+/**@file\r
+  Last PEIM.\r
+  Responsibility of this module is to load the DXE Core from a Firmware Volume.\r
 \r
-Copyright (c) 2006, Intel Corporation\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
@@ -9,23 +11,11 @@ http://opensource.org/licenses/bsd-license.php
 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
-  DxeLoad.c\r
-\r
-Abstract:\r
-\r
-  Last PEIM.\r
-  Responsibility of this module is to load the DXE Core from a Firmware Volume.\r
-\r
---*/\r
+**/\r
 \r
 #include "DxeIpl.h"\r
 #include <Ppi/GuidedSectionExtraction.h>\r
-\r
-// porting note remove later\r
-#include "FrameworkPei.h"\r
-// end of remove later\r
+#include <FrameworkPei.h>\r
 \r
 EFI_STATUS\r
 CustomDecompressExtractSection (\r
@@ -36,6 +26,17 @@ CustomDecompressExtractSection (
   OUT       UINT32                                *AuthenticationStatus\r
 );\r
 \r
+STATIC\r
+EFI_STATUS\r
+EFIAPI \r
+Decompress (\r
+  IN CONST  EFI_PEI_DECOMPRESS_PPI  *This,\r
+  IN CONST  EFI_COMPRESSION_SECTION *InputSection,\r
+  OUT       VOID                    **OutputBuffer,\r
+  OUT       UINTN                   *OutputSize\r
+);\r
+\r
+\r
 BOOLEAN gInMemory = FALSE;\r
 \r
 //\r
@@ -46,24 +47,24 @@ static EFI_DXE_IPL_PPI mDxeIplPpi = {
   DxeLoadCore\r
 };\r
 \r
-static EFI_PEI_FV_FILE_LOADER_PPI mLoadFilePpi = {\r
-  DxeIplLoadFile\r
+STATIC EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI mCustomDecompressExtractiongPpi = {\r
+  CustomDecompressExtractSection\r
 };\r
 \r
-static EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI mCustomDecompressExtractiongPpi = {\r
-  CustomDecompressExtractSection\r
+STATIC EFI_PEI_DECOMPRESS_PPI mDecompressPpi = {\r
+  Decompress\r
 };\r
 \r
 static EFI_PEI_PPI_DESCRIPTOR     mPpiList[] = {\r
   {\r
-  EFI_PEI_PPI_DESCRIPTOR_PPI,\r
-  &gEfiPeiFvFileLoaderPpiGuid,\r
-  &mLoadFilePpi\r
+    EFI_PEI_PPI_DESCRIPTOR_PPI,\r
+    &gEfiDxeIplPpiGuid,\r
+    &mDxeIplPpi\r
   },\r
   {\r
-  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
-  &gEfiDxeIplPpiGuid,\r
-  &mDxeIplPpi\r
+    (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
+    &gEfiPeiDecompressPpiGuid,\r
+    &mDecompressPpi\r
   }\r
 };\r
 \r
@@ -73,31 +74,30 @@ static EFI_PEI_PPI_DESCRIPTOR     mPpiSignal = {
   NULL\r
 };\r
 \r
+STATIC EFI_PEI_FIRMWARE_VOLUME_INFO_PPI mFvInfoPpiTemplate = {\r
+  EFI_FIRMWARE_FILE_SYSTEM2_GUID,\r
+  NULL,\r
+  0,    //FvInfoSize\r
+  NULL, //ParentFvName\r
+  NULL //ParentFileName;\r
+};\r
+\r
+/**\r
+  Initializes the Dxe Ipl PPI\r
+\r
+  @param  FfsHandle   The handle of FFS file.\r
+  @param  PeiServices General purpose services available to\r
+                      every PEIM.\r
+  @return EFI_SUCESS \r
+*/ \r
 EFI_STATUS\r
 EFIAPI\r
 PeimInitializeDxeIpl (\r
-  IN EFI_FFS_FILE_HEADER       *FfsHeader,\r
+  IN EFI_PEI_FILE_HANDLE       FfsHandle,\r
   IN EFI_PEI_SERVICES          **PeiServices\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Initializes the Dxe Ipl PPI\r
-\r
-Arguments:\r
-\r
-  FfsHeader   - Pointer to FFS file header\r
-  PeiServices - General purpose services available to every PEIM.\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS\r
-\r
---*/\r
 {\r
   EFI_STATUS                                Status;\r
-  EFI_PEI_PE_COFF_LOADER_PROTOCOL           *PeiEfiPeiPeCoffLoader;\r
   EFI_BOOT_MODE                             BootMode;\r
   EFI_GUID                                  **DecompressGuidList;\r
   UINT32                                    DecompressMethodNumber;\r
@@ -106,56 +106,70 @@ Returns:
   Status = PeiServicesGetBootMode (&BootMode);\r
   ASSERT_EFI_ERROR (Status);\r
 \r
-  if (!gInMemory && (BootMode != BOOT_ON_S3_RESUME)) {   \r
-    //\r
-    // The DxeIpl has not yet been shadowed\r
-    //\r
-    PeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)GetPeCoffLoaderProtocol ();\r
+  if (BootMode != BOOT_ON_S3_RESUME) {\r
+    Status = PeiServicesRegisterForShadow (FfsHandle);\r
+    if (Status == EFI_SUCCESS) {\r
 \r
-    //\r
-    // Shadow DxeIpl and then re-run its entry point\r
-    //\r
-    Status = ShadowDxeIpl (FfsHeader, PeiEfiPeiPeCoffLoader);\r
-  } else {\r
-    //\r
-    // Get custom decompress method guid list \r
-    //\r
-    DecompressGuidList     = NULL;\r
-    DecompressMethodNumber = 0;\r
-    Status = CustomDecompressGetAlgorithms (DecompressGuidList, &DecompressMethodNumber);\r
-    if (Status == EFI_OUT_OF_RESOURCES) {\r
+      gInMemory = TRUE;\r
+      //\r
+      // EFI_SUCESS means the first time call register for shadow \r
+      // \r
+      return Status;\r
+    } else if (Status == EFI_ALREADY_STARTED) {\r
+\r
+\r
+      //\r
+      // Get custom decompress method guid list \r
+      //\r
+      DecompressGuidList     = NULL;\r
+      DecompressMethodNumber = 0;\r
+      Status = CustomDecompressGetAlgorithms (DecompressGuidList, &DecompressMethodNumber);\r
+      if (Status == EFI_OUT_OF_RESOURCES) {\r
       DecompressGuidList = (EFI_GUID **) AllocatePages (EFI_SIZE_TO_PAGES (DecompressMethodNumber * sizeof (EFI_GUID *)));\r
       ASSERT (DecompressGuidList != NULL);\r
       Status = CustomDecompressGetAlgorithms (DecompressGuidList, &DecompressMethodNumber);\r
-    }\r
-    ASSERT_EFI_ERROR(Status);\r
-\r
-    //\r
-    // Install custom decompress extraction guid ppi\r
-    //\r
-    if (DecompressMethodNumber > 0) {\r
-      GuidPpi = NULL;\r
-      GuidPpi = (EFI_PEI_PPI_DESCRIPTOR *) AllocatePages (EFI_SIZE_TO_PAGES (DecompressMethodNumber * sizeof (EFI_PEI_PPI_DESCRIPTOR)));\r
-      ASSERT (GuidPpi != NULL);\r
-      while (DecompressMethodNumber-- > 0) {\r
-        GuidPpi->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;\r
-        GuidPpi->Ppi   = &mCustomDecompressExtractiongPpi;\r
-        GuidPpi->Guid  = DecompressGuidList [DecompressMethodNumber];\r
-        Status = PeiServicesInstallPpi (GuidPpi++);\r
-        ASSERT_EFI_ERROR(Status);\r
       }\r
+      ASSERT_EFI_ERROR(Status);\r
+      \r
+      //\r
+      // Install custom decompress extraction guid ppi\r
+      //\r
+      if (DecompressMethodNumber > 0) {\r
+       GuidPpi = NULL;\r
+       GuidPpi = (EFI_PEI_PPI_DESCRIPTOR *) AllocatePages (EFI_SIZE_TO_PAGES (DecompressMethodNumber * sizeof (EFI_PEI_PPI_DESCRIPTOR)));\r
+       ASSERT (GuidPpi != NULL);\r
+       while (DecompressMethodNumber-- > 0) {\r
+         GuidPpi->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;\r
+         GuidPpi->Ppi   = &mCustomDecompressExtractiongPpi;\r
+         GuidPpi->Guid  = DecompressGuidList [DecompressMethodNumber];\r
+         Status = PeiServicesInstallPpi (GuidPpi++);\r
+         ASSERT_EFI_ERROR(Status);\r
+       }\r
+      }\r
+    } else {\r
+      ASSERT_EFI_ERROR (FALSE);\r
     }\r
-    \r
-    //\r
-    // Install FvFileLoader and DxeIpl PPIs.\r
-    //\r
-    Status = PeiServicesInstallPpi (mPpiList);\r
-    ASSERT_EFI_ERROR(Status);\r
   }\r
   \r
+  //\r
+  // Install FvFileLoader and DxeIpl PPIs.\r
+  //\r
+  Status = PeiServicesInstallPpi (mPpiList);\r
+  ASSERT_EFI_ERROR(Status);  \r
+       \r
   return Status;\r
 }\r
 \r
+/**\r
+   Main entry point to last PEIM \r
+    \r
+   @param This          Entry point for DXE IPL PPI\r
+   @param PeiServices   General purpose services available to every PEIM.\r
+   @param HobList       Address to the Pei HOB list\r
+   \r
+   @return EFI_SUCCESS              DXE core was successfully loaded. \r
+   @return EFI_OUT_OF_RESOURCES     There are not enough resources to load DXE core.\r
+**/\r
 EFI_STATUS\r
 EFIAPI\r
 DxeLoadCore (\r
@@ -163,29 +177,9 @@ DxeLoadCore (
   IN EFI_PEI_SERVICES      **PeiServices,\r
   IN EFI_PEI_HOB_POINTERS  HobList\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Main entry point to last PEIM\r
-\r
-Arguments:\r
-  This         - Entry point for DXE IPL PPI\r
-  PeiServices  - General purpose services available to every PEIM.\r
-  HobList      - Address to the Pei HOB list\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS          - DEX core was successfully loaded.\r
-  EFI_OUT_OF_RESOURCES - There are not enough resources to load DXE core.\r
-\r
---*/\r
 {\r
   EFI_STATUS                                Status;\r
   EFI_GUID                                  DxeCoreFileName;\r
-  EFI_GUID                                  FirmwareFileName;\r
-  VOID                                      *Pe32Data;\r
-  VOID                                      *FvImageData;     \r
   EFI_PHYSICAL_ADDRESS                      DxeCoreAddress;\r
   UINT64                                    DxeCoreSize;\r
   EFI_PHYSICAL_ADDRESS                      DxeCoreEntryPoint;\r
@@ -193,8 +187,9 @@ Returns:
   EFI_BOOT_MODE                             BootMode;\r
   EFI_PEI_RECOVERY_MODULE_PPI               *PeiRecovery;\r
   EFI_PEI_S3_RESUME_PPI                     *S3Resume;\r
-\r
-//  PERF_START (PeiServices, L"DxeIpl", NULL, 0);\r
+  EFI_PEI_FV_HANDLE                         VolumeHandle;\r
+  EFI_PEI_FILE_HANDLE                       FileHandle;\r
+  UINTN                                     Instance;\r
 \r
   //\r
   // if in S3 Resume, restore configure\r
@@ -237,42 +232,33 @@ Returns:
   //\r
   // Install the PEI Protocols that are shared between PEI and DXE\r
   //\r
-  PeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)GetPeCoffLoaderProtocol ();\r
+  PeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *) GetPeCoffLoaderProtocol ();\r
   ASSERT (PeiEfiPeiPeCoffLoader != NULL);\r
-\r
+  \r
   //\r
-  // Find the EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE type compressed Firmware Volume file\r
-  // The file found will be processed by PeiProcessFile: It will first be decompressed to\r
-  // a normal FV, then a corresponding FV type hob will be built. \r
+  // If any FV contains an encapsulated FV extract that FV\r
   //\r
-  Status = PeiFindFile (\r
-             EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE,\r
-             EFI_SECTION_FIRMWARE_VOLUME_IMAGE,\r
-             &FirmwareFileName,\r
-             &FvImageData\r
-             );\r
-\r
+  DxeIplAddEncapsulatedFirmwareVolumes ();\r
+  \r
   //\r
-  // Find the DXE Core in a Firmware Volume\r
+  // Look in all the FVs present in PEI and find the DXE Core\r
   //\r
-  Status = PeiFindFile (\r
-            EFI_FV_FILETYPE_DXE_CORE,\r
-            EFI_SECTION_PE32,\r
-            &DxeCoreFileName,\r
-            &Pe32Data\r
-            );\r
+  Instance = 0;\r
+  Status = DxeIplFindFirmwareVolumeInstance (&Instance, EFI_FV_FILETYPE_DXE_CORE, &VolumeHandle, &FileHandle);\r
   ASSERT_EFI_ERROR (Status);\r
 \r
+  CopyMem(&DxeCoreFileName, &(((EFI_FFS_FILE_HEADER*)FileHandle)->Name), sizeof (EFI_GUID));\r
+\r
   //\r
   // Load the DXE Core from a Firmware Volume\r
   //\r
   Status = PeiLoadFile (\r
-             PeiEfiPeiPeCoffLoader,\r
-             Pe32Data,\r
-             &DxeCoreAddress,\r
-             &DxeCoreSize,\r
-             &DxeCoreEntryPoint\r
-             );\r
+            FileHandle,\r
+            &DxeCoreAddress,\r
+            &DxeCoreSize,\r
+            &DxeCoreEntryPoint\r
+            );\r
+\r
   ASSERT_EFI_ERROR (Status);\r
 \r
   //\r
@@ -305,7 +291,6 @@ Returns:
   // Transfer control to the DXE Core\r
   // The handoff state is simply a pointer to the HOB list\r
   //\r
-\r
   DEBUG ((EFI_D_INFO, "DXE Core Entry Point 0x%08x\n", (UINTN) DxeCoreEntryPoint));\r
   HandOffToDxeCore (DxeCoreEntryPoint, HobList, &mPpiSignal);\r
   //\r
@@ -318,124 +303,235 @@ Returns:
   return EFI_OUT_OF_RESOURCES;\r
 }\r
 \r
+\r
+STATIC\r
 EFI_STATUS\r
-PeiFindFile (\r
-  IN  UINT8                  Type,\r
-  IN  EFI_SECTION_TYPE       SectionType,\r
-  OUT EFI_GUID               *FileName,\r
-  OUT VOID                   **Pe32Data\r
+GetFvAlignment (\r
+  IN    EFI_FIRMWARE_VOLUME_HEADER   *FvHeader,\r
+  OUT   UINT32                      *FvAlignment\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Finds a PE/COFF of a specific Type and SectionType in the Firmware Volumes\r
-  described in the HOB list. Able to search in a compression set in a FFS file.\r
-  But only one level of compression is supported, that is, not able to search\r
-  in a compression set that is within another compression set.\r
-\r
-Arguments:\r
+{\r
+  //\r
+  // Because FvLength in FvHeader is UINT64 type, \r
+  // so FvHeader must meed at least 8 bytes alignment.\r
+  // Get the appropriate alignment requirement.\r
+  // \r
+  if ((FvHeader->Attributes & EFI_FVB2_ALIGNMENT) < EFI_FVB2_ALIGNMENT_8) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  \r
+   *FvAlignment = 1 << ((FvHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16);\r
+   return EFI_SUCCESS;\r
+}\r
 \r
-  Type        - The Type of file to retrieve\r
+/**\r
+   Search EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE image and expand \r
+   as memory FV \r
+    \r
+   @return EFI_OUT_OF_RESOURCES There are no memory space to exstract FV\r
+   @return EFI_SUCESS           Sucess to find the FV \r
+**/\r
+EFI_STATUS\r
+DxeIplAddEncapsulatedFirmwareVolumes (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  EFI_STATUS                  VolumeStatus;\r
+  UINTN                       Index;\r
+  EFI_FV_INFO                 VolumeInfo; \r
+  EFI_PEI_FV_HANDLE           VolumeHandle;\r
+  EFI_PEI_FILE_HANDLE         FileHandle;\r
+  UINT32                      SectionLength;\r
+  EFI_FIRMWARE_VOLUME_HEADER  *FvHeader;\r
+  EFI_FIRMWARE_VOLUME_IMAGE_SECTION *SectionHeader;\r
+  VOID                        *DstBuffer;\r
+  UINT32                       FvAlignment;\r
+  EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *FvInfoPpi;\r
+  EFI_PEI_PPI_DESCRIPTOR           *FvInfoPpiDescriptor;\r
+\r
+  Status = EFI_NOT_FOUND;\r
+  Index  = 0;\r
 \r
-  SectionType - The type of section to retrieve from a file\r
+  do {\r
+    VolumeStatus = DxeIplFindFirmwareVolumeInstance (\r
+                    &Index, \r
+                    EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, \r
+                    &VolumeHandle, \r
+                    &FileHandle\r
+                    );\r
+                    \r
+    if (!EFI_ERROR (VolumeStatus)) {\r
+         Status = PeiServicesFfsFindSectionData (\r
+                    EFI_SECTION_FIRMWARE_VOLUME_IMAGE, \r
+                    (EFI_FFS_FILE_HEADER *)FileHandle, \r
+                    (VOID **)&FvHeader\r
+                    );\r
+                    \r
+      if (!EFI_ERROR (Status)) {\r
+        if (FvHeader->Signature == EFI_FVH_SIGNATURE) {\r
+          //\r
+          // Because FvLength in FvHeader is UINT64 type, \r
+          // so FvHeader must meed at least 8 bytes alignment.\r
+          // If current FvImage base address doesn't meet its alignment,\r
+          // we need to reload this FvImage to another correct memory address.\r
+          //\r
+          Status = GetFvAlignment(FvHeader, &FvAlignment); \r
+          if (EFI_ERROR(Status)) {\r
+            return Status;\r
+          }\r
+          if (((UINTN) FvHeader % FvAlignment) != 0) {\r
+            SectionHeader = (EFI_FIRMWARE_VOLUME_IMAGE_SECTION*)((UINTN)FvHeader - sizeof(EFI_FIRMWARE_VOLUME_IMAGE_SECTION));\r
+            SectionLength =  *(UINT32 *)SectionHeader->Size & 0x00FFFFFF;\r
+            \r
+            DstBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINTN) SectionLength - sizeof (EFI_COMMON_SECTION_HEADER)), FvAlignment);\r
+            if (DstBuffer == NULL) {\r
+              return EFI_OUT_OF_RESOURCES;\r
+            }\r
+            CopyMem (DstBuffer, FvHeader, (UINTN) SectionLength - sizeof (EFI_COMMON_SECTION_HEADER));\r
+            FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) DstBuffer;  \r
+          }\r
 \r
-  FileName    - The name of the file found in the Firmware Volume\r
+          //\r
+          // This new Firmware Volume comes from a firmware file within a firmware volume.\r
+          // Record the original Firmware Volume Name.\r
+          //\r
+          PeiServicesFfsGetVolumeInfo (&VolumeHandle, &VolumeInfo);\r
 \r
-  Pe32Data    - Pointer to the beginning of the PE/COFF file found in the Firmware Volume\r
+          //\r
+          // Prepare to install FirmwareVolumeInfo PPI to expose new FV to PeiCore.\r
+          //\r
+          FvInfoPpi = AllocateCopyPool (sizeof (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI), &mFvInfoPpiTemplate);\r
+          ASSERT(FvInfoPpi != NULL);\r
+\r
+          FvInfoPpi->FvInfo     = (VOID*)FvHeader;\r
+          FvInfoPpi->FvInfoSize = (UINT32)FvHeader->FvLength;\r
+          CopyMem (\r
+            &FvInfoPpi->ParentFvName,\r
+            &(VolumeInfo.FvName),\r
+            sizeof (EFI_GUID)\r
+            );\r
+          CopyMem (\r
+            &FvInfoPpi->ParentFileName,\r
+            &(((EFI_FFS_FILE_HEADER*)FileHandle)->Name),\r
+            sizeof (EFI_GUID)\r
+            );\r
 \r
-Returns:\r
+          FvInfoPpiDescriptor = AllocatePool (sizeof(EFI_PEI_PPI_DESCRIPTOR));\r
+          ASSERT (FvInfoPpiDescriptor != NULL);\r
+         \r
+          FvInfoPpiDescriptor->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI|EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;\r
+          FvInfoPpiDescriptor->Guid  = &gEfiPeiFirmwareVolumeInfoPpiGuid;\r
+          FvInfoPpiDescriptor->Ppi   = (VOID *) FvInfoPpi;\r
 \r
-  EFI_SUCCESS   - The file was found, and the name is returned in FileName, and a pointer to\r
-                  the PE/COFF image is returned in Pe32Data\r
+          Status          = PeiServicesInstallPpi (FvInfoPpiDescriptor);\r
+          ASSERT_EFI_ERROR (Status);\r
 \r
-  EFI_NOT_FOUND - The file was not found in the Firmware Volumes present in the HOB List\r
+          //\r
+          // Makes the encapsulated volume show up in DXE phase to skip processing of\r
+          // encapsulated file again.\r
+          //\r
+          BuildFv2Hob (\r
+            (EFI_PHYSICAL_ADDRESS)(UINTN)FvHeader,\r
+            FvHeader->FvLength, \r
+            &VolumeInfo.FvName,\r
+            &(((EFI_FFS_FILE_HEADER *)FileHandle)->Name)\r
+            );\r
+          return Status;\r
+        }\r
+      }\r
+    }\r
+  } while (!EFI_ERROR (VolumeStatus));\r
+  \r
+  return Status;\r
+}\r
 \r
---*/\r
+/**\r
+   Find the First Volume that contains the first FileType.\r
+\r
+   @param Instance      The Fv instance.\r
+   @param SeachType     The type of file to search.\r
+   @param VolumeHandle  Pointer to Fv which contains the file to search. \r
+   @param FileHandle    Pointer to FFS file to search.\r
+   \r
+   @return EFI_SUCESS   Success to find the FFS in specificed FV\r
+   @return others       Fail to find the FFS in specificed FV\r
+ */\r
+EFI_STATUS\r
+DxeIplFindFirmwareVolumeInstance (\r
+  IN OUT UINTN              *Instance,\r
+  IN  EFI_FV_FILETYPE       SeachType,\r
+  OUT EFI_PEI_FV_HANDLE     *VolumeHandle,\r
+  OUT EFI_PEI_FILE_HANDLE   *FileHandle\r
+  )\r
 {\r
-  EFI_FIRMWARE_VOLUME_HEADER  *FwVolHeader;\r
-  EFI_FFS_FILE_HEADER         *FfsFileHeader;\r
-  EFI_STATUS                  Status;\r
-  EFI_PEI_HOB_POINTERS        Hob;\r
+  EFI_STATUS  Status;\r
+  EFI_STATUS  VolumeStatus;\r
 \r
-\r
-  FwVolHeader   = NULL;\r
-  FfsFileHeader = NULL;\r
-  Status        = EFI_SUCCESS;\r
-\r
-  //\r
-  // For each Firmware Volume, look for a specified type\r
-  // of file and break out until no one is found \r
-  //\r
-  Hob.Raw = GetHobList ();\r
-  while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_FV, Hob.Raw)) != NULL) {\r
-    FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) (Hob.FirmwareVolume->BaseAddress);\r
-    //\r
-    // Make sure the FV HOB does not get corrupted.\r
-    //\r
-    ASSERT (FwVolHeader->Signature == EFI_FVH_SIGNATURE);\r
-\r
-    Status = PeiServicesFfsFindNextFile (\r
-               Type,\r
-               (EFI_PEI_FV_HANDLE)    FwVolHeader,\r
-               (EFI_PEI_FILE_HANDLE*) &FfsFileHeader\r
-               );\r
-    if (!EFI_ERROR (Status)) {\r
-      Status = PeiProcessFile (\r
-                 SectionType,\r
-                 FfsFileHeader,\r
-                 Pe32Data,\r
-                 &Hob\r
-                 );\r
-      CopyMem (FileName, &FfsFileHeader->Name, sizeof (EFI_GUID));\r
-      //\r
-      // Find all Fv type ffs to get all FvImage and add them into FvHob\r
-      //\r
-      if (!EFI_ERROR (Status) && (Type != EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE)) {\r
-        return EFI_SUCCESS;\r
+  do {\r
+    VolumeStatus = PeiServicesFfsFindNextVolume (*Instance, VolumeHandle);\r
+    if (!EFI_ERROR (VolumeStatus)) {\r
+      *FileHandle = NULL;\r
+      Status = PeiServicesFfsFindNextFile (SeachType, *VolumeHandle, FileHandle);\r
+      if (!EFI_ERROR (Status)) {\r
+        return Status;\r
       }\r
     }\r
-    Hob.Raw = GET_NEXT_HOB (Hob);\r
-  }\r
-  return EFI_NOT_FOUND;\r
+    *Instance += 1;\r
+  } while (!EFI_ERROR (VolumeStatus));\r
+\r
+  return VolumeStatus;\r
 }\r
 \r
+/**\r
+   Loads and relocates a PE/COFF image into memory.\r
+\r
+   @param FileHandle        The image file handle\r
+   @param ImageAddress      The base address of the relocated PE/COFF image\r
+   @param ImageSize         The size of the relocated PE/COFF image\r
+   @param EntryPoint        The entry point of the relocated PE/COFF image\r
+   \r
+   @return EFI_SUCCESS           The file was loaded and relocated\r
+   @return EFI_OUT_OF_RESOURCES  There was not enough memory to load and relocate the PE/COFF file\r
+**/\r
 EFI_STATUS\r
 PeiLoadFile (\r
-  IN  EFI_PEI_PE_COFF_LOADER_PROTOCOL           *PeiEfiPeiPeCoffLoader,\r
-  IN  VOID                                      *Pe32Data,\r
+  IN  EFI_PEI_FILE_HANDLE                       FileHandle,\r
   OUT EFI_PHYSICAL_ADDRESS                      *ImageAddress,\r
   OUT UINT64                                    *ImageSize,\r
   OUT EFI_PHYSICAL_ADDRESS                      *EntryPoint\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Loads and relocates a PE/COFF image into memory.\r
-\r
-Arguments:\r
-\r
-  PeiEfiPeiPeCoffLoader - Pointer to a PE COFF loader protocol\r
-\r
-  Pe32Data         - The base address of the PE/COFF file that is to be loaded and relocated\r
-\r
-  ImageAddress     - The base address of the relocated PE/COFF image\r
-\r
-  ImageSize        - The size of the relocated PE/COFF image\r
-\r
-  EntryPoint       - The entry point of the relocated PE/COFF image\r
-\r
-Returns:\r
+{\r
 \r
-  EFI_SUCCESS   - The file was loaded and relocated\r
+  EFI_STATUS                        Status;\r
+  PE_COFF_LOADER_IMAGE_CONTEXT      ImageContext;\r
+  VOID                              *Pe32Data;\r
+  EFI_PEI_PE_COFF_LOADER_PROTOCOL   *PeiEfiPeiPeCoffLoader;\r
 \r
-  EFI_OUT_OF_RESOURCES - There was not enough memory to load and relocate the PE/COFF file\r
+  PeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)GetPeCoffLoaderProtocol ();\r
+  //\r
+  // First try to find the required section in this ffs file.\r
+  //\r
+  Status = PeiServicesFfsFindSectionData (\r
+             EFI_SECTION_PE32,\r
+             FileHandle,\r
+             &Pe32Data\r
+             );\r
 \r
---*/\r
-{\r
-  EFI_STATUS                            Status;\r
-  PE_COFF_LOADER_IMAGE_CONTEXT          ImageContext;\r
+  if (EFI_ERROR (Status)) {\r
+    Status = PeiServicesFfsFindSectionData (\r
+               EFI_SECTION_TE,\r
+               FileHandle,\r
+               &Pe32Data\r
+               );\r
+  }\r
+  \r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // NO image types we support so exit.\r
+    //\r
+    return Status;\r
+  }\r
 \r
   ZeroMem (&ImageContext, sizeof (ImageContext));\r
   ImageContext.Handle = Pe32Data;\r
@@ -480,430 +576,6 @@ Returns:
   return EFI_SUCCESS;\r
 }\r
 \r
-EFI_STATUS\r
-ShadowDxeIpl (\r
-  IN EFI_FFS_FILE_HEADER                       *DxeIplFileHeader,\r
-  IN EFI_PEI_PE_COFF_LOADER_PROTOCOL           *PeiEfiPeiPeCoffLoader\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Shadow the DXE IPL to a different memory location. This occurs after permanent\r
-  memory has been discovered.\r
-\r
-Arguments:\r
-\r
-  DxeIplFileHeader      - Pointer to the FFS file header of the DXE IPL driver\r
-\r
-  PeiEfiPeiPeCoffLoader - Pointer to a PE COFF loader protocol\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS   - DXE IPL was successfully shadowed to a different memory location.\r
-\r
-  EFI_ ERROR    - The shadow was unsuccessful.\r
-\r
-\r
---*/\r
-{\r
-  UINTN                     SectionLength;\r
-  UINTN                     OccupiedSectionLength;\r
-  EFI_PHYSICAL_ADDRESS      DxeIplAddress;\r
-  UINT64                    DxeIplSize;\r
-  EFI_PHYSICAL_ADDRESS      DxeIplEntryPoint;\r
-  EFI_STATUS                Status;\r
-  EFI_COMMON_SECTION_HEADER *Section;\r
-\r
-  Section = (EFI_COMMON_SECTION_HEADER *) (DxeIplFileHeader + 1);\r
-\r
-  while ((Section->Type != EFI_SECTION_PE32) && (Section->Type != EFI_SECTION_TE)) {\r
-    SectionLength         = *(UINT32 *) (Section->Size) & 0x00ffffff;\r
-    OccupiedSectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);\r
-    Section               = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + OccupiedSectionLength);\r
-  }\r
-  //\r
-  // Relocate DxeIpl into memory by using loadfile service\r
-  //\r
-  Status = PeiLoadFile (\r
-            PeiEfiPeiPeCoffLoader,\r
-            (VOID *) (Section + 1),\r
-            &DxeIplAddress,\r
-            &DxeIplSize,\r
-            &DxeIplEntryPoint\r
-            );\r
-\r
-  if (Status == EFI_SUCCESS) {\r
-    //\r
-    // Set gInMemory global variable to TRUE to indicate the dxeipl is shadowed.\r
-    //\r
-    *(BOOLEAN *) ((UINTN) &gInMemory + (UINTN) DxeIplEntryPoint - (UINTN) _ModuleEntryPoint) = TRUE;\r
-    Status = ((EFI_PEIM_ENTRY_POINT2) (UINTN) DxeIplEntryPoint) ((EFI_PEI_FILE_HANDLE *) DxeIplFileHeader, GetPeiServicesTablePointer());\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-DxeIplLoadFile (\r
-  IN EFI_PEI_FV_FILE_LOADER_PPI                 *This,\r
-  IN  EFI_FFS_FILE_HEADER                       *FfsHeader,\r
-  OUT EFI_PHYSICAL_ADDRESS                      *ImageAddress,\r
-  OUT UINT64                                    *ImageSize,\r
-  OUT EFI_PHYSICAL_ADDRESS                      *EntryPoint\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Given a pointer to an FFS file containing a PE32 image, get the\r
-  information on the PE32 image, and then "load" it so that it\r
-  can be executed.\r
-\r
-Arguments:\r
-\r
-  This  - pointer to our file loader protocol\r
-\r
-  FfsHeader - pointer to the FFS file header of the FFS file that\r
-              contains the PE32 image we want to load\r
-\r
-  ImageAddress  - returned address where the PE32 image is loaded\r
-\r
-  ImageSize     - returned size of the loaded PE32 image\r
-\r
-  EntryPoint    - entry point to the loaded PE32 image\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS  - The FFS file was successfully loaded.\r
-\r
-  EFI_ERROR    - Unable to load the FFS file.\r
-\r
---*/\r
-{\r
-  EFI_PEI_PE_COFF_LOADER_PROTOCOL           *PeiEfiPeiPeCoffLoader;\r
-  EFI_STATUS                                Status;\r
-  VOID                                      *Pe32Data;\r
-\r
-  Pe32Data = NULL;\r
-  PeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)GetPeCoffLoaderProtocol ();\r
-\r
-  //\r
-  // Preprocess the FFS file to get a pointer to the PE32 information\r
-  // in the enclosed PE32 image.\r
-  //\r
- Status = PeiProcessFile (\r
-            EFI_SECTION_TE,\r
-            FfsHeader,\r
-            &Pe32Data,\r
-            NULL\r
-            );\r
-  if (EFI_ERROR (Status)) {\r
-    Status = PeiProcessFile (\r
-              EFI_SECTION_PE32,\r
-              FfsHeader,\r
-              &Pe32Data,\r
-              NULL\r
-              );\r
-    \r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-  }\r
-  //\r
-  // Load the PE image from the FFS file\r
-  //\r
-  Status = PeiLoadFile (\r
-            PeiEfiPeiPeCoffLoader,\r
-            Pe32Data,\r
-            ImageAddress,\r
-            ImageSize,\r
-            EntryPoint\r
-            );\r
-\r
-  return Status;\r
-}\r
-\r
-EFI_STATUS\r
-PeiProcessFile (\r
-  IN      EFI_SECTION_TYPE       SectionType,\r
-  IN      EFI_FFS_FILE_HEADER    *FfsFileHeader,\r
-  OUT     VOID                   **Pe32Data,\r
-  IN      EFI_PEI_HOB_POINTERS   *OrigHob\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-  SectionType       - The type of section in the FFS file to process.\r
-\r
-  FfsFileHeader     - Pointer to the FFS file to process, looking for the\r
-                      specified SectionType\r
-\r
-  Pe32Data          - returned pointer to the start of the PE32 image found\r
-                      in the FFS file.\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS       - found the PE32 section in the FFS file\r
-\r
---*/\r
-{\r
-  EFI_STATUS                      Status;\r
-  UINT8                           *DstBuffer;\r
-  UINT8                           *ScratchBuffer;\r
-  UINTN                           DstBufferSize;\r
-  UINT32                          ScratchBufferSize;\r
-  EFI_COMMON_SECTION_HEADER       *CmpSection;\r
-  UINTN                           CmpSectionLength;\r
-  UINTN                           OccupiedCmpSectionLength;\r
-  VOID                            *CmpFileData;\r
-  UINTN                           CmpFileSize;\r
-  EFI_COMMON_SECTION_HEADER       *Section;\r
-  UINTN                           SectionLength;\r
-  UINTN                           OccupiedSectionLength;\r
-  UINTN                           FileSize;\r
-  EFI_FIRMWARE_VOLUME_HEADER      *FvHeader;\r
-  EFI_COMPRESSION_SECTION         *CompressionSection;\r
-  EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI  *SectionExtract;\r
-  UINT32                          AuthenticationStatus;\r
-\r
-  //\r
-  // First try to find the required section in this ffs file.\r
-  //\r
-  Status = PeiServicesFfsFindSectionData (\r
-             SectionType,\r
-             FfsFileHeader,\r
-             Pe32Data\r
-             );\r
-  if (!EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-  \r
-  //\r
-  // If not found, the required section may be in guided or compressed section.\r
-  // So, search guided or compressed section to process\r
-  //\r
-  Section   = (EFI_COMMON_SECTION_HEADER *) (UINTN) (VOID *) ((UINT8 *) (FfsFileHeader) + (UINTN) sizeof (EFI_FFS_FILE_HEADER));\r
-  FileSize  = FfsFileHeader->Size[0] & 0xFF;\r
-  FileSize += (FfsFileHeader->Size[1] << 8) & 0xFF00;\r
-  FileSize += (FfsFileHeader->Size[2] << 16) & 0xFF0000;\r
-  FileSize &= 0x00FFFFFF;\r
-  OccupiedSectionLength = 0;\r
-\r
-  do {\r
-    //\r
-    // Initialize local variables.\r
-    //\r
-    DstBuffer         = NULL;\r
-    DstBufferSize     = 0; \r
-\r
-    Section               = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + OccupiedSectionLength);\r
-    SectionLength         = *(UINT32 *) (Section->Size) & 0x00ffffff;\r
-    OccupiedSectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);\r
-\r
-    //\r
-    // Was the DXE Core file encapsulated in a GUID'd section?\r
-    //\r
-    if (Section->Type == EFI_SECTION_GUID_DEFINED) {\r
-      //\r
-      // Set a default authenticatino state\r
-      //\r
-      AuthenticationStatus = 0;\r
-      //\r
-      // Locate extract guid section ppi\r
-      //\r
-      Status = PeiServicesLocatePpi (\r
-                 (EFI_GUID *) (Section + 1),\r
-                 0,\r
-                 NULL,\r
-                 (VOID **)&SectionExtract\r
-                 );\r
-\r
-      if (EFI_ERROR (Status)) {\r
-        //\r
-        // ignore the unknown guid section\r
-        //\r
-        continue;\r
-      }\r
-      //\r
-      // Extract the contents from guid section\r
-      //\r
-      Status = SectionExtract->ExtractSection (\r
-                                SectionExtract,\r
-                                (VOID *) Section,\r
-                                (VOID **) &DstBuffer,\r
-                                &DstBufferSize,\r
-                                &AuthenticationStatus\r
-                                );\r
-\r
-      if (EFI_ERROR (Status)) {\r
-        DEBUG ((EFI_D_ERROR, "Extract section content failed - %r\n", Status));\r
-        return Status;\r
-      }\r
-      \r
-      //\r
-      // Todo check AuthenticationStatus and do the verify\r
-      //\r
-    } else if (Section->Type == EFI_SECTION_COMPRESSION) {\r
-      //\r
-      // This is a compression set, expand it\r
-      //\r
-      CompressionSection  = (EFI_COMPRESSION_SECTION *) Section;\r
-\r
-      switch (CompressionSection->CompressionType) {\r
-      case EFI_STANDARD_COMPRESSION:\r
-        //\r
-        // Load EFI standard compression.\r
-        // For compressed data, decompress them to dstbuffer.\r
-        //\r
-        Status = UefiDecompressGetInfo (\r
-                   (UINT8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),\r
-                   (UINT32) SectionLength - sizeof (EFI_COMPRESSION_SECTION),\r
-                   (UINT32 *) &DstBufferSize,\r
-                   &ScratchBufferSize\r
-                   );\r
-        if (EFI_ERROR (Status)) {\r
-          //\r
-          // GetInfo failed\r
-          //\r
-          DEBUG ((EFI_D_ERROR, "Decompress GetInfo Failed - %r\n", Status));\r
-          return EFI_NOT_FOUND;\r
-        }\r
-        //\r
-        // Allocate scratch buffer\r
-        //\r
-        ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));\r
-        if (ScratchBuffer == NULL) {\r
-          return EFI_OUT_OF_RESOURCES;\r
-        }\r
-        //\r
-        // Allocate destination buffer\r
-        //\r
-        DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));\r
-        if (DstBuffer == NULL) {\r
-          return EFI_OUT_OF_RESOURCES;\r
-        }\r
-        //\r
-        // Call decompress function\r
-        //\r
-        Status = UefiDecompress (\r
-                    (CHAR8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),\r
-                    DstBuffer,\r
-                    ScratchBuffer\r
-                    );\r
-        if (EFI_ERROR (Status)) {\r
-          //\r
-          // Decompress failed\r
-          //\r
-          DEBUG ((EFI_D_ERROR, "Decompress Failed - %r\n", Status));\r
-          return EFI_NOT_FOUND;\r
-        }\r
-        break;\r
-\r
-      // porting note the original branch for customized compress is removed, it should be change to use GUID compress\r
-\r
-      case EFI_NOT_COMPRESSED:\r
-        //\r
-        // Allocate destination buffer\r
-        //\r
-        DstBufferSize = CompressionSection->UncompressedLength;\r
-        DstBuffer     = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));\r
-        if (DstBuffer == NULL) {\r
-          return EFI_OUT_OF_RESOURCES;\r
-        }\r
-        //\r
-        // stream is not actually compressed, just encapsulated.  So just copy it.\r
-        //\r
-        CopyMem (DstBuffer, CompressionSection + 1, DstBufferSize);\r
-        break;\r
-\r
-      default:\r
-        //\r
-        // Don't support other unknown compression type.\r
-        //\r
-        ASSERT_EFI_ERROR (Status);\r
-        return EFI_NOT_FOUND;\r
-      }\r
-    } else {\r
-      //\r
-      // ignore other type sections\r
-      //\r
-      continue;\r
-    }\r
-\r
-    //\r
-    // Extract contents from guided or compressed sections.\r
-    // Loop the decompressed data searching for expected section.\r
-    //\r
-    CmpSection = (EFI_COMMON_SECTION_HEADER *) DstBuffer;\r
-    CmpFileData = (VOID *) DstBuffer;\r
-    CmpFileSize = DstBufferSize;\r
-    do {\r
-      CmpSectionLength          = *(UINT32 *) (CmpSection->Size) & 0x00ffffff;\r
-      if (CmpSection->Type == SectionType) {\r
-        //\r
-        // This is what we want\r
-        //\r
-        if (SectionType == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) {\r
-          // \r
-          // Firmware Volume Image in this Section\r
-          // Skip the section header to get FvHeader\r
-          //\r
-          FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (CmpSection + 1);\r
-\r
-          if (FvHeader->Signature == EFI_FVH_SIGNATURE) {\r
-            //\r
-            // Because FvLength in FvHeader is UINT64 type, \r
-            // so FvHeader must meed at least 8 bytes alignment.\r
-            // If current FvImage base address doesn't meet its alignment,\r
-            // we need to reload this FvImage to another correct memory address.\r
-            //\r
-            if (((UINTN) FvHeader % sizeof (UINT64)) != 0) {\r
-              CopyMem (DstBuffer, FvHeader, (UINTN) CmpSectionLength - sizeof (EFI_COMMON_SECTION_HEADER));\r
-              FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) DstBuffer;  \r
-            }\r
-\r
-            //\r
-            // Build new FvHob for new decompressed Fv image.\r
-            //\r
-            BuildFvHob ((EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader, FvHeader->FvLength);\r
-            \r
-            //\r
-            // Set the original FvHob to unused.\r
-            //\r
-            if (OrigHob != NULL) {\r
-              OrigHob->Header->HobType = EFI_HOB_TYPE_UNUSED;\r
-            }\r
-            //\r
-            // return found FvImage data.\r
-            //\r
-            *Pe32Data = (VOID *) FvHeader;\r
-            return EFI_SUCCESS;\r
-          }\r
-        } else {\r
-          //\r
-          // direct return the found section.\r
-          //\r
-          *Pe32Data = (VOID *) (CmpSection + 1);\r
-          return EFI_SUCCESS;\r
-        }\r
-      }\r
-      OccupiedCmpSectionLength  = GET_OCCUPIED_SIZE (CmpSectionLength, 4);\r
-      CmpSection                = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) CmpSection + OccupiedCmpSectionLength);\r
-    } while (CmpSection->Type != 0 && (UINTN) ((UINT8 *) CmpSection - (UINT8 *) CmpFileData) < CmpFileSize);\r
-  } while (Section->Type != 0 && (UINTN) ((UINT8 *) Section + OccupiedSectionLength - (UINT8 *) FfsFileHeader) < FileSize);\r
-\r
-  //\r
-  // search all sections (compression and non compression) in this FFS, don't \r
-  // find expected section.\r
-  //\r
-  return EFI_NOT_FOUND;\r
-}\r
-\r
 /**\r
   The ExtractSection() function processes the input section and\r
   returns a pointer to the section contents. If the section being\r
@@ -1032,3 +704,114 @@ CustomDecompressExtractSection (
   \r
   return EFI_SUCCESS;\r
 }\r
+\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI \r
+Decompress (\r
+  IN CONST  EFI_PEI_DECOMPRESS_PPI  *This,\r
+  IN CONST  EFI_COMPRESSION_SECTION *CompressionSection,\r
+  OUT       VOID                    **OutputBuffer,\r
+  OUT       UINTN                   *OutputSize\r
+ )\r
+{\r
+  EFI_STATUS                      Status;\r
+  UINT8                           *DstBuffer;\r
+  UINT8                           *ScratchBuffer;\r
+  UINTN                           DstBufferSize;\r
+  UINT32                          ScratchBufferSize;\r
+  EFI_COMMON_SECTION_HEADER       *Section;\r
+  UINTN                           SectionLength;\r
+\r
+  if (CompressionSection->CommonHeader.Type != EFI_SECTION_COMPRESSION) {\r
+    ASSERT (FALSE);\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Section = (EFI_COMMON_SECTION_HEADER *) CompressionSection;\r
+  SectionLength         = *(UINT32 *) (Section->Size) & 0x00ffffff;\r
+  \r
+  //\r
+  // This is a compression set, expand it\r
+  //\r
+  switch (CompressionSection->CompressionType) {\r
+  case EFI_STANDARD_COMPRESSION:\r
+    //\r
+    // Load EFI standard compression.\r
+    // For compressed data, decompress them to dstbuffer.\r
+    //\r
+    Status = UefiDecompressGetInfo (\r
+               (UINT8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),\r
+               (UINT32) SectionLength - sizeof (EFI_COMPRESSION_SECTION),\r
+               (UINT32 *) &DstBufferSize,\r
+               &ScratchBufferSize\r
+               );\r
+    if (EFI_ERROR (Status)) {\r
+      //\r
+      // GetInfo failed\r
+      //\r
+      DEBUG ((EFI_D_ERROR, "Decompress GetInfo Failed - %r\n", Status));\r
+      return EFI_NOT_FOUND;\r
+    }\r
+    //\r
+    // Allocate scratch buffer\r
+    //\r
+    ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));\r
+    if (ScratchBuffer == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+    //\r
+    // Allocate destination buffer\r
+    //\r
+    DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));\r
+    if (DstBuffer == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+    //\r
+    // Call decompress function\r
+    //\r
+    Status = UefiDecompress (\r
+                (CHAR8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),\r
+                DstBuffer,\r
+                ScratchBuffer\r
+                );\r
+    if (EFI_ERROR (Status)) {\r
+      //\r
+      // Decompress failed\r
+      //\r
+      DEBUG ((EFI_D_ERROR, "Decompress Failed - %r\n", Status));\r
+      return EFI_NOT_FOUND;\r
+    }\r
+    break;\r
+\r
+  // porting note the original branch for customized compress is removed, it should be change to use GUID compress\r
+\r
+  case EFI_NOT_COMPRESSED:\r
+    //\r
+    // Allocate destination buffer\r
+    //\r
+    DstBufferSize = CompressionSection->UncompressedLength;\r
+    DstBuffer     = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));\r
+    if (DstBuffer == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+    //\r
+    // stream is not actually compressed, just encapsulated.  So just copy it.\r
+    //\r
+    CopyMem (DstBuffer, CompressionSection + 1, DstBufferSize);\r
+    break;\r
+\r
+  default:\r
+    //\r
+    // Don't support other unknown compression type.\r
+    //\r
+    ASSERT (FALSE);\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  *OutputSize = DstBufferSize;\r
+  *OutputBuffer = DstBuffer;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
index c817a3d1717ad722aa145496f44dffc565c860b1..7ea840d23a49daa65bbfde158f9df98fd38f13ae 100644 (file)
@@ -87,11 +87,10 @@ Returns:
 }\r
 \r
 \r
-EFI_STATUS\r
+BOOLEAN\r
 PeimDispatchReadiness (\r
   IN EFI_PEI_SERVICES   **PeiServices,\r
-  IN VOID               *DependencyExpression,\r
-  OUT BOOLEAN           *Runnable\r
+  IN VOID               *DependencyExpression\r
   )\r
 /*++\r
 \r
@@ -130,7 +129,6 @@ Returns:
   EVAL_STACK_ENTRY               EvalStack[MAX_GRAMMAR_SIZE];\r
 \r
   Iterator  = DependencyExpression;\r
-  *Runnable = FALSE;\r
 \r
   StackPtr = &EvalStack[0];\r
 \r
@@ -149,7 +147,7 @@ Returns:
         // EvalStack on the push\r
         //\r
         if (StackPtr > &EvalStack[MAX_GRAMMAR_SIZE-1]) {\r
-          return EFI_INVALID_PARAMETER;\r
+          return FALSE;\r
         }\r
 \r
         //\r
@@ -170,7 +168,7 @@ Returns:
         // did two POPs.\r
         //\r
         if (StackPtr < &EvalStack[2]) {\r
-          return EFI_INVALID_PARAMETER;\r
+          return FALSE;\r
         }\r
 \r
         //\r
@@ -208,10 +206,9 @@ Returns:
         // an error in the dependency grammar, so return EFI_INVALID_PARAMETER.\r
         //\r
         if (StackPtr != &EvalStack[0]) {\r
-          return EFI_INVALID_PARAMETER;\r
+          return FALSE;\r
         }\r
-        *Runnable = IsPpiInstalled (PeiServices, StackPtr);\r
-        return EFI_SUCCESS;\r
+        return IsPpiInstalled (PeiServices, StackPtr);\r
         break;\r
 \r
       case (EFI_DEP_NOT):    \r
@@ -222,7 +219,7 @@ Returns:
         // did a POP.\r
         //\r
         if (StackPtr < &EvalStack[1]) {\r
-          return EFI_INVALID_PARAMETER;\r
+          return FALSE;\r
         }\r
         (StackPtr-1)->Result = (BOOLEAN) !IsPpiInstalled (PeiServices, (StackPtr-1));\r
         (StackPtr-1)->Operator = NULL;\r
@@ -235,7 +232,7 @@ Returns:
         // EvalStack on the push\r
         //\r
         if (StackPtr > &EvalStack[MAX_GRAMMAR_SIZE-1]) {\r
-          return EFI_INVALID_PARAMETER;\r
+          return FALSE;\r
         }\r
         //\r
         // Iterator has increased by 1 after we retrieve the operand, so here we \r
@@ -255,7 +252,7 @@ Returns:
         //\r
         // The grammar should never arrive here\r
         //\r
-        return EFI_INVALID_PARAMETER;\r
+        return FALSE;\r
         break;\r
     }\r
   }\r
index 900e1d2d5040a396703c288cb89fed8a1ca1b2b3..b9780a2c7b46b75577bc90ea1848998111d78aa6 100644 (file)
@@ -23,12 +23,6 @@ Revision History
 \r
 #include <PeiMain.h>\r
 \r
-STATIC\r
-VOID *\r
-TransferOldDataToNewDataRange (\r
-  IN PEI_CORE_INSTANCE        *PrivateData\r
-  );\r
-\r
 STATIC\r
 VOID\r
 InvokePeiCore (\r
@@ -36,11 +30,165 @@ InvokePeiCore (
   VOID          *Context2\r
   );\r
 \r
-EFI_STATUS\r
+\r
+VOID\r
+DiscoverPeimsAndOrderWithApriori (\r
+  IN  PEI_CORE_INSTANCE    *Private,\r
+  IN  EFI_PEI_FV_HANDLE    VolumeHandle\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Discover all Peims and optional Apriori file in one FV. There is at most one\r
+  Apriori file in one FV.\r
+\r
+Arguments:\r
+\r
+  Private          - Pointer to the private data passed in from caller\r
+  VolumeHandle     - Fv handle.\r
+Returns:\r
+\r
+  NONE\r
+\r
+--*/  \r
+{\r
+  EFI_STATUS                          Status;\r
+  EFI_PEI_FV_HANDLE                   FileHandle;\r
+  EFI_PEI_FV_HANDLE                   AprioriFileHandle;\r
+  EFI_GUID                            *Apriori;\r
+  UINTN                               Index;\r
+  UINTN                               Index2;\r
+  UINTN                               PeimIndex;\r
+  UINTN                               PeimCount;\r
+  EFI_GUID                            *Guid;\r
+  EFI_PEI_FV_HANDLE                   TempFileHandles[PEI_CORE_MAX_PEIM_PER_FV];\r
+  EFI_GUID                            FileGuid[PEI_CORE_MAX_PEIM_PER_FV];\r
+\r
+  //\r
+  // Walk the FV and find all the PEIMs and the Apriori file.\r
+  //\r
+  AprioriFileHandle = NULL;\r
+  Private->CurrentFvFileHandles[0] = NULL;\r
+  Guid = NULL;\r
+  FileHandle = NULL;\r
+\r
+  //\r
+  // If the current Fv has been scanned, directly get its cachable record.\r
+  //\r
+  if (Private->Fv[Private->CurrentPeimFvCount].ScanFv) {\r
+    CopyMem (Private->CurrentFvFileHandles, Private->Fv[Private->CurrentPeimFvCount].FvFileHandles, sizeof (Private->CurrentFvFileHandles));\r
+    return;\r
+  }\r
+\r
+  //\r
+  // Go ahead to scan this Fv, and cache FileHandles within it.\r
+  //\r
+  for (PeimCount = 0; PeimCount < PEI_CORE_MAX_PEIM_PER_FV; PeimCount++) {\r
+    Status = PeiFindFileEx (\r
+                VolumeHandle, \r
+                NULL, \r
+                PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE, \r
+                &FileHandle,\r
+                &AprioriFileHandle\r
+                );\r
+    if (Status != EFI_SUCCESS) {\r
+      break;\r
+    }\r
+    \r
+    Private->CurrentFvFileHandles[PeimCount] = FileHandle;\r
+  }\r
+\r
+  Private->AprioriCount = 0; \r
+  if (AprioriFileHandle != NULL) {\r
+    //\r
+    // Read the Apriori file\r
+    //\r
+    Status = PeiServicesFfsFindSectionData (EFI_SECTION_RAW, &AprioriFileHandle, (VOID **) &Apriori);\r
+    if (!EFI_ERROR (Status)) {\r
+      //\r
+      // Calculate the number of PEIMs in the A Priori list\r
+      //\r
+      Private->AprioriCount = *(UINT32 *)(((EFI_FFS_FILE_HEADER *)AprioriFileHandle)->Size) & 0x00FFFFFF;\r
+      Private->AprioriCount -= sizeof (EFI_FFS_FILE_HEADER) - sizeof (EFI_COMMON_SECTION_HEADER);   \r
+      Private->AprioriCount /= sizeof (EFI_GUID);\r
+        \r
+      SetMem (FileGuid, sizeof (FileGuid), 0);\r
+      for (Index = 0; Index < PeimCount; Index++) {\r
+        //\r
+        // Make an array of file name guids that matches the FileHandle array so we can convert\r
+        // quickly from file name to file handle\r
+        //\r
+        CopyMem (&FileGuid[Index], &((EFI_FFS_FILE_HEADER *)Private->CurrentFvFileHandles[Index])->Name,sizeof(EFI_GUID));    \r
+      }\r
+\r
+      //\r
+      // Walk through FileGuid array to find out who is invalid PEIM guid in Apriori file.\r
+      // Add avalible PEIMs in Apriori file into TempFileHandles array at first. \r
+      //\r
+      Index2 = 0;\r
+      for (Index = 0; Index2 < Private->AprioriCount; Index++) {\r
+        while (Index2 < Private->AprioriCount) {\r
+          Guid = ScanGuid (FileGuid, PeimCount * sizeof (EFI_GUID), &Apriori[Index2++]);\r
+          if (Guid != NULL) {\r
+            break;\r
+          }\r
+        }\r
+        if (Guid == NULL) {\r
+          break;  \r
+        }\r
+        PeimIndex = ((UINTN)Guid - (UINTN)&FileGuid[0])/sizeof (EFI_GUID);\r
+        TempFileHandles[Index] = Private->CurrentFvFileHandles[PeimIndex];\r
+\r
+        //\r
+        // Since we have copied the file handle we can remove it from this list.\r
+        //\r
+        Private->CurrentFvFileHandles[PeimIndex] = NULL;\r
+      }\r
+\r
+      //\r
+      // Update valid Aprioricount\r
+      //\r
+      Private->AprioriCount = Index;\r
+      \r
+      //\r
+      // Add in any PEIMs not in the Apriori file\r
+      //\r
+      for (;Index < PeimCount; Index++) {\r
+        for (Index2 = 0; Index2 < PeimCount; Index2++) {\r
+          if (Private->CurrentFvFileHandles[Index2] != NULL) {\r
+            TempFileHandles[Index] = Private->CurrentFvFileHandles[Index2];\r
+            Private->CurrentFvFileHandles[Index2] = NULL;\r
+            break;\r
+          }\r
+        }\r
+      }\r
+      //\r
+      //Index the end of array contains re-range Pei moudle.\r
+      //\r
+      TempFileHandles[Index] = NULL;\r
+      \r
+      //\r
+      // Private->CurrentFvFileHandles is currently in PEIM in the FV order.\r
+      // We need to update it to start with files in the A Priori list and \r
+      // then the remaining files in PEIM order. \r
+      //\r
+      CopyMem (Private->CurrentFvFileHandles, TempFileHandles, sizeof (Private->CurrentFvFileHandles));\r
+    }\r
+  }\r
+  //\r
+  // Cache the current Fv File Handle. So that we don't have to scan the Fv again.\r
+  // Instead, we can retrieve the file handles within this Fv from cachable data.\r
+  //\r
+  Private->Fv[Private->CurrentPeimFvCount].ScanFv = TRUE;\r
+  CopyMem (Private->Fv[Private->CurrentPeimFvCount].FvFileHandles, Private->CurrentFvFileHandles, sizeof (Private->CurrentFvFileHandles));\r
+  \r
+}\r
+\r
+VOID\r
 PeiDispatcher (\r
   IN CONST EFI_SEC_PEI_HAND_OFF  *SecCoreData,\r
-  IN PEI_CORE_INSTANCE           *PrivateData,\r
-  IN PEI_CORE_DISPATCH_DATA      *DispatchData\r
+  IN PEI_CORE_INSTANCE           *Private\r
   )\r
 \r
 /*++\r
@@ -64,24 +212,78 @@ Returns:
 \r
 --*/\r
 {\r
-  EFI_STATUS                        Status;\r
-  PEI_CORE_TEMP_POINTERS            TempPtr;\r
-  BOOLEAN                           NextFvFound;\r
-  EFI_FIRMWARE_VOLUME_HEADER        *NextFvAddress;\r
-  EFI_FIRMWARE_VOLUME_HEADER        *DefaultFvAddress;\r
-  VOID                              *TopOfStack;\r
-  PEI_CORE_PARAMETERS               PeiCoreParameters;\r
-\r
-  //\r
-  // Debug data for uninstalled Peim list\r
-  //\r
-  EFI_GUID                          DebugFoundPeimList[32];\r
-  EFI_DEVICE_HANDLE_EXTENDED_DATA   ExtendedData;\r
-\r
-  //\r
-  // save the Current FV Address so that we will not process it again if FindFv returns it later\r
-  //\r
-  DefaultFvAddress = DispatchData->BootFvAddress;\r
+  EFI_STATUS                          Status;\r
+  UINT32                              Index1;\r
+  UINT32                              Index2;\r
+  EFI_PEI_SERVICES                    **PeiServices;\r
+  VOID                                *PrivateInMem;\r
+  EFI_PEI_FV_HANDLE                   VolumeHandle; \r
+  EFI_PEI_FILE_HANDLE                 PeiCoreFileHandle;\r
+  EFI_PEI_FILE_HANDLE                 PeimFileHandle;\r
+  UINTN                               FvCount;\r
+  UINTN                               PeimCount;\r
+  UINT32                              AuthenticationState;\r
+  EFI_PHYSICAL_ADDRESS                EntryPoint;\r
+  EFI_PEIM_ENTRY_POINT                PeimEntryPoint;\r
+  BOOLEAN                             PeimNeedingDispatch;\r
+  BOOLEAN                             PeimDispatchOnThisPass;\r
+  UINTN                               SaveCurrentPeimCount;\r
+  EFI_PEI_FILE_HANDLE                 SaveCurrentFileHandle;\r
+  VOID                                *TopOfStack;\r
+  PEI_CORE_PARAMETERS                 PeiCoreParameters;\r
+  EFI_DEVICE_HANDLE_EXTENDED_DATA     ExtendedData;\r
+\r
+\r
+  PeiServices = &Private->PS;\r
+  PeimEntryPoint = NULL;\r
+  PeimFileHandle = NULL;\r
+\r
+  if ((Private->PeiMemoryInstalled) && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {\r
+    //\r
+    // Once real memory is available, shadow the RegisterForShadow modules. And meanwhile\r
+    // update the modules' status from PEIM_STATE_REGISITER_FOR_SHADOW to PEIM_STATE_DONE.\r
+    //\r
+    SaveCurrentPeimCount  = Private->CurrentPeimCount;\r
+    SaveCurrentFileHandle =  Private->CurrentFileHandle;\r
+\r
+    for (Index1 = 0;Index1 <= Private->CurrentPeimFvCount; Index1++) {\r
+      for (Index2 = 0; (Index2 < PEI_CORE_MAX_PEIM_PER_FV) && (Private->Fv[Index1].FvFileHandles[Index2] != NULL); Index2++) {\r
+        if (Private->Fv[Index1].PeimState[Index2] == PEIM_STATE_REGISITER_FOR_SHADOW) {\r
+          PeimFileHandle = Private->Fv[Index1].FvFileHandles[Index2];  \r
+          Status = PeiLoadImage (\r
+                    &Private->PS, \r
+                    PeimFileHandle,  \r
+                    &EntryPoint, \r
+                    &AuthenticationState\r
+                    );\r
+          if (Status == EFI_SUCCESS) {\r
+            //\r
+            // PEIM_STATE_REGISITER_FOR_SHADOW move to PEIM_STATE_DONE\r
+            //\r
+            Private->Fv[Index1].PeimState[Index2]++;\r
+            Private->CurrentFileHandle = PeimFileHandle;\r
+            Private->CurrentPeimCount  = Index2;        \r
+            //\r
+            // Call the PEIM entry point\r
+            //\r
+            PeimEntryPoint = (EFI_PEIM_ENTRY_POINT)(UINTN)EntryPoint;\r
+            \r
+            PERF_START (0, "PEIM", NULL, 0);\r
+            PeimEntryPoint(PeimFileHandle, &Private->PS);\r
+            PERF_END (0, "PEIM", NULL, 0);\r
+          } \r
+          \r
+          //\r
+          // Process the Notify list and dispatch any notifies for\r
+          // newly installed PPIs.\r
+          //\r
+          ProcessNotifyList (Private);\r
+        }\r
+      }\r
+    }\r
+    Private->CurrentFileHandle = SaveCurrentFileHandle;   \r
+    Private->CurrentPeimCount  = SaveCurrentPeimCount;    \r
+  }\r
 \r
   //\r
   // This is the main dispatch loop.  It will search known FVs for PEIMs and\r
@@ -91,69 +293,50 @@ Returns:
   // FV where PEIMs are found in the order their dependencies are also\r
   // satisfied, this dipatcher should run only once.\r
   //\r
-  for (;;) {\r
-    //\r
-    // This is the PEIM search loop. It will scan through all PEIMs it can find\r
-    // looking for PEIMs to dispatch, and will dipatch them if they have not\r
-    // already been dispatched and all of their dependencies are met.\r
-    // If no more PEIMs can be found in this pass through all known FVs,\r
-    // then it will break out of this loop.\r
-    //\r
-    for (;;) {\r
+  do {\r
+    PeimNeedingDispatch = FALSE;\r
+    PeimDispatchOnThisPass = FALSE;\r
+\r
+    for (FvCount = Private->CurrentPeimFvCount; FvCount < Private->FvCount; FvCount++) {\r
+      Private->CurrentPeimFvCount = FvCount;\r
+      VolumeHandle = Private->Fv[FvCount].FvHeader;\r
 \r
-      Status = FindNextPeim (\r
-                 &PrivateData->PS,\r
-                 DispatchData->CurrentFvAddress,\r
-                 &DispatchData->CurrentPeimAddress\r
-                 );\r
+      if (Private->CurrentPeimCount == 0) {\r
+        //\r
+        // When going through each FV, at first, search Apriori file to\r
+        // reorder all PEIMs to ensure the PEIMs in Apriori file to get \r
+        // dispatch at first.\r
+        //\r
+        DiscoverPeimsAndOrderWithApriori (Private, VolumeHandle);\r
+      }\r
 \r
       //\r
-      // If we found a PEIM, check if it is dispatched.  If so, go to the\r
-      // next PEIM.  If not, dispatch it if its dependencies are satisfied.\r
-      // If its dependencies are not satisfied, go to the next PEIM.\r
+      // Start to dispatch all modules within the current Fv.\r
       //\r
-      if (Status == EFI_SUCCESS) {\r
-\r
-        DEBUG_CODE_BEGIN ();\r
-\r
-          //\r
-          // Fill list of found Peims for later list of those not installed\r
-          //\r
-          CopyMem (\r
-            &DebugFoundPeimList[DispatchData->CurrentPeim],\r
-            &DispatchData->CurrentPeimAddress->Name,\r
-            sizeof (EFI_GUID)\r
-            );\r
-\r
-        DEBUG_CODE_END ();\r
-\r
-        if (!Dispatched (\r
-               DispatchData->CurrentPeim,\r
-               DispatchData->DispatchedPeimBitMap\r
-               )) {\r
-          if (DepexSatisfied (&PrivateData->PS, DispatchData->CurrentPeimAddress)) {\r
+      for (PeimCount = Private->CurrentPeimCount; \r
+           (PeimCount < PEI_CORE_MAX_PEIM_PER_FV) && (Private->CurrentFvFileHandles[PeimCount] != NULL); \r
+           PeimCount++) {\r
+        Private->CurrentPeimCount  = PeimCount;\r
+        PeimFileHandle = Private->CurrentFileHandle = Private->CurrentFvFileHandles[PeimCount];\r
+\r
+        if (Private->Fv[FvCount].PeimState[PeimCount] == PEIM_STATE_NOT_DISPATCHED) {\r
+          if (!DepexSatisfied (Private, PeimFileHandle, PeimCount)) {\r
+            PeimNeedingDispatch = TRUE;\r
+          } else {\r
             Status = PeiLoadImage (\r
-                       &PrivateData->PS,\r
-                       DispatchData->CurrentPeimAddress,\r
-                       &TempPtr.Raw\r
+                       PeiServices, \r
+                       PeimFileHandle,  \r
+                       &EntryPoint, \r
+                       &AuthenticationState\r
                        );\r
-            if (Status == EFI_SUCCESS) {\r
-\r
+            if ((Status == EFI_SUCCESS)) {\r
               //\r
               // The PEIM has its dependencies satisfied, and its entry point\r
               // has been found, so invoke it.\r
               //\r
-              PERF_START (\r
-                (VOID *) (UINTN) (DispatchData->CurrentPeimAddress),\r
-                "PEIM",\r
-                NULL,\r
-                0\r
-                );\r
+              PERF_START (0, "PEIM", NULL, 0);\r
 \r
-              //\r
-              // BUGBUG: Used to be EFI_PEI_REPORT_STATUS_CODE_CODE\r
-              //\r
-              ExtendedData.Handle = (EFI_HANDLE)DispatchData->CurrentPeimAddress;\r
+              ExtendedData.Handle = (EFI_HANDLE)PeimFileHandle;\r
 \r
               REPORT_STATUS_CODE_WITH_EXTENDED_DATA (\r
                 EFI_PROGRESS_CODE,\r
@@ -162,24 +345,19 @@ Returns:
                 sizeof (ExtendedData)\r
                 );\r
 \r
-              //\r
-              // Is this a authentic image\r
-              //\r
-              Status = VerifyPeim (\r
-                        &PrivateData->PS,\r
-                        DispatchData->CurrentPeimAddress\r
-                        );\r
-\r
-              if (Status != EFI_SECURITY_VIOLATION) {\r
+              Status = VerifyPeim (Private, VolumeHandle, PeimFileHandle);\r
+              if (Status != EFI_SECURITY_VIOLATION && (AuthenticationState == 0)) {\r
+                //\r
+                // PEIM_STATE_NOT_DISPATCHED move to PEIM_STATE_DISPATCHED\r
+                //\r
+                Private->Fv[FvCount].PeimState[PeimCount]++;\r
 \r
                 //\r
-                // BUGBUG: Before enable PI, we need cast EFI_FFS_FILE_HEADER* to EFI_PEI_FILE_HANDLE*\r
-                //         Because we use new MdePkg's definition, but they are binary compatible in fact.\r
+                // Call the PEIM entry point\r
                 //\r
-                Status =  TempPtr.PeimEntry (\r
-                                    (EFI_PEI_FILE_HANDLE*)DispatchData->CurrentPeimAddress,\r
-                                    &PrivateData->PS\r
-                                    );\r
+                PeimEntryPoint = (EFI_PEIM_ENTRY_POINT)(UINTN)EntryPoint;\r
+                PeimEntryPoint (PeimFileHandle, PeiServices);\r
+                PeimDispatchOnThisPass = TRUE;\r
               }\r
 \r
               REPORT_STATUS_CODE_WITH_EXTENDED_DATA (\r
@@ -188,189 +366,146 @@ Returns:
                 (VOID *)(&ExtendedData),\r
                 sizeof (ExtendedData)\r
                 );\r
+              PERF_END (0, "PEIM", NULL, 0);\r
+\r
+            }\r
 \r
-              PERF_END ((VOID *) (UINTN) (DispatchData->CurrentPeimAddress), "PEIM", NULL, 0);\r
+            //\r
+            // Process the Notify list and dispatch any notifies for\r
+            // newly installed PPIs.\r
+            //\r
+            ProcessNotifyList (Private);\r
+\r
+            //\r
+            // If permanent memory was discovered and installed by this\r
+            // PEIM, shadow PEI Core and switch the stacks to the new memory.  \r
+            //\r
+            if (Private->SwitchStackSignal) {\r
 \r
               //\r
-              // Mark the PEIM as dispatched so we don't attempt to run it again\r
+              // Make sure we don't retry the same PEIM that added memory\r
               //\r
-              SetDispatched (\r
-                &PrivateData->PS,\r
-                DispatchData->CurrentPeim,\r
-                &DispatchData->DispatchedPeimBitMap\r
-                );\r
+              Private->CurrentPeimCount++;\r
 \r
               //\r
-              // Process the Notify list and dispatch any notifies for\r
-              // newly installed PPIs.\r
+              // Migrate IDT from CAR into real memory, so after stack switches to\r
+              // the new memory, the caller can get memory version PeiServiceTable. \r
               //\r
-              ProcessNotifyList (&PrivateData->PS);\r
+              //MigrateIdtTable (PeiServices);              \r
+              //\r
+              // Since we are at dispatch level, only the Core's private data \r
+              // is preserved, nobody else should have any data on the stack. \r
+              // So we need to copy PEI core instance data to memory.\r
+              //\r
+              PrivateInMem = AllocateCopyPool (sizeof (PEI_CORE_INSTANCE), Private);\r
+              ASSERT (PrivateInMem != NULL);\r
 \r
               //\r
-              // If real system memory was discovered and installed by this\r
-              // PEIM, switch the stacks to the new memory.  Since we are\r
-              // at dispatch level, only the Core's private data is preserved,\r
-              // nobody else should have any data on the stack.\r
+              // Shadow PEI Core. When permanent memory is avaiable, shadow\r
+              // PEI Core and PEIMs to get high performance.\r
               //\r
-              if (PrivateData->SwitchStackSignal) {\r
-                //\r
-                // Adjust the top of stack to be aligned at CPU_STACK_ALIGNMENT\r
-                //\r
-                TopOfStack = (VOID *)((UINTN)PrivateData->StackBase + (UINTN)PrivateData->StackSize - CPU_STACK_ALIGNMENT);\r
-                TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);\r
-                \r
-                PeiCoreParameters.SecCoreData = SecCoreData;\r
-                PeiCoreParameters.PpiList     = NULL;\r
-                PeiCoreParameters.Data        = TransferOldDataToNewDataRange (PrivateData);\r
-                ASSERT (PeiCoreParameters.Data != 0);\r
-\r
-                PeiSwitchStacks (\r
-                  InvokePeiCore,\r
-                  (VOID*) (UINTN) PeiCore,\r
-                  (VOID*) &PeiCoreParameters,  \r
-                  TopOfStack,\r
-                  (VOID*)(UINTN)PrivateData->StackBase\r
-                  );\r
-              }\r
+              PeiCoreFileHandle = NULL;\r
+              //\r
+              // Find the PEI Core in the BFV\r
+              //\r
+              Status = PeiFindFileEx (\r
+                        (EFI_PEI_FV_HANDLE)Private->Fv[0].FvHeader, \r
+                        NULL, \r
+                        EFI_FV_FILETYPE_PEI_CORE, \r
+                        &PeiCoreFileHandle,\r
+                        NULL\r
+                        );\r
+              ASSERT_EFI_ERROR (Status);\r
+  \r
+              //\r
+              // Shadow PEI Core into memory so it will run faster\r
+              //\r
+              Status = PeiLoadImage (PeiServices, PeiCoreFileHandle, &EntryPoint, &AuthenticationState);\r
+              ASSERT_EFI_ERROR (Status);\r
+  \r
+              //\r
+              // Switch to memory based stack and reenter PEI Core that has been\r
+              //  shadowed to memory.\r
+              //\r
+              //\r
+              // Adjust the top of stack to be aligned at CPU_STACK_ALIGNMENT\r
+              //\r
+              TopOfStack = (VOID *)((UINTN)Private->StackBase + (UINTN)Private->StackSize - CPU_STACK_ALIGNMENT);\r
+              TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);\r
+              \r
+              PeiCoreParameters.SecCoreData = SecCoreData;\r
+              PeiCoreParameters.PpiList     = NULL;\r
+              PeiCoreParameters.Data        = PrivateInMem;\r
+              ASSERT (PeiCoreParameters.Data != 0);\r
+\r
+              PeiSwitchStacks (\r
+                InvokePeiCore,\r
+                (VOID*) (UINTN) PeiCore,\r
+                (VOID*) &PeiCoreParameters,  \r
+                TopOfStack,\r
+                (VOID*)(UINTN)Private->StackBase\r
+                );\r
             }\r
-          }\r
-        }\r
-        DispatchData->CurrentPeim++;\r
-        continue;\r
 \r
-      } else {\r
-\r
-        //\r
-        // If we could not find another PEIM in the current FV, go try\r
-        // the FindFv PPI to look in other FVs for more PEIMs.  If we can\r
-        // not locate the FindFv PPI, or if the FindFv PPI can not find\r
-        // anymore FVs, then exit the PEIM search loop.\r
-        //\r
-        if (DispatchData->FindFv == NULL) {\r
-          Status = PeiServicesLocatePpi (\r
-                     &gEfiFindFvPpiGuid,\r
-                     0,\r
-                     NULL,\r
-                     (VOID **)&DispatchData->FindFv\r
-                     );\r
-          if (Status != EFI_SUCCESS) {\r
-            break;\r
-          }\r
-        }\r
-        NextFvFound = FALSE;\r
-        while (!NextFvFound) {\r
-          Status = DispatchData->FindFv->FindFv (\r
-                                           DispatchData->FindFv,\r
-                                           &PrivateData->PS,\r
-                                           &DispatchData->CurrentFv,\r
-                                           &NextFvAddress\r
-                                           );\r
-          //\r
-          // if there is no next fv, get out of this loop of finding FVs\r
-          //\r
-          if (Status != EFI_SUCCESS) {\r
-            break;\r
-          }\r
-          //\r
-          // don't process the default Fv again. (we don't know the order in which the hobs were created)\r
-          //\r
-          if ((NextFvAddress != DefaultFvAddress) &&\r
-              (NextFvAddress != DispatchData->CurrentFvAddress)) {\r
+            if ((Private->PeiMemoryInstalled) && (Private->Fv[FvCount].PeimState[PeimCount] == PEIM_STATE_REGISITER_FOR_SHADOW) &&   \\r
+                (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {\r
+              //\r
+              // If memory is availble we shadow images by default for performance reasons. \r
+              // We call the entry point a 2nd time so the module knows it's shadowed. \r
+              //\r
+              //PERF_START (PeiServices, L"PEIM", PeimFileHandle, 0);\r
+              PeimEntryPoint (PeimFileHandle, PeiServices);\r
+              //PERF_END (PeiServices, L"PEIM", PeimFileHandle, 0);\r
+              \r
+              //\r
+              // PEIM_STATE_REGISITER_FOR_SHADOW move to PEIM_STATE_DONE\r
+              //\r
+              Private->Fv[FvCount].PeimState[PeimCount]++;\r
 \r
-            //\r
-            // VerifyFv() is currently returns SUCCESS all the time, add code to it to\r
-            // actually verify the given FV\r
-            //\r
-            Status = VerifyFv (NextFvAddress);\r
-            if (Status == EFI_SUCCESS) {\r
-              NextFvFound = TRUE;\r
-              DispatchData->CurrentFvAddress = NextFvAddress;\r
-              DispatchData->CurrentPeimAddress = NULL;\r
               //\r
-              // current PRIM number (CurrentPeim) must continue as is, don't reset it here\r
+              // Process the Notify list and dispatch any notifies for\r
+              // newly installed PPIs.\r
               //\r
+              ProcessNotifyList (Private);\r
             }\r
           }\r
         }\r
-        //\r
-        // if there is no next fv, get out of this loop of dispatching PEIMs\r
-        //\r
-        if (!NextFvFound) {\r
-          break;\r
-        }\r
-        //\r
-        // continue in the inner for(;;) loop with a new FV;\r
-        //\r
       }\r
-    }\r
 \r
-    //\r
-    // If all the PEIMs that we have found have been dispatched, then\r
-    // there is nothing left to dispatch and we don't need to go search\r
-    // through all PEIMs again.\r
-    //\r
-    if ((~(DispatchData->DispatchedPeimBitMap) &\r
-         ((1 << DispatchData->CurrentPeim)-1)) == 0) {\r
-      break;\r
-    }\r
-\r
-    //\r
-    // Check if no more PEIMs that depex was satisfied\r
-    //\r
-    if (DispatchData->DispatchedPeimBitMap == DispatchData->PreviousPeimBitMap) {\r
-      break;\r
+      //\r
+      // We set to NULL here to optimize the 2nd entry to this routine after\r
+      //  memory is found. This reprevents rescanning of the FV. We set to\r
+      //  NULL here so we start at the begining of the next FV\r
+      //\r
+      Private->CurrentFileHandle = NULL;\r
+      Private->CurrentPeimCount = 0;\r
+      //\r
+      // Before walking through the next FV,Private->CurrentFvFileHandles[]should set to NULL\r
+      //\r
+      SetMem (Private->CurrentFvFileHandles, sizeof (Private->CurrentFvFileHandles), 0);\r
     }\r
 \r
     //\r
-    // Case when Depex is not satisfied and has to traverse the list again\r
+    // Before making another pass, we should set Private->CurrentPeimFvCount =0 to go \r
+    // through all the FV.\r
     //\r
-    DispatchData->CurrentPeim = 0;\r
-    DispatchData->CurrentPeimAddress = 0;\r
-    DispatchData->PreviousPeimBitMap = DispatchData->DispatchedPeimBitMap;\r
+    Private->CurrentPeimFvCount = 0;\r
 \r
     //\r
-    // don't go back to the loop without making sure that the CurrentFvAddress is the\r
-    // same as the 1st (or default) FV we started with. otherwise we will interpret the bimap wrongly and\r
-    // mess it up, always start processing the PEIMs from the default FV just like in the first time around.\r
-    //\r
-    DispatchData->CurrentFv = 0;\r
-    DispatchData->CurrentFvAddress = DefaultFvAddress;\r
-  }\r
-\r
-  DEBUG_CODE_BEGIN ();\r
+    // PeimNeedingDispatch being TRUE means we found a PEIM that did not get \r
+    //  dispatched. So we need to make another pass\r
     //\r
-    // Debug data for uninstalled Peim list\r
+    // PeimDispatchOnThisPass being TRUE means we dispatched a PEIM on this \r
+    //  pass. If we did not dispatch a PEIM there is no point in trying again\r
+    //  as it will fail the next time too (nothing has changed).\r
     //\r
-    UINT32        DebugNotDispatchedBitmap;\r
-    UINT8         DebugFoundPeimPoint;\r
+  } while (PeimNeedingDispatch && PeimDispatchOnThisPass);\r
 \r
-    DebugFoundPeimPoint = 0;\r
-    //\r
-    // Get bitmap of Peims that were not dispatched,\r
-    //\r
-\r
-    DebugNotDispatchedBitmap = ((DispatchData->DispatchedPeimBitMap) ^ ((1 << DispatchData->CurrentPeim)-1));\r
-    //\r
-    // Scan bitmap of Peims not installed and print GUIDS\r
-    //\r
-    while (DebugNotDispatchedBitmap != 0) {\r
-      if ((DebugNotDispatchedBitmap & 1) != 0) {\r
-        DEBUG ((EFI_D_INFO, "WARNING -> InstallPpi: Not Installed: %g\n",\r
-           &DebugFoundPeimList[DebugFoundPeimPoint]\r
-           ));\r
-      }\r
-      DebugFoundPeimPoint++;\r
-      DebugNotDispatchedBitmap >>= 1;\r
-    }\r
-\r
-  DEBUG_CODE_END ();\r
-\r
-  return EFI_NOT_FOUND;\r
 }\r
 \r
 VOID\r
 InitializeDispatcherData (\r
-  IN EFI_PEI_SERVICES             **PeiServices,\r
+  IN PEI_CORE_INSTANCE            *PrivateData,\r
   IN PEI_CORE_INSTANCE            *OldCoreData,\r
   IN CONST EFI_SEC_PEI_HAND_OFF   *SecCoreData\r
   )\r
@@ -395,87 +530,19 @@ Returns:
 \r
 --*/\r
 {\r
-  PEI_CORE_INSTANCE *PrivateData;\r
-\r
-  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
-\r
   if (OldCoreData == NULL) {\r
-    PrivateData->DispatchData.CurrentFvAddress = (EFI_FIRMWARE_VOLUME_HEADER *) SecCoreData->BootFirmwareVolumeBase;\r
-    PrivateData->DispatchData.BootFvAddress = (EFI_FIRMWARE_VOLUME_HEADER *) SecCoreData->BootFirmwareVolumeBase;\r
-  } else {\r
-\r
-    //\r
-    // Current peim has been dispatched, but not count\r
-    //\r
-    PrivateData->DispatchData.CurrentPeim = (UINT8)(OldCoreData->DispatchData.CurrentPeim + 1);\r
+    PeiInitializeFv (PrivateData, SecCoreData);\r
   }\r
 \r
   return;\r
 }\r
 \r
 \r
-BOOLEAN\r
-Dispatched (\r
-  IN UINT8  CurrentPeim,\r
-  IN UINT32 DispatchedPeimBitMap\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  This routine checks to see if a particular PEIM has been dispatched during\r
-  the PEI core dispatch.\r
-\r
-Arguments:\r
-  CurrentPeim          - The PEIM/FV in the bit array to check.\r
-  DispatchedPeimBitMap - Bit array, each bit corresponds to a PEIM/FV.\r
-\r
-Returns:\r
-  TRUE  - PEIM already dispatched\r
-  FALSE - Otherwise\r
-\r
---*/\r
-{\r
-  return (BOOLEAN)((DispatchedPeimBitMap & (1 << CurrentPeim)) != 0);\r
-}\r
-\r
-VOID\r
-SetDispatched (\r
-  IN EFI_PEI_SERVICES   **PeiServices,\r
-  IN UINT8              CurrentPeim,\r
-  OUT UINT32            *DispatchedPeimBitMap\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  This routine sets a PEIM as having been dispatched once its entry\r
-  point has been invoked.\r
-\r
-Arguments:\r
-\r
-  PeiServices          - The PEI core services table.\r
-  CurrentPeim          - The PEIM/FV in the bit array to check.\r
-  DispatchedPeimBitMap - Bit array, each bit corresponds to a PEIM/FV.\r
-\r
-Returns:\r
-  None\r
-\r
---*/\r
-{\r
-  //\r
-  // Check if the total number of PEIMs exceed the bitmap.\r
-  // CurrentPeim is 0-based\r
-  //\r
-  ASSERT (CurrentPeim < (sizeof (*DispatchedPeimBitMap) * 8));\r
-  *DispatchedPeimBitMap |= (1 << CurrentPeim);\r
-  return;\r
-}\r
-\r
 BOOLEAN\r
 DepexSatisfied (\r
-  IN EFI_PEI_SERVICES  **PeiServices,\r
-  IN VOID              *CurrentPeimAddress\r
+  IN PEI_CORE_INSTANCE          *Private,\r
+  IN EFI_PEI_FILE_HANDLE        FileHandle,\r
+  IN UINTN                      PeimCount\r
   )\r
 /*++\r
 \r
@@ -495,59 +562,27 @@ Returns:
 --*/\r
 {\r
   EFI_STATUS  Status;\r
-  INT8        *DepexData;\r
-  BOOLEAN     Runnable;\r
-\r
-  Status = PeiServicesFfsFindSectionData (\r
-             EFI_SECTION_PEI_DEPEX,\r
-             CurrentPeimAddress,\r
-             (VOID **)&DepexData\r
-             );\r
-  //\r
-  // If there is no DEPEX, assume the module can be executed\r
-  //\r
+  VOID        *DepexData;\r
+\r
+  if (PeimCount < Private->AprioriCount) {\r
+    //\r
+    // If its in the A priori file then we set Depex to TRUE\r
+    //\r
+    return TRUE;\r
+  }\r
+\r
+  Status = PeiServicesFfsFindSectionData (EFI_SECTION_PEI_DEPEX, FileHandle, (VOID **) &DepexData);\r
   if (EFI_ERROR (Status)) {\r
+    //\r
+    // If there is no DEPEX, assume the module can be executed\r
+    //\r
     return TRUE;\r
   }\r
 \r
   //\r
   // Evaluate a given DEPEX\r
   //\r
-  Status = PeimDispatchReadiness (\r
-            PeiServices,\r
-            DepexData,\r
-            &Runnable\r
-            );\r
-\r
-  return Runnable;\r
-}\r
-\r
-STATIC\r
-VOID *\r
-TransferOldDataToNewDataRange (\r
-  IN PEI_CORE_INSTANCE        *PrivateData\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  This routine transfers the contents of the pre-permanent memory\r
-  PEI Core private data to a post-permanent memory data location.\r
-\r
-Arguments:\r
-\r
-  PrivateData       - Pointer to the current PEI Core private data pre-permanent memory\r
-\r
-Returns:\r
-\r
-  Pointer to the PrivateData once the private data has been transferred to permanent memory\r
-\r
---*/\r
-{\r
-  //\r
-  //Build private HOB to PEI core to transfer old NEM-range data to new NEM-range\r
-  //\r
-  return BuildGuidDataHob (&gEfiPeiCorePrivateGuid, PrivateData, sizeof (PEI_CORE_INSTANCE));\r
+  return PeimDispatchReadiness (&Private->PS, DepexData);\r
 }\r
 \r
 /**\r
@@ -589,6 +624,7 @@ PeiRegisterForShadow (
   return EFI_SUCCESS;\r
 }\r
 \r
+\r
 /**\r
   This routine invoke the PeiCore's entry in new stack environment.\r
 \r
@@ -627,7 +663,3 @@ InvokePeiCore (
   //\r
   ASSERT_EFI_ERROR (FALSE);\r
 }\r
-\r
-\r
-\r
-\r
index a5065632c3c7bf695ddfeea2ea920863eba9f125..958263b522e79f4bc0ad788ab9d085a49f14358f 100644 (file)
@@ -1,6 +1,6 @@
 /*++\r
 \r
-Copyright (c) 2006, Intel Corporation                                                         \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
@@ -21,7 +21,14 @@ Abstract:
 \r
 #include <PeiMain.h>\r
 \r
-#define GETOCCUPIEDSIZE(ActualSize, Alignment) \\r
+STATIC EFI_PEI_NOTIFY_DESCRIPTOR mNotifyOnFvInfoList = {\r
+  (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
+  &gEfiPeiFirmwareVolumeInfoPpiGuid,\r
+  FirmwareVolmeInfoPpiNotifyCallback \r
+};\r
+\r
+\r
+#define GET_OCCUPIED_SIZE(ActualSize, Alignment) \\r
   (ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1))\r
 \r
 STATIC\r
@@ -121,12 +128,37 @@ Bugbug: For PEI performance reason, we comments this code at this time.
 }\r
 \r
 STATIC\r
+BOOLEAN\r
+EFIAPI\r
+PeiFileHandleToVolume (\r
+  IN   EFI_PEI_FILE_HANDLE     FileHandle,\r
+  OUT  EFI_PEI_FV_HANDLE       *VolumeHandle\r
+  )\r
+{\r
+  UINTN                       Index;\r
+  PEI_CORE_INSTANCE           *PrivateData;\r
+  EFI_FIRMWARE_VOLUME_HEADER  *FwVolHeader;\r
+\r
+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());\r
+  for (Index = 0; Index < PrivateData->FvCount; Index++) {\r
+    FwVolHeader = PrivateData->Fv[Index].FvHeader;\r
+    if (((UINT64) FileHandle > (UINT64) FwVolHeader ) &&   \\r
+        ((UINT64) FileHandle <= ((UINT64) FwVolHeader + FwVolHeader->FvLength - 1))) {\r
+      *VolumeHandle = (EFI_PEI_FV_HANDLE)FwVolHeader;\r
+      return TRUE;\r
+    }\r
+  }\r
+  return FALSE;\r
+}\r
+\r
+\r
 EFI_STATUS\r
-PeiFfsFindNextFileEx (\r
-  IN     EFI_FV_FILETYPE             SearchType,\r
-  IN     EFI_FIRMWARE_VOLUME_HEADER  *FwVolHeader,\r
-  IN OUT EFI_FFS_FILE_HEADER         **FileHeader,\r
-  IN     BOOLEAN                     Flag\r
+PeiFindFileEx (\r
+  IN  CONST EFI_PEI_FV_HANDLE        FvHandle,\r
+  IN  CONST EFI_GUID                 *FileName,   OPTIONAL\r
+  IN        EFI_FV_FILETYPE          SearchType,\r
+  IN OUT    EFI_PEI_FILE_HANDLE      *FileHandle,\r
+  IN OUT    EFI_PEI_FV_HANDLE        *AprioriFile  OPTIONAL\r
   )\r
 /*++\r
 \r
@@ -144,53 +176,63 @@ Arguments:
     FileHeader  - Pointer to the current file from which to begin searching.\r
       This pointer will be updated upon return to reflect the file found.\r
     Flag        - Indicator for if this is for PEI Dispath search \r
+    \r
 Returns:\r
     EFI_NOT_FOUND - No files matching the search criteria were found\r
     EFI_SUCCESS\r
 \r
 --*/\r
 {\r
-  EFI_FFS_FILE_HEADER  *FfsFileHeader;\r
-  UINT32               FileLength;\r
-  UINT32               FileOccupiedSize;\r
-  UINT32               FileOffset;\r
-  UINT64               FvLength;\r
-  UINT8                ErasePolarity;\r
-  UINT8                FileState;\r
-  \r
+  EFI_FIRMWARE_VOLUME_HEADER           *FwVolHeader;\r
+  EFI_FFS_FILE_HEADER                   **FileHeader;\r
+  EFI_FFS_FILE_HEADER                   *FfsFileHeader;\r
+  EFI_FIRMWARE_VOLUME_EXT_HEADER        *FwVolExHeaderInfo;\r
+  UINT32                                FileLength;\r
+  UINT32                                FileOccupiedSize;\r
+  UINT32                                FileOffset;\r
+  UINT64                                FvLength;\r
+  UINT8                                 ErasePolarity;\r
+  UINT8                                 FileState;\r
+\r
+  FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)FvHandle;\r
+  FileHeader  = (EFI_FFS_FILE_HEADER **)FileHandle;\r
 \r
   FvLength = FwVolHeader->FvLength;\r
-  if (FwVolHeader->Attributes & EFI_FVB2_ERASE_POLARITY) {\r
+  if (FwVolHeader->Attributes & EFI_FVB_ERASE_POLARITY) {\r
     ErasePolarity = 1;\r
   } else {\r
     ErasePolarity = 0;\r
   }\r
   \r
   //\r
-  // If FileHeader is not specified (NULL) start with the first file in the\r
-  // firmware volume.  Otherwise, start from the FileHeader.\r
+  // If FileHeader is not specified (NULL) or FileName is not NULL,\r
+  // start with the first file in the firmware volume.  Otherwise,\r
+  // start from the FileHeader.\r
   //\r
-  if (*FileHeader == NULL)  {\r
+  if ((*FileHeader == NULL) || (FileName != NULL)) {\r
     FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FwVolHeader + FwVolHeader->HeaderLength);\r
+    if (FwVolHeader->ExtHeaderOffset != 0) {\r
+      FwVolExHeaderInfo = (EFI_FIRMWARE_VOLUME_EXT_HEADER *)(((UINT8 *)FwVolHeader) + FwVolHeader->ExtHeaderOffset);\r
+      FfsFileHeader = (EFI_FFS_FILE_HEADER *)(((UINT8 *)FwVolExHeaderInfo) + FwVolExHeaderInfo->ExtHeaderSize);\r
+    }\r
   } else {\r
     //\r
     // Length is 24 bits wide so mask upper 8 bits\r
     // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned.\r
     //\r
     FileLength = *(UINT32 *)(*FileHeader)->Size & 0x00FFFFFF;\r
-    FileOccupiedSize = GETOCCUPIEDSIZE(FileLength, 8);\r
+    FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);\r
     FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)*FileHeader + FileOccupiedSize);\r
   }\r
 \r
   FileOffset = (UINT32) ((UINT8 *)FfsFileHeader - (UINT8 *)FwVolHeader);\r
   ASSERT (FileOffset <= 0xFFFFFFFF);\r
   \r
-  while (FileOffset < (FvLength - sizeof(EFI_FFS_FILE_HEADER))) {\r
+  while (FileOffset < (FvLength - sizeof (EFI_FFS_FILE_HEADER))) {\r
     //\r
     // Get FileState which is the highest bit of the State \r
     //\r
     FileState = GetFileState (ErasePolarity, FfsFileHeader);\r
-\r
     switch (FileState) {\r
 \r
     case EFI_FILE_HEADER_INVALID:\r
@@ -200,40 +242,44 @@ Returns:
         \r
     case EFI_FILE_DATA_VALID:\r
     case EFI_FILE_MARKED_FOR_UPDATE:\r
-       if (CalculateHeaderChecksum (FfsFileHeader) == 0) {\r
-        FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;\r
-        FileOccupiedSize = GETOCCUPIEDSIZE(FileLength, 8);\r
-        if (Flag) {\r
-          if ((FfsFileHeader->Type == EFI_FV_FILETYPE_PEIM) || \r
-              (FfsFileHeader->Type == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER)) { \r
-            \r
-            *FileHeader = FfsFileHeader;\r
-        \r
-        \r
-            return EFI_SUCCESS;\r
-          }\r
-        } else {        \r
-          if ((SearchType == FfsFileHeader->Type) || \r
-              (SearchType == EFI_FV_FILETYPE_ALL)) { \r
-          \r
-            *FileHeader = FfsFileHeader;\r
-        \r
-        \r
-            return EFI_SUCCESS;\r
-          }\r
-        }\r
-\r
-        FileOffset += FileOccupiedSize; \r
-        FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);\r
-      } else {\r
+      if (CalculateHeaderChecksum (FfsFileHeader) != 0) {\r
         ASSERT (FALSE);\r
         return EFI_NOT_FOUND;\r
       }\r
+\r
+      FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;\r
+      FileOccupiedSize = GET_OCCUPIED_SIZE(FileLength, 8);\r
+\r
+      if (FileName != NULL) {\r
+        if (CompareGuid (&FfsFileHeader->Name, (EFI_GUID*)FileName)) {\r
+          *FileHeader = FfsFileHeader;\r
+          return EFI_SUCCESS;\r
+        }\r
+      } else if (SearchType == PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE) {\r
+        if ((FfsFileHeader->Type == EFI_FV_FILETYPE_PEIM) || \r
+            (FfsFileHeader->Type == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER)) { \r
+          \r
+          *FileHeader = FfsFileHeader;\r
+          return EFI_SUCCESS;\r
+        } else if (AprioriFile != NULL) {\r
+          if (FfsFileHeader->Type == EFI_FV_FILETYPE_FREEFORM) {\r
+            if (CompareGuid (&FfsFileHeader->Name, &gPeiAprioriFileNameGuid)) {\r
+              *AprioriFile = FfsFileHeader;\r
+            }           \r
+          } \r
+        }\r
+      } else if ((SearchType == FfsFileHeader->Type) || (SearchType == EFI_FV_FILETYPE_ALL)) { \r
+        *FileHeader = FfsFileHeader;\r
+        return EFI_SUCCESS;\r
+      }\r
+\r
+      FileOffset += FileOccupiedSize; \r
+      FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);\r
       break;\r
     \r
     case EFI_FILE_DELETED:\r
       FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;\r
-      FileOccupiedSize = GETOCCUPIEDSIZE(FileLength, 8);\r
+      FileOccupiedSize = GET_OCCUPIED_SIZE(FileLength, 8);\r
       FileOffset += FileOccupiedSize;\r
       FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);\r
       break;\r
@@ -247,6 +293,206 @@ Returns:
   return EFI_NOT_FOUND;  \r
 }\r
 \r
+VOID \r
+PeiInitializeFv (\r
+  IN  PEI_CORE_INSTANCE           *PrivateData,\r
+  IN CONST EFI_SEC_PEI_HAND_OFF   *SecCoreData\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Initialize PeiCore Fv List.\r
+\r
+Arguments:\r
+  PrivateData     - Pointer to PEI_CORE_INSTANCE.\r
+  SecCoreData     - Pointer to EFI_SEC_PEI_HAND_OFF.\r
+\r
+Returns:\r
+  NONE  \r
+  \r
+--*/  \r
+{\r
+  EFI_STATUS  Status;\r
+  //\r
+  // The BFV must be the first entry. The Core FV support is stateless \r
+  // The AllFV list has a single entry per FV in PEI. \r
+  // The Fv list only includes FV that PEIMs will be dispatched from and\r
+  // its File System Format is PI 1.0 definition.\r
+  //\r
+  PrivateData->FvCount = 1;\r
+  PrivateData->Fv[0].FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)SecCoreData->BootFirmwareVolumeBase;\r
+\r
+  PrivateData->AllFvCount = 1;\r
+  PrivateData->AllFv[0] = (EFI_PEI_FV_HANDLE)PrivateData->Fv[0].FvHeader;\r
+\r
+\r
+  //\r
+  // Post a call-back for the FvInfoPPI services to expose\r
+  // additional Fvs to PeiCore.\r
+  //\r
+  Status = PeiServicesNotifyPpi (&mNotifyOnFvInfoList);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+FirmwareVolmeInfoPpiNotifyCallback (\r
+  IN EFI_PEI_SERVICES              **PeiServices,\r
+  IN EFI_PEI_NOTIFY_DESCRIPTOR     *NotifyDescriptor,\r
+  IN VOID                          *Ppi\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Process Firmware Volum Information once FvInfoPPI install.\r
+\r
+Arguments:\r
+\r
+  PeiServices - General purpose services available to every PEIM.\r
+    \r
+Returns:\r
+\r
+  Status -  EFI_SUCCESS if the interface could be successfully\r
+            installed\r
+\r
+--*/\r
+{\r
+  UINT8                                 FvCount;\r
+  EFI_PEI_FIRMWARE_VOLUME_INFO_PPI      *Fv;\r
+  PEI_CORE_INSTANCE                     *PrivateData;\r
+  \r
+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
+\r
+  if (PrivateData->FvCount >= PEI_CORE_MAX_FV_SUPPORTED) {\r
+    ASSERT (FALSE);\r
+  }\r
+\r
+  Fv = (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *)Ppi;\r
+\r
+   if (CompareGuid (&Fv->FvFormat, &gEfiFirmwareFileSystem2Guid)) {\r
+     for (FvCount = 0; FvCount < PrivateData->FvCount; FvCount ++) {\r
+       if ((UINTN)PrivateData->Fv[FvCount].FvHeader == (UINTN)Fv->FvInfo) {\r
+         return EFI_SUCCESS;\r
+       }\r
+     }\r
+    PrivateData->Fv[PrivateData->FvCount++].FvHeader = (EFI_FIRMWARE_VOLUME_HEADER*)Fv->FvInfo;\r
+    BuildFvHob ((EFI_PHYSICAL_ADDRESS) (UINTN) Fv->FvInfo, (UINT64) Fv->FvInfoSize);\r
+  }\r
+\r
+  //\r
+  // Allways add to the All list\r
+  //\r
+  PrivateData->AllFv[PrivateData->AllFvCount++] = (EFI_PEI_FV_HANDLE)Fv->FvInfo;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+PeiFfsProcessSection (\r
+  IN CONST EFI_PEI_SERVICES     **PeiServices,\r
+  IN EFI_SECTION_TYPE           SectionType,\r
+  IN EFI_COMMON_SECTION_HEADER  *Section,\r
+  IN UINTN                      SectionSize,\r
+  OUT VOID                      **OutputBuffer,\r
+  OUT UINTN                     *OutputSize,\r
+  OUT UINT32                    *Authentication\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Go through the file to search SectionType section,\r
+  when meeting an encapsuled section, search recursively. \r
+  \r
+Arguments:\r
+  PeiServices  - Pointer to the PEI Core Services Table.\r
+  SearchType   - Filter to find only section of this type.\r
+  Section      - From where to search.\r
+  SectionSize  - The file size to search.\r
+  OutputBuffer - Pointer to the section to search.\r
+  OutputSize   - The size of the section to search.\r
+  Authentication -  Authenticate the section.\r
+\r
+Returns:\r
+  EFI_STATUS\r
+  \r
+--*/\r
+{\r
+  EFI_STATUS                              Status;\r
+  UINT32                                  SectionLength;\r
+  UINT32                                  ParsedLength;\r
+  EFI_GUID_DEFINED_SECTION                *GuidSection; \r
+  EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI   *GuidSectionPpi;\r
+  EFI_COMPRESSION_SECTION                 *CompressionSection;\r
+  EFI_PEI_DECOMPRESS_PPI                  *DecompressPpi;\r
+  VOID                                    *PpiOutput;\r
+  UINTN                                   PpiOutputSize;\r
+\r
+  *OutputBuffer = NULL;\r
+  ParsedLength = 0;\r
+  while (ParsedLength < SectionSize) {\r
+    if (Section->Type == SectionType) {\r
+      *OutputBuffer = (VOID *)(Section + 1);\r
+      return EFI_SUCCESS;\r
+    } else if (Section->Type == EFI_SECTION_GUID_DEFINED) {\r
+      GuidSection = (EFI_GUID_DEFINED_SECTION *)Section;\r
+      Status = PeiServicesLocatePpi (&GuidSection->SectionDefinitionGuid, 0, NULL, (VOID **) &GuidSectionPpi);\r
+      if (!EFI_ERROR (Status)) {\r
+        Status = GuidSectionPpi->ExtractSection (\r
+                                  GuidSectionPpi,\r
+                                  Section,\r
+                                  &PpiOutput,\r
+                                  &PpiOutputSize,\r
+                                  Authentication\r
+                                  );\r
+        if (!EFI_ERROR (Status)) {\r
+          return PeiFfsProcessSection (\r
+                  PeiServices,\r
+                  SectionType, \r
+                  PpiOutput, \r
+                  PpiOutputSize, \r
+                  OutputBuffer, \r
+                  OutputSize, \r
+                  Authentication\r
+                  );\r
+        }\r
+      }\r
+    } else if (Section->Type == EFI_SECTION_COMPRESSION) {\r
+      CompressionSection = (EFI_COMPRESSION_SECTION *)Section;\r
+      Status = PeiServicesLocatePpi (&gEfiPeiDecompressPpiGuid, 0, NULL, (VOID **) &DecompressPpi);\r
+      if (!EFI_ERROR (Status)) {\r
+        Status = DecompressPpi->Decompress (\r
+                                  DecompressPpi,\r
+                                  CompressionSection,\r
+                                  &PpiOutput,\r
+                                  &PpiOutputSize\r
+                                  );\r
+        if (!EFI_ERROR (Status)) {\r
+          return PeiFfsProcessSection (\r
+                  PeiServices, SectionType, PpiOutput, PpiOutputSize, OutputBuffer, OutputSize, Authentication\r
+                  );\r
+        }\r
+      }\r
+    }\r
+\r
+    //\r
+    // Size is 24 bits wide so mask upper 8 bits. \r
+    // SectionLength is adjusted it is 4 byte aligned.\r
+    // Go to the next section\r
+    //\r
+    SectionLength = *(UINT32 *)Section->Size & 0x00FFFFFF;\r
+    SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);\r
+    ASSERT (SectionLength != 0);\r
+    ParsedLength += SectionLength;\r
+    Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength);\r
+  }\r
+  \r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
 \r
 EFI_STATUS\r
 EFIAPI\r
@@ -275,46 +521,33 @@ Returns:
 \r
 --*/\r
 {\r
-  UINT32                        FileSize;\r
-  EFI_COMMON_SECTION_HEADER     *Section;\r
-  UINT32                        SectionLength;\r
-  UINT32                        ParsedLength;\r
-  EFI_FFS_FILE_HEADER           *FfsFileHeader;\r
+  EFI_FFS_FILE_HEADER                     *FfsFileHeader;\r
+  UINT32                                  FileSize;\r
+  EFI_COMMON_SECTION_HEADER               *Section;\r
+  UINTN                                   OutputSize;\r
+  UINT32                                  AuthenticationStatus;\r
+\r
+\r
+  FfsFileHeader = (EFI_FFS_FILE_HEADER *)(FileHandle);\r
 \r
-  FfsFileHeader = (EFI_FFS_FILE_HEADER *) FileHandle;\r
-  \r
   //\r
   // Size is 24 bits wide so mask upper 8 bits. \r
-  //    Does not include FfsFileHeader header size\r
+  // Does not include FfsFileHeader header size\r
   // FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned.\r
   //\r
   Section = (EFI_COMMON_SECTION_HEADER *)(FfsFileHeader + 1);\r
   FileSize = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;\r
-  FileSize -= sizeof(EFI_FFS_FILE_HEADER);\r
-  \r
-  *SectionData = NULL;\r
-  ParsedLength = 0;\r
-  while (ParsedLength < FileSize) {\r
-    if (Section->Type == SectionType) {\r
-      *SectionData = (VOID *)(Section + 1);\r
-\r
-\r
-      return EFI_SUCCESS;\r
-    }\r
-    //\r
-    // Size is 24 bits wide so mask upper 8 bits. \r
-    // SectionLength is adjusted it is 4 byte aligned.\r
-    // Go to the next section\r
-    //\r
-    SectionLength = *(UINT32 *)Section->Size & 0x00FFFFFF;\r
-    SectionLength = GETOCCUPIEDSIZE (SectionLength, 4);\r
-    ASSERT (SectionLength != 0);\r
-    ParsedLength += SectionLength;\r
-    Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength);\r
-  }\r
-  \r
-  return EFI_NOT_FOUND;\r
-  \r
+  FileSize -= sizeof (EFI_FFS_FILE_HEADER);\r
+\r
+  return PeiFfsProcessSection (\r
+          PeiServices, \r
+          SectionType, \r
+          Section, \r
+          FileSize, \r
+          SectionData, \r
+          &OutputSize, \r
+          &AuthenticationStatus\r
+          );\r
 }\r
 \r
 \r
@@ -346,11 +579,12 @@ Returns:
 \r
 --*/\r
 {\r
-  return PeiFfsFindNextFileEx ( \r
-           0,\r
-           FwVolHeader,\r
-           PeimFileHeader,\r
-           TRUE\r
+  return PeiFindFileEx (\r
+           (EFI_PEI_FV_HANDLE) FwVolHeader, \r
+           NULL, \r
+           EFI_FV_FILETYPE_PEIM, \r
+           (EFI_PEI_FILE_HANDLE *)PeimFileHeader, \r
+           NULL\r
            );\r
 }\r
 \r
@@ -387,20 +621,10 @@ Returns:
 \r
 --*/\r
 {\r
-  EFI_FIRMWARE_VOLUME_HEADER  *FwVolHeader;\r
-  EFI_FFS_FILE_HEADER         **FileHeader;\r
-\r
-  FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER  *)VolumeHandle;\r
-  FileHeader = (EFI_FFS_FILE_HEADER **) FileHandle;\r
-\r
-  return PeiFfsFindNextFileEx ( \r
-           SearchType,\r
-           FwVolHeader,\r
-           FileHeader,\r
-           FALSE\r
-           );\r
+  return PeiFindFileEx (VolumeHandle, NULL, SearchType, FileHandle, NULL);\r
 }\r
 \r
+\r
 EFI_STATUS \r
 EFIAPI\r
 PeiFvFindNextVolume (\r
@@ -433,52 +657,162 @@ Returns:
 \r
 --*/\r
 {\r
-  PEI_CORE_INSTANCE       *PrivateData;\r
-  EFI_STATUS              Status;\r
-  EFI_PEI_FIND_FV_PPI     *FindFvPpi;\r
-  UINT8                   LocalInstance;\r
-  EFI_FIRMWARE_VOLUME_HEADER **FwVolHeader;\r
+  PEI_CORE_INSTANCE   *Private;\r
 \r
-  FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER **) VolumeHandle;\r
+  Private = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
+  if (VolumeHandle == NULL) {\r
+   return EFI_INVALID_PARAMETER;\r
+  } \r
 \r
-  LocalInstance = (UINT8) Instance;\r
+  if (Instance >= Private->AllFvCount) {\r
+   VolumeHandle = NULL;\r
+   return EFI_NOT_FOUND;\r
+  }\r
 \r
-  Status = EFI_SUCCESS;\r
-  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);\r
+  *VolumeHandle = Private->AllFv[Instance];\r
+  return EFI_SUCCESS;\r
+}\r
 \r
-  if (FwVolHeader == NULL) {\r
 \r
+EFI_STATUS\r
+EFIAPI \r
+PeiFfsFindFileByName (\r
+  IN  CONST EFI_GUID        *FileName,\r
+  IN  EFI_PEI_FV_HANDLE     VolumeHandle,\r
+  OUT EFI_PEI_FILE_HANDLE   *FileHandle\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Given the input VolumeHandle, search for the next matching name file.\r
+\r
+Arguments:\r
+\r
+  FileName      - File name to search.\r
+  VolumeHandle  - The current FV to search.\r
+  FileHandle    - Pointer to the file matching name in VolumeHandle.\r
+                - NULL if file not found\r
+Returns:\r
+  EFI_STATUS\r
+  \r
+--*/  \r
+{\r
+  EFI_STATUS  Status;\r
+  if ((VolumeHandle == NULL) || (FileName == NULL) || (FileHandle == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
+  Status = PeiFindFileEx (VolumeHandle, FileName, 0, FileHandle, NULL);\r
+  if (Status == EFI_NOT_FOUND) {\r
+    *FileHandle = NULL;\r
+  }\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI \r
+PeiFfsGetFileInfo (\r
+  IN EFI_PEI_FILE_HANDLE  FileHandle,\r
+  OUT EFI_FV_FILE_INFO    *FileInfo\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
 \r
-  if (Instance == 0) {\r
-    *FwVolHeader = PrivateData->DispatchData.BootFvAddress;\r
+  Collect information of given file.\r
 \r
+Arguments:\r
+  FileHandle   - The handle to file.\r
+  FileInfo     - Pointer to the file information.\r
 \r
-    return Status;\r
+Returns:\r
+  EFI_STATUS\r
+  \r
+--*/    \r
+{\r
+  UINT8                       FileState;\r
+  UINT8                       ErasePolarity;\r
+  EFI_FFS_FILE_HEADER         *FileHeader;\r
+  EFI_PEI_FV_HANDLE           VolumeHandle;\r
+\r
+  if ((FileHandle == NULL) || (FileInfo == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Retrieve the FirmwareVolume which the file resides in.\r
+  //\r
+  if (!PeiFileHandleToVolume(FileHandle, &VolumeHandle)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (((EFI_FIRMWARE_VOLUME_HEADER*)VolumeHandle)->Attributes & EFI_FVB_ERASE_POLARITY) {\r
+    ErasePolarity = 1;\r
   } else {\r
-    //\r
-    // Locate all instances of FindFV\r
-    // Alternately, could use FV HOBs, but the PPI is cleaner\r
-    //\r
-    Status = PeiServicesLocatePpi (\r
-               &gEfiFindFvPpiGuid,\r
-               0,\r
-               NULL,\r
-               (VOID **)&FindFvPpi\r
-               );\r
-\r
-    if (Status != EFI_SUCCESS) {\r
-      Status = EFI_NOT_FOUND;\r
-    } else {\r
-      Status = FindFvPpi->FindFv (\r
-                            FindFvPpi,\r
-                            (EFI_PEI_SERVICES **)PeiServices,\r
-                            &LocalInstance,\r
-                            FwVolHeader\r
-                            );  \r
+    ErasePolarity = 0;\r
+  }\r
+\r
+  //\r
+  // Get FileState which is the highest bit of the State \r
+  //\r
+  FileState = GetFileState (ErasePolarity, (EFI_FFS_FILE_HEADER*)FileHandle);\r
 \r
+  switch (FileState) {\r
+    case EFI_FILE_DATA_VALID:\r
+    case EFI_FILE_MARKED_FOR_UPDATE:\r
+      break;  \r
+    default:\r
+      return EFI_INVALID_PARAMETER;\r
     }\r
+\r
+  FileHeader = (EFI_FFS_FILE_HEADER *)FileHandle;\r
+  CopyMem (&FileInfo->FileName, &FileHeader->Name, sizeof(EFI_GUID));\r
+  FileInfo->FileType = FileHeader->Type;\r
+  FileInfo->FileAttributes = FileHeader->Attributes;\r
+  FileInfo->BufferSize = ((*(UINT32 *)FileHeader->Size) & 0x00FFFFFF) -  sizeof (EFI_FFS_FILE_HEADER);\r
+  FileInfo->Buffer = (FileHeader + 1);\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI \r
+PeiFfsGetVolumeInfo (\r
+  IN EFI_PEI_FV_HANDLE  VolumeHandle,\r
+  OUT EFI_FV_INFO       *VolumeInfo\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Collect information of given Fv Volume.\r
+\r
+Arguments:\r
+  VolumeHandle    - The handle to Fv Volume.\r
+  VolumeInfo      - The pointer to volume information.\r
+  \r
+Returns:\r
+  EFI_STATUS\r
+  \r
+--*/    \r
+{\r
+  EFI_FIRMWARE_VOLUME_HEADER             *FwVolHeader;\r
+  EFI_FIRMWARE_VOLUME_EXT_HEADER         *FwVolExHeaderInfo;\r
+\r
+  if (VolumeInfo == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
   }\r
-  return Status;\r
+\r
+  FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(VolumeHandle);\r
+  VolumeInfo->FvAttributes = FwVolHeader->Attributes;\r
+  VolumeInfo->FvStart = FwVolHeader;\r
+  VolumeInfo->FvSize = FwVolHeader->FvLength;\r
+  CopyMem (&VolumeInfo->FvFormat, &FwVolHeader->FileSystemGuid,sizeof(EFI_GUID));\r
+\r
+  if (FwVolHeader->ExtHeaderOffset != 0) {\r
+    FwVolExHeaderInfo = (EFI_FIRMWARE_VOLUME_EXT_HEADER*)(((UINT8 *)FwVolHeader) + FwVolHeader->ExtHeaderOffset);\r
+    CopyMem (&VolumeInfo->FvName, &FwVolExHeaderInfo->FvName, sizeof(EFI_GUID));\r
+  }\r
+  return EFI_SUCCESS;\r
 }\r
+\r
index 202936869b62eb4b2f9417f4b5dc6562d76f934c..ebe79a6c50a05fd7ee013f4eacd6720bd910945a 100644 (file)
@@ -21,13 +21,33 @@ Abstract:
 \r
 #include <PeiMain.h>\r
 \r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file\r
 \r
+Arguments:\r
+\r
+  FileHandle - The handle to the PE/COFF file\r
+  FileOffset - The offset, in bytes, into the file to read\r
+  ReadSize   - The number of bytes to read from the file starting at FileOffset\r
+  Buffer     - A pointer to the buffer to read the data into.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset\r
+\r
+--*/  \r
 \r
 EFI_STATUS\r
-PeiLoadImage (\r
-  IN EFI_PEI_SERVICES         **PeiServices,\r
-  IN EFI_FFS_FILE_HEADER      *PeimFileHeader,\r
-  OUT VOID                    **EntryPoint\r
+PeiLoadImageLoadImage (\r
+  IN     EFI_PEI_SERVICES             **PeiServices,\r
+  IN     EFI_PEI_FILE_HANDLE          FileHandle,\r
+  OUT    EFI_PHYSICAL_ADDRESS         *ImageAddressArg,  OPTIONAL\r
+  OUT    UINT64                       *ImageSizeArg,     OPTIONAL\r
+  OUT    EFI_PHYSICAL_ADDRESS         *EntryPoint,\r
+  OUT    UINT32                       *AuthenticationState\r
   )\r
 /*++\r
 \r
@@ -37,9 +57,247 @@ Routine Description:
 \r
 Arguments:\r
 \r
-  PeiServices     - The PEI core services table.\r
-  PeimFileHeader  - Pointer to the FFS file header of the image.\r
-  EntryPoint      - Pointer to entry point of specified image file for output.\r
+  PeiServices          - The PEI core services table.\r
+  FileHandle           - Pointer to the FFS file header of the image.\r
+  ImageAddressArg      - Pointer to PE/TE image.\r
+  ImageSizeArg         - Size of PE/TE image.\r
+  EntryPoint           - Pointer to entry point of specified image file for output.\r
+  AuthenticationState  - Pointer to attestation authentication state of image.\r
+\r
+Returns:\r
+\r
+  Status - EFI_SUCCESS    - Image is successfully loaded.\r
+           EFI_NOT_FOUND  - Fail to locate necessary PPI\r
+           Others         - Fail to load file.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiLoadImageLoadImageWrapper (\r
+  IN     CONST EFI_PEI_LOAD_FILE_PPI  *This,\r
+  IN     EFI_PEI_FILE_HANDLE          FileHandle,\r
+  OUT    EFI_PHYSICAL_ADDRESS         *ImageAddressArg,  OPTIONAL\r
+  OUT    UINT64                       *ImageSizeArg,     OPTIONAL\r
+  OUT    EFI_PHYSICAL_ADDRESS         *EntryPoint,\r
+  OUT    UINT32                       *AuthenticationState\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  The wrapper function of PeiLoadImageLoadImage().\r
+\r
+Arguments:\r
+\r
+  This                 - Pointer to EFI_PEI_LOAD_FILE_PPI.\r
+  PeiServices          - The PEI core services table.\r
+  FileHandle           - Pointer to the FFS file header of the image.\r
+  ImageAddressArg      - Pointer to PE/TE image.\r
+  ImageSizeArg         - Size of PE/TE image.\r
+  EntryPoint           - Pointer to entry point of specified image file for output.\r
+  AuthenticationState  - Pointer to attestation authentication state of image.\r
+\r
+Returns:\r
+\r
+  EFI_STATUS.\r
+  \r
+--*/ \r
+;\r
+\r
+STATIC EFI_PEI_LOAD_FILE_PPI   mPeiLoadImagePpi = {\r
+  PeiLoadImageLoadImageWrapper\r
+};\r
+\r
+\r
+STATIC EFI_PEI_PPI_DESCRIPTOR     gPpiLoadFilePpiList = {\r
+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
+  &gEfiPeiLoadFilePpiGuid,\r
+  &mPeiLoadImagePpi\r
+};\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiImageRead (\r
+  IN     VOID    *FileHandle,\r
+  IN     UINTN   FileOffset,\r
+  IN OUT UINTN   *ReadSize,\r
+  OUT    VOID    *Buffer\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file\r
+\r
+Arguments:\r
+\r
+  FileHandle - The handle to the PE/COFF file\r
+  FileOffset - The offset, in bytes, into the file to read\r
+  ReadSize   - The number of bytes to read from the file starting at FileOffset\r
+  Buffer     - A pointer to the buffer to read the data into.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset\r
+\r
+--*/\r
+{\r
+  CHAR8 *Destination8;\r
+  CHAR8 *Source8;\r
+  UINTN Length;\r
+\r
+  Destination8  = Buffer;\r
+  Source8       = (CHAR8 *) ((UINTN) FileHandle + FileOffset);\r
+  Length        = *ReadSize;\r
+  while (Length--) {\r
+    *(Destination8++) = *(Source8++);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+GetImageReadFunction (\r
+  IN      PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Support routine to return the Image Read\r
+\r
+Arguments:\r
+\r
+  PeiServices   - PEI Services Table\r
+\r
+  ImageContext  - The context of the image being loaded\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS - If Image function location is found\r
+\r
+--*/\r
+{\r
+  VOID*  MemoryBuffer;\r
+\r
+  MemoryBuffer = AllocatePages (0x400 / EFI_PAGE_SIZE + 1);\r
+  ASSERT (MemoryBuffer != NULL);\r
+\r
+  CopyMem (MemoryBuffer, (CONST VOID *) (UINTN) PeiImageRead, 0x400);\r
+\r
+  ImageContext->ImageRead = (PE_COFF_LOADER_READ_FILE) (UINTN) MemoryBuffer;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+LoadAndRelocatePeCoffImage (\r
+  IN  EFI_PEI_PE_COFF_LOADER_PROTOCOL           *PeiEfiPeiPeCoffLoader,\r
+  IN  VOID                                      *Pe32Data,\r
+  OUT EFI_PHYSICAL_ADDRESS                      *ImageAddress,\r
+  OUT UINT64                                    *ImageSize,\r
+  OUT EFI_PHYSICAL_ADDRESS                      *EntryPoint\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Loads and relocates a PE/COFF image into memory.\r
+\r
+Arguments:\r
+\r
+  PeiEfiPeiPeCoffLoader - Pointer to a PE COFF loader protocol\r
+\r
+  Pe32Data         - The base address of the PE/COFF file that is to be loaded and relocated\r
+\r
+  ImageAddress     - The base address of the relocated PE/COFF image\r
+\r
+  ImageSize        - The size of the relocated PE/COFF image\r
+\r
+  EntryPoint       - The entry point of the relocated PE/COFF image\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS   - The file was loaded and relocated\r
+\r
+  EFI_OUT_OF_RESOURCES - There was not enough memory to load and relocate the PE/COFF file\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                            Status;\r
+  PE_COFF_LOADER_IMAGE_CONTEXT          ImageContext;\r
+\r
+  ASSERT (PeiEfiPeiPeCoffLoader != NULL);\r
+\r
+  ZeroMem (&ImageContext, sizeof (ImageContext));\r
+  ImageContext.Handle = Pe32Data;\r
+  Status              = GetImageReadFunction (&ImageContext);\r
+\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  Status = PeiEfiPeiPeCoffLoader->GetImageInfo (PeiEfiPeiPeCoffLoader, &ImageContext);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  //\r
+  // Allocate Memory for the image\r
+  //\r
+  ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) AllocatePages (EFI_SIZE_TO_PAGES ((UINT32) ImageContext.ImageSize));\r
+  ASSERT (ImageContext.ImageAddress != 0);\r
+\r
+  //\r
+  // Load the image to our new buffer\r
+  //\r
+  Status = PeiEfiPeiPeCoffLoader->LoadImage (PeiEfiPeiPeCoffLoader, &ImageContext);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  //\r
+  // Relocate the image in our new buffer\r
+  //\r
+  Status = PeiEfiPeiPeCoffLoader->RelocateImage (PeiEfiPeiPeCoffLoader, &ImageContext);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Flush the instruction cache so the image data is written before we execute it\r
+  //\r
+  InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);\r
+\r
+  *ImageAddress = ImageContext.ImageAddress;\r
+  *ImageSize    = ImageContext.ImageSize;\r
+  *EntryPoint   = ImageContext.EntryPoint;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+PeiLoadImageLoadImage (\r
+  IN     EFI_PEI_SERVICES             **PeiServices,\r
+  IN     EFI_PEI_FILE_HANDLE          FileHandle,\r
+  OUT    EFI_PHYSICAL_ADDRESS         *ImageAddressArg,  OPTIONAL\r
+  OUT    UINT64                       *ImageSizeArg,     OPTIONAL\r
+  OUT    EFI_PHYSICAL_ADDRESS         *EntryPoint,\r
+  OUT    UINT32                       *AuthenticationState\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Routine for loading file image.\r
+\r
+Arguments:\r
+\r
+  PeiServices          - The PEI core services table.\r
+  FileHandle           - Pointer to the FFS file header of the image.\r
+  ImageAddressArg      - Pointer to PE/TE image.\r
+  ImageSizeArg         - Size of PE/TE image.\r
+  EntryPoint           - Pointer to entry point of specified image file for output.\r
+  AuthenticationState  - Pointer to attestation authentication state of image.\r
 \r
 Returns:\r
 \r
@@ -51,55 +309,63 @@ Returns:
 {\r
   EFI_STATUS                  Status;\r
   VOID                        *Pe32Data;\r
-  EFI_PEI_FV_FILE_LOADER_PPI  *FvLoadFilePpi;\r
   EFI_PHYSICAL_ADDRESS        ImageAddress;\r
   UINT64                      ImageSize;\r
   EFI_PHYSICAL_ADDRESS        ImageEntryPoint;\r
   EFI_TE_IMAGE_HEADER         *TEImageHeader;\r
   UINT16                      Machine;\r
+  PEI_CORE_INSTANCE           *Private;\r
+  VOID                        *EntryPointArg;\r
 \r
-  *EntryPoint   = NULL;\r
+  *EntryPoint   = 0;\r
   TEImageHeader = NULL;\r
+  ImageSize = 0;\r
+  *AuthenticationState = 0;\r
 \r
   //\r
-  // Try to find a PE32 section.\r
+  // Try to find a TE section.\r
   //\r
   Status = PeiServicesFfsFindSectionData (\r
-             EFI_SECTION_PE32,\r
-             PeimFileHeader,\r
+             EFI_SECTION_TE,\r
+             FileHandle,\r
              &Pe32Data\r
              );\r
+  if (!EFI_ERROR (Status)) {\r
+     TEImageHeader = (EFI_TE_IMAGE_HEADER *)Pe32Data;\r
+  }\r
   //\r
   // If we didn't find a PE32 section, try to find a TE section.\r
   //\r
   if (EFI_ERROR (Status)) {\r
     Status = PeiServicesFfsFindSectionData (\r
-               EFI_SECTION_TE,\r
-               PeimFileHeader,\r
-               (VOID **) &TEImageHeader\r
+               EFI_SECTION_PE32,\r
+               FileHandle,\r
+               &Pe32Data\r
                );\r
-    if (EFI_ERROR (Status) || TEImageHeader == NULL) {\r
+    if (EFI_ERROR (Status)) {\r
       //\r
-      // There was not a PE32 or a TE section, so assume that it's a Compressed section\r
-      // and use the LoadFile\r
+      // PEI core only carry the loader function fro TE and PE32 executables\r
+      // If this two section does not exist, just return.\r
       //\r
-      Status = PeiServicesLocatePpi (\r
-                &gEfiPeiFvFileLoaderPpiGuid,\r
-                0,\r
-                NULL,\r
-                (VOID **)&FvLoadFilePpi\r
-                );\r
-      if (EFI_ERROR (Status)) {\r
-        return EFI_NOT_FOUND;\r
-      }\r
+      return Status;\r
+    }\r
+  }\r
+  \r
+  Private = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
 \r
-      Status = FvLoadFilePpi->FvLoadFile (\r
-                                FvLoadFilePpi,\r
-                                PeimFileHeader,\r
-                                &ImageAddress,\r
-                                &ImageSize,\r
-                                &ImageEntryPoint\r
-                                );\r
+  if (Private->PeiMemoryInstalled && \r
+      (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {\r
+    {\r
+      //\r
+      // If memory is installed, perform the shadow operations\r
+      //\r
+      Status = LoadAndRelocatePeCoffImage (\r
+        Private->PeCoffLoader,\r
+        Pe32Data,\r
+        &ImageAddress,\r
+        &ImageSize,\r
+        &ImageEntryPoint\r
+      );\r
 \r
       if (EFI_ERROR (Status)) {\r
         return EFI_NOT_FOUND;\r
@@ -109,23 +375,28 @@ Returns:
       // Got the entry point from ImageEntryPoint and ImageStartAddress\r
       //\r
       Pe32Data    = (VOID *) ((UINTN) ImageAddress);\r
-      *EntryPoint = (VOID *) ((UINTN) ImageEntryPoint);\r
-    } else {\r
+      *EntryPoint = ImageEntryPoint;\r
+    }\r
+  } else {\r
+   if (TEImageHeader != NULL) {\r
       //\r
       // Retrieve the entry point from the TE image header\r
       //\r
       ImageAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) TEImageHeader;\r
-      *EntryPoint  = (VOID *)((UINTN) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) +\r
+      ImageSize = 0;\r
+      *EntryPoint  = (EFI_PHYSICAL_ADDRESS)((UINTN) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) +\r
                     TEImageHeader->AddressOfEntryPoint - TEImageHeader->StrippedSize);\r
-    }\r
-  } else {\r
-    //\r
-    // Retrieve the entry point from the PE/COFF image header\r
-    //\r
-    ImageAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) Pe32Data;\r
-    Status = PeCoffLoaderGetEntryPoint (Pe32Data, EntryPoint);\r
-    if (EFI_ERROR (Status)) {\r
-      return EFI_NOT_FOUND;\r
+    } else {\r
+      //\r
+      // Retrieve the entry point from the PE/COFF image header\r
+      //\r
+      ImageAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) Pe32Data;\r
+      ImageSize = 0;\r
+      Status = PeCoffLoaderGetEntryPoint (Pe32Data, &EntryPointArg);\r
+      *EntryPoint = (EFI_PHYSICAL_ADDRESS) (UINTN) EntryPointArg;\r
+      if (EFI_ERROR (Status)) {\r
+        return EFI_NOT_FOUND;\r
+      }\r
     }\r
   }\r
 \r
@@ -140,6 +411,14 @@ Returns:
     return EFI_UNSUPPORTED;  \r
   }\r
 \r
+  if (ImageAddressArg != NULL) {\r
+    *ImageAddressArg = ImageAddress;\r
+  }\r
+\r
+  if (ImageSizeArg != NULL) {\r
+    *ImageSizeArg = ImageSize;\r
+  }\r
+  \r
   //\r
   // Print debug message: Loading PEIM at 0x12345678 EntryPoint=0x12345688 Driver.efi\r
   //\r
@@ -264,4 +543,175 @@ Returns:
   DEBUG ((EFI_D_INFO | EFI_D_LOAD, "\n"));\r
 \r
   return EFI_SUCCESS;\r
+\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiLoadImageLoadImageWrapper (\r
+  IN     CONST EFI_PEI_LOAD_FILE_PPI  *This,\r
+  IN     EFI_PEI_FILE_HANDLE          FileHandle,\r
+  OUT    EFI_PHYSICAL_ADDRESS         *ImageAddressArg,  OPTIONAL\r
+  OUT    UINT64                       *ImageSizeArg,     OPTIONAL\r
+  OUT    EFI_PHYSICAL_ADDRESS         *EntryPoint,\r
+  OUT    UINT32                       *AuthenticationState\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  The wrapper function of PeiLoadImageLoadImage().\r
+\r
+Arguments:\r
+\r
+  This                 - Pointer to EFI_PEI_LOAD_FILE_PPI.\r
+  PeiServices          - The PEI core services table.\r
+  FileHandle           - Pointer to the FFS file header of the image.\r
+  ImageAddressArg      - Pointer to PE/TE image.\r
+  ImageSizeArg         - Size of PE/TE image.\r
+  EntryPoint           - Pointer to entry point of specified image file for output.\r
+  AuthenticationState  - Pointer to attestation authentication state of image.\r
+\r
+Returns:\r
+\r
+  EFI_STATUS.\r
+  \r
+--*/      \r
+{\r
+  return PeiLoadImageLoadImage (\r
+           GetPeiServicesTablePointer (),\r
+           FileHandle,\r
+           ImageAddressArg,\r
+           ImageSizeArg,\r
+           EntryPoint,\r
+           AuthenticationState\r
+           );\r
 }\r
+\r
+EFI_STATUS\r
+PeiLoadImage (\r
+  IN     EFI_PEI_SERVICES             **PeiServices,\r
+  IN     EFI_PEI_FILE_HANDLE          FileHandle,\r
+  OUT    EFI_PHYSICAL_ADDRESS         *EntryPoint,\r
+  OUT    UINT32                       *AuthenticationState\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Routine for load image file.\r
+\r
+Arguments:\r
+\r
+  PeiServices          - The PEI core services table.\r
+  FileHandle           - Pointer to the FFS file header of the image.\r
+  EntryPoint           - Pointer to entry point of specified image file for output.\r
+  AuthenticationState  - Pointer to attestation authentication state of image.\r
+\r
+Returns:\r
+\r
+  Status - EFI_SUCCESS    - Image is successfully loaded.\r
+           EFI_NOT_FOUND  - Fail to locate necessary PPI\r
+           Others         - Fail to load file.\r
+  \r
+--*/    \r
+{\r
+  EFI_STATUS              PpiStatus;\r
+  EFI_STATUS              Status;\r
+  UINTN                   Index;\r
+  EFI_PEI_LOAD_FILE_PPI   *LoadFile;\r
+  EFI_PHYSICAL_ADDRESS    ImageAddress;\r
+  UINT64                  ImageSize;\r
+\r
+  //\r
+  // If any instances of PEI_LOAD_FILE_PPI are installed, they are called.\r
+  // one at a time, until one reports EFI_SUCCESS.\r
+  //\r
+  Index = 0;\r
+  do {\r
+    PpiStatus = PeiServicesLocatePpi (\r
+                  &gEfiPeiLoadFilePpiGuid,\r
+                  Index,\r
+                  NULL,\r
+                  (VOID **)&LoadFile\r
+                  );\r
+    if (!EFI_ERROR (PpiStatus)) {\r
+      Status = LoadFile->LoadFile (\r
+                          LoadFile, \r
+                          FileHandle, \r
+                          &ImageAddress, \r
+                          &ImageSize,\r
+                          EntryPoint,\r
+                          AuthenticationState\r
+                          );\r
+      if (!EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+    }\r
+    Index++;\r
+  } while (!EFI_ERROR (PpiStatus));\r
+\r
+  //\r
+  // If no instances reports EFI_SUCCESS, then build-in support for\r
+  // the PE32+/TE XIP image format is used.\r
+  //\r
+  Status = PeiLoadImageLoadImage (\r
+            PeiServices, \r
+            FileHandle, \r
+            NULL, \r
+            NULL, \r
+            EntryPoint, \r
+            AuthenticationState\r
+            );\r
+  return Status;\r
+}\r
+\r
+\r
+VOID\r
+InitializeImageServices (\r
+  IN  PEI_CORE_INSTANCE   *PrivateData,\r
+  IN  PEI_CORE_INSTANCE   *OldCoreData\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Regitser PeCoffLoader to PeiCore PrivateData. And install\r
+  Pei Load File PPI.\r
+\r
+Arguments:\r
+\r
+  PrivateData    - Pointer to PEI_CORE_INSTANCE.\r
+  OldCoreData    - Pointer to PEI_CORE_INSTANCE.\r
+\r
+Returns:\r
+\r
+  NONE.\r
+  \r
+--*/      \r
+{\r
+  //\r
+  // Always update PeCoffLoader pointer as PEI core itself may get \r
+  // shadowed into memory\r
+  //\r
+  PrivateData->PeCoffLoader = GetPeCoffLoaderProtocol ();\r
+  \r
+  if (OldCoreData == NULL) {\r
+    //\r
+    // The first time we are XIP (running from FLASH). We need to remember the\r
+    // FLASH address so we can reinstall the memory version that runs faster\r
+    //\r
+    PrivateData->XipLoadFile = &gPpiLoadFilePpiList;\r
+    PeiServicesInstallPpi (PrivateData->XipLoadFile);\r
+  } else {\r
+    //\r
+    // 2nd time we are running from memory so replace the XIP version with the \r
+    // new memory version. \r
+    //\r
+    PeiServicesReInstallPpi (PrivateData->XipLoadFile, &gPpiLoadFilePpiList); \r
+  }\r
+}\r
+\r
+\r
+\r
index 49e9f7f5528154c6417d4e1464d11ef79185b1ab..0976e2cbdd7623368c8b6938d5934898e4ae4eb3 100644 (file)
@@ -23,7 +23,7 @@ Abstract:
 \r
 VOID\r
 InitializeMemoryServices (\r
-  IN EFI_PEI_SERVICES            **PeiServices,\r
+  IN PEI_CORE_INSTANCE           *PrivateData,\r
   IN CONST EFI_SEC_PEI_HAND_OFF  *SecCoreData,\r
   IN PEI_CORE_INSTANCE           *OldCoreData\r
   )\r
@@ -49,9 +49,6 @@ Returns:
 \r
 --*/\r
 {\r
-  PEI_CORE_INSTANCE                    *PrivateData;\r
-\r
-  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
   PrivateData->SwitchStackSignal = FALSE;\r
 \r
   if (OldCoreData == NULL) {\r
@@ -64,6 +61,8 @@ Returns:
     DEBUG_CODE_BEGIN ();\r
       PrivateData->SizeOfCacheAsRam = SecCoreData->PeiTemporaryRamSize + SecCoreData->StackSize;\r
       PrivateData->MaxTopOfCarHeap  = (VOID *) ((UINTN) PrivateData->BottomOfCarHeap + (UINTN) PrivateData->SizeOfCacheAsRam);\r
+      PrivateData->StackBase        = (EFI_PHYSICAL_ADDRESS) (UINTN) SecCoreData->StackBase;\r
+      PrivateData->StackSize        = (UINT64) SecCoreData->StackSize;\r
     DEBUG_CODE_END ();\r
 \r
     PrivateData->HobList.Raw = PrivateData->BottomOfCarHeap;\r
@@ -73,23 +72,13 @@ Returns:
       (EFI_PHYSICAL_ADDRESS) (UINTN) PrivateData->BottomOfCarHeap,\r
       (UINTN) SecCoreData->PeiTemporaryRamSize\r
       );\r
-    //\r
-    // Copy PeiServices from ROM to Cache in PrivateData\r
-    //\r
-    CopyMem (&(PrivateData->ServiceTableShadow), *PeiServices, sizeof (EFI_PEI_SERVICES));\r
 \r
     //\r
     // Set PS to point to ServiceTableShadow in Cache\r
     //\r
     PrivateData->PS = &(PrivateData->ServiceTableShadow);\r
-  } else {\r
-  //                                                                    \r
-  // Set PS to point to ServiceTableShadow in Cache one time after the  \r
-  // stack switched to main memory                                      \r
-  //                                                                    \r
-  PrivateData->PS = &(PrivateData->ServiceTableShadow);                 \r
-}                                                                       \r
-\r
+  }\r
+  \r
   return;\r
 }\r
 \r
index 50fd40a00e8f8704d165eb3daf4893a56e8e05be..da0c0aa1af281d8fd46de5c6b459e2fd8c774a23 100644 (file)
@@ -29,11 +29,14 @@ Revision History
 #include <Guid/StatusCodeDataTypeId.h>\r
 #include <Ppi/DxeIpl.h>\r
 #include <Ppi/MemoryDiscovered.h>\r
-#include <Ppi/FindFv.h>\r
 #include <Ppi/StatusCode.h>\r
-#include <Ppi/Security.h>\r
 #include <Ppi/Reset.h>\r
-#include <Ppi/FvLoadFile.h>\r
+#include <Ppi/FirmwareVolume.h>\r
+#include <Ppi/FirmwareVolumeInfo.h>\r
+#include <Ppi/Decompress.h>\r
+#include <Ppi/GuidedSectionExtraction.h>\r
+#include <Ppi/LoadFile.h>\r
+#include <Ppi/Security2.h>\r
 #include <Library/DebugLib.h>\r
 #include <Library/PeiCoreEntryPoint.h>\r
 #include <Library/BaseLib.h>\r
@@ -43,11 +46,15 @@ Revision History
 #include <Library/ReportStatusCodeLib.h>\r
 #include <Library/PeCoffGetEntryPointLib.h>\r
 #include <Library/BaseMemoryLib.h>\r
+#include <Library/CacheMaintenanceLib.h>\r
 #include <Library/TimerLib.h>\r
+#include <Library/PeCoffLoaderLib.h>\r
 #include <IndustryStandard/PeImage.h>\r
 #include <Library/PeiServicesTablePointerLib.h>\r
-\r
-extern EFI_GUID gEfiPeiCorePrivateGuid;\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Guid/FirmwareFileSystem2.h>\r
+#include <Guid/AprioriFileName.h>\r
+#include <Guid/PeiPeCoffLoader.h>\r
 \r
 #define PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE   0xff\r
 \r
@@ -94,18 +101,6 @@ typedef struct {
   BOOLEAN                             ScanFv;\r
 } PEI_CORE_FV_HANDLE;\r
 \r
-typedef struct {\r
-  UINT8                       CurrentPeim;\r
-  UINT8                       CurrentFv;\r
-  UINT32                      DispatchedPeimBitMap;\r
-  UINT32                      PreviousPeimBitMap;\r
-  EFI_FFS_FILE_HEADER         *CurrentPeimAddress;\r
-  EFI_FIRMWARE_VOLUME_HEADER  *CurrentFvAddress;\r
-  EFI_FIRMWARE_VOLUME_HEADER  *BootFvAddress;\r
-  EFI_PEI_FIND_FV_PPI         *FindFv;\r
-} PEI_CORE_DISPATCH_DATA;\r
-\r
-\r
 //\r
 // Pei Core private data structure instance\r
 //\r
@@ -116,7 +111,6 @@ typedef struct{
   UINTN                              Signature;\r
   EFI_PEI_SERVICES                   *PS;     // Point to ServiceTableShadow\r
   PEI_PPI_DATABASE                   PpiData;\r
-  PEI_CORE_DISPATCH_DATA             DispatchData;\r
   UINTN                              FvCount;\r
   PEI_CORE_FV_HANDLE                 Fv[PEI_CORE_MAX_FV_SUPPORTED];\r
   EFI_PEI_FILE_HANDLE                CurrentFvFileHandles[PEI_CORE_MAX_PEIM_PER_FV];\r
@@ -134,10 +128,12 @@ typedef struct{
   VOID                               *BottomOfCarHeap;\r
   VOID                               *TopOfCarHeap;\r
   VOID                               *CpuIo;\r
-  EFI_PEI_SECURITY_PPI               *PrivateSecurityPpi;\r
+  EFI_PEI_SECURITY2_PPI              *PrivateSecurityPpi;\r
   EFI_PEI_SERVICES                   ServiceTableShadow;\r
   UINTN                              SizeOfCacheAsRam;\r
   VOID                               *MaxTopOfCarHeap;\r
+  EFI_PEI_PPI_DESCRIPTOR             *XipLoadFile;\r
+  EFI_PEI_PE_COFF_LOADER_PROTOCOL    *PeCoffLoader; \r
 } PEI_CORE_INSTANCE;\r
 \r
 //\r
@@ -215,11 +211,10 @@ Returns:
 // Dispatcher support functions\r
 //\r
 \r
-EFI_STATUS\r
+BOOLEAN\r
 PeimDispatchReadiness (\r
   IN EFI_PEI_SERVICES   **PeiServices,\r
-  IN VOID               *DependencyExpression,\r
-  IN OUT BOOLEAN        *Runnable\r
+  IN VOID               *DependencyExpression\r
   )\r
 /*++\r
 \r
@@ -255,11 +250,10 @@ Returns:
 ;\r
 \r
 \r
-EFI_STATUS\r
+VOID\r
 PeiDispatcher (\r
   IN CONST EFI_SEC_PEI_HAND_OFF  *SecCoreData,\r
-  IN PEI_CORE_INSTANCE           *PrivateData,\r
-  IN PEI_CORE_DISPATCH_DATA      *DispatchData\r
+  IN PEI_CORE_INSTANCE           *PrivateData\r
   )\r
 \r
 /*++\r
@@ -285,7 +279,7 @@ Returns:
 \r
 VOID\r
 InitializeDispatcherData (\r
-  IN EFI_PEI_SERVICES             **PeiServices,\r
+  IN PEI_CORE_INSTANCE            *PrivateData,\r
   IN PEI_CORE_INSTANCE            *OldCoreData,\r
   IN CONST EFI_SEC_PEI_HAND_OFF   *SecCoreData\r
   )\r
@@ -390,8 +384,9 @@ Returns:
 \r
 BOOLEAN\r
 DepexSatisfied (\r
-  IN EFI_PEI_SERVICES  **PeiServices,\r
-  IN  VOID             *CurrentPeimAddress\r
+  IN PEI_CORE_INSTANCE          *Private,\r
+  IN EFI_PEI_FILE_HANDLE        FileHandle,\r
+  IN UINTN                      PeimCount\r
   )\r
 /*++\r
 \r
@@ -448,7 +443,7 @@ Returns:
 //\r
 VOID\r
 InitializePpiServices (\r
-  IN EFI_PEI_SERVICES    **PeiServices,\r
+  IN PEI_CORE_INSTANCE   *PrivateData,\r
   IN PEI_CORE_INSTANCE   *OldCoreData\r
   )\r
 /*++\r
@@ -607,7 +602,7 @@ Returns:
 \r
 VOID\r
 ProcessNotifyList (\r
-  IN EFI_PEI_SERVICES    **PeiServices\r
+  IN PEI_CORE_INSTANCE  *PrivateData\r
   )\r
 /*++\r
 \r
@@ -626,7 +621,7 @@ Returns:
 \r
 VOID\r
 DispatchNotify (\r
-  IN CONST EFI_PEI_SERVICES    **PeiServices,\r
+  IN PEI_CORE_INSTANCE  *PrivateData,\r
   IN UINTN               NotifyType,\r
   IN INTN                InstallStartIndex,\r
   IN INTN                InstallStopIndex,\r
@@ -755,8 +750,9 @@ Returns:
 \r
 EFI_STATUS\r
 VerifyPeim (\r
-  IN EFI_PEI_SERVICES     **PeiServices,\r
-  IN EFI_FFS_FILE_HEADER  *CurrentPeimAddress\r
+  IN PEI_CORE_INSTANCE      *PrivateData,\r
+  IN EFI_PEI_FV_HANDLE      VolumeHandle,\r
+  IN EFI_PEI_FILE_HANDLE    FileHandle\r
   )\r
 /*++\r
 \r
@@ -901,7 +897,7 @@ Returns:
 EFI_STATUS\r
 EFIAPI\r
 PeiFfsFindSectionData (\r
-  IN CONST EFI_PEI_SERVICES            **PeiServices,\r
+  IN CONST EFI_PEI_SERVICES      **PeiServices,\r
   IN EFI_SECTION_TYPE            SectionType,\r
   IN EFI_PEI_FILE_HANDLE         FfsFileHeader,\r
   IN OUT VOID                    **SectionData\r
@@ -964,7 +960,7 @@ Returns:
 //\r
 VOID\r
 InitializeMemoryServices (\r
-  IN EFI_PEI_SERVICES            **PeiServices,\r
+  IN PEI_CORE_INSTANCE           *PrivateData,\r
   IN CONST EFI_SEC_PEI_HAND_OFF  *SecCoreData,\r
   IN PEI_CORE_INSTANCE           *OldCoreData\r
   )\r
@@ -1082,8 +1078,9 @@ Returns:
 EFI_STATUS\r
 PeiLoadImage (\r
   IN  EFI_PEI_SERVICES            **PeiServices,\r
-  IN  EFI_FFS_FILE_HEADER         *PeimFileHeader,\r
-  OUT VOID                        **EntryPoint\r
+  IN  EFI_PEI_FILE_HANDLE         FileHandle,\r
+  OUT    EFI_PHYSICAL_ADDRESS     *EntryPoint,\r
+  OUT    UINT32                   *AuthenticationState\r
   )\r
 /*++\r
 \r
@@ -1149,7 +1146,7 @@ Returns:
 EFI_STATUS\r
 EFIAPI\r
 PeiResetSystem (\r
-  IN EFI_PEI_SERVICES   **PeiServices\r
+  IN CONST EFI_PEI_SERVICES   **PeiServices\r
   )\r
 /*++\r
 \r
@@ -1171,6 +1168,148 @@ Returns:
 --*/\r
 ;\r
 \r
+VOID \r
+PeiInitializeFv (\r
+  IN  PEI_CORE_INSTANCE           *PrivateData,\r
+  IN CONST EFI_SEC_PEI_HAND_OFF   *SecCoreData\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Initialize PeiCore Fv List.\r
+\r
+Arguments:\r
+  PrivateData     - Pointer to PEI_CORE_INSTANCE.\r
+  SecCoreData     - Pointer to EFI_SEC_PEI_HAND_OFF.\r
+\r
+Returns:\r
+  NONE  \r
+  \r
+--*/  \r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+FirmwareVolmeInfoPpiNotifyCallback (\r
+  IN EFI_PEI_SERVICES              **PeiServices,\r
+  IN EFI_PEI_NOTIFY_DESCRIPTOR     *NotifyDescriptor,\r
+  IN VOID                          *Ppi\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Process Firmware Volum Information once FvInfoPPI install.\r
+\r
+Arguments:\r
+\r
+  PeiServices - General purpose services available to every PEIM.\r
+    \r
+Returns:\r
+\r
+  Status -  EFI_SUCCESS if the interface could be successfully\r
+            installed\r
+\r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI \r
+PeiFfsFindFileByName (\r
+  IN  CONST EFI_GUID        *FileName,\r
+  IN  EFI_PEI_FV_HANDLE     VolumeHandle,\r
+  OUT EFI_PEI_FILE_HANDLE   *FileHandle\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Given the input VolumeHandle, search for the next matching name file.\r
+\r
+Arguments:\r
+\r
+  FileName      - File name to search.\r
+  VolumeHandle  - The current FV to search.\r
+  FileHandle    - Pointer to the file matching name in VolumeHandle.\r
+                - NULL if file not found\r
+Returns:\r
+  EFI_STATUS\r
+  \r
+--*/  \r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI \r
+PeiFfsGetFileInfo (\r
+  IN EFI_PEI_FILE_HANDLE  FileHandle,\r
+  OUT EFI_FV_FILE_INFO    *FileInfo\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Collect information of given file.\r
+\r
+Arguments:\r
+  FileHandle   - The handle to file.\r
+  FileInfo     - Pointer to the file information.\r
+\r
+Returns:\r
+  EFI_STATUS\r
+  \r
+--*/    \r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI \r
+PeiFfsGetVolumeInfo (\r
+  IN EFI_PEI_FV_HANDLE  VolumeHandle,\r
+  OUT EFI_FV_INFO       *VolumeInfo\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Collect information of given Fv Volume.\r
+\r
+Arguments:\r
+  VolumeHandle    - The handle to Fv Volume.\r
+  VolumeInfo      - The pointer to volume information.\r
+  \r
+Returns:\r
+  EFI_STATUS\r
+  \r
+--*/    \r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiRegisterForShadow (\r
+  IN EFI_PEI_FILE_HANDLE       FileHandle\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This routine enable a PEIM to register itself to shadow when PEI Foundation\r
+  discovery permanent memory.\r
+\r
+Arguments:\r
+  FileHandle  - File handle of a PEIM.\r
+  \r
+Returns:\r
+  EFI_NOT_FOUND        - The file handle doesn't point to PEIM itself.\r
+  EFI_ALREADY_STARTED  - Indicate that the PEIM has been registered itself.\r
+  EFI_SUCCESS          - Successfully to register itself.\r
+\r
+--*/  \r
+;\r
+\r
+\r
 /**\r
   This routine enable a PEIM to register itself to shadow when PEI Foundation\r
   discovery permanent memory.\r
@@ -1221,4 +1360,60 @@ PeiSwitchStacks (
   IN      VOID                      *NewBsp\r
   );\r
 \r
+EFI_STATUS\r
+PeiFindFileEx (\r
+  IN  CONST EFI_PEI_FV_HANDLE        FvHandle,\r
+  IN  CONST EFI_GUID                 *FileName,   OPTIONAL\r
+  IN        EFI_FV_FILETYPE          SearchType,\r
+  IN OUT    EFI_PEI_FILE_HANDLE      *FileHandle,\r
+  IN OUT    EFI_PEI_FV_HANDLE        *AprioriFile  OPTIONAL\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+    Given the input file pointer, search for the next matching file in the\r
+    FFS volume as defined by SearchType. The search starts from FileHeader inside\r
+    the Firmware Volume defined by FwVolHeader.\r
+\r
+Arguments:\r
+    PeiServices - Pointer to the PEI Core Services Table.\r
+    SearchType - Filter to find only files of this type.\r
+      Type EFI_FV_FILETYPE_ALL causes no filtering to be done.\r
+    FwVolHeader - Pointer to the FV header of the volume to search.\r
+      This parameter must point to a valid FFS volume.\r
+    FileHeader  - Pointer to the current file from which to begin searching.\r
+      This pointer will be updated upon return to reflect the file found.\r
+    Flag        - Indicator for if this is for PEI Dispath search \r
+    \r
+Returns:\r
+    EFI_NOT_FOUND - No files matching the search criteria were found\r
+    EFI_SUCCESS\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+InitializeImageServices (\r
+  IN  PEI_CORE_INSTANCE   *PrivateData,\r
+  IN  PEI_CORE_INSTANCE   *OldCoreData\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Regitser PeCoffLoader to PeiCore PrivateData. And install\r
+  Pei Load File PPI.\r
+\r
+Arguments:\r
+\r
+  PrivateData    - Pointer to PEI_CORE_INSTANCE.\r
+  OldCoreData    - Pointer to PEI_CORE_INSTANCE.\r
+\r
+Returns:\r
+\r
+  NONE.\r
+  \r
+--*/      \r
+;\r
+\r
 #endif\r
index b8e188d5fb5b79a3928a7f2aec653ae8d2645609..7701696850cc86173873551e27ad682af1884028 100644 (file)
   BaseLib\r
   PeiCoreEntryPoint\r
   DebugLib\r
+  MemoryAllocationLib\r
+  CacheMaintenanceLib\r
+  PeCoffLoaderLib\r
+  PeCoffLib\r
 \r
 [Guids]\r
-  gEfiPeiCorePrivateGuid                        # PRIVATE\r
+  gPeiAprioriFileNameGuid\r
+  gEfiFirmwareFileSystem2Guid\r
+\r
 \r
 [Ppis]\r
   gEfiPeiSecurityPpiGuid                        # PPI_NOTIFY SOMETIMES_CONSUMED\r
   gEfiPeiStatusCodePpiGuid                      # PPI SOMETIMES_CONSUMED\r
   gEfiPeiResetPpiGuid                           # PPI SOMETIMES_CONSUMED\r
   gEfiDxeIplPpiGuid                             # PPI ALWAYS_CONSUMED\r
-  gEfiPeiFvFileLoaderPpiGuid                    # PPI ALWAYS_CONSUMED\r
-  gEfiFindFvPpiGuid                             # PPI ALWAYS_CONSUMED\r
   gEfiPeiMemoryDiscoveredPpiGuid                # PPI ALWAYS_PRODUCED\r
+  gEfiPeiDecompressPpiGuid\r
+  gEfiPeiFirmwareVolumeInfoPpiGuid\r
+  gEfiPeiLoadFilePpiGuid\r
+  gEfiPeiSecurity2PpiGuid\r
+\r
+[BuildOptions.common]\r
+  MSFT:DEBUG_*_IA32_CC_FLAGS = /FAcs\r
 \r
index b8873a8ab6f385e0fd1b1b6b5d92bb32b67e51fa..31ebc45621bff6a9efacbdcdaf90fbd940c93bca 100644 (file)
       <PpiNotifyCName>gEfiPeiSecurityPpiGuid</PpiNotifyCName>\r
     </PpiNotify>\r
   </PPIs>\r
-  <Guids>\r
-    <GuidCNames Usage="PRIVATE">\r
-      <GuidCName>gEfiPeiCorePrivateGuid</GuidCName>\r
-    </GuidCNames>\r
-  </Guids>\r
   <Externs>\r
     <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>\r
     <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>\r
index 250c7cf504179f3d6273666340ff43a639a56635..f8eb92e12877fd0081ae906be9b00a6474322023 100644 (file)
@@ -61,20 +61,21 @@ static EFI_PEI_SERVICES  mPS = {
   PeiFfsFindNextFile,\r
   PeiFfsFindSectionData,\r
 \r
-  PeiInstallPeiMemory,\r
+  PeiInstallPeiMemory,      \r
   PeiAllocatePages,\r
   PeiAllocatePool,\r
   (EFI_PEI_COPY_MEM)CopyMem,\r
   (EFI_PEI_SET_MEM)SetMem,\r
 \r
   PeiReportStatusCode,\r
-\r
   PeiResetSystem,\r
+\r
   NULL,\r
   NULL,\r
-  NULL,\r
-  NULL,\r
-  NULL,\r
+\r
+  PeiFfsFindFileByName,\r
+  PeiFfsGetFileInfo,\r
+  PeiFfsGetVolumeInfo,\r
   PeiRegisterForShadow\r
 };\r
 \r
@@ -82,7 +83,7 @@ EFI_STATUS
 EFIAPI\r
 PeiCore (\r
   IN CONST EFI_SEC_PEI_HAND_OFF        *SecCoreData,\r
-  IN CONST EFI_PEI_PPI_DESCRIPTOR      *PpiList,\r
+  IN CONST EFI_PEI_PPI_DESCRIPTOR      *PpList,\r
   IN VOID                              *Data\r
   )\r
 /*++\r
@@ -117,9 +118,10 @@ Returns:
   PEI_CORE_INSTANCE                                     PrivateData;\r
   EFI_STATUS                                            Status;\r
   PEI_CORE_TEMP_POINTERS                                TempPtr;\r
-  PEI_CORE_DISPATCH_DATA                                *DispatchData;\r
   UINT64                                                mTick;\r
   PEI_CORE_INSTANCE                                     *OldCoreData;\r
+  EFI_PEI_CPU_IO_PPI                                    *CpuIo;\r
+  EFI_PEI_PCI_CFG2_PPI                                  *PciCfg;\r
 \r
   mTick = 0;\r
   OldCoreData = (PEI_CORE_INSTANCE *) Data;\r
@@ -138,26 +140,31 @@ Returns:
 \r
   if (OldCoreData != NULL) {\r
     CopyMem (&PrivateData, OldCoreData, sizeof (PEI_CORE_INSTANCE));\r
+    \r
+    CpuIo = (VOID*)PrivateData.ServiceTableShadow.CpuIo;\r
+    PciCfg = (VOID*)PrivateData.ServiceTableShadow.PciCfg;\r
+    \r
+    CopyMem (&PrivateData.ServiceTableShadow, &mPS, sizeof (mPS));\r
+    \r
+    PrivateData.ServiceTableShadow.CpuIo  = CpuIo;\r
+    PrivateData.ServiceTableShadow.PciCfg = PciCfg;\r
   } else {\r
     ZeroMem (&PrivateData, sizeof (PEI_CORE_INSTANCE));\r
+    PrivateData.Signature = PEI_CORE_HANDLE_SIGNATURE;\r
+    CopyMem (&PrivateData.ServiceTableShadow, &mPS, sizeof (mPS));\r
   }\r
 \r
-  PrivateData.Signature = PEI_CORE_HANDLE_SIGNATURE;\r
-  PrivateData.PS = &mPS;\r
+  PrivateData.PS = &PrivateData.ServiceTableShadow;\r
 \r
   //\r
   // Initialize libraries that the PeiCore is linked against\r
-  // BUGBUG: The FfsHeader is passed in as NULL.  Do we look it up or remove it from the lib init?\r
+  // BUGBUG: The FileHandle is passed in as NULL.  Do we look it up or remove it from the lib init?\r
   //\r
   ProcessLibraryConstructorList (NULL, &PrivateData.PS);\r
 \r
-  InitializeMemoryServices (&PrivateData.PS, SecCoreData, OldCoreData);\r
+  InitializeMemoryServices (&PrivateData, SecCoreData, OldCoreData);\r
 \r
-  InitializePpiServices (&PrivateData.PS, OldCoreData);\r
-\r
-  InitializeSecurityServices (&PrivateData.PS, OldCoreData);\r
-\r
-  InitializeDispatcherData (&PrivateData.PS, OldCoreData, SecCoreData);\r
+  InitializePpiServices (&PrivateData, OldCoreData);\r
 \r
   if (OldCoreData != NULL) {\r
 \r
@@ -219,18 +226,25 @@ Returns:
     //\r
     // If SEC provided any PPI services to PEI, install them.\r
     //\r
-    if (PpiList != NULL) {\r
-      Status = PeiServicesInstallPpi (PpiList);\r
+    if (PpList != NULL) {\r
+      Status = PeiServicesInstallPpi (PpList);\r
       ASSERT_EFI_ERROR (Status);\r
     }\r
   }\r
 \r
-  DispatchData = &PrivateData.DispatchData;\r
+  InitializeSecurityServices (&PrivateData.PS, OldCoreData);\r
+\r
+  InitializeDispatcherData (&PrivateData, OldCoreData, SecCoreData);\r
+\r
+  //\r
+  // Install Pei Load File PPI. \r
+  //\r
+  InitializeImageServices (&PrivateData, OldCoreData);\r
 \r
   //\r
   // Call PEIM dispatcher\r
   //\r
-  PeiDispatcher (SecCoreData, &PrivateData, DispatchData);\r
+  PeiDispatcher (SecCoreData, &PrivateData);\r
 \r
   //\r
   // Check if InstallPeiMemory service was called.\r
index e429b665a28c8ffa7adba12cce8a06ed5b77cb5d..2ee45c44f7c1e5f387565ee9f82e85f171150ac6 100644 (file)
@@ -25,7 +25,7 @@ Revision History
 \r
 VOID\r
 InitializePpiServices (\r
-  IN EFI_PEI_SERVICES  **PeiServices,\r
+  IN PEI_CORE_INSTANCE *PrivateData,\r
   IN PEI_CORE_INSTANCE *OldCoreData\r
   )\r
 /*++\r
@@ -45,11 +45,7 @@ Returns:
 \r
 --*/\r
 {\r
-  PEI_CORE_INSTANCE                    *PrivateData;\r
-  \r
   if (OldCoreData == NULL) {\r
-    PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);\r
-\r
     PrivateData->PpiData.NotifyListEnd = MAX_PPI_DESCRIPTORS-1;\r
     PrivateData->PpiData.DispatchListEnd = MAX_PPI_DESCRIPTORS-1;\r
     PrivateData->PpiData.LastDispatchedNotify = MAX_PPI_DESCRIPTORS-1;\r
@@ -220,7 +216,7 @@ Returns:
   // Dispatch any callback level notifies for newly installed PPIs.\r
   //\r
   DispatchNotify (\r
-    (CONST EFI_PEI_SERVICES **) PeiServices,\r
+    PrivateData,\r
     EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,\r
     LastCallbackInstall,\r
     PrivateData->PpiData.PpiListEnd,\r
@@ -298,7 +294,7 @@ Returns:
   // Dispatch any callback level notifies for the newly installed PPI.\r
   //\r
   DispatchNotify (\r
-    (CONST EFI_PEI_SERVICES **) PeiServices,\r
+    PrivateData,\r
     EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,\r
     Index,\r
     Index+1,\r
@@ -496,7 +492,7 @@ Returns:
   // Dispatch any callback level notifies for all previously installed PPIs.\r
   //\r
   DispatchNotify (\r
-    (CONST EFI_PEI_SERVICES **) PeiServices,\r
+    PrivateData,\r
     EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,\r
     0,\r
     PrivateData->PpiData.PpiListEnd,\r
@@ -511,7 +507,7 @@ Returns:
 \r
 VOID\r
 ProcessNotifyList (\r
-  IN EFI_PEI_SERVICES    **PeiServices\r
+  IN PEI_CORE_INSTANCE  *PrivateData\r
   )\r
 /*++\r
 \r
@@ -528,11 +524,7 @@ Returns:
 --*/\r
 \r
 {\r
-  PEI_CORE_INSTANCE       *PrivateData;\r
   INTN                    TempValue;\r
-\r
-  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);\r
-\r
  \r
   while (TRUE) {\r
     //\r
@@ -545,7 +537,7 @@ Returns:
     while (PrivateData->PpiData.LastDispatchedNotify != PrivateData->PpiData.DispatchListEnd) {\r
       TempValue = PrivateData->PpiData.DispatchListEnd;\r
       DispatchNotify (\r
-        (CONST EFI_PEI_SERVICES **) PeiServices,\r
+        PrivateData,\r
         EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH,\r
         0,\r
         PrivateData->PpiData.LastDispatchedInstall,\r
@@ -566,7 +558,7 @@ Returns:
     while (PrivateData->PpiData.LastDispatchedInstall != PrivateData->PpiData.PpiListEnd) {\r
       TempValue = PrivateData->PpiData.PpiListEnd;\r
       DispatchNotify (\r
-        (CONST EFI_PEI_SERVICES **) PeiServices,\r
+        PrivateData,\r
         EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH,\r
         PrivateData->PpiData.LastDispatchedInstall,\r
         PrivateData->PpiData.PpiListEnd,\r
@@ -585,7 +577,7 @@ Returns:
 \r
 VOID\r
 DispatchNotify (\r
-  IN CONST EFI_PEI_SERVICES    **PeiServices,\r
+  IN PEI_CORE_INSTANCE  *PrivateData,\r
   IN UINTN               NotifyType,\r
   IN INTN                InstallStartIndex,\r
   IN INTN                InstallStopIndex,\r
@@ -612,15 +604,12 @@ Returns:  None
 --*/\r
 \r
 {\r
-  PEI_CORE_INSTANCE       *PrivateData;\r
   INTN                   Index1;\r
   INTN                   Index2;\r
   EFI_GUID                *SearchGuid;\r
   EFI_GUID                *CheckGuid;\r
   EFI_PEI_NOTIFY_DESCRIPTOR   *NotifyDescriptor;\r
 \r
-  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);\r
-\r
   //\r
   // Remember that Installs moves up and Notifies moves down.\r
   //\r
@@ -645,7 +634,7 @@ Returns:  None
           NotifyDescriptor->Notify\r
           ));\r
         NotifyDescriptor->Notify (\r
-                            (EFI_PEI_SERVICES **)PeiServices,\r
+                            GetPeiServicesTablePointer (),\r
                             NotifyDescriptor,\r
                             (PrivateData->PpiData.PpiListPtrs[Index2].Ppi)->Ppi\r
                             );\r
index ef0ceb3b1962d645962093a3af75f6105a70e8f1..2788a0e161a2be1ca899fbc08ff16f01c6692286 100644 (file)
@@ -26,7 +26,7 @@ Revision History
 EFI_STATUS\r
 EFIAPI\r
 PeiResetSystem (\r
-  IN EFI_PEI_SERVICES         **PeiServices\r
+  IN CONST EFI_PEI_SERVICES         **PeiServices\r
   )\r
 /*++\r
 \r
index 089995e5297be166318ba8ed9239779123bc24b5..8fda8bd05595f8b28fa2442fdc8912cc9ff91b9d 100644 (file)
@@ -32,7 +32,7 @@ SecurityPpiNotifyCallback (
 \r
 static EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList = {\r
    EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
-   &gEfiPeiSecurityPpiGuid,\r
+   &gEfiPeiSecurity2PpiGuid,\r
    SecurityPpiNotifyCallback\r
 };\r
 \r
@@ -101,15 +101,16 @@ Returns:
   // If there isn't a security PPI installed, use the one from notification\r
   //\r
   if (PrivateData->PrivateSecurityPpi == NULL) {\r
-    PrivateData->PrivateSecurityPpi = (EFI_PEI_SECURITY_PPI *)Ppi;\r
+    PrivateData->PrivateSecurityPpi = (EFI_PEI_SECURITY2_PPI *)Ppi;\r
   }\r
   return EFI_SUCCESS;\r
 }\r
 \r
 EFI_STATUS\r
 VerifyPeim (\r
-  IN EFI_PEI_SERVICES     **PeiServices,\r
-  IN EFI_FFS_FILE_HEADER  *CurrentPeimAddress\r
+  IN PEI_CORE_INSTANCE      *PrivateData,\r
+  IN EFI_PEI_FV_HANDLE      VolumeHandle,\r
+  IN EFI_PEI_FILE_HANDLE    FileHandle\r
   )\r
 /*++\r
 \r
@@ -129,21 +130,15 @@ Returns:
 \r
 --*/\r
 {\r
-  PEI_CORE_INSTANCE               *PrivateData;\r
   EFI_STATUS                      Status;\r
   UINT32                          AuthenticationStatus;\r
-  BOOLEAN                         StartCrisisRecovery;\r
+  BOOLEAN                         DeferExection;\r
 \r
   //\r
   // Set a default authentication state\r
   //\r
   AuthenticationStatus = 0;\r
 \r
-  //\r
-  // get security PPI instance from PEI private data\r
-  //\r
-  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
-\r
   if (PrivateData->PrivateSecurityPpi == NULL) {\r
     Status = EFI_NOT_FOUND;\r
   } else {\r
@@ -151,13 +146,14 @@ Returns:
     // Check to see if the image is OK\r
     //\r
     Status = PrivateData->PrivateSecurityPpi->AuthenticationState (\r
-                                                PeiServices,\r
+                                                (CONST EFI_PEI_SERVICES **) &PrivateData->PS,\r
                                                 PrivateData->PrivateSecurityPpi,\r
                                                 AuthenticationStatus,\r
-                                                CurrentPeimAddress,\r
-                                                &StartCrisisRecovery\r
+                                                VolumeHandle,\r
+                                                FileHandle,\r
+                                                &DeferExection\r
                                                 );\r
-    if (StartCrisisRecovery) {\r
+    if (DeferExection) {\r
       Status = EFI_SECURITY_VIOLATION;\r
     }\r
   }\r
index 752ed166942783e74bb68c89e75b312db43d4dd8..7d9f5a871c38e4f8698a10552e411bede370e190 100644 (file)
@@ -62,7 +62,6 @@
   gEfiShellFileGuid              = { 0xC57AD6B7, 0x0515, 0x40A8, { 0x9D, 0x21, 0x55, 0x16, 0x52, 0x85, 0x4E, 0x37 }}\r
   gEfiFlashMapHobGuid            = { 0xB091E7D2, 0x05A0, 0x4198, { 0x94, 0xF0, 0x74, 0xB7, 0xB8, 0xC5, 0x54, 0x59 }}\r
   gEfiStandardErrorDeviceGuid    = { 0xD3B36F2D, 0xD551, 0x11D4, { 0x9A, 0x46, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }}\r
-  gEfiPeiCorePrivateGuid         = { 0xd641a0f5, 0xcb7c, 0x4846, { 0xa3, 0x80, 0x1d, 0x01, 0xb4, 0xd9, 0xe3, 0xb9 }}\r
 \r
   gEfiPeiPeCoffLoaderGuid        = { 0xD8117CFF, 0x94A6, 0x11D4, { 0x9A, 0x3A, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }}\r
 \r
index f86444fd69a6023dea9b19a00d1babf053f5044c..ee3bc9803a1c2c04b610284491c1a5f8d83f5c6e 100644 (file)
@@ -71,6 +71,8 @@
   ReportStatusCodeLib|IntelFrameworkModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf\r
   PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf\r
   PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf\r
+  PeCoffLoaderLib|MdeModulePkg/Library/PeiDxePeCoffLoaderLib/PeCoffLoaderLib.inf\r
+\r
 \r
 [LibraryClasses.common.PEIM]\r
   HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf\r
index 0e1555de1043299c923d4ce4b8b96fa6245c0a41..50e0d1067630379359c54c3a552e01957a9e15fb 100644 (file)
@@ -262,6 +262,30 @@ BuildFvHob (
   )\r
 ;\r
 \r
+/**\r
+  Builds a EFI_HOB_TYPE_FV2 HOB.\r
+\r
+  This function builds a EFI_HOB_TYPE_FV2 HOB.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+\r
+  @param  BaseAddress   The base address of the Firmware Volume.\r
+  @param  Length        The size of the Firmware Volume in bytes.\r
+  @param  FvName       The name of the Firmware Volume.\r
+  @param  FileName      The name of the file.\r
+  \r
+**/\r
+VOID\r
+EFIAPI\r
+BuildFv2Hob (\r
+  IN          EFI_PHYSICAL_ADDRESS        BaseAddress,\r
+  IN          UINT64                      Length,\r
+  IN CONST    EFI_GUID                    *FvName,\r
+  IN CONST    EFI_GUID                    *FileName\r
+  )\r
+;\r
+\r
 /**\r
   Builds a Capsule Volume HOB.\r
 \r
diff --git a/MdePkg/Include/Library/PeiPiLib.h b/MdePkg/Include/Library/PeiPiLib.h
new file mode 100644 (file)
index 0000000..a34fd50
--- /dev/null
@@ -0,0 +1,30 @@
+/** @file\r
+  MDE PI library functions and macros for PEI phase\r
+\r
+  Copyright (c) 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
+**/\r
+\r
+#ifndef __PEI_PI_LIB_H__\r
+#define __PEI_PI_LIB_H__\r
+\r
+#include <Pi/PiFirmwareFile.h>\r
+\r
+VOID\r
+EFIAPI\r
+PeiPiLibBuildPiFvInfoPpi (\r
+  IN EFI_PHYSICAL_ADDRESS    FvStart,\r
+  IN UINT64                  FvLength,\r
+  IN EFI_GUID                *ParentFvName,\r
+  IN EFI_GUID                *PraentFileName\r
+);\r
+\r
+#endif\r
+\r
index 3d0deb9ba49e50d2f8d8cabbc2bf0284d6a25dba..2d028239d737155f09be01f0550ce4bb5ad3ded4 100644 (file)
@@ -293,4 +293,35 @@ PeiServicesResetSystem (
   );\r
 \r
 \r
+EFI_STATUS\r
+EFIAPI\r
+PeiServicesFfsFindByName (\r
+  IN CONST  EFI_GUID            *FileName,\r
+  IN CONST  EFI_PEI_FV_HANDLE   VolumeHandle,\r
+  OUT       EFI_PEI_FILE_HANDLE *FileHandle\r
+  );\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI \r
+PeiServicesFfsGetFileInfo (\r
+  IN CONST  EFI_PEI_FILE_HANDLE   FileHandle,\r
+  OUT EFI_FV_FILE_INFO            *FileInfo\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiServicesFfsGetVolumeInfo (\r
+  IN  EFI_PEI_FV_HANDLE       VolumeHandle,\r
+  OUT EFI_FV_INFO             *VolumeInfo\r
+  );\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiServicesRegisterForShadow (\r
+  IN  EFI_PEI_FILE_HANDLE FileHandle\r
+  );\r
+\r
+\r
 #endif\r
index ede033773034e40ff17710fd652412d5132782fa..7a602f9041126c67aae6bb4a6f736771e739267f 100644 (file)
@@ -30,5 +30,11 @@ GetPeiServicesTablePointer (
   VOID\r
   );\r
 \r
+VOID\r
+EFIAPI\r
+SetPeiServicesTablePointer (\r
+  EFI_PEI_SERVICES ** PeiServicesTablePointer\r
+  );\r
+\r
 #endif\r
 \r
index d15a712678067981bccf443ed63998fb76b10f16..8aaad25058b1422dbbbb615868559778ca759d64 100644 (file)
@@ -75,6 +75,233 @@ GetSectionFromFvFile (
   )\r
 ;\r
 \r
+/**\r
+  Identify the device handle from which the Image is loaded from. As this device handle is passed to\r
+  GetSectionFromFv as the identifier for a Firmware Volume, an EFI_FIRMWARE_VOLUME2_PROTOCOL \r
+  protocol instance should be located succesfully by calling gBS->HandleProtocol ().\r
+\r
+  This function locates the EFI_LOADED_IMAGE_PROTOCOL instance installed\r
+  on ImageHandle. It then returns EFI_LOADED_IMAGE_PROTOCOL.DeviceHandle.\r
+  \r
+  If ImageHandle is NULL, then ASSERT ();\r
+  If failed to locate a EFI_LOADED_IMAGE_PROTOCOL on ImageHandle, then ASSERT ();\r
+  \r
+  @param  ImageHandle         The firmware allocated handle for UEFI image.\r
+\r
+  @retval  EFI_HANDLE          The device handle from which the Image is loaded from.\r
+\r
+**/\r
+\r
+EFI_HANDLE\r
+EFIAPI\r
+ImageHandleToFvHandle (\r
+  EFI_HANDLE ImageHandle\r
+  )\r
+;\r
+\r
+/**\r
+    Allocate and fill a buffer from the Firmware Section identified by a Firmware File GUID name and a Firmware \r
+    Section type and instance number from the any Firmware Volumes in the system.\r
+  \r
+    The function will read the first Firmware Section found sepcifed by NameGuid and SectionType from the \r
+    any Firmware Volume in the system. \r
+\r
+    The search order for Firmware Volumes in the system is determistic but abitrary if no new Firmware Volume is installed\r
+    into the system. The search order for the section specified by SectionType within a Firmware File is defined by\r
+    EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection (). Please check Section 2.4 of Volume 3: Platform Initialization \r
+    Shared Architectural Elements for detailes.\r
+    \r
+    If SectionType is EFI_SECTION_TE, EFI_SECTION_TE will be used as Firmware Section type to read Firmware Section \r
+    data from the Firmware File. If no such section exists, EFI_SECTION_PE32 will be used as Firmware Section type to \r
+    read Firmware Section data from the Firmware File. If no such section specified is found to match , \r
+    EFI_NOT_FOUND is returned.\r
+\r
+    The data and size is returned by Buffer and Size. The caller is responsible to free the Buffer allocated \r
+    by this function. This function can only be called at TPL_NOTIFY and below.\r
+    \r
+    If NameGuid is NULL, then ASSERT();\r
+    If Buffer is NULL, then ASSERT();\r
+    If Size is NULL, then ASSERT().\r
+  \r
+    @param  NameGuid             The GUID name of a Firmware File.\r
+    @param  SectionType         The Firmware Section type.\r
+    @param  Instance              The instance number of Firmware Section to read from starting from 0.\r
+    @param  Buffer                  On output, Buffer contains the the data read from the section in the Firmware File found.\r
+    @param  Size                    On output, the size of Buffer.\r
+  \r
+    @retval  EFI_SUCCESS        The image is found and data and size is returned.\r
+    @retval  EFI_NOT_FOUND      The image specified by NameGuid and SectionType can't be found.\r
+    @retval  EFI_OUT_OF_RESOURCES There were not enough resources to allocate the output data buffer or complete the operations.\r
+    @retval  EFI_DEVICE_ERROR A hardware error occurs during reading from the Firmware Volume.\r
+    @retval  EFI_ACCESS_DENIED  The firmware volume containing the searched Firmware File is configured to disallow reads.\r
+  \r
+  **/\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+GetSectionFromAnyFv (\r
+  IN  CONST EFI_GUID                *NameGuid,\r
+  IN  EFI_SECTION_TYPE              SectionType,\r
+  IN  UINTN                         Instance,\r
+  OUT VOID                          **Buffer,\r
+  OUT UINTN                         *Size\r
+  )\r
+;\r
+\r
+/**\r
+    Allocate and fill a buffer from a Firmware Section identified by a Firmware File GUID name, a Firmware \r
+    Section type and instance number from the specified Firmware Volume.\r
+  \r
+    This functions first locate the EFI_FIRMWARE_VOLUME2_PROTOCOL protocol instance on FvHandle in order to \r
+    carry out the Firmware Volume read operation. The function then reads the Firmware Section found sepcifed \r
+    by NameGuid, SectionType and Instance. \r
+    \r
+    The search order for the section specified by SectionType within a Firmware File is defined by\r
+    EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection (). Please check Section 2.4 of Volume 3: Platform Initialization \r
+    Shared Architectural Elements for detailes.\r
+    \r
+    If SectionType is EFI_SECTION_TE, EFI_SECTION_TE will be used as Firmware Section type to read Firmware Section \r
+    data from the Firmware File. If no such section exists, EFI_SECTION_PE32 will be used as Firmware Section type to \r
+    read Firmware Section data from the Firmware File. If no such section specified is found to match , \r
+    EFI_NOT_FOUND is returned.\r
+    \r
+    The data and size is returned by Buffer and Size. The caller is responsible to free the Buffer allocated \r
+    by this function. This function can be only called at TPL_NOTIFY and below.\r
+    \r
+    If FvHandle is NULL, then ASSERT ();\r
+    If NameGuid is NULL, then ASSERT();\r
+    If Buffer is NULL, then ASSERT();\r
+    If Size is NULL, then ASSERT().\r
+\r
+    @param  FvHandle              The device handle that contains a instance of EFI_FIRMWARE_VOLUME2_PROTOCOL instance.\r
+    @param  NameGuid             The GUID name of a Firmware File.\r
+    @param  SectionType         The Firmware Section type.\r
+    @param  Instance              The instance number of Firmware Section to read from starting from 0.\r
+    @param  Buffer                  On output, Buffer contains the the data read from the section in the Firmware File found.\r
+    @param  Size                    On output, the size of Buffer.\r
+  \r
+    @retval  EFI_SUCCESS        The image is found and data and size is returned.\r
+    @retval  EFI_UNSUPPORTED   FvHandle does not support EFI_FIRMWARE_VOLUME2_PROTOCOL.\r
+    @retval  EFI_NOT_FOUND      The image specified by NameGuid and SectionType can't be found.\r
+    @retval  EFI_OUT_OF_RESOURCES There were not enough resources to allocate the output data buffer or complete the operations.\r
+    @retval  EFI_DEVICE_ERROR A hardware error occurs during reading from the Firmware Volume.\r
+    @retval  EFI_ACCESS_DENIED  The firmware volume containing the searched Firmware File is configured to disallow reads.\r
+  \r
+  **/\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+GetSectionFromFv (\r
+  IN  EFI_HANDLE                    FvHandle,\r
+  IN  CONST EFI_GUID                *NameGuid,\r
+  IN  EFI_SECTION_TYPE              SectionType,\r
+  IN  UINTN                         Instance,\r
+  OUT VOID                          **Buffer,\r
+  OUT UINTN                         *Size\r
+  )\r
+;\r
+\r
+/**\r
+    Allocate and fill a buffer from a Firmware Section identified by a Firmware File GUID name, a Firmware \r
+    Section type and instance number from the same Firmware Volume with the caller's FFS.\r
+  \r
+    This functions first locates the EFI_FIRMWARE_VOLUME2_PROTOCOL protocol instance for same Firmrware Volume\r
+    which also contains the FFS of the caller in order to carry out the Firmware Volume read operation. \r
+    The function then reads the Firmware Section found sepcifed by NameGuid, SectionType and Instance. \r
+    \r
+    The search order for the section specified by SectionType within a Firmware File is defined by\r
+    EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection (). Please check Section 2.4 of Volume 3: Platform Initialization \r
+    Shared Architectural Elements for detailes.\r
+    \r
+    If SectionType is EFI_SECTION_TE, EFI_SECTION_TE will be used as Firmware Section type to read Firmware Section \r
+    data from the Firmware File. If no such section exists, EFI_SECTION_PE32 will be used as Firmware Section type to \r
+    read Firmware Section data from the Firmware File. If no such section specified is found to match , \r
+    EFI_NOT_FOUND is returned.\r
+    \r
+    The data and size is returned by Buffer and Size. The caller is responsible to free the Buffer allocated \r
+    by this function. This function can be only called at TPL_NOTIFY and below.\r
+    \r
+    If FvHandle is NULL, then ASSERT ();\r
+    If NameGuid is NULL, then ASSERT();\r
+    If Buffer is NULL, then ASSERT();\r
+    If Size is NULL, then ASSERT().\r
+\r
+    @param  NameGuid             The GUID name of a Firmware File.\r
+    @param  SectionType         The Firmware Section type.\r
+    @param  Instance              The instance number of Firmware Section to read from starting from 0.\r
+    @param  Buffer                  On output, Buffer contains the the data read from the section in the Firmware File found.\r
+    @param  Size                    On output, the size of Buffer.\r
+  \r
+    @retval  EFI_SUCCESS        The image is found and data and size is returned.\r
+    @retval  EFI_UNSUPPORTED   FvHandle does not support EFI_FIRMWARE_VOLUME2_PROTOCOL.\r
+    @retval  EFI_NOT_FOUND      The image specified by NameGuid and SectionType can't be found.\r
+    @retval  EFI_OUT_OF_RESOURCES There were not enough resources to allocate the output data buffer or complete the operations.\r
+    @retval  EFI_DEVICE_ERROR A hardware error occurs during reading from the Firmware Volume.\r
+    @retval  EFI_ACCESS_DENIED  The firmware volume containing the searched Firmware File is configured to disallow reads.\r
+  \r
+  **/\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+GetSectionFromCurrentFv (\r
+  IN  CONST EFI_GUID                *NameGuid,\r
+  IN  EFI_SECTION_TYPE              SectionType,\r
+  IN  UINTN                         Instance,\r
+  OUT VOID                          **Buffer,\r
+  OUT UINTN                         *Size\r
+  )\r
+;\r
+\r
+\r
+/**\r
+    Allocate and fill a buffer from the first Firmware Section in the same Firmware File as the caller of this function.\r
+  \r
+    The function will read the first Firmware Section found sepcifed by NameGuid and SectionType from the \r
+    Firmware Volume specified by FvHandle. On this FvHandle, an EFI_FIRMWARE_VOLUME2_PROTOCOL protocol instance \r
+    should be located succesfully in order to carry out the Firmware Volume operations.\r
+    \r
+    The search order for the section type specified by SectionType in the Firmware File is using a depth-first \r
+    and left-to-right algorithm through all sections. The first section found to match SectionType will be returned. \r
+    \r
+    If SectionType is EFI_SECTION_PE32, EFI_SECTION_PE32 will be used as Firmware Section type \r
+    to read Firmware Section data from the Firmware File. If no such section exists, the function will try \r
+    to read a Firmware File named with NameGuid. If no such file exists, EFI_NOT_FOUND is returned.\r
+    \r
+    If SectionType is EFI_SECTION_TE, EFI_SECTION_TE will be used as Firmware Section type to read Firmware Section \r
+    data from the Firmware File. If no such section exists, EFI_SECTION_PE32 will be used as Firmware Section type to \r
+    read Firmware Section data from the Firmware File. If no such section exists, the function will try to read a Firmware \r
+    File named with NameGuid. If no such file exists, EFI_NOT_FOUND is returned.\r
+    \r
+    The data and size is returned by Buffer and Size. The caller is responsible to free the Buffer allocated \r
+    by this function. This function can only be called at TPL_NOTIFY and below.\r
+    \r
+    If FvHandle is NULL and WithinImage is TRUE, then ASSERT ();\r
+    If NameGuid is NULL, then ASSERT();\r
+    If Buffer is NULL, then ASSERT();\r
+    If Size is NULL, then ASSERT().\r
+  \r
+    @param  NameGuid             The GUID name of a Firmware File.\r
+    @param  SectionType         The Firmware Section type.\r
+    @param  Buffer                  On output, Buffer contains the the data read from the section in the Firmware File found.\r
+    @param  Size                    On output, the size of Buffer.\r
+  \r
+    @retval  EFI_SUCCESS        The image is found and data and size is returned.\r
+    @retval  EFI_NOT_FOUND      The image specified by NameGuid and SectionType can't be found.\r
+    @retval  EFI_OUT_OF_RESOURCES There were not enough resources to allocate the output data buffer or complete the operations.\r
+    @retval  EFI_DEVICE_ERROR A hardware error occurs during reading from the Firmware Volume.\r
+    @retval  EFI_ACCESS_DENIED  The firmware volume containing the searched Firmware File is configured to disallow reads.\r
+  \r
+  **/\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+GetSectionFromCurrentFfs (\r
+  IN  EFI_SECTION_TYPE              SectionType,\r
+  IN  UINTN                         Instance,\r
+  OUT VOID                          **Buffer,\r
+  OUT UINTN                         *Size\r
+  )\r
+;\r
 \r
 #endif\r
 \r
index 4d95c7fbd80fd145137d95b058852f520511db9d..d75a79c6b70f905b22a8a4c985ca3cc94f704d66 100644 (file)
@@ -51,8 +51,8 @@ typedef struct _EFI_PEI_NOTIFY_DESCRIPTOR EFI_PEI_NOTIFY_DESCRIPTOR;
 typedef\r
 EFI_STATUS\r
 (EFIAPI *EFI_PEIM_ENTRY_POINT2)(\r
-  IN EFI_PEI_FILE_HANDLE       *FileHandle,\r
-  IN EFI_PEI_SERVICES          **PeiServices\r
+  IN EFI_PEI_FILE_HANDLE             FileHandle,\r
+  IN CONST EFI_PEI_SERVICES          **PeiServices\r
   );\r
 \r
 /**\r
@@ -491,7 +491,7 @@ EFI_STATUS
 typedef\r
 EFI_STATUS\r
 (EFIAPI *EFI_PEI_RESET_SYSTEM) (\r
-  IN EFI_PEI_SERVICES   **PeiServices\r
+  IN CONST EFI_PEI_SERVICES   **PeiServices\r
   );\r
 \r
 /**\r
index 3261e08ade6db7cec3a77da643cc1b37b23d1ca1..32e0337c19c97e2b073134431e4f6b6524b9a55c 100644 (file)
@@ -16,6 +16,7 @@
 #include <Library/DebugLib.h>\r
 #include <Library/MemoryAllocationLib.h>\r
 #include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/PiLib.h>\r
 #include <Protocol/FirmwareVolume2.h>\r
 #include <Protocol/LoadedImage.h>\r
 \r
@@ -40,7 +41,7 @@
 **/\r
 STATIC\r
 EFI_STATUS\r
-GetImageFromFv (\r
+InternalGetImageFromFv (\r
   IN         EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv,\r
   IN  CONST  EFI_GUID           *NameGuid,\r
   IN         EFI_SECTION_TYPE   SectionType,\r
@@ -193,7 +194,7 @@ GetSectionFromFvFile (
                     (VOID **) &ImageFv\r
                     );\r
     if (!EFI_ERROR (Status)) {\r
-      Status = GetImageFromFv (ImageFv, NameGuid, SectionType, Buffer, Size);\r
+      Status = InternalGetImageFromFv (ImageFv, NameGuid, SectionType, Buffer, Size);\r
     }\r
   }\r
 \r
@@ -231,7 +232,7 @@ GetSectionFromFvFile (
       continue;\r
     }\r
 \r
-    Status = GetImageFromFv (Fv, NameGuid, SectionType, Buffer, Size);\r
+    Status = InternalGetImageFromFv (Fv, NameGuid, SectionType, Buffer, Size);\r
 \r
     if (!EFI_ERROR (Status)) {\r
       goto Done;\r
@@ -254,3 +255,216 @@ Done:
   return Status;\r
 }\r
 \r
+EFI_HANDLE\r
+EFIAPI\r
+ImageHandleToFvHandle (\r
+  EFI_HANDLE ImageHandle\r
+  )\r
+{\r
+  EFI_STATUS                    Status;\r
+  EFI_LOADED_IMAGE_PROTOCOL     *LoadedImage;\r
+  \r
+  ASSERT (ImageHandle != NULL);\r
+\r
+  Status = gBS->HandleProtocol (\r
+             (EFI_HANDLE *) ImageHandle,\r
+             &gEfiLoadedImageProtocolGuid,\r
+             (VOID **) &LoadedImage\r
+             );\r
+\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return LoadedImage->DeviceHandle;\r
+\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+GetSectionFromAnyFv (\r
+  IN CONST  EFI_GUID           *NameGuid,\r
+  IN        EFI_SECTION_TYPE   SectionType,\r
+  IN        UINTN              Instance,\r
+  OUT       VOID               **Buffer,\r
+  OUT       UINTN              *Size\r
+  )\r
+{\r
+  EFI_STATUS                    Status;\r
+  EFI_HANDLE                    *HandleBuffer;\r
+  UINTN                         HandleCount;\r
+  UINTN                         Index;\r
+  EFI_HANDLE                    FvHandle;\r
+  EFI_TPL                       OldTpl;\r
+\r
+  //\r
+  // Search the FV that contain the caller's FFS first.\r
+  // FV builder can choose to build FFS into the this FV\r
+  // so that this implementation of GetSectionFromAnyFv\r
+  // will locate the FFS faster.\r
+  //\r
+  FvHandle = ImageHandleToFvHandle (gImageHandle);\r
+  Status = GetSectionFromFv (\r
+             FvHandle,\r
+             NameGuid,\r
+             SectionType,\r
+             Instance,\r
+             Buffer,\r
+             Size\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+  \r
+  HandleBuffer = NULL;\r
+  Status = gBS->LocateHandleBuffer (\r
+                  ByProtocol,\r
+                  &gEfiFirmwareVolume2ProtocolGuid,\r
+                  NULL,\r
+                  &HandleCount,\r
+                  &HandleBuffer\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+\r
+  for (Index = 0; Index < HandleCount; ++Index) {\r
+    //\r
+    // Skip the FV that contain the caller's FFS\r
+    //\r
+    if (HandleBuffer[Index] == FvHandle) {\r
+      continue;\r
+    }\r
+\r
+    Status = GetSectionFromFv (\r
+               HandleBuffer[Index], \r
+               NameGuid, \r
+               SectionType, \r
+               Instance,\r
+               Buffer, \r
+               Size\r
+               );\r
+\r
+    if (!EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+  }\r
+\r
+  if (Index == HandleCount) {\r
+    Status = EFI_NOT_FOUND;\r
+  }\r
+\r
+Done:\r
+  \r
+  gBS->RestoreTPL (OldTpl);\r
+  \r
+  if (HandleBuffer != NULL) {  \r
+    FreePool(HandleBuffer);\r
+  }\r
+  return Status;\r
+  \r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+GetSectionFromFv (\r
+  IN  EFI_HANDLE                    FvHandle,\r
+  IN  CONST EFI_GUID                *NameGuid,\r
+  IN  EFI_SECTION_TYPE              SectionType,\r
+  IN  UINTN                         Instance,\r
+  OUT VOID                          **Buffer,\r
+  OUT UINTN                         *Size\r
+  )\r
+{\r
+  EFI_STATUS                    Status;\r
+  EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;\r
+  UINT32                        AuthenticationStatus;\r
+\r
+  ASSERT (FvHandle != NULL);\r
+\r
+  Status = gBS->HandleProtocol (\r
+                  FvHandle,\r
+                  &gEfiFirmwareVolume2ProtocolGuid,\r
+                  (VOID **) &Fv\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Read desired section content in NameGuid file\r
+  //\r
+  *Buffer     = NULL;\r
+  *Size       = 0;\r
+  Status      = Fv->ReadSection (\r
+                      Fv,\r
+                      NameGuid,\r
+                      SectionType,\r
+                      0,\r
+                      Buffer,\r
+                      Size,\r
+                      &AuthenticationStatus\r
+                      );\r
+\r
+  if (EFI_ERROR (Status) && (SectionType == EFI_SECTION_TE)) {\r
+    //\r
+    // Try reading PE32 section, if the required section is TE type \r
+    //\r
+    *Buffer = NULL;\r
+    *Size   = 0;\r
+    Status  = Fv->ReadSection (\r
+                    Fv,\r
+                    NameGuid,\r
+                    EFI_SECTION_PE32,\r
+                    0,\r
+                    Buffer,\r
+                    Size,\r
+                    &AuthenticationStatus\r
+                    );\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+GetSectionFromCurrentFv (\r
+  IN  CONST EFI_GUID                *NameGuid,\r
+  IN  EFI_SECTION_TYPE              SectionType,\r
+  IN  UINTN                         Instance,\r
+  OUT VOID                          **Buffer,\r
+  OUT UINTN                         *Size\r
+    )\r
+{\r
+  return GetSectionFromFv(\r
+          ImageHandleToFvHandle(gImageHandle),\r
+          NameGuid,\r
+          SectionType,\r
+          Instance,\r
+          Buffer,\r
+          Size\r
+          );\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+GetSectionFromCurrentFfs (\r
+  IN  EFI_SECTION_TYPE              SectionType,\r
+  IN  UINTN                         Instance,\r
+  OUT VOID                          **Buffer,\r
+  OUT UINTN                         *Size\r
+    )\r
+{\r
+  return GetSectionFromFv(\r
+          ImageHandleToFvHandle(gImageHandle),\r
+          &gEfiCallerIdGuid,\r
+          SectionType,\r
+          Instance,\r
+          Buffer,\r
+          Size\r
+          );\r
+}\r
+\r
diff --git a/MdePkg/Library/PeiPiLib/PeiPiLib.c b/MdePkg/Library/PeiPiLib/PeiPiLib.c
new file mode 100644 (file)
index 0000000..49894df
--- /dev/null
@@ -0,0 +1,67 @@
+/** @file\r
+  MDE PI library functions and macros for PEI phase\r
+\r
+  Copyright (c) 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
+**/\r
+\r
+#include <PiPei.h>\r
+#include <Ppi/FirmwareVolumeInfo.h>\r
+#include <Guid/FirmwareFileSystem2.h>\r
+\r
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/PeiServicesLib.h>\r
+#include <Library/PeiPiLib.h>\r
+\r
+\r
+STATIC CONST EFI_PEI_FIRMWARE_VOLUME_INFO_PPI mFvInfoPpiTemplate = {\r
+  EFI_FIRMWARE_FILE_SYSTEM2_GUID,\r
+  NULL,\r
+  0,    //FvInfoSize\r
+  NULL, //ParentFvName\r
+  NULL //ParentFileName;\r
+};\r
+\r
+VOID\r
+EFIAPI\r
+PeiPiLibBuildPiFvInfoPpi (\r
+  IN EFI_PHYSICAL_ADDRESS    FvStart,\r
+  IN UINT64                  FvLength,\r
+  IN EFI_GUID                *ParentFvName,\r
+  IN EFI_GUID                *ParentFileName\r
+  ) {\r
+  \r
+  EFI_STATUS                       Status;   \r
+  EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *FvInfoPpi;\r
+  EFI_PEI_PPI_DESCRIPTOR           *FvInfoPpiDescriptor;\r
+\r
+  FvInfoPpi = AllocateCopyPool (sizeof (*FvInfoPpi), &mFvInfoPpiTemplate);\r
+  ASSERT( FvInfoPpi != NULL);\r
+\r
+  FvInfoPpi->FvInfo = (VOID *) (UINTN) FvStart;\r
+  FvInfoPpi->FvInfoSize = (UINT32) FvLength;\r
+  FvInfoPpi->ParentFvName = ParentFvName;\r
+  FvInfoPpi->ParentFileName = ParentFileName;\r
+\r
+\r
+  FvInfoPpiDescriptor = AllocatePool (sizeof(EFI_PEI_PPI_DESCRIPTOR));\r
+  ASSERT (FvInfoPpiDescriptor != NULL);\r
+\r
+  FvInfoPpiDescriptor->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;\r
+  FvInfoPpiDescriptor->Guid  = &gEfiPeiFirmwareVolumeInfoPpiGuid;\r
+  FvInfoPpiDescriptor->Ppi   = (VOID *) FvInfoPpi;\r
+  Status = PeiServicesInstallPpi (FvInfoPpiDescriptor);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+   \r
+}\r
+\r
diff --git a/MdePkg/Library/PeiPiLib/PeiPiLib.inf b/MdePkg/Library/PeiPiLib/PeiPiLib.inf
new file mode 100644 (file)
index 0000000..61e9061
--- /dev/null
@@ -0,0 +1,50 @@
+#/** @file\r
+# Component description file library instance for PiLib for PEI phase.\r
+#\r
+# Library to abstract utility functions that is related to PI Specification.\r
+#\r
+# Copyright (c) 2007, Intel Corporation.\r
+#\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
+#  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
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = PeiPiLib\r
+  FILE_GUID                      = 6196FE81-4FA4-469a-B759-2C4DFE935B79\r
+  MODULE_TYPE                    = PEIM\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = PiLib|PEIM\r
+  EDK_RELEASE_VERSION            = 0x00020000\r
+  EFI_SPECIFICATION_VERSION      = 0x00020000\r
+\r
+\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources.common]\r
+  PeiPiLib.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+\r
+\r
+[LibraryClasses]\r
+  MemoryAllocationLib\r
+  DebugLib\r
+\r
+[Guids]\r
+\r
+[Ppis]\r
+  gEfiPeiFirmwareVolumeInfoPpiGuid\r
+\r
+\r
+\r
index c5b12be721718d519d4dabd7850710ce21dc5559..29aaaaa235e94196df250f554ba0cb75895686f4 100644 (file)
@@ -379,9 +379,58 @@ EFIAPI
 PeiServicesResetSystem (\r
   VOID\r
   )\r
+{\r
+  CONST EFI_PEI_SERVICES **PeiServices;\r
+\r
+  PeiServices = (CONST EFI_PEI_SERVICES **) GetPeiServicesTablePointer ();\r
+  return (*PeiServices)->ResetSystem (PeiServices);\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiServicesRegisterForShadow (\r
+  IN  EFI_PEI_FILE_HANDLE FileHandle\r
+  )\r
 {\r
   EFI_PEI_SERVICES **PeiServices;\r
 \r
   PeiServices = GetPeiServicesTablePointer ();\r
-  return (*PeiServices)->ResetSystem (PeiServices);\r
+  return (*PeiServices)->RegisterForShadow (FileHandle);\r
 }\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiServicesFfsGetFileInfo (\r
+  IN CONST  EFI_PEI_FILE_HANDLE   FileHandle,\r
+  OUT EFI_FV_FILE_INFO            *FileInfo\r
+  )\r
+{\r
+  EFI_PEI_SERVICES **PeiServices;\r
+\r
+  PeiServices = GetPeiServicesTablePointer ();\r
+  return (*PeiServices)->FfsGetFileInfo (FileHandle, FileInfo);\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiServicesFfsFindFileByName (\r
+  IN CONST  EFI_GUID            *FileName,\r
+  IN CONST  EFI_PEI_FV_HANDLE   VolumeHandle,\r
+  OUT       EFI_PEI_FILE_HANDLE *FileHandle\r
+  )\r
+{\r
+  return (*GetPeiServicesTablePointer())->FfsFindFileByName (FileName, VolumeHandle, FileHandle);\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiServicesFfsGetVolumeInfo (\r
+  IN  EFI_PEI_FV_HANDLE       VolumeHandle,\r
+  OUT EFI_FV_INFO             *VolumeInfo\r
+  )\r
+{\r
+  return (*GetPeiServicesTablePointer())->FfsGetVolumeInfo (VolumeHandle, VolumeInfo);\r
+}\r
+\r
index 49c233ce73f1bea0d335df46074363348159576e..54a500a7326b1ff3aa25126ab6579b6185721c4d 100644 (file)
 \r
 static EFI_PEI_SERVICES  **gPeiServices;\r
 \r
+VOID\r
+EFIAPI\r
+SetPeiServicesTablePointer (\r
+  EFI_PEI_SERVICES  **PeiServices\r
+  )\r
+{\r
+  gPeiServices = PeiServices;\r
+}\r
+\r
 /**\r
   The function returns the pointer to PEI services.\r
 \r
index d26a0be939061802a52cba73cc51841e6411d423..4c439ebd5f6a4cac9b8fda8f16b69906ddbff4a7 100644 (file)
 #include <Library/BaseLib.h>\r
 #include <Library/DebugLib.h>\r
 \r
+VOID\r
+EFIAPI\r
+SetPeiServicesTablePointer (\r
+  IN EFI_PEI_SERVICES     **PeiServices\r
+  )\r
+{\r
+  AsmWriteMm7 ((UINT64)(UINTN)PeiServices);\r
+}\r
+\r
 /**\r
   The function returns the pointer to PeiServices.\r
 \r
index c7c8d97715aecca97dd37b16372ad1b9bc8cb692..4f0e19dd6d704d47add5cbec2b7c2042333edec1 100644 (file)
@@ -82,6 +82,7 @@
   MdePkg/Library/PeiMemoryLib/PeiMemoryLib.inf\r
   MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf\r
   MdePkg/Library/PeiPcdLib/PeiPcdLib.inf\r
+  MdePkg/Library/PeiPiLib/PeiPiLib.inf\r
   MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf\r
   MdePkg/Library/PeiServicesLib/PeiServicesLib.inf\r
   MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf\r
index 8eaa2aba432bbd929e07f62830c832c19f0842c8..3d5353b4238082fc981734edaf5cc97dd62f29ad 100644 (file)
@@ -21,35 +21,30 @@ Abstract:
 --*/\r
 \r
 #include <PiPei.h>\r
+#include <Library/DebugLib.h>\r
 #include <Guid/PeiPeCoffLoader.h>\r
-#include <Library/PeCoffLoaderLib.h>\r
+#include <Library/PeCoffLoaderLib.h>  \r
+#include <Library/PeiServicesLib.h>\r
 \r
 \r
-EFI_PEI_PE_COFF_LOADER_PROTOCOL  *mPeiEfiPeiPeCoffLoader;\r
+EFI_PEI_PE_COFF_LOADER_PROTOCOL  *mPeiEfiPeiPeCoffLoader = NULL;\r
 \r
-EFI_STATUS\r
-EFIAPI\r
-PeCoffLoaderConstructor (\r
-  IN EFI_FFS_FILE_HEADER      *FfsHeader,\r
-  IN EFI_PEI_SERVICES          **PeiServices\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-\r
-  Status = (*PeiServices)->LocatePpi (\r
-                            PeiServices,\r
-                            &gEfiPeiPeCoffLoaderGuid,\r
-                            0,\r
-                            NULL,\r
-                            &mPeiEfiPeiPeCoffLoader\r
-                            );\r
-  return Status;\r
-}\r
 \r
 EFI_PEI_PE_COFF_LOADER_PROTOCOL *\r
 EFIAPI\r
 GetPeCoffLoaderProtocol (\r
   )\r
 {\r
+  EFI_STATUS Status;\r
+  \r
+  if (mPeiEfiPeiPeCoffLoader == NULL) {\r
+    Status = PeiServicesLocatePpi(\r
+                              &gEfiPeiPeCoffLoaderGuid,\r
+                              0,\r
+                              NULL,\r
+                              (VOID **) &mPeiEfiPeiPeCoffLoader\r
+                              );\r
+    ASSERT_EFI_ERROR (Status);\r
+   }\r
   return mPeiEfiPeiPeCoffLoader;\r
 }\r
index 04a010291954cd9ddfc47fab62af8cd33f2f7e84..d6a57b22b0af68e667da7f521f58ac75a4488f17 100644 (file)
@@ -24,8 +24,6 @@
   EDK_RELEASE_VERSION            = 0x00020000\r
   EFI_SPECIFICATION_VERSION      = 0x00020000\r
 \r
-  CONSTRUCTOR                    = PeCoffLoaderConstructor\r
-\r
 #\r
 # The following information is for reference only and not required by the build tools.\r
 #\r
index 01a725a8d8735c92e913faa064621e586d4dc596..98ed118f8b31acb6d83073562bd4fe2096aa0353 100644 (file)
   PeCoffGetEntryPointLib|Nt32Pkg/Library/Nt32PeiPeCoffGetEntryPointLib/Nt32PeiPeCoffGetEntryPointLib.inf\r
   PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf\r
   DebugLib|IntelFrameworkModulePkg/Library/PeiDxeDebugLibReportStatusCode/PeiDxeDebugLibReportStatusCode.inf\r
+  PeCoffLoaderLib|Nt32Pkg/Library/Nt32PeCoffLoaderLib/Nt32PeCoffLoaderLib.inf\r
 \r
 [LibraryClasses.common.DXE_RUNTIME_DRIVER]\r
   UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf\r