DxeLoad.c revision 4e2dd553a6531e04d2ceb55e1f91159188ba51ec
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
18b98da1b1f9b726f580d05f8680455122ba924da6qhuang//
19b98da1b1f9b726f580d05f8680455122ba924da6qhuang// This global variable indicates whether this module has been shadowed
20b98da1b1f9b726f580d05f8680455122ba924da6qhuang// to memory.
21b98da1b1f9b726f580d05f8680455122ba924da6qhuang//
2295276127e373f2e2fb2a208ff77267422a197d9fxguBOOLEAN gInMemory = FALSE;
2395276127e373f2e2fb2a208ff77267422a197d9fxgu
2495276127e373f2e2fb2a208ff77267422a197d9fxgu//
2595276127e373f2e2fb2a208ff77267422a197d9fxgu// Module Globals used in the DXE to PEI handoff
2695276127e373f2e2fb2a208ff77267422a197d9fxgu// These must be module globals, so the stack can be switched
2795276127e373f2e2fb2a208ff77267422a197d9fxgu//
289b937a73b079d7368cf309247585e63e6a4afbecqhuangCONST EFI_DXE_IPL_PPI mDxeIplPpi = {
2995276127e373f2e2fb2a208ff77267422a197d9fxgu  DxeLoadCore
3095276127e373f2e2fb2a208ff77267422a197d9fxgu};
3195276127e373f2e2fb2a208ff77267422a197d9fxgu
329b937a73b079d7368cf309247585e63e6a4afbecqhuangCONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI mCustomGuidedSectionExtractionPpi = {
3318fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  CustomGuidedSectionExtract
3495276127e373f2e2fb2a208ff77267422a197d9fxgu};
3595276127e373f2e2fb2a208ff77267422a197d9fxgu
369b937a73b079d7368cf309247585e63e6a4afbecqhuangCONST EFI_PEI_DECOMPRESS_PPI mDecompressPpi = {
37b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  Decompress
38d8c79a815f9e993b741ec38cd39498e674e1739elgao};
39d8c79a815f9e993b741ec38cd39498e674e1739elgao
409b937a73b079d7368cf309247585e63e6a4afbecqhuangCONST EFI_PEI_PPI_DESCRIPTOR     mPpiList[] = {
4195276127e373f2e2fb2a208ff77267422a197d9fxgu  {
42b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    EFI_PEI_PPI_DESCRIPTOR_PPI,
43b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    &gEfiDxeIplPpiGuid,
449b937a73b079d7368cf309247585e63e6a4afbecqhuang    (VOID *) &mDxeIplPpi
4595276127e373f2e2fb2a208ff77267422a197d9fxgu  },
4695276127e373f2e2fb2a208ff77267422a197d9fxgu  {
47b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
48b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    &gEfiPeiDecompressPpiGuid,
499b937a73b079d7368cf309247585e63e6a4afbecqhuang    (VOID *) &mDecompressPpi
5095276127e373f2e2fb2a208ff77267422a197d9fxgu  }
5195276127e373f2e2fb2a208ff77267422a197d9fxgu};
5295276127e373f2e2fb2a208ff77267422a197d9fxgu
539b937a73b079d7368cf309247585e63e6a4afbecqhuangCONST EFI_PEI_PPI_DESCRIPTOR     gEndOfPeiSignalPpi = {
5495276127e373f2e2fb2a208ff77267422a197d9fxgu  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
5595276127e373f2e2fb2a208ff77267422a197d9fxgu  &gEfiEndOfPeiSignalPpiGuid,
5695276127e373f2e2fb2a208ff77267422a197d9fxgu  NULL
5795276127e373f2e2fb2a208ff77267422a197d9fxgu};
5895276127e373f2e2fb2a208ff77267422a197d9fxgu
59b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu/**
60b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  Initializes the Dxe Ipl PPI
61b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
62a55caa53354b0bb6684f703ba62b403a74e85495lgao  @param  FileHandle  Handle of the file being invoked.
63a55caa53354b0bb6684f703ba62b403a74e85495lgao  @param  PeiServices Describes the list of possible PEI Services.
6491d92e25647e9a26392b454499d309330710a076qhuang
65a55caa53354b0bb6684f703ba62b403a74e85495lgao  @return EFI_SUCESS
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      //
86b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      // EFI_SUCESS means the first time call register for shadow
87b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      //
88b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      return Status;
89b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    } else if (Status == EFI_ALREADY_STARTED) {
90b98da1b1f9b726f580d05f8680455122ba924da6qhuang
91b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      //
9218fd8d651d7383c429cbcdf3a4262aa32268cd6clgao      // Get custom extract guided section method guid list
93b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      //
9418fd8d651d7383c429cbcdf3a4262aa32268cd6clgao      ExtractHandlerNumber = ExtractGuidedSectionGetGuidList (&ExtractHandlerGuidTable);
95b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
96b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      //
9718fd8d651d7383c429cbcdf3a4262aa32268cd6clgao      // Install custom extraction guid ppi
98b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      //
9918fd8d651d7383c429cbcdf3a4262aa32268cd6clgao      if (ExtractHandlerNumber > 0) {
10091d92e25647e9a26392b454499d309330710a076qhuang        GuidPpi = (EFI_PEI_PPI_DESCRIPTOR *) AllocatePool (ExtractHandlerNumber * sizeof (EFI_PEI_PPI_DESCRIPTOR));
10191d92e25647e9a26392b454499d309330710a076qhuang        ASSERT (GuidPpi != NULL);
10291d92e25647e9a26392b454499d309330710a076qhuang        while (ExtractHandlerNumber-- > 0) {
10391d92e25647e9a26392b454499d309330710a076qhuang          GuidPpi->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
1049b937a73b079d7368cf309247585e63e6a4afbecqhuang          GuidPpi->Ppi   = (VOID *) &mCustomGuidedSectionExtractionPpi;
10591d92e25647e9a26392b454499d309330710a076qhuang          GuidPpi->Guid  = &(ExtractHandlerGuidTable [ExtractHandlerNumber]);
10691d92e25647e9a26392b454499d309330710a076qhuang          Status = PeiServicesInstallPpi (GuidPpi++);
10791d92e25647e9a26392b454499d309330710a076qhuang          ASSERT_EFI_ERROR(Status);
10891d92e25647e9a26392b454499d309330710a076qhuang        }
109b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      }
110b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    } else {
111fb8749d0aff393e5e9e9f5a8604f17dc2bed3033qwang      ASSERT (FALSE);
112d8c79a815f9e993b741ec38cd39498e674e1739elgao    }
11395276127e373f2e2fb2a208ff77267422a197d9fxgu  }
11495276127e373f2e2fb2a208ff77267422a197d9fxgu
115b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  //
116288f9b382445a50278155f703ccce9a0293fceb5lgao  // Install DxeIpl and Decompress PPIs.
117b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  //
118b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  Status = PeiServicesInstallPpi (mPpiList);
119288f9b382445a50278155f703ccce9a0293fceb5lgao  ASSERT_EFI_ERROR(Status);
120288f9b382445a50278155f703ccce9a0293fceb5lgao
12195276127e373f2e2fb2a208ff77267422a197d9fxgu  return Status;
12295276127e373f2e2fb2a208ff77267422a197d9fxgu}
12395276127e373f2e2fb2a208ff77267422a197d9fxgu
124b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu/**
125b98da1b1f9b726f580d05f8680455122ba924da6qhuang   Main entry point to last PEIM.
126b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
127b98da1b1f9b726f580d05f8680455122ba924da6qhuang   @param This          Entry point for DXE IPL PPI.
128b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu   @param PeiServices   General purpose services available to every PEIM.
129b98da1b1f9b726f580d05f8680455122ba924da6qhuang   @param HobList       Address to the Pei HOB list.
130b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
131b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu   @return EFI_SUCCESS              DXE core was successfully loaded.
132b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu   @return EFI_OUT_OF_RESOURCES     There are not enough resources to load DXE core.
13391d92e25647e9a26392b454499d309330710a076qhuang
134b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu**/
13595276127e373f2e2fb2a208ff77267422a197d9fxguEFI_STATUS
13695276127e373f2e2fb2a208ff77267422a197d9fxguEFIAPI
13795276127e373f2e2fb2a208ff77267422a197d9fxguDxeLoadCore (
1381f3a753ee68ac1c7a620e8064fdda718cf413761xli  IN CONST EFI_DXE_IPL_PPI *This,
13995276127e373f2e2fb2a208ff77267422a197d9fxgu  IN EFI_PEI_SERVICES      **PeiServices,
14095276127e373f2e2fb2a208ff77267422a197d9fxgu  IN EFI_PEI_HOB_POINTERS  HobList
14195276127e373f2e2fb2a208ff77267422a197d9fxgu  )
14295276127e373f2e2fb2a208ff77267422a197d9fxgu{
14395276127e373f2e2fb2a208ff77267422a197d9fxgu  EFI_STATUS                                Status;
144b6b98e9133020e8e7752200b496ffe073d673883qhuang  EFI_FV_FILE_INFO                          DxeCoreFileInfo;
14595276127e373f2e2fb2a208ff77267422a197d9fxgu  EFI_PHYSICAL_ADDRESS                      DxeCoreAddress;
14695276127e373f2e2fb2a208ff77267422a197d9fxgu  UINT64                                    DxeCoreSize;
14795276127e373f2e2fb2a208ff77267422a197d9fxgu  EFI_PHYSICAL_ADDRESS                      DxeCoreEntryPoint;
14895276127e373f2e2fb2a208ff77267422a197d9fxgu  EFI_BOOT_MODE                             BootMode;
149b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  EFI_PEI_FILE_HANDLE                       FileHandle;
150b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney  EFI_PEI_READ_ONLY_VARIABLE2_PPI           *Variable;
151b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney  UINTN                                     DataSize;
152708919bef7fa8e0ae611173fbe7d297c74acd3d4qhuang  EFI_MEMORY_TYPE_INFORMATION               MemoryData[EfiMaxMemoryType + 1];
15395276127e373f2e2fb2a208ff77267422a197d9fxgu
15495276127e373f2e2fb2a208ff77267422a197d9fxgu  //
15595276127e373f2e2fb2a208ff77267422a197d9fxgu  // if in S3 Resume, restore configure
15695276127e373f2e2fb2a208ff77267422a197d9fxgu  //
157b98da1b1f9b726f580d05f8680455122ba924da6qhuang  BootMode = GetBootModeHob ();
15895276127e373f2e2fb2a208ff77267422a197d9fxgu
15995276127e373f2e2fb2a208ff77267422a197d9fxgu  if (BootMode == BOOT_ON_S3_RESUME) {
160e8da1266b93d62d1998f73a7ec34bd54a074dbcfklu    Status = AcpiS3ResumeOs();
16195276127e373f2e2fb2a208ff77267422a197d9fxgu    ASSERT_EFI_ERROR (Status);
16295276127e373f2e2fb2a208ff77267422a197d9fxgu  } else if (BootMode == BOOT_IN_RECOVERY_MODE) {
163e8da1266b93d62d1998f73a7ec34bd54a074dbcfklu    Status = PeiRecoverFirmware ();
16495276127e373f2e2fb2a208ff77267422a197d9fxgu    if (EFI_ERROR (Status)) {
16591d92e25647e9a26392b454499d309330710a076qhuang      DEBUG ((DEBUG_ERROR, "Load Recovery Capsule Failed.(Status = %r)\n", Status));
16695276127e373f2e2fb2a208ff77267422a197d9fxgu      CpuDeadLoop ();
16795276127e373f2e2fb2a208ff77267422a197d9fxgu    }
16895276127e373f2e2fb2a208ff77267422a197d9fxgu
16995276127e373f2e2fb2a208ff77267422a197d9fxgu    //
17095276127e373f2e2fb2a208ff77267422a197d9fxgu    // Now should have a HOB with the DXE core w/ the old HOB destroyed
17195276127e373f2e2fb2a208ff77267422a197d9fxgu    //
17295276127e373f2e2fb2a208ff77267422a197d9fxgu  }
173288f9b382445a50278155f703ccce9a0293fceb5lgao
174b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney  Status = PeiServicesLocatePpi (
175b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney             &gEfiPeiReadOnlyVariable2PpiGuid,
176b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney             0,
177b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney             NULL,
178b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney             (VOID **)&Variable
179b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney             );
180b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney  if (!EFI_ERROR (Status)) {
1811ad76c3466e260a7d58ba260eddc1e87beabee79mdkinney    DataSize = sizeof (MemoryData);
1821ad76c3466e260a7d58ba260eddc1e87beabee79mdkinney    Status = Variable->GetVariable (
1831ad76c3466e260a7d58ba260eddc1e87beabee79mdkinney                         Variable,
1841ad76c3466e260a7d58ba260eddc1e87beabee79mdkinney                         EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,
1851ad76c3466e260a7d58ba260eddc1e87beabee79mdkinney                         &gEfiMemoryTypeInformationGuid,
1861ad76c3466e260a7d58ba260eddc1e87beabee79mdkinney                         NULL,
1871ad76c3466e260a7d58ba260eddc1e87beabee79mdkinney                         &DataSize,
1881ad76c3466e260a7d58ba260eddc1e87beabee79mdkinney                         &MemoryData
1891ad76c3466e260a7d58ba260eddc1e87beabee79mdkinney                         );
1901ad76c3466e260a7d58ba260eddc1e87beabee79mdkinney    if (!EFI_ERROR (Status)) {
1911ad76c3466e260a7d58ba260eddc1e87beabee79mdkinney      //
1921ad76c3466e260a7d58ba260eddc1e87beabee79mdkinney      // Build the GUID'd HOB for DXE
1931ad76c3466e260a7d58ba260eddc1e87beabee79mdkinney      //
1941ad76c3466e260a7d58ba260eddc1e87beabee79mdkinney      BuildGuidDataHob (
1951ad76c3466e260a7d58ba260eddc1e87beabee79mdkinney        &gEfiMemoryTypeInformationGuid,
1961ad76c3466e260a7d58ba260eddc1e87beabee79mdkinney        MemoryData,
1971ad76c3466e260a7d58ba260eddc1e87beabee79mdkinney        DataSize
1981ad76c3466e260a7d58ba260eddc1e87beabee79mdkinney        );
1991ad76c3466e260a7d58ba260eddc1e87beabee79mdkinney    }
200b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney  }
201288f9b382445a50278155f703ccce9a0293fceb5lgao
20295276127e373f2e2fb2a208ff77267422a197d9fxgu  //
203b6b98e9133020e8e7752200b496ffe073d673883qhuang  // Look in all the FVs present in PEI and find the DXE Core FileHandle
20495276127e373f2e2fb2a208ff77267422a197d9fxgu  //
205b6b98e9133020e8e7752200b496ffe073d673883qhuang  FileHandle = DxeIplFindDxeCore ();
206b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
20795276127e373f2e2fb2a208ff77267422a197d9fxgu  //
2086b978d166b08cc915eac4f5e93360aba2233cf30lgao  // Load the DXE Core from a Firmware Volume, may use LoadFile ppi to do this for save code size.
20995276127e373f2e2fb2a208ff77267422a197d9fxgu  //
21095276127e373f2e2fb2a208ff77267422a197d9fxgu  Status = PeiLoadFile (
211b98da1b1f9b726f580d05f8680455122ba924da6qhuang             FileHandle,
212b98da1b1f9b726f580d05f8680455122ba924da6qhuang             &DxeCoreAddress,
213b98da1b1f9b726f580d05f8680455122ba924da6qhuang             &DxeCoreSize,
214b98da1b1f9b726f580d05f8680455122ba924da6qhuang             &DxeCoreEntryPoint
215b98da1b1f9b726f580d05f8680455122ba924da6qhuang             );
21695276127e373f2e2fb2a208ff77267422a197d9fxgu  ASSERT_EFI_ERROR (Status);
21795276127e373f2e2fb2a208ff77267422a197d9fxgu
21895276127e373f2e2fb2a208ff77267422a197d9fxgu  //
219b6b98e9133020e8e7752200b496ffe073d673883qhuang  // Get the DxeCore File Info from the FileHandle for the DxeCore GUID file name.
220b6b98e9133020e8e7752200b496ffe073d673883qhuang  //
221b6b98e9133020e8e7752200b496ffe073d673883qhuang  Status = PeiServicesFfsGetFileInfo (FileHandle, &DxeCoreFileInfo);
222b6b98e9133020e8e7752200b496ffe073d673883qhuang  ASSERT_EFI_ERROR (Status);
223b6b98e9133020e8e7752200b496ffe073d673883qhuang
224b6b98e9133020e8e7752200b496ffe073d673883qhuang  //
22595276127e373f2e2fb2a208ff77267422a197d9fxgu  // Add HOB for the DXE Core
22695276127e373f2e2fb2a208ff77267422a197d9fxgu  //
22795276127e373f2e2fb2a208ff77267422a197d9fxgu  BuildModuleHob (
228b6b98e9133020e8e7752200b496ffe073d673883qhuang    &DxeCoreFileInfo.FileName,
22995276127e373f2e2fb2a208ff77267422a197d9fxgu    DxeCoreAddress,
230b98da1b1f9b726f580d05f8680455122ba924da6qhuang    EFI_SIZE_TO_PAGES ((UINTN) DxeCoreSize) * EFI_PAGE_SIZE,
23195276127e373f2e2fb2a208ff77267422a197d9fxgu    DxeCoreEntryPoint
23295276127e373f2e2fb2a208ff77267422a197d9fxgu    );
23395276127e373f2e2fb2a208ff77267422a197d9fxgu
23495276127e373f2e2fb2a208ff77267422a197d9fxgu  //
23595276127e373f2e2fb2a208ff77267422a197d9fxgu  // Report Status Code EFI_SW_PEI_PC_HANDOFF_TO_NEXT
23695276127e373f2e2fb2a208ff77267422a197d9fxgu  //
23795276127e373f2e2fb2a208ff77267422a197d9fxgu  REPORT_STATUS_CODE (
23895276127e373f2e2fb2a208ff77267422a197d9fxgu    EFI_PROGRESS_CODE,
239797a9d6791a7529c20c7b10f2843e9f38ed5a6a5klu    PcdGet32(PcdStatusCodeValuePeiHandoffToDxe)
24095276127e373f2e2fb2a208ff77267422a197d9fxgu    );
24195276127e373f2e2fb2a208ff77267422a197d9fxgu
2424e2dd553a6531e04d2ceb55e1f91159188ba51ecmdkinney  DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading DXE CORE at 0x%11p EntryPoint=0x%11p\n", (VOID *)(UINTN)DxeCoreAddress, FUNCTION_ENTRY_POINT (DxeCoreEntryPoint)));
243e98cd821ebedd6472c12738bd53dc7cfd02bb4fblgao
24495276127e373f2e2fb2a208ff77267422a197d9fxgu  //
24595276127e373f2e2fb2a208ff77267422a197d9fxgu  // Transfer control to the DXE Core
24695276127e373f2e2fb2a208ff77267422a197d9fxgu  // The handoff state is simply a pointer to the HOB list
24795276127e373f2e2fb2a208ff77267422a197d9fxgu  //
2489b937a73b079d7368cf309247585e63e6a4afbecqhuang  HandOffToDxeCore (DxeCoreEntryPoint, HobList);
24995276127e373f2e2fb2a208ff77267422a197d9fxgu  //
25095276127e373f2e2fb2a208ff77267422a197d9fxgu  // If we get here, then the DXE Core returned.  This is an error
25195276127e373f2e2fb2a208ff77267422a197d9fxgu  // Dxe Core should not return.
25295276127e373f2e2fb2a208ff77267422a197d9fxgu  //
25395276127e373f2e2fb2a208ff77267422a197d9fxgu  ASSERT (FALSE);
25495276127e373f2e2fb2a208ff77267422a197d9fxgu  CpuDeadLoop ();
25595276127e373f2e2fb2a208ff77267422a197d9fxgu
25695276127e373f2e2fb2a208ff77267422a197d9fxgu  return EFI_OUT_OF_RESOURCES;
25795276127e373f2e2fb2a208ff77267422a197d9fxgu}
25895276127e373f2e2fb2a208ff77267422a197d9fxgu
25991d92e25647e9a26392b454499d309330710a076qhuang
260b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu/**
2619b937a73b079d7368cf309247585e63e6a4afbecqhuang   Searches DxeCore in all firmware Volumes and loads the first
2629b937a73b079d7368cf309247585e63e6a4afbecqhuang   instance that contains DxeCore.
263b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
2649b937a73b079d7368cf309247585e63e6a4afbecqhuang   @return FileHandle of DxeCore to load DxeCore.
2659b937a73b079d7368cf309247585e63e6a4afbecqhuang
26691d92e25647e9a26392b454499d309330710a076qhuang**/
2679b937a73b079d7368cf309247585e63e6a4afbecqhuangEFI_PEI_FILE_HANDLE
268288f9b382445a50278155f703ccce9a0293fceb5lgaoDxeIplFindDxeCore (
269b6b98e9133020e8e7752200b496ffe073d673883qhuang  VOID
270b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  )
27195276127e373f2e2fb2a208ff77267422a197d9fxgu{
2729b937a73b079d7368cf309247585e63e6a4afbecqhuang  EFI_STATUS            Status;
2739b937a73b079d7368cf309247585e63e6a4afbecqhuang  UINTN                 Instance;
2749b937a73b079d7368cf309247585e63e6a4afbecqhuang  EFI_PEI_FV_HANDLE     VolumeHandle;
2759b937a73b079d7368cf309247585e63e6a4afbecqhuang  EFI_PEI_FILE_HANDLE   FileHandle;
276288f9b382445a50278155f703ccce9a0293fceb5lgao
277288f9b382445a50278155f703ccce9a0293fceb5lgao  Instance    = 0;
2789b937a73b079d7368cf309247585e63e6a4afbecqhuang  while (TRUE) {
2799b937a73b079d7368cf309247585e63e6a4afbecqhuang    //
2809b937a73b079d7368cf309247585e63e6a4afbecqhuang    // Traverse all firmware volume instances
2819b937a73b079d7368cf309247585e63e6a4afbecqhuang    //
2829b937a73b079d7368cf309247585e63e6a4afbecqhuang    Status = PeiServicesFfsFindNextVolume (Instance, &VolumeHandle);
2839b937a73b079d7368cf309247585e63e6a4afbecqhuang    //
2849b937a73b079d7368cf309247585e63e6a4afbecqhuang    // If some error occurs here, then we cannot find any firmware
2859b937a73b079d7368cf309247585e63e6a4afbecqhuang    // volume that may contain DxeCore.
2869b937a73b079d7368cf309247585e63e6a4afbecqhuang    //
2879b937a73b079d7368cf309247585e63e6a4afbecqhuang    ASSERT_EFI_ERROR (Status);
2889b937a73b079d7368cf309247585e63e6a4afbecqhuang
2899b937a73b079d7368cf309247585e63e6a4afbecqhuang    //
2909b937a73b079d7368cf309247585e63e6a4afbecqhuang    // Find the DxeCore file type from the beginning in this firmware volume.
2919b937a73b079d7368cf309247585e63e6a4afbecqhuang    //
2929b937a73b079d7368cf309247585e63e6a4afbecqhuang    FileHandle = NULL;
2939b937a73b079d7368cf309247585e63e6a4afbecqhuang    Status = PeiServicesFfsFindNextFile (EFI_FV_FILETYPE_DXE_CORE, VolumeHandle, &FileHandle);
294288f9b382445a50278155f703ccce9a0293fceb5lgao    if (!EFI_ERROR (Status)) {
2959b937a73b079d7368cf309247585e63e6a4afbecqhuang      //
296b6b98e9133020e8e7752200b496ffe073d673883qhuang      // Find DxeCore FileHandle in this volume, then we skip other firmware volume and
297b6b98e9133020e8e7752200b496ffe073d673883qhuang      // return the FileHandle.
2989b937a73b079d7368cf309247585e63e6a4afbecqhuang      //
299b6b98e9133020e8e7752200b496ffe073d673883qhuang      return FileHandle;
30095276127e373f2e2fb2a208ff77267422a197d9fxgu    }
3019b937a73b079d7368cf309247585e63e6a4afbecqhuang    //
3029b937a73b079d7368cf309247585e63e6a4afbecqhuang    // We cannot find DxeCore in this firmware volume, then search the next volume.
3039b937a73b079d7368cf309247585e63e6a4afbecqhuang    //
3049b937a73b079d7368cf309247585e63e6a4afbecqhuang    Instance++;
3059b937a73b079d7368cf309247585e63e6a4afbecqhuang  }
30695276127e373f2e2fb2a208ff77267422a197d9fxgu}
30795276127e373f2e2fb2a208ff77267422a197d9fxgu
30891d92e25647e9a26392b454499d309330710a076qhuang
309b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu/**
310b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu   Loads and relocates a PE/COFF image into memory.
311b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
312b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu   @param FileHandle        The image file handle
313b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu   @param ImageAddress      The base address of the relocated PE/COFF image
314b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu   @param ImageSize         The size of the relocated PE/COFF image
315b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu   @param EntryPoint        The entry point of the relocated PE/COFF image
316b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
317b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu   @return EFI_SUCCESS           The file was loaded and relocated
318b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu   @return EFI_OUT_OF_RESOURCES  There was not enough memory to load and relocate the PE/COFF file
31991d92e25647e9a26392b454499d309330710a076qhuang
320b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu**/
32195276127e373f2e2fb2a208ff77267422a197d9fxguEFI_STATUS
32295276127e373f2e2fb2a208ff77267422a197d9fxguPeiLoadFile (
323b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  IN  EFI_PEI_FILE_HANDLE                       FileHandle,
32495276127e373f2e2fb2a208ff77267422a197d9fxgu  OUT EFI_PHYSICAL_ADDRESS                      *ImageAddress,
32595276127e373f2e2fb2a208ff77267422a197d9fxgu  OUT UINT64                                    *ImageSize,
32695276127e373f2e2fb2a208ff77267422a197d9fxgu  OUT EFI_PHYSICAL_ADDRESS                      *EntryPoint
32795276127e373f2e2fb2a208ff77267422a197d9fxgu  )
328b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu{
32995276127e373f2e2fb2a208ff77267422a197d9fxgu
330b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  EFI_STATUS                        Status;
331b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  PE_COFF_LOADER_IMAGE_CONTEXT      ImageContext;
332b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  VOID                              *Pe32Data;
333b98da1b1f9b726f580d05f8680455122ba924da6qhuang
334b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  //
3356b978d166b08cc915eac4f5e93360aba2233cf30lgao  // First try to find the PE32 section in this ffs file.
336b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  //
337b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  Status = PeiServicesFfsFindSectionData (
338b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu             EFI_SECTION_PE32,
339b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu             FileHandle,
340b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu             &Pe32Data
341b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu             );
342b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  if (EFI_ERROR (Status)) {
343b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
344b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    // NO image types we support so exit.
345b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
346b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    return Status;
347b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  }
34895276127e373f2e2fb2a208ff77267422a197d9fxgu
34995276127e373f2e2fb2a208ff77267422a197d9fxgu  ZeroMem (&ImageContext, sizeof (ImageContext));
35095276127e373f2e2fb2a208ff77267422a197d9fxgu  ImageContext.Handle = Pe32Data;
35195276127e373f2e2fb2a208ff77267422a197d9fxgu  Status              = GetImageReadFunction (&ImageContext);
35295276127e373f2e2fb2a208ff77267422a197d9fxgu
35395276127e373f2e2fb2a208ff77267422a197d9fxgu  ASSERT_EFI_ERROR (Status);
35495276127e373f2e2fb2a208ff77267422a197d9fxgu
3553d7b0992fccc89cc049de91d02b4869ec81cf9fblgao  Status = PeCoffLoaderGetImageInfo (&ImageContext);
35695276127e373f2e2fb2a208ff77267422a197d9fxgu  if (EFI_ERROR (Status)) {
35795276127e373f2e2fb2a208ff77267422a197d9fxgu    return Status;
35895276127e373f2e2fb2a208ff77267422a197d9fxgu  }
35995276127e373f2e2fb2a208ff77267422a197d9fxgu  //
36095276127e373f2e2fb2a208ff77267422a197d9fxgu  // Allocate Memory for the image
36195276127e373f2e2fb2a208ff77267422a197d9fxgu  //
3624bf952d181b1c8db4b4b021795abc1680685f7fdmdkinney  Status = PeiServicesAllocatePages (
3634bf952d181b1c8db4b4b021795abc1680685f7fdmdkinney             EfiBootServicesCode,
3644bf952d181b1c8db4b4b021795abc1680685f7fdmdkinney             EFI_SIZE_TO_PAGES ((UINT32) ImageContext.ImageSize),
3654bf952d181b1c8db4b4b021795abc1680685f7fdmdkinney             &ImageContext.ImageAddress
3664bf952d181b1c8db4b4b021795abc1680685f7fdmdkinney             );
3674bf952d181b1c8db4b4b021795abc1680685f7fdmdkinney  ASSERT_EFI_ERROR (Status);
36895276127e373f2e2fb2a208ff77267422a197d9fxgu  ASSERT (ImageContext.ImageAddress != 0);
36995276127e373f2e2fb2a208ff77267422a197d9fxgu
37095276127e373f2e2fb2a208ff77267422a197d9fxgu  //
37195276127e373f2e2fb2a208ff77267422a197d9fxgu  // Load the image to our new buffer
37295276127e373f2e2fb2a208ff77267422a197d9fxgu  //
3733d7b0992fccc89cc049de91d02b4869ec81cf9fblgao  Status = PeCoffLoaderLoadImage (&ImageContext);
37495276127e373f2e2fb2a208ff77267422a197d9fxgu  if (EFI_ERROR (Status)) {
37595276127e373f2e2fb2a208ff77267422a197d9fxgu    return Status;
37695276127e373f2e2fb2a208ff77267422a197d9fxgu  }
37795276127e373f2e2fb2a208ff77267422a197d9fxgu  //
37895276127e373f2e2fb2a208ff77267422a197d9fxgu  // Relocate the image in our new buffer
37995276127e373f2e2fb2a208ff77267422a197d9fxgu  //
3803d7b0992fccc89cc049de91d02b4869ec81cf9fblgao  Status = PeCoffLoaderRelocateImage (&ImageContext);
38195276127e373f2e2fb2a208ff77267422a197d9fxgu  if (EFI_ERROR (Status)) {
38295276127e373f2e2fb2a208ff77267422a197d9fxgu    return Status;
38395276127e373f2e2fb2a208ff77267422a197d9fxgu  }
38495276127e373f2e2fb2a208ff77267422a197d9fxgu
38595276127e373f2e2fb2a208ff77267422a197d9fxgu  //
38695276127e373f2e2fb2a208ff77267422a197d9fxgu  // Flush the instruction cache so the image data is written before we execute it
38795276127e373f2e2fb2a208ff77267422a197d9fxgu  //
38895276127e373f2e2fb2a208ff77267422a197d9fxgu  InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);
38995276127e373f2e2fb2a208ff77267422a197d9fxgu
39095276127e373f2e2fb2a208ff77267422a197d9fxgu  *ImageAddress = ImageContext.ImageAddress;
39195276127e373f2e2fb2a208ff77267422a197d9fxgu  *ImageSize    = ImageContext.ImageSize;
39295276127e373f2e2fb2a208ff77267422a197d9fxgu  *EntryPoint   = ImageContext.EntryPoint;
39395276127e373f2e2fb2a208ff77267422a197d9fxgu
39495276127e373f2e2fb2a208ff77267422a197d9fxgu  return EFI_SUCCESS;
39595276127e373f2e2fb2a208ff77267422a197d9fxgu}
39695276127e373f2e2fb2a208ff77267422a197d9fxgu
39791d92e25647e9a26392b454499d309330710a076qhuang
39891d92e25647e9a26392b454499d309330710a076qhuang
39991d92e25647e9a26392b454499d309330710a076qhuang
400d8c79a815f9e993b741ec38cd39498e674e1739elgao/**
401d8c79a815f9e993b741ec38cd39498e674e1739elgao  The ExtractSection() function processes the input section and
402d8c79a815f9e993b741ec38cd39498e674e1739elgao  returns a pointer to the section contents. If the section being
403d8c79a815f9e993b741ec38cd39498e674e1739elgao  extracted does not require processing (if the section
404d8c79a815f9e993b741ec38cd39498e674e1739elgao  GuidedSectionHeader.Attributes has the
405d8c79a815f9e993b741ec38cd39498e674e1739elgao  EFI_GUIDED_SECTION_PROCESSING_REQUIRED field cleared), then
406d8c79a815f9e993b741ec38cd39498e674e1739elgao  OutputBuffer is just updated to point to the start of the
407d8c79a815f9e993b741ec38cd39498e674e1739elgao  section's contents. Otherwise, *Buffer must be allocated
408d8c79a815f9e993b741ec38cd39498e674e1739elgao  from PEI permanent memory.
409d8c79a815f9e993b741ec38cd39498e674e1739elgao
410d8c79a815f9e993b741ec38cd39498e674e1739elgao  @param This                   Indicates the
411d8c79a815f9e993b741ec38cd39498e674e1739elgao                                EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI instance.
412d8c79a815f9e993b741ec38cd39498e674e1739elgao                                Buffer containing the input GUIDed section to be
413d8c79a815f9e993b741ec38cd39498e674e1739elgao                                processed. OutputBuffer OutputBuffer is
414d8c79a815f9e993b741ec38cd39498e674e1739elgao                                allocated from PEI permanent memory and contains
415d8c79a815f9e993b741ec38cd39498e674e1739elgao                                the new section stream.
41691d92e25647e9a26392b454499d309330710a076qhuang  @param InputSection           A pointer to the input buffer, which contains
41791d92e25647e9a26392b454499d309330710a076qhuang                                the input section to be processed.
41891d92e25647e9a26392b454499d309330710a076qhuang  @param OutputBuffer           A pointer to a caller-allocated buffer, whose
41991d92e25647e9a26392b454499d309330710a076qhuang                                size is specified by the contents of OutputSize.
420d8c79a815f9e993b741ec38cd39498e674e1739elgao  @param OutputSize             A pointer to a caller-allocated
421d8c79a815f9e993b741ec38cd39498e674e1739elgao                                UINTN in which the size of *OutputBuffer
422d8c79a815f9e993b741ec38cd39498e674e1739elgao                                allocation is stored. If the function
423d8c79a815f9e993b741ec38cd39498e674e1739elgao                                returns anything other than EFI_SUCCESS,
424d8c79a815f9e993b741ec38cd39498e674e1739elgao                                the value of OutputSize is undefined.
425d8c79a815f9e993b741ec38cd39498e674e1739elgao  @param AuthenticationStatus   A pointer to a caller-allocated
426d8c79a815f9e993b741ec38cd39498e674e1739elgao                                UINT32 that indicates the
427d8c79a815f9e993b741ec38cd39498e674e1739elgao                                authentication status of the
428d8c79a815f9e993b741ec38cd39498e674e1739elgao                                output buffer. If the input
429d8c79a815f9e993b741ec38cd39498e674e1739elgao                                section's GuidedSectionHeader.
430d8c79a815f9e993b741ec38cd39498e674e1739elgao                                Attributes field has the
431d8c79a815f9e993b741ec38cd39498e674e1739elgao                                EFI_GUIDED_SECTION_AUTH_STATUS_VALID
432d8c79a815f9e993b741ec38cd39498e674e1739elgao                                bit as clear,
433d8c79a815f9e993b741ec38cd39498e674e1739elgao                                AuthenticationStatus must return
434d8c79a815f9e993b741ec38cd39498e674e1739elgao                                zero. These bits reflect the
435d8c79a815f9e993b741ec38cd39498e674e1739elgao                                status of the extraction
436d8c79a815f9e993b741ec38cd39498e674e1739elgao                                operation. If the function
437d8c79a815f9e993b741ec38cd39498e674e1739elgao                                returns anything other than
438d8c79a815f9e993b741ec38cd39498e674e1739elgao                                EFI_SUCCESS, the value of
439d8c79a815f9e993b741ec38cd39498e674e1739elgao                                AuthenticationStatus is
440d8c79a815f9e993b741ec38cd39498e674e1739elgao                                undefined.
441d8c79a815f9e993b741ec38cd39498e674e1739elgao
442d8c79a815f9e993b741ec38cd39498e674e1739elgao  @retval EFI_SUCCESS           The InputSection was
443d8c79a815f9e993b741ec38cd39498e674e1739elgao                                successfully processed and the
444d8c79a815f9e993b741ec38cd39498e674e1739elgao                                section contents were returned.
445d8c79a815f9e993b741ec38cd39498e674e1739elgao
446d8c79a815f9e993b741ec38cd39498e674e1739elgao  @retval EFI_OUT_OF_RESOURCES  The system has insufficient
447d8c79a815f9e993b741ec38cd39498e674e1739elgao                                resources to process the request.
448d8c79a815f9e993b741ec38cd39498e674e1739elgao
449708919bef7fa8e0ae611173fbe7d297c74acd3d4qhuang  @retval EFI_INVALID_PARAMETER The GUID in InputSection does
450d8c79a815f9e993b741ec38cd39498e674e1739elgao                                not match this instance of the
451d8c79a815f9e993b741ec38cd39498e674e1739elgao                                GUIDed Section Extraction PPI.
45291d92e25647e9a26392b454499d309330710a076qhuang
453d8c79a815f9e993b741ec38cd39498e674e1739elgao**/
454d8c79a815f9e993b741ec38cd39498e674e1739elgaoEFI_STATUS
45518fd8d651d7383c429cbcdf3a4262aa32268cd6clgaoCustomGuidedSectionExtract (
456d8c79a815f9e993b741ec38cd39498e674e1739elgao  IN CONST  EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *This,
457d8c79a815f9e993b741ec38cd39498e674e1739elgao  IN CONST  VOID                                  *InputSection,
458d8c79a815f9e993b741ec38cd39498e674e1739elgao  OUT       VOID                                  **OutputBuffer,
459d8c79a815f9e993b741ec38cd39498e674e1739elgao  OUT       UINTN                                 *OutputSize,
460d8c79a815f9e993b741ec38cd39498e674e1739elgao  OUT       UINT32                                *AuthenticationStatus
461d8c79a815f9e993b741ec38cd39498e674e1739elgao)
462d8c79a815f9e993b741ec38cd39498e674e1739elgao{
463d8c79a815f9e993b741ec38cd39498e674e1739elgao  EFI_STATUS      Status;
464d8c79a815f9e993b741ec38cd39498e674e1739elgao  UINT8           *ScratchBuffer;
46518fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  UINT32          ScratchBufferSize;
46618fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  UINT32          OutputBufferSize;
46718fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  UINT16          SectionAttribute;
468d8c79a815f9e993b741ec38cd39498e674e1739elgao
469d8c79a815f9e993b741ec38cd39498e674e1739elgao  //
47018fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  // Init local variable
471d8c79a815f9e993b741ec38cd39498e674e1739elgao  //
47218fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  ScratchBuffer = NULL;
47318fd8d651d7383c429cbcdf3a4262aa32268cd6clgao
474d8c79a815f9e993b741ec38cd39498e674e1739elgao  //
47518fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  // Call GetInfo to get the size and attribute of input guided section data.
476d8c79a815f9e993b741ec38cd39498e674e1739elgao  //
47718fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  Status = ExtractGuidedSectionGetInfo (
478b6b98e9133020e8e7752200b496ffe073d673883qhuang             InputSection,
479b6b98e9133020e8e7752200b496ffe073d673883qhuang             &OutputBufferSize,
480b6b98e9133020e8e7752200b496ffe073d673883qhuang             &ScratchBufferSize,
481b6b98e9133020e8e7752200b496ffe073d673883qhuang             &SectionAttribute
482b6b98e9133020e8e7752200b496ffe073d673883qhuang             );
48318fd8d651d7383c429cbcdf3a4262aa32268cd6clgao
484d8c79a815f9e993b741ec38cd39498e674e1739elgao  if (EFI_ERROR (Status)) {
48591d92e25647e9a26392b454499d309330710a076qhuang    DEBUG ((DEBUG_ERROR, "GetInfo from guided section Failed - %r\n", Status));
48618fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    return Status;
48718fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  }
48818fd8d651d7383c429cbcdf3a4262aa32268cd6clgao
48918fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  if (ScratchBufferSize != 0) {
49095276127e373f2e2fb2a208ff77267422a197d9fxgu    //
49118fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    // Allocate scratch buffer
49295276127e373f2e2fb2a208ff77267422a197d9fxgu    //
49318fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));
49418fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    if (ScratchBuffer == NULL) {
49518fd8d651d7383c429cbcdf3a4262aa32268cd6clgao      return EFI_OUT_OF_RESOURCES;
49618fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    }
497d8c79a815f9e993b741ec38cd39498e674e1739elgao  }
49895276127e373f2e2fb2a208ff77267422a197d9fxgu
499708919bef7fa8e0ae611173fbe7d297c74acd3d4qhuang  if (((SectionAttribute & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) && OutputBufferSize > 0) {
50018fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    //
50118fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    // Allocate output buffer
50218fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    //
503288f9b382445a50278155f703ccce9a0293fceb5lgao    *OutputBuffer = AllocatePages (EFI_SIZE_TO_PAGES (OutputBufferSize) + 1);
50418fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    if (*OutputBuffer == NULL) {
50518fd8d651d7383c429cbcdf3a4262aa32268cd6clgao      return EFI_OUT_OF_RESOURCES;
50618fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    }
50791d92e25647e9a26392b454499d309330710a076qhuang    DEBUG ((DEBUG_INFO, "Customed Guided section Memory Size required is 0x%x and address is 0x%p\n", OutputBufferSize, *OutputBuffer));
508288f9b382445a50278155f703ccce9a0293fceb5lgao    //
509288f9b382445a50278155f703ccce9a0293fceb5lgao    // *OutputBuffer still is one section. Adjust *OutputBuffer offset,
510288f9b382445a50278155f703ccce9a0293fceb5lgao    // skip EFI section header to make section data at page alignment.
511288f9b382445a50278155f703ccce9a0293fceb5lgao    //
512288f9b382445a50278155f703ccce9a0293fceb5lgao    *OutputBuffer = (VOID *)((UINT8 *) *OutputBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER));
51395276127e373f2e2fb2a208ff77267422a197d9fxgu  }
51418fd8d651d7383c429cbcdf3a4262aa32268cd6clgao
51518fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  Status = ExtractGuidedSectionDecode (
51618fd8d651d7383c429cbcdf3a4262aa32268cd6clgao             InputSection,
51718fd8d651d7383c429cbcdf3a4262aa32268cd6clgao             OutputBuffer,
51818fd8d651d7383c429cbcdf3a4262aa32268cd6clgao             ScratchBuffer,
51918fd8d651d7383c429cbcdf3a4262aa32268cd6clgao             AuthenticationStatus
52018fd8d651d7383c429cbcdf3a4262aa32268cd6clgao           );
521d8c79a815f9e993b741ec38cd39498e674e1739elgao  if (EFI_ERROR (Status)) {
522d8c79a815f9e993b741ec38cd39498e674e1739elgao    //
52318fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    // Decode failed
524d8c79a815f9e993b741ec38cd39498e674e1739elgao    //
52591d92e25647e9a26392b454499d309330710a076qhuang    DEBUG ((DEBUG_ERROR, "Extract guided section Failed - %r\n", Status));
526d8c79a815f9e993b741ec38cd39498e674e1739elgao    return Status;
527d8c79a815f9e993b741ec38cd39498e674e1739elgao  }
528d8c79a815f9e993b741ec38cd39498e674e1739elgao
52918fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  *OutputSize = (UINTN) OutputBufferSize;
53018fd8d651d7383c429cbcdf3a4262aa32268cd6clgao
53195276127e373f2e2fb2a208ff77267422a197d9fxgu  return EFI_SUCCESS;
53295276127e373f2e2fb2a208ff77267422a197d9fxgu}
533b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
53491d92e25647e9a26392b454499d309330710a076qhuang
53591d92e25647e9a26392b454499d309330710a076qhuang
53691d92e25647e9a26392b454499d309330710a076qhuang/**
53791d92e25647e9a26392b454499d309330710a076qhuang   Decompresses a section to the output buffer.
53891d92e25647e9a26392b454499d309330710a076qhuang
53991d92e25647e9a26392b454499d309330710a076qhuang   This function lookes up the compression type field in the input section and
54091d92e25647e9a26392b454499d309330710a076qhuang   applies the appropriate compression algorithm to compress the section to a
54191d92e25647e9a26392b454499d309330710a076qhuang   callee allocated buffer.
54291d92e25647e9a26392b454499d309330710a076qhuang
54391d92e25647e9a26392b454499d309330710a076qhuang   @param  This                  Points to this instance of the
54491d92e25647e9a26392b454499d309330710a076qhuang                                 EFI_PEI_DECOMPRESS_PEI PPI.
54591d92e25647e9a26392b454499d309330710a076qhuang   @param  CompressionSection    Points to the compressed section.
54691d92e25647e9a26392b454499d309330710a076qhuang   @param  OutputBuffer          Holds the returned pointer to the decompressed
54791d92e25647e9a26392b454499d309330710a076qhuang                                 sections.
54891d92e25647e9a26392b454499d309330710a076qhuang   @param  OutputSize            Holds the returned size of the decompress
54991d92e25647e9a26392b454499d309330710a076qhuang                                 section streams.
55091d92e25647e9a26392b454499d309330710a076qhuang
55191d92e25647e9a26392b454499d309330710a076qhuang   @retval EFI_SUCCESS           The section was decompressed successfully.
55291d92e25647e9a26392b454499d309330710a076qhuang                                 OutputBuffer contains the resulting data and
55391d92e25647e9a26392b454499d309330710a076qhuang                                 OutputSize contains the resulting size.
55491d92e25647e9a26392b454499d309330710a076qhuang
55591d92e25647e9a26392b454499d309330710a076qhuang**/
556b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3kluEFI_STATUS
557b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3kluEFIAPI
558b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3kluDecompress (
559b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  IN CONST  EFI_PEI_DECOMPRESS_PPI  *This,
560b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  IN CONST  EFI_COMPRESSION_SECTION *CompressionSection,
561b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  OUT       VOID                    **OutputBuffer,
562b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  OUT       UINTN                   *OutputSize
563b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu )
564b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu{
565b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  EFI_STATUS                      Status;
566b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  UINT8                           *DstBuffer;
567b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  UINT8                           *ScratchBuffer;
568b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  UINTN                           DstBufferSize;
569b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  UINT32                          ScratchBufferSize;
570b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  EFI_COMMON_SECTION_HEADER       *Section;
571b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  UINTN                           SectionLength;
572b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
573b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  if (CompressionSection->CommonHeader.Type != EFI_SECTION_COMPRESSION) {
574b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    ASSERT (FALSE);
575b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    return EFI_INVALID_PARAMETER;
576b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  }
577b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
578b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  Section = (EFI_COMMON_SECTION_HEADER *) CompressionSection;
579b98da1b1f9b726f580d05f8680455122ba924da6qhuang  SectionLength = *(UINT32 *) (Section->Size) & 0x00ffffff;
580b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
581b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  //
582b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  // This is a compression set, expand it
583b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  //
584b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  switch (CompressionSection->CompressionType) {
585b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  case EFI_STANDARD_COMPRESSION:
586b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
587b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    // Load EFI standard compression.
588b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    // For compressed data, decompress them to dstbuffer.
589b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
590b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    Status = UefiDecompressGetInfo (
591b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu               (UINT8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),
592b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu               (UINT32) SectionLength - sizeof (EFI_COMPRESSION_SECTION),
593b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu               (UINT32 *) &DstBufferSize,
594b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu               &ScratchBufferSize
595b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu               );
596b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    if (EFI_ERROR (Status)) {
597b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      //
598b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      // GetInfo failed
599b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      //
60091d92e25647e9a26392b454499d309330710a076qhuang      DEBUG ((DEBUG_ERROR, "Decompress GetInfo Failed - %r\n", Status));
601b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      return EFI_NOT_FOUND;
602b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    }
603b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
604b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    // Allocate scratch buffer
605b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
606b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));
607b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    if (ScratchBuffer == NULL) {
608b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      return EFI_OUT_OF_RESOURCES;
609b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    }
610b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
611288f9b382445a50278155f703ccce9a0293fceb5lgao    // Allocate destination buffer, extra one page for adjustment
612b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
613288f9b382445a50278155f703ccce9a0293fceb5lgao    DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize) + 1);
614b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    if (DstBuffer == NULL) {
615b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      return EFI_OUT_OF_RESOURCES;
616b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    }
617b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
618288f9b382445a50278155f703ccce9a0293fceb5lgao    // DstBuffer still is one section. Adjust DstBuffer offset, skip EFI section header
619288f9b382445a50278155f703ccce9a0293fceb5lgao    // to make section data at page alignment.
620288f9b382445a50278155f703ccce9a0293fceb5lgao    //
621288f9b382445a50278155f703ccce9a0293fceb5lgao    DstBuffer = DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER);
622288f9b382445a50278155f703ccce9a0293fceb5lgao    //
623b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    // Call decompress function
624b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
625b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    Status = UefiDecompress (
626b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu                (CHAR8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),
627b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu                DstBuffer,
628b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu                ScratchBuffer
629b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu                );
630b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    if (EFI_ERROR (Status)) {
631b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      //
632b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      // Decompress failed
633b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      //
63491d92e25647e9a26392b454499d309330710a076qhuang      DEBUG ((DEBUG_ERROR, "Decompress Failed - %r\n", Status));
635b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      return EFI_NOT_FOUND;
636b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    }
637b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    break;
638b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
639b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  case EFI_NOT_COMPRESSED:
640b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
641b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    // Allocate destination buffer
642b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
643b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    DstBufferSize = CompressionSection->UncompressedLength;
644288f9b382445a50278155f703ccce9a0293fceb5lgao    DstBuffer     = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize) + 1);
645b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    if (DstBuffer == NULL) {
646b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      return EFI_OUT_OF_RESOURCES;
647b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    }
648b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
649288f9b382445a50278155f703ccce9a0293fceb5lgao    // Adjust DstBuffer offset, skip EFI section header
650288f9b382445a50278155f703ccce9a0293fceb5lgao    // to make section data at page alignment.
651288f9b382445a50278155f703ccce9a0293fceb5lgao    //
652288f9b382445a50278155f703ccce9a0293fceb5lgao    DstBuffer = DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER);
653288f9b382445a50278155f703ccce9a0293fceb5lgao    //
654b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    // stream is not actually compressed, just encapsulated.  So just copy it.
655b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
656b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    CopyMem (DstBuffer, CompressionSection + 1, DstBufferSize);
657b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    break;
658b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
659b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  default:
660b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
661b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    // Don't support other unknown compression type.
662b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
663b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    ASSERT (FALSE);
664b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    return EFI_NOT_FOUND;
665b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  }
666b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
667b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  *OutputSize = DstBufferSize;
668b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  *OutputBuffer = DstBuffer;
669b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
670b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  return EFI_SUCCESS;
671b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu}
672b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
67391d92e25647e9a26392b454499d309330710a076qhuang
67491d92e25647e9a26392b454499d309330710a076qhuang
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