DxeLoad.c revision 96226baa2884ba0776dec3431f84b20cb3062915
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"
17d8c79a815f9e993b741ec38cd39498e674e1739elgao#include <Ppi/GuidedSectionExtraction.h>
1895276127e373f2e2fb2a208ff77267422a197d9fxgu
19d8c79a815f9e993b741ec38cd39498e674e1739elgaoEFI_STATUS
2018fd8d651d7383c429cbcdf3a4262aa32268cd6clgaoCustomGuidedSectionExtract (
21d8c79a815f9e993b741ec38cd39498e674e1739elgao  IN CONST  EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *This,
22d8c79a815f9e993b741ec38cd39498e674e1739elgao  IN CONST  VOID                                  *InputSection,
23d8c79a815f9e993b741ec38cd39498e674e1739elgao  OUT       VOID                                  **OutputBuffer,
24d8c79a815f9e993b741ec38cd39498e674e1739elgao  OUT       UINTN                                 *OutputSize,
25d8c79a815f9e993b741ec38cd39498e674e1739elgao  OUT       UINT32                                *AuthenticationStatus
26d8c79a815f9e993b741ec38cd39498e674e1739elgao);
27d8c79a815f9e993b741ec38cd39498e674e1739elgao
28b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3kluSTATIC
29b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3kluEFI_STATUS
30b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3kluEFIAPI
31b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3kluDecompress (
32b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  IN CONST  EFI_PEI_DECOMPRESS_PPI  *This,
33b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  IN CONST  EFI_COMPRESSION_SECTION *InputSection,
34b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  OUT       VOID                    **OutputBuffer,
35b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  OUT       UINTN                   *OutputSize
36b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu);
37b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
38b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
3995276127e373f2e2fb2a208ff77267422a197d9fxguBOOLEAN gInMemory = FALSE;
4095276127e373f2e2fb2a208ff77267422a197d9fxgu
4195276127e373f2e2fb2a208ff77267422a197d9fxgu//
4295276127e373f2e2fb2a208ff77267422a197d9fxgu// Module Globals used in the DXE to PEI handoff
4395276127e373f2e2fb2a208ff77267422a197d9fxgu// These must be module globals, so the stack can be switched
4495276127e373f2e2fb2a208ff77267422a197d9fxgu//
4595276127e373f2e2fb2a208ff77267422a197d9fxgustatic EFI_DXE_IPL_PPI mDxeIplPpi = {
4695276127e373f2e2fb2a208ff77267422a197d9fxgu  DxeLoadCore
4795276127e373f2e2fb2a208ff77267422a197d9fxgu};
4895276127e373f2e2fb2a208ff77267422a197d9fxgu
4918fd8d651d7383c429cbcdf3a4262aa32268cd6clgaoSTATIC EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI mCustomGuidedSectionExtractionPpi = {
5018fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  CustomGuidedSectionExtract
5195276127e373f2e2fb2a208ff77267422a197d9fxgu};
5295276127e373f2e2fb2a208ff77267422a197d9fxgu
53b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3kluSTATIC EFI_PEI_DECOMPRESS_PPI mDecompressPpi = {
54b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  Decompress
55d8c79a815f9e993b741ec38cd39498e674e1739elgao};
56d8c79a815f9e993b741ec38cd39498e674e1739elgao
5795276127e373f2e2fb2a208ff77267422a197d9fxgustatic EFI_PEI_PPI_DESCRIPTOR     mPpiList[] = {
5895276127e373f2e2fb2a208ff77267422a197d9fxgu  {
59b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    EFI_PEI_PPI_DESCRIPTOR_PPI,
60b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    &gEfiDxeIplPpiGuid,
61b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    &mDxeIplPpi
6295276127e373f2e2fb2a208ff77267422a197d9fxgu  },
6395276127e373f2e2fb2a208ff77267422a197d9fxgu  {
64b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
65b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    &gEfiPeiDecompressPpiGuid,
66b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    &mDecompressPpi
6795276127e373f2e2fb2a208ff77267422a197d9fxgu  }
6895276127e373f2e2fb2a208ff77267422a197d9fxgu};
6995276127e373f2e2fb2a208ff77267422a197d9fxgu
7095276127e373f2e2fb2a208ff77267422a197d9fxgustatic EFI_PEI_PPI_DESCRIPTOR     mPpiSignal = {
7195276127e373f2e2fb2a208ff77267422a197d9fxgu  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
7295276127e373f2e2fb2a208ff77267422a197d9fxgu  &gEfiEndOfPeiSignalPpiGuid,
7395276127e373f2e2fb2a208ff77267422a197d9fxgu  NULL
7495276127e373f2e2fb2a208ff77267422a197d9fxgu};
7595276127e373f2e2fb2a208ff77267422a197d9fxgu
76b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu/**
77b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  Initializes the Dxe Ipl PPI
78b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
79b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  @param  FfsHandle   The handle of FFS file.
80b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  @param  PeiServices General purpose services available to
81b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu                      every PEIM.
82b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  @return EFI_SUCESS
83b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu*/
8495276127e373f2e2fb2a208ff77267422a197d9fxguEFI_STATUS
8595276127e373f2e2fb2a208ff77267422a197d9fxguEFIAPI
8695276127e373f2e2fb2a208ff77267422a197d9fxguPeimInitializeDxeIpl (
87b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  IN EFI_PEI_FILE_HANDLE       FfsHandle,
8895276127e373f2e2fb2a208ff77267422a197d9fxgu  IN EFI_PEI_SERVICES          **PeiServices
8995276127e373f2e2fb2a208ff77267422a197d9fxgu  )
9095276127e373f2e2fb2a208ff77267422a197d9fxgu{
9195276127e373f2e2fb2a208ff77267422a197d9fxgu  EFI_STATUS                                Status;
9295276127e373f2e2fb2a208ff77267422a197d9fxgu  EFI_BOOT_MODE                             BootMode;
9318fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  EFI_GUID                                  *ExtractHandlerGuidTable;
9418fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  UINTN                                     ExtractHandlerNumber;
95d8c79a815f9e993b741ec38cd39498e674e1739elgao  EFI_PEI_PPI_DESCRIPTOR                    *GuidPpi;
96d8c79a815f9e993b741ec38cd39498e674e1739elgao
9795276127e373f2e2fb2a208ff77267422a197d9fxgu  Status = PeiServicesGetBootMode (&BootMode);
9895276127e373f2e2fb2a208ff77267422a197d9fxgu  ASSERT_EFI_ERROR (Status);
9995276127e373f2e2fb2a208ff77267422a197d9fxgu
100b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  if (BootMode != BOOT_ON_S3_RESUME) {
101b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    Status = PeiServicesRegisterForShadow (FfsHandle);
102b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    if (Status == EFI_SUCCESS) {
103b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      //
104b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      // EFI_SUCESS means the first time call register for shadow
105b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      //
106b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      return Status;
107b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    } else if (Status == EFI_ALREADY_STARTED) {
1085516d05a59f0c2028ef58c56f19204f323b3fce6klu
1095516d05a59f0c2028ef58c56f19204f323b3fce6klu      gInMemory = TRUE;
1105516d05a59f0c2028ef58c56f19204f323b3fce6klu
111b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      //
11218fd8d651d7383c429cbcdf3a4262aa32268cd6clgao      // Get custom extract guided section method guid list
113b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      //
11418fd8d651d7383c429cbcdf3a4262aa32268cd6clgao      ExtractHandlerNumber = ExtractGuidedSectionGetGuidList (&ExtractHandlerGuidTable);
115b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
116b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      //
11718fd8d651d7383c429cbcdf3a4262aa32268cd6clgao      // Install custom extraction guid ppi
118b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      //
11918fd8d651d7383c429cbcdf3a4262aa32268cd6clgao      if (ExtractHandlerNumber > 0) {
120b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      	GuidPpi = NULL;
12118fd8d651d7383c429cbcdf3a4262aa32268cd6clgao      	GuidPpi = (EFI_PEI_PPI_DESCRIPTOR *) AllocatePool (ExtractHandlerNumber * sizeof (EFI_PEI_PPI_DESCRIPTOR));
122b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      	ASSERT (GuidPpi != NULL);
12318fd8d651d7383c429cbcdf3a4262aa32268cd6clgao      	while (ExtractHandlerNumber-- > 0) {
124b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      	  GuidPpi->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
12518fd8d651d7383c429cbcdf3a4262aa32268cd6clgao      	  GuidPpi->Ppi   = &mCustomGuidedSectionExtractionPpi;
12618fd8d651d7383c429cbcdf3a4262aa32268cd6clgao      	  GuidPpi->Guid  = &(ExtractHandlerGuidTable [ExtractHandlerNumber]);
127b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      	  Status = PeiServicesInstallPpi (GuidPpi++);
128b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      	  ASSERT_EFI_ERROR(Status);
129b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      	}
130b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      }
131b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    } else {
132fb8749d0aff393e5e9e9f5a8604f17dc2bed3033qwang      ASSERT (FALSE);
133d8c79a815f9e993b741ec38cd39498e674e1739elgao    }
13495276127e373f2e2fb2a208ff77267422a197d9fxgu  }
13595276127e373f2e2fb2a208ff77267422a197d9fxgu
136b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  //
137288f9b382445a50278155f703ccce9a0293fceb5lgao  // Install DxeIpl and Decompress PPIs.
138b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  //
139b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  Status = PeiServicesInstallPpi (mPpiList);
140288f9b382445a50278155f703ccce9a0293fceb5lgao  ASSERT_EFI_ERROR(Status);
141288f9b382445a50278155f703ccce9a0293fceb5lgao
14295276127e373f2e2fb2a208ff77267422a197d9fxgu  return Status;
14395276127e373f2e2fb2a208ff77267422a197d9fxgu}
14495276127e373f2e2fb2a208ff77267422a197d9fxgu
145b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu/**
146b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu   Main entry point to last PEIM
147b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
148b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu   @param This          Entry point for DXE IPL PPI
149b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu   @param PeiServices   General purpose services available to every PEIM.
150b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu   @param HobList       Address to the Pei HOB list
151b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
152b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu   @return EFI_SUCCESS              DXE core was successfully loaded.
153b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu   @return EFI_OUT_OF_RESOURCES     There are not enough resources to load DXE core.
154b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu**/
15595276127e373f2e2fb2a208ff77267422a197d9fxguEFI_STATUS
15695276127e373f2e2fb2a208ff77267422a197d9fxguEFIAPI
15795276127e373f2e2fb2a208ff77267422a197d9fxguDxeLoadCore (
15895276127e373f2e2fb2a208ff77267422a197d9fxgu  IN EFI_DXE_IPL_PPI       *This,
15995276127e373f2e2fb2a208ff77267422a197d9fxgu  IN EFI_PEI_SERVICES      **PeiServices,
16095276127e373f2e2fb2a208ff77267422a197d9fxgu  IN EFI_PEI_HOB_POINTERS  HobList
16195276127e373f2e2fb2a208ff77267422a197d9fxgu  )
16295276127e373f2e2fb2a208ff77267422a197d9fxgu{
16395276127e373f2e2fb2a208ff77267422a197d9fxgu  EFI_STATUS                                Status;
16495276127e373f2e2fb2a208ff77267422a197d9fxgu  EFI_GUID                                  DxeCoreFileName;
16595276127e373f2e2fb2a208ff77267422a197d9fxgu  EFI_PHYSICAL_ADDRESS                      DxeCoreAddress;
16695276127e373f2e2fb2a208ff77267422a197d9fxgu  UINT64                                    DxeCoreSize;
16795276127e373f2e2fb2a208ff77267422a197d9fxgu  EFI_PHYSICAL_ADDRESS                      DxeCoreEntryPoint;
16895276127e373f2e2fb2a208ff77267422a197d9fxgu  EFI_BOOT_MODE                             BootMode;
169b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  EFI_PEI_FILE_HANDLE                       FileHandle;
170b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney  EFI_PEI_READ_ONLY_VARIABLE2_PPI           *Variable;
171b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney  UINTN                                     DataSize;
172b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney  EFI_MEMORY_TYPE_INFORMATION               MemoryData [EfiMaxMemoryType + 1];
17395276127e373f2e2fb2a208ff77267422a197d9fxgu
17495276127e373f2e2fb2a208ff77267422a197d9fxgu  //
17595276127e373f2e2fb2a208ff77267422a197d9fxgu  // if in S3 Resume, restore configure
17695276127e373f2e2fb2a208ff77267422a197d9fxgu  //
17795276127e373f2e2fb2a208ff77267422a197d9fxgu  Status = PeiServicesGetBootMode (&BootMode);
17895276127e373f2e2fb2a208ff77267422a197d9fxgu  ASSERT_EFI_ERROR(Status);
17995276127e373f2e2fb2a208ff77267422a197d9fxgu
18095276127e373f2e2fb2a208ff77267422a197d9fxgu  if (BootMode == BOOT_ON_S3_RESUME) {
181e8da1266b93d62d1998f73a7ec34bd54a074dbcfklu    Status = AcpiS3ResumeOs();
18295276127e373f2e2fb2a208ff77267422a197d9fxgu    ASSERT_EFI_ERROR (Status);
18395276127e373f2e2fb2a208ff77267422a197d9fxgu  } else if (BootMode == BOOT_IN_RECOVERY_MODE) {
184e8da1266b93d62d1998f73a7ec34bd54a074dbcfklu    Status = PeiRecoverFirmware ();
18595276127e373f2e2fb2a208ff77267422a197d9fxgu    if (EFI_ERROR (Status)) {
18695276127e373f2e2fb2a208ff77267422a197d9fxgu      DEBUG ((EFI_D_ERROR, "Load Recovery Capsule Failed.(Status = %r)\n", Status));
18795276127e373f2e2fb2a208ff77267422a197d9fxgu      CpuDeadLoop ();
18895276127e373f2e2fb2a208ff77267422a197d9fxgu    }
18995276127e373f2e2fb2a208ff77267422a197d9fxgu
19095276127e373f2e2fb2a208ff77267422a197d9fxgu    //
19195276127e373f2e2fb2a208ff77267422a197d9fxgu    // Now should have a HOB with the DXE core w/ the old HOB destroyed
19295276127e373f2e2fb2a208ff77267422a197d9fxgu    //
19395276127e373f2e2fb2a208ff77267422a197d9fxgu  }
194288f9b382445a50278155f703ccce9a0293fceb5lgao
195b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney  Status = PeiServicesLocatePpi (
196b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney             &gEfiPeiReadOnlyVariable2PpiGuid,
197b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney             0,
198b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney             NULL,
199b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney             (VOID **)&Variable
200b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney             );
201b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney  ASSERT_EFI_ERROR (Status);
202b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney
203b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney  DataSize = sizeof (MemoryData);
204b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney  Status = Variable->GetVariable (
205b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney                       Variable,
206b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney                       EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,
207b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney                       &gEfiMemoryTypeInformationGuid,
208b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney                       NULL,
209b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney                       &DataSize,
210b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney                       &MemoryData
211b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney                       );
212b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney
213b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney  if (!EFI_ERROR (Status)) {
214b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney    //
215b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney    // Build the GUID'd HOB for DXE
216b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney    //
217b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney    BuildGuidDataHob (
218b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney      &gEfiMemoryTypeInformationGuid,
219b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney      MemoryData,
220b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney      DataSize
221b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney      );
222b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney  }
223288f9b382445a50278155f703ccce9a0293fceb5lgao
22495276127e373f2e2fb2a208ff77267422a197d9fxgu  //
225b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  // Look in all the FVs present in PEI and find the DXE Core
22695276127e373f2e2fb2a208ff77267422a197d9fxgu  //
227288f9b382445a50278155f703ccce9a0293fceb5lgao  FileHandle = NULL;
228288f9b382445a50278155f703ccce9a0293fceb5lgao  Status = DxeIplFindDxeCore (&FileHandle);
22995276127e373f2e2fb2a208ff77267422a197d9fxgu  ASSERT_EFI_ERROR (Status);
23095276127e373f2e2fb2a208ff77267422a197d9fxgu
231b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  CopyMem(&DxeCoreFileName, &(((EFI_FFS_FILE_HEADER*)FileHandle)->Name), sizeof (EFI_GUID));
232b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
23395276127e373f2e2fb2a208ff77267422a197d9fxgu  //
2346b978d166b08cc915eac4f5e93360aba2233cf30lgao  // Load the DXE Core from a Firmware Volume, may use LoadFile ppi to do this for save code size.
23595276127e373f2e2fb2a208ff77267422a197d9fxgu  //
23695276127e373f2e2fb2a208ff77267422a197d9fxgu  Status = PeiLoadFile (
237b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu            FileHandle,
238b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu            &DxeCoreAddress,
239b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu            &DxeCoreSize,
240b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu            &DxeCoreEntryPoint
241b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu            );
242b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
24395276127e373f2e2fb2a208ff77267422a197d9fxgu  ASSERT_EFI_ERROR (Status);
24495276127e373f2e2fb2a208ff77267422a197d9fxgu
24595276127e373f2e2fb2a208ff77267422a197d9fxgu  //
24695276127e373f2e2fb2a208ff77267422a197d9fxgu  // Add HOB for the DXE Core
24795276127e373f2e2fb2a208ff77267422a197d9fxgu  //
24895276127e373f2e2fb2a208ff77267422a197d9fxgu  BuildModuleHob (
24995276127e373f2e2fb2a208ff77267422a197d9fxgu    &DxeCoreFileName,
25095276127e373f2e2fb2a208ff77267422a197d9fxgu    DxeCoreAddress,
2510a7d0741b624ef927dce432c4ccd72a7b855732fklu    EFI_SIZE_TO_PAGES ((UINT32) DxeCoreSize) * EFI_PAGE_SIZE,
25295276127e373f2e2fb2a208ff77267422a197d9fxgu    DxeCoreEntryPoint
25395276127e373f2e2fb2a208ff77267422a197d9fxgu    );
25495276127e373f2e2fb2a208ff77267422a197d9fxgu
25595276127e373f2e2fb2a208ff77267422a197d9fxgu  //
25695276127e373f2e2fb2a208ff77267422a197d9fxgu  // Report Status Code EFI_SW_PEI_PC_HANDOFF_TO_NEXT
25795276127e373f2e2fb2a208ff77267422a197d9fxgu  //
25895276127e373f2e2fb2a208ff77267422a197d9fxgu  REPORT_STATUS_CODE (
25995276127e373f2e2fb2a208ff77267422a197d9fxgu    EFI_PROGRESS_CODE,
260797a9d6791a7529c20c7b10f2843e9f38ed5a6a5klu    PcdGet32(PcdStatusCodeValuePeiHandoffToDxe)
26195276127e373f2e2fb2a208ff77267422a197d9fxgu    );
26295276127e373f2e2fb2a208ff77267422a197d9fxgu
263e98cd821ebedd6472c12738bd53dc7cfd02bb4fblgao  DEBUG_CODE_BEGIN ();
264e98cd821ebedd6472c12738bd53dc7cfd02bb4fblgao
265e98cd821ebedd6472c12738bd53dc7cfd02bb4fblgao    EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION       PtrPeImage;
266e98cd821ebedd6472c12738bd53dc7cfd02bb4fblgao    PtrPeImage.Pe32 = (EFI_IMAGE_NT_HEADERS32 *) ((UINTN) DxeCoreAddress + ((EFI_IMAGE_DOS_HEADER *) (UINTN) DxeCoreAddress)->e_lfanew);
267e98cd821ebedd6472c12738bd53dc7cfd02bb4fblgao
268e98cd821ebedd6472c12738bd53dc7cfd02bb4fblgao    if (PtrPeImage.Pe32->FileHeader.Machine != IMAGE_FILE_MACHINE_IA64) {
269a85e7bfcd84b46cfbf5d945dcd1f54fe883ab37dlgao      DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Loading DXE CORE at 0x%10p EntryPoint=0x%10p\n", (VOID *)(UINTN)DxeCoreAddress, (VOID *)(UINTN)DxeCoreEntryPoint));
270e98cd821ebedd6472c12738bd53dc7cfd02bb4fblgao    } else {
271e98cd821ebedd6472c12738bd53dc7cfd02bb4fblgao      //
272e98cd821ebedd6472c12738bd53dc7cfd02bb4fblgao      // For IPF Image, the real entry point should be print.
273e98cd821ebedd6472c12738bd53dc7cfd02bb4fblgao      //
274a85e7bfcd84b46cfbf5d945dcd1f54fe883ab37dlgao      DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Loading DXE CORE at 0x%10p EntryPoint=0x%10p\n", (VOID *)(UINTN)DxeCoreAddress, (VOID *)(UINTN)(*(UINT64 *)(UINTN)DxeCoreEntryPoint)));
275e98cd821ebedd6472c12738bd53dc7cfd02bb4fblgao    }
276e98cd821ebedd6472c12738bd53dc7cfd02bb4fblgao
277e98cd821ebedd6472c12738bd53dc7cfd02bb4fblgao  DEBUG_CODE_END ();
27895276127e373f2e2fb2a208ff77267422a197d9fxgu  //
27995276127e373f2e2fb2a208ff77267422a197d9fxgu  // Transfer control to the DXE Core
28095276127e373f2e2fb2a208ff77267422a197d9fxgu  // The handoff state is simply a pointer to the HOB list
28195276127e373f2e2fb2a208ff77267422a197d9fxgu  //
28295276127e373f2e2fb2a208ff77267422a197d9fxgu  HandOffToDxeCore (DxeCoreEntryPoint, HobList, &mPpiSignal);
28395276127e373f2e2fb2a208ff77267422a197d9fxgu  //
28495276127e373f2e2fb2a208ff77267422a197d9fxgu  // If we get here, then the DXE Core returned.  This is an error
28595276127e373f2e2fb2a208ff77267422a197d9fxgu  // Dxe Core should not return.
28695276127e373f2e2fb2a208ff77267422a197d9fxgu  //
28795276127e373f2e2fb2a208ff77267422a197d9fxgu  ASSERT (FALSE);
28895276127e373f2e2fb2a208ff77267422a197d9fxgu  CpuDeadLoop ();
28995276127e373f2e2fb2a208ff77267422a197d9fxgu
29095276127e373f2e2fb2a208ff77267422a197d9fxgu  return EFI_OUT_OF_RESOURCES;
29195276127e373f2e2fb2a208ff77267422a197d9fxgu}
29295276127e373f2e2fb2a208ff77267422a197d9fxgu
293b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu/**
294288f9b382445a50278155f703ccce9a0293fceb5lgao   Find DxeCore driver from all First Volumes.
295b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
296b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu   @param FileHandle    Pointer to FFS file to search.
297b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
298b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu   @return EFI_SUCESS   Success to find the FFS in specificed FV
299b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu   @return others       Fail to find the FFS in specificed FV
300b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu */
301b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3kluEFI_STATUS
302288f9b382445a50278155f703ccce9a0293fceb5lgaoDxeIplFindDxeCore (
303b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  OUT EFI_PEI_FILE_HANDLE   *FileHandle
304b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  )
30595276127e373f2e2fb2a208ff77267422a197d9fxgu{
306288f9b382445a50278155f703ccce9a0293fceb5lgao  EFI_STATUS        Status;
307288f9b382445a50278155f703ccce9a0293fceb5lgao  EFI_STATUS        FileStatus;
308288f9b382445a50278155f703ccce9a0293fceb5lgao  UINTN             Instance;
309288f9b382445a50278155f703ccce9a0293fceb5lgao  EFI_PEI_FV_HANDLE VolumeHandle;
310288f9b382445a50278155f703ccce9a0293fceb5lgao
311288f9b382445a50278155f703ccce9a0293fceb5lgao  Instance    = 0;
312288f9b382445a50278155f703ccce9a0293fceb5lgao  *FileHandle = NULL;
31395276127e373f2e2fb2a208ff77267422a197d9fxgu
314b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  do {
315288f9b382445a50278155f703ccce9a0293fceb5lgao    Status = PeiServicesFfsFindNextVolume (Instance++, &VolumeHandle);
316288f9b382445a50278155f703ccce9a0293fceb5lgao    if (!EFI_ERROR (Status)) {
317288f9b382445a50278155f703ccce9a0293fceb5lgao      FileStatus = PeiServicesFfsFindNextFile (EFI_FV_FILETYPE_DXE_CORE, VolumeHandle, FileHandle);
318288f9b382445a50278155f703ccce9a0293fceb5lgao      if (!EFI_ERROR (FileStatus)) {
319288f9b382445a50278155f703ccce9a0293fceb5lgao        return FileStatus;
32095276127e373f2e2fb2a208ff77267422a197d9fxgu      }
32195276127e373f2e2fb2a208ff77267422a197d9fxgu    }
322288f9b382445a50278155f703ccce9a0293fceb5lgao  } while (!EFI_ERROR (Status));
323b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
324288f9b382445a50278155f703ccce9a0293fceb5lgao  return EFI_NOT_FOUND;
32595276127e373f2e2fb2a208ff77267422a197d9fxgu}
32695276127e373f2e2fb2a208ff77267422a197d9fxgu
327b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu/**
328b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu   Loads and relocates a PE/COFF image into memory.
329b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
330b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu   @param FileHandle        The image file handle
331b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu   @param ImageAddress      The base address of the relocated PE/COFF image
332b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu   @param ImageSize         The size of the relocated PE/COFF image
333b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu   @param EntryPoint        The entry point of the relocated PE/COFF image
334b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
335b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu   @return EFI_SUCCESS           The file was loaded and relocated
336b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu   @return EFI_OUT_OF_RESOURCES  There was not enough memory to load and relocate the PE/COFF file
337b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu**/
33895276127e373f2e2fb2a208ff77267422a197d9fxguEFI_STATUS
33995276127e373f2e2fb2a208ff77267422a197d9fxguPeiLoadFile (
340b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  IN  EFI_PEI_FILE_HANDLE                       FileHandle,
34195276127e373f2e2fb2a208ff77267422a197d9fxgu  OUT EFI_PHYSICAL_ADDRESS                      *ImageAddress,
34295276127e373f2e2fb2a208ff77267422a197d9fxgu  OUT UINT64                                    *ImageSize,
34395276127e373f2e2fb2a208ff77267422a197d9fxgu  OUT EFI_PHYSICAL_ADDRESS                      *EntryPoint
34495276127e373f2e2fb2a208ff77267422a197d9fxgu  )
345b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu{
34695276127e373f2e2fb2a208ff77267422a197d9fxgu
347b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  EFI_STATUS                        Status;
348b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  PE_COFF_LOADER_IMAGE_CONTEXT      ImageContext;
349b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  VOID                              *Pe32Data;
350b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  //
3516b978d166b08cc915eac4f5e93360aba2233cf30lgao  // First try to find the PE32 section in this ffs file.
352b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  //
353b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  Status = PeiServicesFfsFindSectionData (
354b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu             EFI_SECTION_PE32,
355b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu             FileHandle,
356b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu             &Pe32Data
357b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu             );
358b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
359b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  if (EFI_ERROR (Status)) {
360b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
361b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    // NO image types we support so exit.
362b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
363b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    return Status;
364b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  }
36595276127e373f2e2fb2a208ff77267422a197d9fxgu
36695276127e373f2e2fb2a208ff77267422a197d9fxgu  ZeroMem (&ImageContext, sizeof (ImageContext));
36795276127e373f2e2fb2a208ff77267422a197d9fxgu  ImageContext.Handle = Pe32Data;
36895276127e373f2e2fb2a208ff77267422a197d9fxgu  Status              = GetImageReadFunction (&ImageContext);
36995276127e373f2e2fb2a208ff77267422a197d9fxgu
37095276127e373f2e2fb2a208ff77267422a197d9fxgu  ASSERT_EFI_ERROR (Status);
37195276127e373f2e2fb2a208ff77267422a197d9fxgu
3723d7b0992fccc89cc049de91d02b4869ec81cf9fblgao  Status = PeCoffLoaderGetImageInfo (&ImageContext);
37395276127e373f2e2fb2a208ff77267422a197d9fxgu  if (EFI_ERROR (Status)) {
37495276127e373f2e2fb2a208ff77267422a197d9fxgu    return Status;
37595276127e373f2e2fb2a208ff77267422a197d9fxgu  }
37695276127e373f2e2fb2a208ff77267422a197d9fxgu  //
37795276127e373f2e2fb2a208ff77267422a197d9fxgu  // Allocate Memory for the image
37895276127e373f2e2fb2a208ff77267422a197d9fxgu  //
37995276127e373f2e2fb2a208ff77267422a197d9fxgu  ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) AllocatePages (EFI_SIZE_TO_PAGES ((UINT32) ImageContext.ImageSize));
38095276127e373f2e2fb2a208ff77267422a197d9fxgu  ASSERT (ImageContext.ImageAddress != 0);
38195276127e373f2e2fb2a208ff77267422a197d9fxgu
38295276127e373f2e2fb2a208ff77267422a197d9fxgu  //
38395276127e373f2e2fb2a208ff77267422a197d9fxgu  // Load the image to our new buffer
38495276127e373f2e2fb2a208ff77267422a197d9fxgu  //
3853d7b0992fccc89cc049de91d02b4869ec81cf9fblgao  Status = PeCoffLoaderLoadImage (&ImageContext);
38695276127e373f2e2fb2a208ff77267422a197d9fxgu  if (EFI_ERROR (Status)) {
38795276127e373f2e2fb2a208ff77267422a197d9fxgu    return Status;
38895276127e373f2e2fb2a208ff77267422a197d9fxgu  }
38995276127e373f2e2fb2a208ff77267422a197d9fxgu  //
39095276127e373f2e2fb2a208ff77267422a197d9fxgu  // Relocate the image in our new buffer
39195276127e373f2e2fb2a208ff77267422a197d9fxgu  //
3923d7b0992fccc89cc049de91d02b4869ec81cf9fblgao  Status = PeCoffLoaderRelocateImage (&ImageContext);
39395276127e373f2e2fb2a208ff77267422a197d9fxgu  if (EFI_ERROR (Status)) {
39495276127e373f2e2fb2a208ff77267422a197d9fxgu    return Status;
39595276127e373f2e2fb2a208ff77267422a197d9fxgu  }
39695276127e373f2e2fb2a208ff77267422a197d9fxgu
39795276127e373f2e2fb2a208ff77267422a197d9fxgu  //
39895276127e373f2e2fb2a208ff77267422a197d9fxgu  // Flush the instruction cache so the image data is written before we execute it
39995276127e373f2e2fb2a208ff77267422a197d9fxgu  //
40095276127e373f2e2fb2a208ff77267422a197d9fxgu  InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);
40195276127e373f2e2fb2a208ff77267422a197d9fxgu
40295276127e373f2e2fb2a208ff77267422a197d9fxgu  *ImageAddress = ImageContext.ImageAddress;
40395276127e373f2e2fb2a208ff77267422a197d9fxgu  *ImageSize    = ImageContext.ImageSize;
40495276127e373f2e2fb2a208ff77267422a197d9fxgu  *EntryPoint   = ImageContext.EntryPoint;
40595276127e373f2e2fb2a208ff77267422a197d9fxgu
40695276127e373f2e2fb2a208ff77267422a197d9fxgu  return EFI_SUCCESS;
40795276127e373f2e2fb2a208ff77267422a197d9fxgu}
40895276127e373f2e2fb2a208ff77267422a197d9fxgu
409d8c79a815f9e993b741ec38cd39498e674e1739elgao/**
410d8c79a815f9e993b741ec38cd39498e674e1739elgao  The ExtractSection() function processes the input section and
411d8c79a815f9e993b741ec38cd39498e674e1739elgao  returns a pointer to the section contents. If the section being
412d8c79a815f9e993b741ec38cd39498e674e1739elgao  extracted does not require processing (if the section
413d8c79a815f9e993b741ec38cd39498e674e1739elgao  GuidedSectionHeader.Attributes has the
414d8c79a815f9e993b741ec38cd39498e674e1739elgao  EFI_GUIDED_SECTION_PROCESSING_REQUIRED field cleared), then
415d8c79a815f9e993b741ec38cd39498e674e1739elgao  OutputBuffer is just updated to point to the start of the
416d8c79a815f9e993b741ec38cd39498e674e1739elgao  section's contents. Otherwise, *Buffer must be allocated
417d8c79a815f9e993b741ec38cd39498e674e1739elgao  from PEI permanent memory.
418d8c79a815f9e993b741ec38cd39498e674e1739elgao
419d8c79a815f9e993b741ec38cd39498e674e1739elgao  @param This                   Indicates the
420d8c79a815f9e993b741ec38cd39498e674e1739elgao                                EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI instance.
421d8c79a815f9e993b741ec38cd39498e674e1739elgao                                Buffer containing the input GUIDed section to be
422d8c79a815f9e993b741ec38cd39498e674e1739elgao                                processed. OutputBuffer OutputBuffer is
423d8c79a815f9e993b741ec38cd39498e674e1739elgao                                allocated from PEI permanent memory and contains
424d8c79a815f9e993b741ec38cd39498e674e1739elgao                                the new section stream.
425d8c79a815f9e993b741ec38cd39498e674e1739elgao
426d8c79a815f9e993b741ec38cd39498e674e1739elgao  @param OutputSize             A pointer to a caller-allocated
427d8c79a815f9e993b741ec38cd39498e674e1739elgao                                UINTN in which the size of *OutputBuffer
428d8c79a815f9e993b741ec38cd39498e674e1739elgao                                allocation is stored. If the function
429d8c79a815f9e993b741ec38cd39498e674e1739elgao                                returns anything other than EFI_SUCCESS,
430d8c79a815f9e993b741ec38cd39498e674e1739elgao                                the value of OutputSize is undefined.
431d8c79a815f9e993b741ec38cd39498e674e1739elgao
432d8c79a815f9e993b741ec38cd39498e674e1739elgao  @param AuthenticationStatus   A pointer to a caller-allocated
433d8c79a815f9e993b741ec38cd39498e674e1739elgao                                UINT32 that indicates the
434d8c79a815f9e993b741ec38cd39498e674e1739elgao                                authentication status of the
435d8c79a815f9e993b741ec38cd39498e674e1739elgao                                output buffer. If the input
436d8c79a815f9e993b741ec38cd39498e674e1739elgao                                section's GuidedSectionHeader.
437d8c79a815f9e993b741ec38cd39498e674e1739elgao                                Attributes field has the
438d8c79a815f9e993b741ec38cd39498e674e1739elgao                                EFI_GUIDED_SECTION_AUTH_STATUS_VALID
439d8c79a815f9e993b741ec38cd39498e674e1739elgao                                bit as clear,
440d8c79a815f9e993b741ec38cd39498e674e1739elgao                                AuthenticationStatus must return
441d8c79a815f9e993b741ec38cd39498e674e1739elgao                                zero. These bits reflect the
442d8c79a815f9e993b741ec38cd39498e674e1739elgao                                status of the extraction
443d8c79a815f9e993b741ec38cd39498e674e1739elgao                                operation. If the function
444d8c79a815f9e993b741ec38cd39498e674e1739elgao                                returns anything other than
445d8c79a815f9e993b741ec38cd39498e674e1739elgao                                EFI_SUCCESS, the value of
446d8c79a815f9e993b741ec38cd39498e674e1739elgao                                AuthenticationStatus is
447d8c79a815f9e993b741ec38cd39498e674e1739elgao                                undefined.
448d8c79a815f9e993b741ec38cd39498e674e1739elgao
449d8c79a815f9e993b741ec38cd39498e674e1739elgao  @retval EFI_SUCCESS           The InputSection was
450d8c79a815f9e993b741ec38cd39498e674e1739elgao                                successfully processed and the
451d8c79a815f9e993b741ec38cd39498e674e1739elgao                                section contents were returned.
452d8c79a815f9e993b741ec38cd39498e674e1739elgao
453d8c79a815f9e993b741ec38cd39498e674e1739elgao  @retval EFI_OUT_OF_RESOURCES  The system has insufficient
454d8c79a815f9e993b741ec38cd39498e674e1739elgao                                resources to process the request.
455d8c79a815f9e993b741ec38cd39498e674e1739elgao
456d8c79a815f9e993b741ec38cd39498e674e1739elgao  @reteval EFI_INVALID_PARAMETER The GUID in InputSection does
457d8c79a815f9e993b741ec38cd39498e674e1739elgao                                not match this instance of the
458d8c79a815f9e993b741ec38cd39498e674e1739elgao                                GUIDed Section Extraction PPI.
459d8c79a815f9e993b741ec38cd39498e674e1739elgao**/
460d8c79a815f9e993b741ec38cd39498e674e1739elgaoEFI_STATUS
46118fd8d651d7383c429cbcdf3a4262aa32268cd6clgaoCustomGuidedSectionExtract (
462d8c79a815f9e993b741ec38cd39498e674e1739elgao  IN CONST  EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *This,
463d8c79a815f9e993b741ec38cd39498e674e1739elgao  IN CONST  VOID                                  *InputSection,
464d8c79a815f9e993b741ec38cd39498e674e1739elgao  OUT       VOID                                  **OutputBuffer,
465d8c79a815f9e993b741ec38cd39498e674e1739elgao  OUT       UINTN                                 *OutputSize,
466d8c79a815f9e993b741ec38cd39498e674e1739elgao  OUT       UINT32                                *AuthenticationStatus
467d8c79a815f9e993b741ec38cd39498e674e1739elgao)
468d8c79a815f9e993b741ec38cd39498e674e1739elgao{
469d8c79a815f9e993b741ec38cd39498e674e1739elgao  EFI_STATUS      Status;
470d8c79a815f9e993b741ec38cd39498e674e1739elgao  UINT8           *ScratchBuffer;
47118fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  UINT32          ScratchBufferSize;
47218fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  UINT32          OutputBufferSize;
47318fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  UINT16          SectionAttribute;
474d8c79a815f9e993b741ec38cd39498e674e1739elgao
475d8c79a815f9e993b741ec38cd39498e674e1739elgao  //
47618fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  // Init local variable
477d8c79a815f9e993b741ec38cd39498e674e1739elgao  //
47818fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  ScratchBuffer = NULL;
47918fd8d651d7383c429cbcdf3a4262aa32268cd6clgao
480d8c79a815f9e993b741ec38cd39498e674e1739elgao  //
48118fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  // Call GetInfo to get the size and attribute of input guided section data.
482d8c79a815f9e993b741ec38cd39498e674e1739elgao  //
48318fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  Status = ExtractGuidedSectionGetInfo (
48418fd8d651d7383c429cbcdf3a4262aa32268cd6clgao            InputSection,
48518fd8d651d7383c429cbcdf3a4262aa32268cd6clgao            &OutputBufferSize,
48618fd8d651d7383c429cbcdf3a4262aa32268cd6clgao            &ScratchBufferSize,
48718fd8d651d7383c429cbcdf3a4262aa32268cd6clgao            &SectionAttribute
48818fd8d651d7383c429cbcdf3a4262aa32268cd6clgao           );
48918fd8d651d7383c429cbcdf3a4262aa32268cd6clgao
490d8c79a815f9e993b741ec38cd39498e674e1739elgao  if (EFI_ERROR (Status)) {
49118fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    DEBUG ((EFI_D_ERROR, "GetInfo from guided section Failed - %r\n", Status));
49218fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    return Status;
49318fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  }
49418fd8d651d7383c429cbcdf3a4262aa32268cd6clgao
49518fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  if (ScratchBufferSize != 0) {
49695276127e373f2e2fb2a208ff77267422a197d9fxgu    //
49718fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    // Allocate scratch buffer
49895276127e373f2e2fb2a208ff77267422a197d9fxgu    //
49918fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));
50018fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    if (ScratchBuffer == NULL) {
50118fd8d651d7383c429cbcdf3a4262aa32268cd6clgao      return EFI_OUT_OF_RESOURCES;
50218fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    }
503d8c79a815f9e993b741ec38cd39498e674e1739elgao  }
50495276127e373f2e2fb2a208ff77267422a197d9fxgu
50518fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  if ((SectionAttribute & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) && OutputBufferSize > 0) {
50618fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    //
50718fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    // Allocate output buffer
50818fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    //
509288f9b382445a50278155f703ccce9a0293fceb5lgao    *OutputBuffer = AllocatePages (EFI_SIZE_TO_PAGES (OutputBufferSize) + 1);
51018fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    if (*OutputBuffer == NULL) {
51118fd8d651d7383c429cbcdf3a4262aa32268cd6clgao      return EFI_OUT_OF_RESOURCES;
51218fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    }
513288f9b382445a50278155f703ccce9a0293fceb5lgao    DEBUG ((EFI_D_INFO, "Customed Guided section Memory Size required is 0x%x and address is 0x%p\n", OutputBufferSize, *OutputBuffer));
514288f9b382445a50278155f703ccce9a0293fceb5lgao    //
515288f9b382445a50278155f703ccce9a0293fceb5lgao    // *OutputBuffer still is one section. Adjust *OutputBuffer offset,
516288f9b382445a50278155f703ccce9a0293fceb5lgao    // skip EFI section header to make section data at page alignment.
517288f9b382445a50278155f703ccce9a0293fceb5lgao    //
518288f9b382445a50278155f703ccce9a0293fceb5lgao    *OutputBuffer = (VOID *)((UINT8 *) *OutputBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER));
51995276127e373f2e2fb2a208ff77267422a197d9fxgu  }
52018fd8d651d7383c429cbcdf3a4262aa32268cd6clgao
52118fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  Status = ExtractGuidedSectionDecode (
52218fd8d651d7383c429cbcdf3a4262aa32268cd6clgao             InputSection,
52318fd8d651d7383c429cbcdf3a4262aa32268cd6clgao             OutputBuffer,
52418fd8d651d7383c429cbcdf3a4262aa32268cd6clgao             ScratchBuffer,
52518fd8d651d7383c429cbcdf3a4262aa32268cd6clgao             AuthenticationStatus
52618fd8d651d7383c429cbcdf3a4262aa32268cd6clgao           );
52795276127e373f2e2fb2a208ff77267422a197d9fxgu
528d8c79a815f9e993b741ec38cd39498e674e1739elgao  if (EFI_ERROR (Status)) {
529d8c79a815f9e993b741ec38cd39498e674e1739elgao    //
53018fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    // Decode failed
531d8c79a815f9e993b741ec38cd39498e674e1739elgao    //
532d8c79a815f9e993b741ec38cd39498e674e1739elgao    DEBUG ((EFI_D_ERROR, "Extract guided section Failed - %r\n", Status));
533d8c79a815f9e993b741ec38cd39498e674e1739elgao    return Status;
534d8c79a815f9e993b741ec38cd39498e674e1739elgao  }
535d8c79a815f9e993b741ec38cd39498e674e1739elgao
53618fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  *OutputSize = (UINTN) OutputBufferSize;
53718fd8d651d7383c429cbcdf3a4262aa32268cd6clgao
53895276127e373f2e2fb2a208ff77267422a197d9fxgu  return EFI_SUCCESS;
53995276127e373f2e2fb2a208ff77267422a197d9fxgu}
540b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
541b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3kluSTATIC
542b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3kluEFI_STATUS
543b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3kluEFIAPI
544b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3kluDecompress (
545b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  IN CONST  EFI_PEI_DECOMPRESS_PPI  *This,
546b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  IN CONST  EFI_COMPRESSION_SECTION *CompressionSection,
547b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  OUT       VOID                    **OutputBuffer,
548b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  OUT       UINTN                   *OutputSize
549b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu )
550b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu{
551b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  EFI_STATUS                      Status;
552b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  UINT8                           *DstBuffer;
553b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  UINT8                           *ScratchBuffer;
554b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  UINTN                           DstBufferSize;
555b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  UINT32                          ScratchBufferSize;
556b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  EFI_COMMON_SECTION_HEADER       *Section;
557b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  UINTN                           SectionLength;
558b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
559b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  if (CompressionSection->CommonHeader.Type != EFI_SECTION_COMPRESSION) {
560b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    ASSERT (FALSE);
561b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    return EFI_INVALID_PARAMETER;
562b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  }
563b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
564b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  Section = (EFI_COMMON_SECTION_HEADER *) CompressionSection;
565b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  SectionLength         = *(UINT32 *) (Section->Size) & 0x00ffffff;
566b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
567b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  //
568b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  // This is a compression set, expand it
569b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  //
570b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  switch (CompressionSection->CompressionType) {
571b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  case EFI_STANDARD_COMPRESSION:
572b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
573b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    // Load EFI standard compression.
574b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    // For compressed data, decompress them to dstbuffer.
575b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
576b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    Status = UefiDecompressGetInfo (
577b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu               (UINT8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),
578b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu               (UINT32) SectionLength - sizeof (EFI_COMPRESSION_SECTION),
579b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu               (UINT32 *) &DstBufferSize,
580b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu               &ScratchBufferSize
581b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu               );
582b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    if (EFI_ERROR (Status)) {
583b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      //
584b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      // GetInfo failed
585b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      //
586b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      DEBUG ((EFI_D_ERROR, "Decompress GetInfo Failed - %r\n", Status));
587b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      return EFI_NOT_FOUND;
588b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    }
589b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
590b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    // Allocate scratch buffer
591b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
592b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));
593b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    if (ScratchBuffer == NULL) {
594b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      return EFI_OUT_OF_RESOURCES;
595b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    }
596b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
597288f9b382445a50278155f703ccce9a0293fceb5lgao    // Allocate destination buffer, extra one page for adjustment
598b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
599288f9b382445a50278155f703ccce9a0293fceb5lgao    DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize) + 1);
600b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    if (DstBuffer == NULL) {
601b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      return EFI_OUT_OF_RESOURCES;
602b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    }
603b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
604288f9b382445a50278155f703ccce9a0293fceb5lgao    // DstBuffer still is one section. Adjust DstBuffer offset, skip EFI section header
605288f9b382445a50278155f703ccce9a0293fceb5lgao    // to make section data at page alignment.
606288f9b382445a50278155f703ccce9a0293fceb5lgao    //
607288f9b382445a50278155f703ccce9a0293fceb5lgao    DstBuffer = DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER);
608288f9b382445a50278155f703ccce9a0293fceb5lgao    //
609b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    // Call decompress function
610b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
611b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    Status = UefiDecompress (
612b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu                (CHAR8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),
613b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu                DstBuffer,
614b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu                ScratchBuffer
615b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu                );
616b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    if (EFI_ERROR (Status)) {
617b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      //
618b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      // Decompress failed
619b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      //
620b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      DEBUG ((EFI_D_ERROR, "Decompress Failed - %r\n", Status));
621b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      return EFI_NOT_FOUND;
622b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    }
623b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    break;
624b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
625b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  case EFI_NOT_COMPRESSED:
626b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
627b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    // Allocate destination buffer
628b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
629b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    DstBufferSize = CompressionSection->UncompressedLength;
630288f9b382445a50278155f703ccce9a0293fceb5lgao    DstBuffer     = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize) + 1);
631b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    if (DstBuffer == NULL) {
632b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      return EFI_OUT_OF_RESOURCES;
633b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    }
634b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
635288f9b382445a50278155f703ccce9a0293fceb5lgao    // Adjust DstBuffer offset, skip EFI section header
636288f9b382445a50278155f703ccce9a0293fceb5lgao    // to make section data at page alignment.
637288f9b382445a50278155f703ccce9a0293fceb5lgao    //
638288f9b382445a50278155f703ccce9a0293fceb5lgao    DstBuffer = DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER);
639288f9b382445a50278155f703ccce9a0293fceb5lgao    //
640b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    // stream is not actually compressed, just encapsulated.  So just copy it.
641b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
642b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    CopyMem (DstBuffer, CompressionSection + 1, DstBufferSize);
643b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    break;
644b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
645b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  default:
646b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
647b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    // Don't support other unknown compression type.
648b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
649b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    ASSERT (FALSE);
650b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    return EFI_NOT_FOUND;
651b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  }
652b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
653b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  *OutputSize = DstBufferSize;
654b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  *OutputBuffer = DstBuffer;
655b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
656b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  return EFI_SUCCESS;
657b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu}
658b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
65930c8f8616d9f2c764e4b8c3566bef4f562115005qhuangVOID
66030c8f8616d9f2c764e4b8c3566bef4f562115005qhuangUpdateStackHob (
66130c8f8616d9f2c764e4b8c3566bef4f562115005qhuang  IN EFI_PHYSICAL_ADDRESS        BaseAddress,
66230c8f8616d9f2c764e4b8c3566bef4f562115005qhuang  IN UINT64                      Length
66330c8f8616d9f2c764e4b8c3566bef4f562115005qhuang  )
66430c8f8616d9f2c764e4b8c3566bef4f562115005qhuang{
66530c8f8616d9f2c764e4b8c3566bef4f562115005qhuang  EFI_PEI_HOB_POINTERS           Hob;
66630c8f8616d9f2c764e4b8c3566bef4f562115005qhuang
66730c8f8616d9f2c764e4b8c3566bef4f562115005qhuang  Hob.Raw = GetHobList ();
66830c8f8616d9f2c764e4b8c3566bef4f562115005qhuang  while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) {
66930c8f8616d9f2c764e4b8c3566bef4f562115005qhuang    if (CompareGuid (&gEfiHobMemoryAllocStackGuid, &(Hob.MemoryAllocationStack->AllocDescriptor.Name))) {
67030c8f8616d9f2c764e4b8c3566bef4f562115005qhuang      //
67130c8f8616d9f2c764e4b8c3566bef4f562115005qhuang      // Build a new memory allocation HOB with old stack info with EfiConventionalMemory type
67230c8f8616d9f2c764e4b8c3566bef4f562115005qhuang      // to be reclaimed by DXE core.
67330c8f8616d9f2c764e4b8c3566bef4f562115005qhuang      //
67430c8f8616d9f2c764e4b8c3566bef4f562115005qhuang      BuildMemoryAllocationHob (
67530c8f8616d9f2c764e4b8c3566bef4f562115005qhuang        Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress,
67630c8f8616d9f2c764e4b8c3566bef4f562115005qhuang        Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength,
67730c8f8616d9f2c764e4b8c3566bef4f562115005qhuang        EfiConventionalMemory
67830c8f8616d9f2c764e4b8c3566bef4f562115005qhuang        );
67930c8f8616d9f2c764e4b8c3566bef4f562115005qhuang      //
68030c8f8616d9f2c764e4b8c3566bef4f562115005qhuang      // Update the BSP Stack Hob to reflect the new stack info.
68130c8f8616d9f2c764e4b8c3566bef4f562115005qhuang      //
68230c8f8616d9f2c764e4b8c3566bef4f562115005qhuang      Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress = BaseAddress;
68330c8f8616d9f2c764e4b8c3566bef4f562115005qhuang      Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength = Length;
68430c8f8616d9f2c764e4b8c3566bef4f562115005qhuang      break;
68530c8f8616d9f2c764e4b8c3566bef4f562115005qhuang    }
68630c8f8616d9f2c764e4b8c3566bef4f562115005qhuang    Hob.Raw = GET_NEXT_HOB (Hob);
68730c8f8616d9f2c764e4b8c3566bef4f562115005qhuang  }
68830c8f8616d9f2c764e4b8c3566bef4f562115005qhuang}
689