DxeLoad.c revision 48557c6550adecf39e1e8e140b1736275d070dfb
196226baa2884ba0776dec3431f84b20cb3062915qhuang/** @file
2b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  Last PEIM.
3b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  Responsibility of this module is to load the DXE Core from a Firmware Volume.
495276127e373f2e2fb2a208ff77267422a197d9fxgu
596226baa2884ba0776dec3431f84b20cb3062915qhuangCopyright (c) 2006 - 2008, Intel Corporation. <BR>
695276127e373f2e2fb2a208ff77267422a197d9fxguAll rights reserved. This program and the accompanying materials
795276127e373f2e2fb2a208ff77267422a197d9fxguare licensed and made available under the terms and conditions of the BSD License
895276127e373f2e2fb2a208ff77267422a197d9fxguwhich accompanies this distribution.  The full text of the license may be found at
995276127e373f2e2fb2a208ff77267422a197d9fxguhttp://opensource.org/licenses/bsd-license.php
1095276127e373f2e2fb2a208ff77267422a197d9fxgu
1195276127e373f2e2fb2a208ff77267422a197d9fxguTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
1295276127e373f2e2fb2a208ff77267422a197d9fxguWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
1395276127e373f2e2fb2a208ff77267422a197d9fxgu
14b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu**/
1595276127e373f2e2fb2a208ff77267422a197d9fxgu
1695276127e373f2e2fb2a208ff77267422a197d9fxgu#include "DxeIpl.h"
17b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
1895276127e373f2e2fb2a208ff77267422a197d9fxgu
1995276127e373f2e2fb2a208ff77267422a197d9fxgu//
2048557c6550adecf39e1e8e140b1736275d070dfbqhuang// Module Globals used in the DXE to PEI hand off
2195276127e373f2e2fb2a208ff77267422a197d9fxgu// These must be module globals, so the stack can be switched
2295276127e373f2e2fb2a208ff77267422a197d9fxgu//
239b937a73b079d7368cf309247585e63e6a4afbecqhuangCONST EFI_DXE_IPL_PPI mDxeIplPpi = {
2495276127e373f2e2fb2a208ff77267422a197d9fxgu  DxeLoadCore
2595276127e373f2e2fb2a208ff77267422a197d9fxgu};
2695276127e373f2e2fb2a208ff77267422a197d9fxgu
279b937a73b079d7368cf309247585e63e6a4afbecqhuangCONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI mCustomGuidedSectionExtractionPpi = {
2818fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  CustomGuidedSectionExtract
2995276127e373f2e2fb2a208ff77267422a197d9fxgu};
3095276127e373f2e2fb2a208ff77267422a197d9fxgu
319b937a73b079d7368cf309247585e63e6a4afbecqhuangCONST EFI_PEI_DECOMPRESS_PPI mDecompressPpi = {
32b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  Decompress
33d8c79a815f9e993b741ec38cd39498e674e1739elgao};
34d8c79a815f9e993b741ec38cd39498e674e1739elgao
3548557c6550adecf39e1e8e140b1736275d070dfbqhuangCONST EFI_PEI_PPI_DESCRIPTOR mPpiList[] = {
3695276127e373f2e2fb2a208ff77267422a197d9fxgu  {
37b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    EFI_PEI_PPI_DESCRIPTOR_PPI,
38b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    &gEfiDxeIplPpiGuid,
399b937a73b079d7368cf309247585e63e6a4afbecqhuang    (VOID *) &mDxeIplPpi
4095276127e373f2e2fb2a208ff77267422a197d9fxgu  },
4195276127e373f2e2fb2a208ff77267422a197d9fxgu  {
42b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
43b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    &gEfiPeiDecompressPpiGuid,
449b937a73b079d7368cf309247585e63e6a4afbecqhuang    (VOID *) &mDecompressPpi
4595276127e373f2e2fb2a208ff77267422a197d9fxgu  }
4695276127e373f2e2fb2a208ff77267422a197d9fxgu};
4795276127e373f2e2fb2a208ff77267422a197d9fxgu
4848557c6550adecf39e1e8e140b1736275d070dfbqhuangCONST EFI_PEI_PPI_DESCRIPTOR gEndOfPeiSignalPpi = {
4995276127e373f2e2fb2a208ff77267422a197d9fxgu  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
5095276127e373f2e2fb2a208ff77267422a197d9fxgu  &gEfiEndOfPeiSignalPpiGuid,
5195276127e373f2e2fb2a208ff77267422a197d9fxgu  NULL
5295276127e373f2e2fb2a208ff77267422a197d9fxgu};
5395276127e373f2e2fb2a208ff77267422a197d9fxgu
54b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu/**
5548557c6550adecf39e1e8e140b1736275d070dfbqhuang  Entry point of DXE IPL PEIM.
5648557c6550adecf39e1e8e140b1736275d070dfbqhuang
5748557c6550adecf39e1e8e140b1736275d070dfbqhuang  This function installs DXE IPL PPI and Decompress PPI.  It also reloads
5848557c6550adecf39e1e8e140b1736275d070dfbqhuang  itself to memory on non-S3 resume boot path.
59b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
60a55caa53354b0bb6684f703ba62b403a74e85495lgao  @param  FileHandle  Handle of the file being invoked.
61a55caa53354b0bb6684f703ba62b403a74e85495lgao  @param  PeiServices Describes the list of possible PEI Services.
6291d92e25647e9a26392b454499d309330710a076qhuang
6348557c6550adecf39e1e8e140b1736275d070dfbqhuang  @retval EFI_SUCESS  The entry point of DXE IPL PEIM executes successfully.
6448557c6550adecf39e1e8e140b1736275d070dfbqhuang  @retval Others      Some error occurs during the execution of this function.
6548557c6550adecf39e1e8e140b1736275d070dfbqhuang
6691d92e25647e9a26392b454499d309330710a076qhuang**/
6795276127e373f2e2fb2a208ff77267422a197d9fxguEFI_STATUS
6895276127e373f2e2fb2a208ff77267422a197d9fxguEFIAPI
6995276127e373f2e2fb2a208ff77267422a197d9fxguPeimInitializeDxeIpl (
70a55caa53354b0bb6684f703ba62b403a74e85495lgao  IN       EFI_PEI_FILE_HANDLE  FileHandle,
71a55caa53354b0bb6684f703ba62b403a74e85495lgao  IN CONST EFI_PEI_SERVICES     **PeiServices
7295276127e373f2e2fb2a208ff77267422a197d9fxgu  )
7395276127e373f2e2fb2a208ff77267422a197d9fxgu{
7495276127e373f2e2fb2a208ff77267422a197d9fxgu  EFI_STATUS                                Status;
7595276127e373f2e2fb2a208ff77267422a197d9fxgu  EFI_BOOT_MODE                             BootMode;
7618fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  EFI_GUID                                  *ExtractHandlerGuidTable;
7718fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  UINTN                                     ExtractHandlerNumber;
78d8c79a815f9e993b741ec38cd39498e674e1739elgao  EFI_PEI_PPI_DESCRIPTOR                    *GuidPpi;
79d8c79a815f9e993b741ec38cd39498e674e1739elgao
80b98da1b1f9b726f580d05f8680455122ba924da6qhuang  BootMode = GetBootModeHob ();
8195276127e373f2e2fb2a208ff77267422a197d9fxgu
82b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  if (BootMode != BOOT_ON_S3_RESUME) {
83a55caa53354b0bb6684f703ba62b403a74e85495lgao    Status = PeiServicesRegisterForShadow (FileHandle);
84b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    if (Status == EFI_SUCCESS) {
85b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      //
8648557c6550adecf39e1e8e140b1736275d070dfbqhuang      // EFI_SUCESS means it is the first time to call register for shadow.
87b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      //
88b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      return Status;
8948557c6550adecf39e1e8e140b1736275d070dfbqhuang    }
9048557c6550adecf39e1e8e140b1736275d070dfbqhuang
9148557c6550adecf39e1e8e140b1736275d070dfbqhuang    //
9248557c6550adecf39e1e8e140b1736275d070dfbqhuang    // Ensure that DXE IPL is shadowed to permanent memory.
9348557c6550adecf39e1e8e140b1736275d070dfbqhuang    //
9448557c6550adecf39e1e8e140b1736275d070dfbqhuang    ASSERT (Status == EFI_ALREADY_STARTED);
95b98da1b1f9b726f580d05f8680455122ba924da6qhuang
9648557c6550adecf39e1e8e140b1736275d070dfbqhuang    //
9748557c6550adecf39e1e8e140b1736275d070dfbqhuang    // Get custom extract guided section method guid list
9848557c6550adecf39e1e8e140b1736275d070dfbqhuang    //
9948557c6550adecf39e1e8e140b1736275d070dfbqhuang    ExtractHandlerNumber = ExtractGuidedSectionGetGuidList (&ExtractHandlerGuidTable);
10048557c6550adecf39e1e8e140b1736275d070dfbqhuang
10148557c6550adecf39e1e8e140b1736275d070dfbqhuang    //
10248557c6550adecf39e1e8e140b1736275d070dfbqhuang    // Install custom extraction guid PPI
10348557c6550adecf39e1e8e140b1736275d070dfbqhuang    //
10448557c6550adecf39e1e8e140b1736275d070dfbqhuang    if (ExtractHandlerNumber > 0) {
10548557c6550adecf39e1e8e140b1736275d070dfbqhuang      GuidPpi = (EFI_PEI_PPI_DESCRIPTOR *) AllocatePool (ExtractHandlerNumber * sizeof (EFI_PEI_PPI_DESCRIPTOR));
10648557c6550adecf39e1e8e140b1736275d070dfbqhuang      ASSERT (GuidPpi != NULL);
10748557c6550adecf39e1e8e140b1736275d070dfbqhuang      while (ExtractHandlerNumber-- > 0) {
10848557c6550adecf39e1e8e140b1736275d070dfbqhuang        GuidPpi->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
10948557c6550adecf39e1e8e140b1736275d070dfbqhuang        GuidPpi->Ppi   = (VOID *) &mCustomGuidedSectionExtractionPpi;
11048557c6550adecf39e1e8e140b1736275d070dfbqhuang        GuidPpi->Guid  = &ExtractHandlerGuidTable[ExtractHandlerNumber];
11148557c6550adecf39e1e8e140b1736275d070dfbqhuang        Status = PeiServicesInstallPpi (GuidPpi++);
11248557c6550adecf39e1e8e140b1736275d070dfbqhuang        ASSERT_EFI_ERROR(Status);
113b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      }
114d8c79a815f9e993b741ec38cd39498e674e1739elgao    }
11548557c6550adecf39e1e8e140b1736275d070dfbqhuang
11695276127e373f2e2fb2a208ff77267422a197d9fxgu  }
11795276127e373f2e2fb2a208ff77267422a197d9fxgu
118b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  //
119288f9b382445a50278155f703ccce9a0293fceb5lgao  // Install DxeIpl and Decompress PPIs.
120b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  //
121b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  Status = PeiServicesInstallPpi (mPpiList);
122288f9b382445a50278155f703ccce9a0293fceb5lgao  ASSERT_EFI_ERROR(Status);
123288f9b382445a50278155f703ccce9a0293fceb5lgao
12495276127e373f2e2fb2a208ff77267422a197d9fxgu  return Status;
12595276127e373f2e2fb2a208ff77267422a197d9fxgu}
12695276127e373f2e2fb2a208ff77267422a197d9fxgu
127b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu/**
128b98da1b1f9b726f580d05f8680455122ba924da6qhuang   Main entry point to last PEIM.
12948557c6550adecf39e1e8e140b1736275d070dfbqhuang
13048557c6550adecf39e1e8e140b1736275d070dfbqhuang   This function finds DXE Core in the firmware volume and transfer the control to
13148557c6550adecf39e1e8e140b1736275d070dfbqhuang   DXE core.
132b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
133b98da1b1f9b726f580d05f8680455122ba924da6qhuang   @param This          Entry point for DXE IPL PPI.
134b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu   @param PeiServices   General purpose services available to every PEIM.
135b98da1b1f9b726f580d05f8680455122ba924da6qhuang   @param HobList       Address to the Pei HOB list.
136b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
137b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu   @return EFI_SUCCESS              DXE core was successfully loaded.
138b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu   @return EFI_OUT_OF_RESOURCES     There are not enough resources to load DXE core.
13991d92e25647e9a26392b454499d309330710a076qhuang
140b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu**/
14195276127e373f2e2fb2a208ff77267422a197d9fxguEFI_STATUS
14295276127e373f2e2fb2a208ff77267422a197d9fxguEFIAPI
14395276127e373f2e2fb2a208ff77267422a197d9fxguDxeLoadCore (
1441f3a753ee68ac1c7a620e8064fdda718cf413761xli  IN CONST EFI_DXE_IPL_PPI *This,
14595276127e373f2e2fb2a208ff77267422a197d9fxgu  IN EFI_PEI_SERVICES      **PeiServices,
14695276127e373f2e2fb2a208ff77267422a197d9fxgu  IN EFI_PEI_HOB_POINTERS  HobList
14795276127e373f2e2fb2a208ff77267422a197d9fxgu  )
14895276127e373f2e2fb2a208ff77267422a197d9fxgu{
14995276127e373f2e2fb2a208ff77267422a197d9fxgu  EFI_STATUS                                Status;
150b6b98e9133020e8e7752200b496ffe073d673883qhuang  EFI_FV_FILE_INFO                          DxeCoreFileInfo;
15195276127e373f2e2fb2a208ff77267422a197d9fxgu  EFI_PHYSICAL_ADDRESS                      DxeCoreAddress;
15295276127e373f2e2fb2a208ff77267422a197d9fxgu  UINT64                                    DxeCoreSize;
15395276127e373f2e2fb2a208ff77267422a197d9fxgu  EFI_PHYSICAL_ADDRESS                      DxeCoreEntryPoint;
15495276127e373f2e2fb2a208ff77267422a197d9fxgu  EFI_BOOT_MODE                             BootMode;
155b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  EFI_PEI_FILE_HANDLE                       FileHandle;
156b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney  EFI_PEI_READ_ONLY_VARIABLE2_PPI           *Variable;
157b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney  UINTN                                     DataSize;
158708919bef7fa8e0ae611173fbe7d297c74acd3d4qhuang  EFI_MEMORY_TYPE_INFORMATION               MemoryData[EfiMaxMemoryType + 1];
15995276127e373f2e2fb2a208ff77267422a197d9fxgu
16095276127e373f2e2fb2a208ff77267422a197d9fxgu  //
16195276127e373f2e2fb2a208ff77267422a197d9fxgu  // if in S3 Resume, restore configure
16295276127e373f2e2fb2a208ff77267422a197d9fxgu  //
163b98da1b1f9b726f580d05f8680455122ba924da6qhuang  BootMode = GetBootModeHob ();
16495276127e373f2e2fb2a208ff77267422a197d9fxgu
16595276127e373f2e2fb2a208ff77267422a197d9fxgu  if (BootMode == BOOT_ON_S3_RESUME) {
166e8da1266b93d62d1998f73a7ec34bd54a074dbcfklu    Status = AcpiS3ResumeOs();
16795276127e373f2e2fb2a208ff77267422a197d9fxgu    ASSERT_EFI_ERROR (Status);
16895276127e373f2e2fb2a208ff77267422a197d9fxgu  } else if (BootMode == BOOT_IN_RECOVERY_MODE) {
169e8da1266b93d62d1998f73a7ec34bd54a074dbcfklu    Status = PeiRecoverFirmware ();
17095276127e373f2e2fb2a208ff77267422a197d9fxgu    if (EFI_ERROR (Status)) {
17191d92e25647e9a26392b454499d309330710a076qhuang      DEBUG ((DEBUG_ERROR, "Load Recovery Capsule Failed.(Status = %r)\n", Status));
17295276127e373f2e2fb2a208ff77267422a197d9fxgu      CpuDeadLoop ();
17395276127e373f2e2fb2a208ff77267422a197d9fxgu    }
17495276127e373f2e2fb2a208ff77267422a197d9fxgu
17595276127e373f2e2fb2a208ff77267422a197d9fxgu    //
17648557c6550adecf39e1e8e140b1736275d070dfbqhuang    // Now should have a HOB with the DXE core
17795276127e373f2e2fb2a208ff77267422a197d9fxgu    //
17895276127e373f2e2fb2a208ff77267422a197d9fxgu  }
179288f9b382445a50278155f703ccce9a0293fceb5lgao
180b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney  Status = PeiServicesLocatePpi (
181b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney             &gEfiPeiReadOnlyVariable2PpiGuid,
182b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney             0,
183b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney             NULL,
184b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney             (VOID **)&Variable
185b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney             );
186b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney  if (!EFI_ERROR (Status)) {
1871ad76c3466e260a7d58ba260eddc1e87beabee79mdkinney    DataSize = sizeof (MemoryData);
1881ad76c3466e260a7d58ba260eddc1e87beabee79mdkinney    Status = Variable->GetVariable (
1891ad76c3466e260a7d58ba260eddc1e87beabee79mdkinney                         Variable,
1901ad76c3466e260a7d58ba260eddc1e87beabee79mdkinney                         EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,
1911ad76c3466e260a7d58ba260eddc1e87beabee79mdkinney                         &gEfiMemoryTypeInformationGuid,
1921ad76c3466e260a7d58ba260eddc1e87beabee79mdkinney                         NULL,
1931ad76c3466e260a7d58ba260eddc1e87beabee79mdkinney                         &DataSize,
1941ad76c3466e260a7d58ba260eddc1e87beabee79mdkinney                         &MemoryData
1951ad76c3466e260a7d58ba260eddc1e87beabee79mdkinney                         );
1961ad76c3466e260a7d58ba260eddc1e87beabee79mdkinney    if (!EFI_ERROR (Status)) {
1971ad76c3466e260a7d58ba260eddc1e87beabee79mdkinney      //
1981ad76c3466e260a7d58ba260eddc1e87beabee79mdkinney      // Build the GUID'd HOB for DXE
1991ad76c3466e260a7d58ba260eddc1e87beabee79mdkinney      //
2001ad76c3466e260a7d58ba260eddc1e87beabee79mdkinney      BuildGuidDataHob (
2011ad76c3466e260a7d58ba260eddc1e87beabee79mdkinney        &gEfiMemoryTypeInformationGuid,
2021ad76c3466e260a7d58ba260eddc1e87beabee79mdkinney        MemoryData,
2031ad76c3466e260a7d58ba260eddc1e87beabee79mdkinney        DataSize
2041ad76c3466e260a7d58ba260eddc1e87beabee79mdkinney        );
2051ad76c3466e260a7d58ba260eddc1e87beabee79mdkinney    }
206b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney  }
207288f9b382445a50278155f703ccce9a0293fceb5lgao
20895276127e373f2e2fb2a208ff77267422a197d9fxgu  //
209b6b98e9133020e8e7752200b496ffe073d673883qhuang  // Look in all the FVs present in PEI and find the DXE Core FileHandle
21095276127e373f2e2fb2a208ff77267422a197d9fxgu  //
211b6b98e9133020e8e7752200b496ffe073d673883qhuang  FileHandle = DxeIplFindDxeCore ();
212b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
21395276127e373f2e2fb2a208ff77267422a197d9fxgu  //
21448557c6550adecf39e1e8e140b1736275d070dfbqhuang  // Load the DXE Core from a Firmware Volume, may use LoadFile PPI to do this to save code size.
21595276127e373f2e2fb2a208ff77267422a197d9fxgu  //
21695276127e373f2e2fb2a208ff77267422a197d9fxgu  Status = PeiLoadFile (
217b98da1b1f9b726f580d05f8680455122ba924da6qhuang             FileHandle,
218b98da1b1f9b726f580d05f8680455122ba924da6qhuang             &DxeCoreAddress,
219b98da1b1f9b726f580d05f8680455122ba924da6qhuang             &DxeCoreSize,
220b98da1b1f9b726f580d05f8680455122ba924da6qhuang             &DxeCoreEntryPoint
221b98da1b1f9b726f580d05f8680455122ba924da6qhuang             );
22295276127e373f2e2fb2a208ff77267422a197d9fxgu  ASSERT_EFI_ERROR (Status);
22395276127e373f2e2fb2a208ff77267422a197d9fxgu
22495276127e373f2e2fb2a208ff77267422a197d9fxgu  //
225b6b98e9133020e8e7752200b496ffe073d673883qhuang  // Get the DxeCore File Info from the FileHandle for the DxeCore GUID file name.
226b6b98e9133020e8e7752200b496ffe073d673883qhuang  //
227b6b98e9133020e8e7752200b496ffe073d673883qhuang  Status = PeiServicesFfsGetFileInfo (FileHandle, &DxeCoreFileInfo);
228b6b98e9133020e8e7752200b496ffe073d673883qhuang  ASSERT_EFI_ERROR (Status);
229b6b98e9133020e8e7752200b496ffe073d673883qhuang
230b6b98e9133020e8e7752200b496ffe073d673883qhuang  //
23195276127e373f2e2fb2a208ff77267422a197d9fxgu  // Add HOB for the DXE Core
23295276127e373f2e2fb2a208ff77267422a197d9fxgu  //
23395276127e373f2e2fb2a208ff77267422a197d9fxgu  BuildModuleHob (
234b6b98e9133020e8e7752200b496ffe073d673883qhuang    &DxeCoreFileInfo.FileName,
23595276127e373f2e2fb2a208ff77267422a197d9fxgu    DxeCoreAddress,
23648557c6550adecf39e1e8e140b1736275d070dfbqhuang    ALIGN_VALUE (DxeCoreSize, EFI_PAGE_SIZE),
23795276127e373f2e2fb2a208ff77267422a197d9fxgu    DxeCoreEntryPoint
23895276127e373f2e2fb2a208ff77267422a197d9fxgu    );
23995276127e373f2e2fb2a208ff77267422a197d9fxgu
24095276127e373f2e2fb2a208ff77267422a197d9fxgu  //
24195276127e373f2e2fb2a208ff77267422a197d9fxgu  // Report Status Code EFI_SW_PEI_PC_HANDOFF_TO_NEXT
24295276127e373f2e2fb2a208ff77267422a197d9fxgu  //
24348557c6550adecf39e1e8e140b1736275d070dfbqhuang  REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PcdGet32 (PcdStatusCodeValuePeiHandoffToDxe));
24495276127e373f2e2fb2a208ff77267422a197d9fxgu
2454e2dd553a6531e04d2ceb55e1f91159188ba51ecmdkinney  DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading DXE CORE at 0x%11p EntryPoint=0x%11p\n", (VOID *)(UINTN)DxeCoreAddress, FUNCTION_ENTRY_POINT (DxeCoreEntryPoint)));
246e98cd821ebedd6472c12738bd53dc7cfd02bb4fblgao
24795276127e373f2e2fb2a208ff77267422a197d9fxgu  //
24895276127e373f2e2fb2a208ff77267422a197d9fxgu  // Transfer control to the DXE Core
24948557c6550adecf39e1e8e140b1736275d070dfbqhuang  // The hand off state is simply a pointer to the HOB list
25095276127e373f2e2fb2a208ff77267422a197d9fxgu  //
2519b937a73b079d7368cf309247585e63e6a4afbecqhuang  HandOffToDxeCore (DxeCoreEntryPoint, HobList);
25295276127e373f2e2fb2a208ff77267422a197d9fxgu  //
25395276127e373f2e2fb2a208ff77267422a197d9fxgu  // If we get here, then the DXE Core returned.  This is an error
25448557c6550adecf39e1e8e140b1736275d070dfbqhuang  // DxeCore should not return.
25595276127e373f2e2fb2a208ff77267422a197d9fxgu  //
25695276127e373f2e2fb2a208ff77267422a197d9fxgu  ASSERT (FALSE);
25795276127e373f2e2fb2a208ff77267422a197d9fxgu  CpuDeadLoop ();
25895276127e373f2e2fb2a208ff77267422a197d9fxgu
25995276127e373f2e2fb2a208ff77267422a197d9fxgu  return EFI_OUT_OF_RESOURCES;
26095276127e373f2e2fb2a208ff77267422a197d9fxgu}
26195276127e373f2e2fb2a208ff77267422a197d9fxgu
26291d92e25647e9a26392b454499d309330710a076qhuang
263b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu/**
2649b937a73b079d7368cf309247585e63e6a4afbecqhuang   Searches DxeCore in all firmware Volumes and loads the first
2659b937a73b079d7368cf309247585e63e6a4afbecqhuang   instance that contains DxeCore.
266b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
2679b937a73b079d7368cf309247585e63e6a4afbecqhuang   @return FileHandle of DxeCore to load DxeCore.
2689b937a73b079d7368cf309247585e63e6a4afbecqhuang
26991d92e25647e9a26392b454499d309330710a076qhuang**/
2709b937a73b079d7368cf309247585e63e6a4afbecqhuangEFI_PEI_FILE_HANDLE
271288f9b382445a50278155f703ccce9a0293fceb5lgaoDxeIplFindDxeCore (
272b6b98e9133020e8e7752200b496ffe073d673883qhuang  VOID
273b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  )
27495276127e373f2e2fb2a208ff77267422a197d9fxgu{
2759b937a73b079d7368cf309247585e63e6a4afbecqhuang  EFI_STATUS            Status;
2769b937a73b079d7368cf309247585e63e6a4afbecqhuang  UINTN                 Instance;
2779b937a73b079d7368cf309247585e63e6a4afbecqhuang  EFI_PEI_FV_HANDLE     VolumeHandle;
2789b937a73b079d7368cf309247585e63e6a4afbecqhuang  EFI_PEI_FILE_HANDLE   FileHandle;
279288f9b382445a50278155f703ccce9a0293fceb5lgao
280288f9b382445a50278155f703ccce9a0293fceb5lgao  Instance    = 0;
2819b937a73b079d7368cf309247585e63e6a4afbecqhuang  while (TRUE) {
2829b937a73b079d7368cf309247585e63e6a4afbecqhuang    //
2839b937a73b079d7368cf309247585e63e6a4afbecqhuang    // Traverse all firmware volume instances
2849b937a73b079d7368cf309247585e63e6a4afbecqhuang    //
2859b937a73b079d7368cf309247585e63e6a4afbecqhuang    Status = PeiServicesFfsFindNextVolume (Instance, &VolumeHandle);
2869b937a73b079d7368cf309247585e63e6a4afbecqhuang    //
2879b937a73b079d7368cf309247585e63e6a4afbecqhuang    // If some error occurs here, then we cannot find any firmware
2889b937a73b079d7368cf309247585e63e6a4afbecqhuang    // volume that may contain DxeCore.
2899b937a73b079d7368cf309247585e63e6a4afbecqhuang    //
2909b937a73b079d7368cf309247585e63e6a4afbecqhuang    ASSERT_EFI_ERROR (Status);
2919b937a73b079d7368cf309247585e63e6a4afbecqhuang
2929b937a73b079d7368cf309247585e63e6a4afbecqhuang    //
2939b937a73b079d7368cf309247585e63e6a4afbecqhuang    // Find the DxeCore file type from the beginning in this firmware volume.
2949b937a73b079d7368cf309247585e63e6a4afbecqhuang    //
2959b937a73b079d7368cf309247585e63e6a4afbecqhuang    FileHandle = NULL;
2969b937a73b079d7368cf309247585e63e6a4afbecqhuang    Status = PeiServicesFfsFindNextFile (EFI_FV_FILETYPE_DXE_CORE, VolumeHandle, &FileHandle);
297288f9b382445a50278155f703ccce9a0293fceb5lgao    if (!EFI_ERROR (Status)) {
2989b937a73b079d7368cf309247585e63e6a4afbecqhuang      //
299b6b98e9133020e8e7752200b496ffe073d673883qhuang      // Find DxeCore FileHandle in this volume, then we skip other firmware volume and
300b6b98e9133020e8e7752200b496ffe073d673883qhuang      // return the FileHandle.
3019b937a73b079d7368cf309247585e63e6a4afbecqhuang      //
302b6b98e9133020e8e7752200b496ffe073d673883qhuang      return FileHandle;
30395276127e373f2e2fb2a208ff77267422a197d9fxgu    }
3049b937a73b079d7368cf309247585e63e6a4afbecqhuang    //
3059b937a73b079d7368cf309247585e63e6a4afbecqhuang    // We cannot find DxeCore in this firmware volume, then search the next volume.
3069b937a73b079d7368cf309247585e63e6a4afbecqhuang    //
3079b937a73b079d7368cf309247585e63e6a4afbecqhuang    Instance++;
3089b937a73b079d7368cf309247585e63e6a4afbecqhuang  }
30995276127e373f2e2fb2a208ff77267422a197d9fxgu}
31095276127e373f2e2fb2a208ff77267422a197d9fxgu
31191d92e25647e9a26392b454499d309330710a076qhuang
312b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu/**
313b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu   Loads and relocates a PE/COFF image into memory.
314b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
315b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu   @param FileHandle        The image file handle
316b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu   @param ImageAddress      The base address of the relocated PE/COFF image
317b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu   @param ImageSize         The size of the relocated PE/COFF image
318b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu   @param EntryPoint        The entry point of the relocated PE/COFF image
319b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
320b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu   @return EFI_SUCCESS           The file was loaded and relocated
321b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu   @return EFI_OUT_OF_RESOURCES  There was not enough memory to load and relocate the PE/COFF file
32291d92e25647e9a26392b454499d309330710a076qhuang
323b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu**/
32495276127e373f2e2fb2a208ff77267422a197d9fxguEFI_STATUS
32595276127e373f2e2fb2a208ff77267422a197d9fxguPeiLoadFile (
326b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  IN  EFI_PEI_FILE_HANDLE                       FileHandle,
32795276127e373f2e2fb2a208ff77267422a197d9fxgu  OUT EFI_PHYSICAL_ADDRESS                      *ImageAddress,
32895276127e373f2e2fb2a208ff77267422a197d9fxgu  OUT UINT64                                    *ImageSize,
32995276127e373f2e2fb2a208ff77267422a197d9fxgu  OUT EFI_PHYSICAL_ADDRESS                      *EntryPoint
33095276127e373f2e2fb2a208ff77267422a197d9fxgu  )
331b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu{
33295276127e373f2e2fb2a208ff77267422a197d9fxgu
333b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  EFI_STATUS                        Status;
334b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  PE_COFF_LOADER_IMAGE_CONTEXT      ImageContext;
335b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  VOID                              *Pe32Data;
336b98da1b1f9b726f580d05f8680455122ba924da6qhuang
337b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  //
3386b978d166b08cc915eac4f5e93360aba2233cf30lgao  // First try to find the PE32 section in this ffs file.
339b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  //
340b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  Status = PeiServicesFfsFindSectionData (
341b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu             EFI_SECTION_PE32,
342b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu             FileHandle,
343b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu             &Pe32Data
344b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu             );
345b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  if (EFI_ERROR (Status)) {
346b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
347b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    // NO image types we support so exit.
348b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
349b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    return Status;
350b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  }
35195276127e373f2e2fb2a208ff77267422a197d9fxgu
35295276127e373f2e2fb2a208ff77267422a197d9fxgu  ZeroMem (&ImageContext, sizeof (ImageContext));
35395276127e373f2e2fb2a208ff77267422a197d9fxgu  ImageContext.Handle = Pe32Data;
35448557c6550adecf39e1e8e140b1736275d070dfbqhuang  ImageContext.ImageRead = PeiImageRead;
35595276127e373f2e2fb2a208ff77267422a197d9fxgu
35695276127e373f2e2fb2a208ff77267422a197d9fxgu
3573d7b0992fccc89cc049de91d02b4869ec81cf9fblgao  Status = PeCoffLoaderGetImageInfo (&ImageContext);
35895276127e373f2e2fb2a208ff77267422a197d9fxgu  if (EFI_ERROR (Status)) {
35995276127e373f2e2fb2a208ff77267422a197d9fxgu    return Status;
36095276127e373f2e2fb2a208ff77267422a197d9fxgu  }
36195276127e373f2e2fb2a208ff77267422a197d9fxgu  //
36295276127e373f2e2fb2a208ff77267422a197d9fxgu  // Allocate Memory for the image
36395276127e373f2e2fb2a208ff77267422a197d9fxgu  //
3644bf952d181b1c8db4b4b021795abc1680685f7fdmdkinney  Status = PeiServicesAllocatePages (
3654bf952d181b1c8db4b4b021795abc1680685f7fdmdkinney             EfiBootServicesCode,
3664bf952d181b1c8db4b4b021795abc1680685f7fdmdkinney             EFI_SIZE_TO_PAGES ((UINT32) ImageContext.ImageSize),
3674bf952d181b1c8db4b4b021795abc1680685f7fdmdkinney             &ImageContext.ImageAddress
3684bf952d181b1c8db4b4b021795abc1680685f7fdmdkinney             );
3694bf952d181b1c8db4b4b021795abc1680685f7fdmdkinney  ASSERT_EFI_ERROR (Status);
37095276127e373f2e2fb2a208ff77267422a197d9fxgu  ASSERT (ImageContext.ImageAddress != 0);
37195276127e373f2e2fb2a208ff77267422a197d9fxgu
37295276127e373f2e2fb2a208ff77267422a197d9fxgu  //
37395276127e373f2e2fb2a208ff77267422a197d9fxgu  // Load the image to our new buffer
37495276127e373f2e2fb2a208ff77267422a197d9fxgu  //
3753d7b0992fccc89cc049de91d02b4869ec81cf9fblgao  Status = PeCoffLoaderLoadImage (&ImageContext);
37695276127e373f2e2fb2a208ff77267422a197d9fxgu  if (EFI_ERROR (Status)) {
37795276127e373f2e2fb2a208ff77267422a197d9fxgu    return Status;
37895276127e373f2e2fb2a208ff77267422a197d9fxgu  }
37995276127e373f2e2fb2a208ff77267422a197d9fxgu  //
38095276127e373f2e2fb2a208ff77267422a197d9fxgu  // Relocate the image in our new buffer
38195276127e373f2e2fb2a208ff77267422a197d9fxgu  //
3823d7b0992fccc89cc049de91d02b4869ec81cf9fblgao  Status = PeCoffLoaderRelocateImage (&ImageContext);
38395276127e373f2e2fb2a208ff77267422a197d9fxgu  if (EFI_ERROR (Status)) {
38495276127e373f2e2fb2a208ff77267422a197d9fxgu    return Status;
38595276127e373f2e2fb2a208ff77267422a197d9fxgu  }
38695276127e373f2e2fb2a208ff77267422a197d9fxgu
38795276127e373f2e2fb2a208ff77267422a197d9fxgu  //
38848557c6550adecf39e1e8e140b1736275d070dfbqhuang  // Flush the instruction cache so the image data are written before we execute it
38995276127e373f2e2fb2a208ff77267422a197d9fxgu  //
39048557c6550adecf39e1e8e140b1736275d070dfbqhuang  InvalidateInstructionCacheRange ((VOID *)(UINTN) ImageContext.ImageAddress, (UINTN) ImageContext.ImageSize);
39195276127e373f2e2fb2a208ff77267422a197d9fxgu
39295276127e373f2e2fb2a208ff77267422a197d9fxgu  *ImageAddress = ImageContext.ImageAddress;
39395276127e373f2e2fb2a208ff77267422a197d9fxgu  *ImageSize    = ImageContext.ImageSize;
39495276127e373f2e2fb2a208ff77267422a197d9fxgu  *EntryPoint   = ImageContext.EntryPoint;
39595276127e373f2e2fb2a208ff77267422a197d9fxgu
39695276127e373f2e2fb2a208ff77267422a197d9fxgu  return EFI_SUCCESS;
39795276127e373f2e2fb2a208ff77267422a197d9fxgu}
39895276127e373f2e2fb2a208ff77267422a197d9fxgu
39991d92e25647e9a26392b454499d309330710a076qhuang
40091d92e25647e9a26392b454499d309330710a076qhuang
40191d92e25647e9a26392b454499d309330710a076qhuang
402d8c79a815f9e993b741ec38cd39498e674e1739elgao/**
403d8c79a815f9e993b741ec38cd39498e674e1739elgao  The ExtractSection() function processes the input section and
404d8c79a815f9e993b741ec38cd39498e674e1739elgao  returns a pointer to the section contents. If the section being
405d8c79a815f9e993b741ec38cd39498e674e1739elgao  extracted does not require processing (if the section
406d8c79a815f9e993b741ec38cd39498e674e1739elgao  GuidedSectionHeader.Attributes has the
407d8c79a815f9e993b741ec38cd39498e674e1739elgao  EFI_GUIDED_SECTION_PROCESSING_REQUIRED field cleared), then
408d8c79a815f9e993b741ec38cd39498e674e1739elgao  OutputBuffer is just updated to point to the start of the
409d8c79a815f9e993b741ec38cd39498e674e1739elgao  section's contents. Otherwise, *Buffer must be allocated
410d8c79a815f9e993b741ec38cd39498e674e1739elgao  from PEI permanent memory.
411d8c79a815f9e993b741ec38cd39498e674e1739elgao
412d8c79a815f9e993b741ec38cd39498e674e1739elgao  @param This                   Indicates the
413d8c79a815f9e993b741ec38cd39498e674e1739elgao                                EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI instance.
414d8c79a815f9e993b741ec38cd39498e674e1739elgao                                Buffer containing the input GUIDed section to be
415d8c79a815f9e993b741ec38cd39498e674e1739elgao                                processed. OutputBuffer OutputBuffer is
416d8c79a815f9e993b741ec38cd39498e674e1739elgao                                allocated from PEI permanent memory and contains
417d8c79a815f9e993b741ec38cd39498e674e1739elgao                                the new section stream.
41891d92e25647e9a26392b454499d309330710a076qhuang  @param InputSection           A pointer to the input buffer, which contains
41991d92e25647e9a26392b454499d309330710a076qhuang                                the input section to be processed.
42091d92e25647e9a26392b454499d309330710a076qhuang  @param OutputBuffer           A pointer to a caller-allocated buffer, whose
42191d92e25647e9a26392b454499d309330710a076qhuang                                size is specified by the contents of OutputSize.
422d8c79a815f9e993b741ec38cd39498e674e1739elgao  @param OutputSize             A pointer to a caller-allocated
423d8c79a815f9e993b741ec38cd39498e674e1739elgao                                UINTN in which the size of *OutputBuffer
424d8c79a815f9e993b741ec38cd39498e674e1739elgao                                allocation is stored. If the function
425d8c79a815f9e993b741ec38cd39498e674e1739elgao                                returns anything other than EFI_SUCCESS,
426d8c79a815f9e993b741ec38cd39498e674e1739elgao                                the value of OutputSize is undefined.
427d8c79a815f9e993b741ec38cd39498e674e1739elgao  @param AuthenticationStatus   A pointer to a caller-allocated
428d8c79a815f9e993b741ec38cd39498e674e1739elgao                                UINT32 that indicates the
429d8c79a815f9e993b741ec38cd39498e674e1739elgao                                authentication status of the
430d8c79a815f9e993b741ec38cd39498e674e1739elgao                                output buffer. If the input
431d8c79a815f9e993b741ec38cd39498e674e1739elgao                                section's GuidedSectionHeader.
432d8c79a815f9e993b741ec38cd39498e674e1739elgao                                Attributes field has the
433d8c79a815f9e993b741ec38cd39498e674e1739elgao                                EFI_GUIDED_SECTION_AUTH_STATUS_VALID
434d8c79a815f9e993b741ec38cd39498e674e1739elgao                                bit as clear,
435d8c79a815f9e993b741ec38cd39498e674e1739elgao                                AuthenticationStatus must return
436d8c79a815f9e993b741ec38cd39498e674e1739elgao                                zero. These bits reflect the
437d8c79a815f9e993b741ec38cd39498e674e1739elgao                                status of the extraction
438d8c79a815f9e993b741ec38cd39498e674e1739elgao                                operation. If the function
439d8c79a815f9e993b741ec38cd39498e674e1739elgao                                returns anything other than
440d8c79a815f9e993b741ec38cd39498e674e1739elgao                                EFI_SUCCESS, the value of
441d8c79a815f9e993b741ec38cd39498e674e1739elgao                                AuthenticationStatus is
442d8c79a815f9e993b741ec38cd39498e674e1739elgao                                undefined.
443d8c79a815f9e993b741ec38cd39498e674e1739elgao
444d8c79a815f9e993b741ec38cd39498e674e1739elgao  @retval EFI_SUCCESS           The InputSection was
445d8c79a815f9e993b741ec38cd39498e674e1739elgao                                successfully processed and the
446d8c79a815f9e993b741ec38cd39498e674e1739elgao                                section contents were returned.
447d8c79a815f9e993b741ec38cd39498e674e1739elgao
448d8c79a815f9e993b741ec38cd39498e674e1739elgao  @retval EFI_OUT_OF_RESOURCES  The system has insufficient
449d8c79a815f9e993b741ec38cd39498e674e1739elgao                                resources to process the request.
450d8c79a815f9e993b741ec38cd39498e674e1739elgao
451708919bef7fa8e0ae611173fbe7d297c74acd3d4qhuang  @retval EFI_INVALID_PARAMETER The GUID in InputSection does
452d8c79a815f9e993b741ec38cd39498e674e1739elgao                                not match this instance of the
453d8c79a815f9e993b741ec38cd39498e674e1739elgao                                GUIDed Section Extraction PPI.
45491d92e25647e9a26392b454499d309330710a076qhuang
455d8c79a815f9e993b741ec38cd39498e674e1739elgao**/
456d8c79a815f9e993b741ec38cd39498e674e1739elgaoEFI_STATUS
45718fd8d651d7383c429cbcdf3a4262aa32268cd6clgaoCustomGuidedSectionExtract (
458d8c79a815f9e993b741ec38cd39498e674e1739elgao  IN CONST  EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *This,
459d8c79a815f9e993b741ec38cd39498e674e1739elgao  IN CONST  VOID                                  *InputSection,
460d8c79a815f9e993b741ec38cd39498e674e1739elgao  OUT       VOID                                  **OutputBuffer,
461d8c79a815f9e993b741ec38cd39498e674e1739elgao  OUT       UINTN                                 *OutputSize,
462d8c79a815f9e993b741ec38cd39498e674e1739elgao  OUT       UINT32                                *AuthenticationStatus
463d8c79a815f9e993b741ec38cd39498e674e1739elgao)
464d8c79a815f9e993b741ec38cd39498e674e1739elgao{
465d8c79a815f9e993b741ec38cd39498e674e1739elgao  EFI_STATUS      Status;
466d8c79a815f9e993b741ec38cd39498e674e1739elgao  UINT8           *ScratchBuffer;
46718fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  UINT32          ScratchBufferSize;
46818fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  UINT32          OutputBufferSize;
46918fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  UINT16          SectionAttribute;
470d8c79a815f9e993b741ec38cd39498e674e1739elgao
471d8c79a815f9e993b741ec38cd39498e674e1739elgao  //
47218fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  // Init local variable
473d8c79a815f9e993b741ec38cd39498e674e1739elgao  //
47418fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  ScratchBuffer = NULL;
47518fd8d651d7383c429cbcdf3a4262aa32268cd6clgao
476d8c79a815f9e993b741ec38cd39498e674e1739elgao  //
47718fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  // Call GetInfo to get the size and attribute of input guided section data.
478d8c79a815f9e993b741ec38cd39498e674e1739elgao  //
47918fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  Status = ExtractGuidedSectionGetInfo (
480b6b98e9133020e8e7752200b496ffe073d673883qhuang             InputSection,
481b6b98e9133020e8e7752200b496ffe073d673883qhuang             &OutputBufferSize,
482b6b98e9133020e8e7752200b496ffe073d673883qhuang             &ScratchBufferSize,
483b6b98e9133020e8e7752200b496ffe073d673883qhuang             &SectionAttribute
484b6b98e9133020e8e7752200b496ffe073d673883qhuang             );
48518fd8d651d7383c429cbcdf3a4262aa32268cd6clgao
486d8c79a815f9e993b741ec38cd39498e674e1739elgao  if (EFI_ERROR (Status)) {
48791d92e25647e9a26392b454499d309330710a076qhuang    DEBUG ((DEBUG_ERROR, "GetInfo from guided section Failed - %r\n", Status));
48818fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    return Status;
48918fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  }
49018fd8d651d7383c429cbcdf3a4262aa32268cd6clgao
49118fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  if (ScratchBufferSize != 0) {
49295276127e373f2e2fb2a208ff77267422a197d9fxgu    //
49318fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    // Allocate scratch buffer
49495276127e373f2e2fb2a208ff77267422a197d9fxgu    //
49518fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));
49618fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    if (ScratchBuffer == NULL) {
49718fd8d651d7383c429cbcdf3a4262aa32268cd6clgao      return EFI_OUT_OF_RESOURCES;
49818fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    }
499d8c79a815f9e993b741ec38cd39498e674e1739elgao  }
50095276127e373f2e2fb2a208ff77267422a197d9fxgu
501708919bef7fa8e0ae611173fbe7d297c74acd3d4qhuang  if (((SectionAttribute & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) && OutputBufferSize > 0) {
50218fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    //
50318fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    // Allocate output buffer
50418fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    //
505288f9b382445a50278155f703ccce9a0293fceb5lgao    *OutputBuffer = AllocatePages (EFI_SIZE_TO_PAGES (OutputBufferSize) + 1);
50618fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    if (*OutputBuffer == NULL) {
50718fd8d651d7383c429cbcdf3a4262aa32268cd6clgao      return EFI_OUT_OF_RESOURCES;
50818fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    }
50948557c6550adecf39e1e8e140b1736275d070dfbqhuang    DEBUG ((DEBUG_INFO, "Customized Guided section Memory Size required is 0x%x and address is 0x%p\n", OutputBufferSize, *OutputBuffer));
510288f9b382445a50278155f703ccce9a0293fceb5lgao    //
511288f9b382445a50278155f703ccce9a0293fceb5lgao    // *OutputBuffer still is one section. Adjust *OutputBuffer offset,
512288f9b382445a50278155f703ccce9a0293fceb5lgao    // skip EFI section header to make section data at page alignment.
513288f9b382445a50278155f703ccce9a0293fceb5lgao    //
514288f9b382445a50278155f703ccce9a0293fceb5lgao    *OutputBuffer = (VOID *)((UINT8 *) *OutputBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER));
51595276127e373f2e2fb2a208ff77267422a197d9fxgu  }
51618fd8d651d7383c429cbcdf3a4262aa32268cd6clgao
51718fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  Status = ExtractGuidedSectionDecode (
51818fd8d651d7383c429cbcdf3a4262aa32268cd6clgao             InputSection,
51918fd8d651d7383c429cbcdf3a4262aa32268cd6clgao             OutputBuffer,
52018fd8d651d7383c429cbcdf3a4262aa32268cd6clgao             ScratchBuffer,
52118fd8d651d7383c429cbcdf3a4262aa32268cd6clgao             AuthenticationStatus
52248557c6550adecf39e1e8e140b1736275d070dfbqhuang             );
523d8c79a815f9e993b741ec38cd39498e674e1739elgao  if (EFI_ERROR (Status)) {
524d8c79a815f9e993b741ec38cd39498e674e1739elgao    //
52518fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    // Decode failed
526d8c79a815f9e993b741ec38cd39498e674e1739elgao    //
52791d92e25647e9a26392b454499d309330710a076qhuang    DEBUG ((DEBUG_ERROR, "Extract guided section Failed - %r\n", Status));
528d8c79a815f9e993b741ec38cd39498e674e1739elgao    return Status;
529d8c79a815f9e993b741ec38cd39498e674e1739elgao  }
530d8c79a815f9e993b741ec38cd39498e674e1739elgao
53118fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  *OutputSize = (UINTN) OutputBufferSize;
53218fd8d651d7383c429cbcdf3a4262aa32268cd6clgao
53395276127e373f2e2fb2a208ff77267422a197d9fxgu  return EFI_SUCCESS;
53495276127e373f2e2fb2a208ff77267422a197d9fxgu}
535b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
53691d92e25647e9a26392b454499d309330710a076qhuang
53791d92e25647e9a26392b454499d309330710a076qhuang
53891d92e25647e9a26392b454499d309330710a076qhuang/**
53991d92e25647e9a26392b454499d309330710a076qhuang   Decompresses a section to the output buffer.
54091d92e25647e9a26392b454499d309330710a076qhuang
54148557c6550adecf39e1e8e140b1736275d070dfbqhuang   This function looks up the compression type field in the input section and
54291d92e25647e9a26392b454499d309330710a076qhuang   applies the appropriate compression algorithm to compress the section to a
54391d92e25647e9a26392b454499d309330710a076qhuang   callee allocated buffer.
54491d92e25647e9a26392b454499d309330710a076qhuang
54591d92e25647e9a26392b454499d309330710a076qhuang   @param  This                  Points to this instance of the
54691d92e25647e9a26392b454499d309330710a076qhuang                                 EFI_PEI_DECOMPRESS_PEI PPI.
54791d92e25647e9a26392b454499d309330710a076qhuang   @param  CompressionSection    Points to the compressed section.
54891d92e25647e9a26392b454499d309330710a076qhuang   @param  OutputBuffer          Holds the returned pointer to the decompressed
54991d92e25647e9a26392b454499d309330710a076qhuang                                 sections.
55091d92e25647e9a26392b454499d309330710a076qhuang   @param  OutputSize            Holds the returned size of the decompress
55191d92e25647e9a26392b454499d309330710a076qhuang                                 section streams.
55291d92e25647e9a26392b454499d309330710a076qhuang
55391d92e25647e9a26392b454499d309330710a076qhuang   @retval EFI_SUCCESS           The section was decompressed successfully.
55491d92e25647e9a26392b454499d309330710a076qhuang                                 OutputBuffer contains the resulting data and
55591d92e25647e9a26392b454499d309330710a076qhuang                                 OutputSize contains the resulting size.
55691d92e25647e9a26392b454499d309330710a076qhuang
55791d92e25647e9a26392b454499d309330710a076qhuang**/
558b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3kluEFI_STATUS
559b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3kluEFIAPI
560b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3kluDecompress (
561b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  IN CONST  EFI_PEI_DECOMPRESS_PPI  *This,
562b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  IN CONST  EFI_COMPRESSION_SECTION *CompressionSection,
563b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  OUT       VOID                    **OutputBuffer,
564b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  OUT       UINTN                   *OutputSize
565b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu )
566b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu{
567b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  EFI_STATUS                      Status;
568b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  UINT8                           *DstBuffer;
569b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  UINT8                           *ScratchBuffer;
570b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  UINTN                           DstBufferSize;
571b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  UINT32                          ScratchBufferSize;
572b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  EFI_COMMON_SECTION_HEADER       *Section;
573b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  UINTN                           SectionLength;
574b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
575b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  if (CompressionSection->CommonHeader.Type != EFI_SECTION_COMPRESSION) {
576b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    ASSERT (FALSE);
577b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    return EFI_INVALID_PARAMETER;
578b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  }
579b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
580b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  Section = (EFI_COMMON_SECTION_HEADER *) CompressionSection;
581b98da1b1f9b726f580d05f8680455122ba924da6qhuang  SectionLength = *(UINT32 *) (Section->Size) & 0x00ffffff;
582b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
583b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  //
584b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  // This is a compression set, expand it
585b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  //
586b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  switch (CompressionSection->CompressionType) {
587b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  case EFI_STANDARD_COMPRESSION:
588b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
589b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    // Load EFI standard compression.
59048557c6550adecf39e1e8e140b1736275d070dfbqhuang    // For compressed data, decompress them to destination buffer.
591b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
592b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    Status = UefiDecompressGetInfo (
593b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu               (UINT8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),
594b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu               (UINT32) SectionLength - sizeof (EFI_COMPRESSION_SECTION),
595b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu               (UINT32 *) &DstBufferSize,
596b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu               &ScratchBufferSize
597b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu               );
598b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    if (EFI_ERROR (Status)) {
599b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      //
600b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      // GetInfo failed
601b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      //
60291d92e25647e9a26392b454499d309330710a076qhuang      DEBUG ((DEBUG_ERROR, "Decompress GetInfo Failed - %r\n", Status));
603b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      return EFI_NOT_FOUND;
604b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    }
605b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
606b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    // Allocate scratch buffer
607b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
608b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));
609b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    if (ScratchBuffer == NULL) {
610b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      return EFI_OUT_OF_RESOURCES;
611b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    }
612b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
613288f9b382445a50278155f703ccce9a0293fceb5lgao    // Allocate destination buffer, extra one page for adjustment
614b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
615288f9b382445a50278155f703ccce9a0293fceb5lgao    DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize) + 1);
616b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    if (DstBuffer == NULL) {
617b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      return EFI_OUT_OF_RESOURCES;
618b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    }
619b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
620288f9b382445a50278155f703ccce9a0293fceb5lgao    // DstBuffer still is one section. Adjust DstBuffer offset, skip EFI section header
621288f9b382445a50278155f703ccce9a0293fceb5lgao    // to make section data at page alignment.
622288f9b382445a50278155f703ccce9a0293fceb5lgao    //
623288f9b382445a50278155f703ccce9a0293fceb5lgao    DstBuffer = DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER);
624288f9b382445a50278155f703ccce9a0293fceb5lgao    //
625b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    // Call decompress function
626b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
627b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    Status = UefiDecompress (
628b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu                (CHAR8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),
629b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu                DstBuffer,
630b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu                ScratchBuffer
631b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu                );
632b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    if (EFI_ERROR (Status)) {
633b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      //
634b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      // Decompress failed
635b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      //
63691d92e25647e9a26392b454499d309330710a076qhuang      DEBUG ((DEBUG_ERROR, "Decompress Failed - %r\n", Status));
637b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      return EFI_NOT_FOUND;
638b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    }
639b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    break;
640b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
641b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  case EFI_NOT_COMPRESSED:
642b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
643b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    // Allocate destination buffer
644b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
645b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    DstBufferSize = CompressionSection->UncompressedLength;
646288f9b382445a50278155f703ccce9a0293fceb5lgao    DstBuffer     = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize) + 1);
647b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    if (DstBuffer == NULL) {
648b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      return EFI_OUT_OF_RESOURCES;
649b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    }
650b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
651288f9b382445a50278155f703ccce9a0293fceb5lgao    // Adjust DstBuffer offset, skip EFI section header
652288f9b382445a50278155f703ccce9a0293fceb5lgao    // to make section data at page alignment.
653288f9b382445a50278155f703ccce9a0293fceb5lgao    //
654288f9b382445a50278155f703ccce9a0293fceb5lgao    DstBuffer = DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER);
655288f9b382445a50278155f703ccce9a0293fceb5lgao    //
656b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    // stream is not actually compressed, just encapsulated.  So just copy it.
657b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
658b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    CopyMem (DstBuffer, CompressionSection + 1, DstBufferSize);
659b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    break;
660b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
661b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  default:
662b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
663b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    // Don't support other unknown compression type.
664b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
665b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    ASSERT (FALSE);
666b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    return EFI_NOT_FOUND;
667b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  }
668b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
669b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  *OutputSize = DstBufferSize;
670b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  *OutputBuffer = DstBuffer;
671b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
672b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  return EFI_SUCCESS;
673b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu}
674b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
67591d92e25647e9a26392b454499d309330710a076qhuang
67691d92e25647e9a26392b454499d309330710a076qhuang/**
67791d92e25647e9a26392b454499d309330710a076qhuang   Updates the Stack HOB passed to DXE phase.
67891d92e25647e9a26392b454499d309330710a076qhuang
67991d92e25647e9a26392b454499d309330710a076qhuang   This function traverses the whole HOB list and update the stack HOB to
68091d92e25647e9a26392b454499d309330710a076qhuang   reflect the real stack that is used by DXE core.
68191d92e25647e9a26392b454499d309330710a076qhuang
68291d92e25647e9a26392b454499d309330710a076qhuang   @param BaseAddress           The lower address of stack used by DxeCore.
68391d92e25647e9a26392b454499d309330710a076qhuang   @param Length                The length of stack used by DxeCore.
68491d92e25647e9a26392b454499d309330710a076qhuang
68591d92e25647e9a26392b454499d309330710a076qhuang**/
68630c8f8616d9f2c764e4b8c3566bef4f562115005qhuangVOID
68730c8f8616d9f2c764e4b8c3566bef4f562115005qhuangUpdateStackHob (
68830c8f8616d9f2c764e4b8c3566bef4f562115005qhuang  IN EFI_PHYSICAL_ADDRESS        BaseAddress,
68930c8f8616d9f2c764e4b8c3566bef4f562115005qhuang  IN UINT64                      Length
69030c8f8616d9f2c764e4b8c3566bef4f562115005qhuang  )
69130c8f8616d9f2c764e4b8c3566bef4f562115005qhuang{
69230c8f8616d9f2c764e4b8c3566bef4f562115005qhuang  EFI_PEI_HOB_POINTERS           Hob;
69330c8f8616d9f2c764e4b8c3566bef4f562115005qhuang
69430c8f8616d9f2c764e4b8c3566bef4f562115005qhuang  Hob.Raw = GetHobList ();
69530c8f8616d9f2c764e4b8c3566bef4f562115005qhuang  while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) {
69630c8f8616d9f2c764e4b8c3566bef4f562115005qhuang    if (CompareGuid (&gEfiHobMemoryAllocStackGuid, &(Hob.MemoryAllocationStack->AllocDescriptor.Name))) {
69730c8f8616d9f2c764e4b8c3566bef4f562115005qhuang      //
69830c8f8616d9f2c764e4b8c3566bef4f562115005qhuang      // Build a new memory allocation HOB with old stack info with EfiConventionalMemory type
69930c8f8616d9f2c764e4b8c3566bef4f562115005qhuang      // to be reclaimed by DXE core.
70030c8f8616d9f2c764e4b8c3566bef4f562115005qhuang      //
70130c8f8616d9f2c764e4b8c3566bef4f562115005qhuang      BuildMemoryAllocationHob (
70230c8f8616d9f2c764e4b8c3566bef4f562115005qhuang        Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress,
70330c8f8616d9f2c764e4b8c3566bef4f562115005qhuang        Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength,
70430c8f8616d9f2c764e4b8c3566bef4f562115005qhuang        EfiConventionalMemory
70530c8f8616d9f2c764e4b8c3566bef4f562115005qhuang        );
70630c8f8616d9f2c764e4b8c3566bef4f562115005qhuang      //
70730c8f8616d9f2c764e4b8c3566bef4f562115005qhuang      // Update the BSP Stack Hob to reflect the new stack info.
70830c8f8616d9f2c764e4b8c3566bef4f562115005qhuang      //
70930c8f8616d9f2c764e4b8c3566bef4f562115005qhuang      Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress = BaseAddress;
71030c8f8616d9f2c764e4b8c3566bef4f562115005qhuang      Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength = Length;
71130c8f8616d9f2c764e4b8c3566bef4f562115005qhuang      break;
71230c8f8616d9f2c764e4b8c3566bef4f562115005qhuang    }
71330c8f8616d9f2c764e4b8c3566bef4f562115005qhuang    Hob.Raw = GET_NEXT_HOB (Hob);
71430c8f8616d9f2c764e4b8c3566bef4f562115005qhuang  }
71530c8f8616d9f2c764e4b8c3566bef4f562115005qhuang}
716