196226baa2884ba0776dec3431f84b20cb3062915qhuang/** @file
2b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  Last PEIM.
3b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  Responsibility of this module is to load the DXE Core from a Firmware Volume.
495276127e373f2e2fb2a208ff77267422a197d9fxgu
537623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvinCopyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
6cd5ebaa06dca3e6ef3c464081e6defe00d358c69hhtianThis program and the accompanying materials
795276127e373f2e2fb2a208ff77267422a197d9fxguare licensed and made available under the terms and conditions of the BSD License
895276127e373f2e2fb2a208ff77267422a197d9fxguwhich accompanies this distribution.  The full text of the license may be found at
995276127e373f2e2fb2a208ff77267422a197d9fxguhttp://opensource.org/licenses/bsd-license.php
1095276127e373f2e2fb2a208ff77267422a197d9fxgu
1195276127e373f2e2fb2a208ff77267422a197d9fxguTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
1295276127e373f2e2fb2a208ff77267422a197d9fxguWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
1395276127e373f2e2fb2a208ff77267422a197d9fxgu
14b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu**/
1595276127e373f2e2fb2a208ff77267422a197d9fxgu
1695276127e373f2e2fb2a208ff77267422a197d9fxgu#include "DxeIpl.h"
17b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
1895276127e373f2e2fb2a208ff77267422a197d9fxgu
1995276127e373f2e2fb2a208ff77267422a197d9fxgu//
2048557c6550adecf39e1e8e140b1736275d070dfbqhuang// Module Globals used in the DXE to PEI hand off
2195276127e373f2e2fb2a208ff77267422a197d9fxgu// These must be module globals, so the stack can be switched
2295276127e373f2e2fb2a208ff77267422a197d9fxgu//
239b937a73b079d7368cf309247585e63e6a4afbecqhuangCONST EFI_DXE_IPL_PPI mDxeIplPpi = {
2495276127e373f2e2fb2a208ff77267422a197d9fxgu  DxeLoadCore
2595276127e373f2e2fb2a208ff77267422a197d9fxgu};
2695276127e373f2e2fb2a208ff77267422a197d9fxgu
279b937a73b079d7368cf309247585e63e6a4afbecqhuangCONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI mCustomGuidedSectionExtractionPpi = {
2818fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  CustomGuidedSectionExtract
2995276127e373f2e2fb2a208ff77267422a197d9fxgu};
3095276127e373f2e2fb2a208ff77267422a197d9fxgu
319b937a73b079d7368cf309247585e63e6a4afbecqhuangCONST EFI_PEI_DECOMPRESS_PPI mDecompressPpi = {
32b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  Decompress
33d8c79a815f9e993b741ec38cd39498e674e1739elgao};
34d8c79a815f9e993b741ec38cd39498e674e1739elgao
3548557c6550adecf39e1e8e140b1736275d070dfbqhuangCONST EFI_PEI_PPI_DESCRIPTOR mPpiList[] = {
3695276127e373f2e2fb2a208ff77267422a197d9fxgu  {
37b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    EFI_PEI_PPI_DESCRIPTOR_PPI,
38b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    &gEfiDxeIplPpiGuid,
399b937a73b079d7368cf309247585e63e6a4afbecqhuang    (VOID *) &mDxeIplPpi
4095276127e373f2e2fb2a208ff77267422a197d9fxgu  },
4195276127e373f2e2fb2a208ff77267422a197d9fxgu  {
42b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
43b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    &gEfiPeiDecompressPpiGuid,
449b937a73b079d7368cf309247585e63e6a4afbecqhuang    (VOID *) &mDecompressPpi
4595276127e373f2e2fb2a208ff77267422a197d9fxgu  }
4695276127e373f2e2fb2a208ff77267422a197d9fxgu};
4795276127e373f2e2fb2a208ff77267422a197d9fxgu
4848557c6550adecf39e1e8e140b1736275d070dfbqhuangCONST EFI_PEI_PPI_DESCRIPTOR gEndOfPeiSignalPpi = {
4995276127e373f2e2fb2a208ff77267422a197d9fxgu  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
5095276127e373f2e2fb2a208ff77267422a197d9fxgu  &gEfiEndOfPeiSignalPpiGuid,
5195276127e373f2e2fb2a208ff77267422a197d9fxgu  NULL
5295276127e373f2e2fb2a208ff77267422a197d9fxgu};
5395276127e373f2e2fb2a208ff77267422a197d9fxgu
54b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu/**
5548557c6550adecf39e1e8e140b1736275d070dfbqhuang  Entry point of DXE IPL PEIM.
5648557c6550adecf39e1e8e140b1736275d070dfbqhuang
5748557c6550adecf39e1e8e140b1736275d070dfbqhuang  This function installs DXE IPL PPI and Decompress PPI.  It also reloads
5848557c6550adecf39e1e8e140b1736275d070dfbqhuang  itself to memory on non-S3 resume boot path.
59b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
60a55caa53354b0bb6684f703ba62b403a74e85495lgao  @param  FileHandle  Handle of the file being invoked.
61a55caa53354b0bb6684f703ba62b403a74e85495lgao  @param  PeiServices Describes the list of possible PEI Services.
6291d92e25647e9a26392b454499d309330710a076qhuang
6348557c6550adecf39e1e8e140b1736275d070dfbqhuang  @retval EFI_SUCESS  The entry point of DXE IPL PEIM executes successfully.
6448557c6550adecf39e1e8e140b1736275d070dfbqhuang  @retval Others      Some error occurs during the execution of this function.
6548557c6550adecf39e1e8e140b1736275d070dfbqhuang
6691d92e25647e9a26392b454499d309330710a076qhuang**/
6795276127e373f2e2fb2a208ff77267422a197d9fxguEFI_STATUS
6895276127e373f2e2fb2a208ff77267422a197d9fxguEFIAPI
6995276127e373f2e2fb2a208ff77267422a197d9fxguPeimInitializeDxeIpl (
70a55caa53354b0bb6684f703ba62b403a74e85495lgao  IN       EFI_PEI_FILE_HANDLE  FileHandle,
71a55caa53354b0bb6684f703ba62b403a74e85495lgao  IN CONST EFI_PEI_SERVICES     **PeiServices
7295276127e373f2e2fb2a208ff77267422a197d9fxgu  )
7395276127e373f2e2fb2a208ff77267422a197d9fxgu{
7495276127e373f2e2fb2a208ff77267422a197d9fxgu  EFI_STATUS                                Status;
7595276127e373f2e2fb2a208ff77267422a197d9fxgu  EFI_BOOT_MODE                             BootMode;
7618fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  EFI_GUID                                  *ExtractHandlerGuidTable;
7718fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  UINTN                                     ExtractHandlerNumber;
78d8c79a815f9e993b741ec38cd39498e674e1739elgao  EFI_PEI_PPI_DESCRIPTOR                    *GuidPpi;
79d8c79a815f9e993b741ec38cd39498e674e1739elgao
80b98da1b1f9b726f580d05f8680455122ba924da6qhuang  BootMode = GetBootModeHob ();
8195276127e373f2e2fb2a208ff77267422a197d9fxgu
82b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  if (BootMode != BOOT_ON_S3_RESUME) {
83a55caa53354b0bb6684f703ba62b403a74e85495lgao    Status = PeiServicesRegisterForShadow (FileHandle);
84b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    if (Status == EFI_SUCCESS) {
85b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      //
8648557c6550adecf39e1e8e140b1736275d070dfbqhuang      // EFI_SUCESS means it is the first time to call register for shadow.
87b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      //
88b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      return Status;
8948557c6550adecf39e1e8e140b1736275d070dfbqhuang    }
9048557c6550adecf39e1e8e140b1736275d070dfbqhuang
9148557c6550adecf39e1e8e140b1736275d070dfbqhuang    //
9248557c6550adecf39e1e8e140b1736275d070dfbqhuang    // Ensure that DXE IPL is shadowed to permanent memory.
9348557c6550adecf39e1e8e140b1736275d070dfbqhuang    //
9448557c6550adecf39e1e8e140b1736275d070dfbqhuang    ASSERT (Status == EFI_ALREADY_STARTED);
9525bc83266653189715ad789eaad0d6264e5c3481lgao  }
96b98da1b1f9b726f580d05f8680455122ba924da6qhuang
9725bc83266653189715ad789eaad0d6264e5c3481lgao  //
9825bc83266653189715ad789eaad0d6264e5c3481lgao  // Get custom extract guided section method guid list
9925bc83266653189715ad789eaad0d6264e5c3481lgao  //
10025bc83266653189715ad789eaad0d6264e5c3481lgao  ExtractHandlerNumber = ExtractGuidedSectionGetGuidList (&ExtractHandlerGuidTable);
10125bc83266653189715ad789eaad0d6264e5c3481lgao
10225bc83266653189715ad789eaad0d6264e5c3481lgao  //
10325bc83266653189715ad789eaad0d6264e5c3481lgao  // Install custom extraction guid PPI
10425bc83266653189715ad789eaad0d6264e5c3481lgao  //
10525bc83266653189715ad789eaad0d6264e5c3481lgao  if (ExtractHandlerNumber > 0) {
10625bc83266653189715ad789eaad0d6264e5c3481lgao    GuidPpi = (EFI_PEI_PPI_DESCRIPTOR *) AllocatePool (ExtractHandlerNumber * sizeof (EFI_PEI_PPI_DESCRIPTOR));
10725bc83266653189715ad789eaad0d6264e5c3481lgao    ASSERT (GuidPpi != NULL);
10825bc83266653189715ad789eaad0d6264e5c3481lgao    while (ExtractHandlerNumber-- > 0) {
10925bc83266653189715ad789eaad0d6264e5c3481lgao      GuidPpi->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
11025bc83266653189715ad789eaad0d6264e5c3481lgao      GuidPpi->Ppi   = (VOID *) &mCustomGuidedSectionExtractionPpi;
11125bc83266653189715ad789eaad0d6264e5c3481lgao      GuidPpi->Guid  = &ExtractHandlerGuidTable[ExtractHandlerNumber];
11225bc83266653189715ad789eaad0d6264e5c3481lgao      Status = PeiServicesInstallPpi (GuidPpi++);
11325bc83266653189715ad789eaad0d6264e5c3481lgao      ASSERT_EFI_ERROR(Status);
114d8c79a815f9e993b741ec38cd39498e674e1739elgao    }
11595276127e373f2e2fb2a208ff77267422a197d9fxgu  }
11695276127e373f2e2fb2a208ff77267422a197d9fxgu
117b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  //
118288f9b382445a50278155f703ccce9a0293fceb5lgao  // Install DxeIpl and Decompress PPIs.
119b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  //
120b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  Status = PeiServicesInstallPpi (mPpiList);
121288f9b382445a50278155f703ccce9a0293fceb5lgao  ASSERT_EFI_ERROR(Status);
122288f9b382445a50278155f703ccce9a0293fceb5lgao
12395276127e373f2e2fb2a208ff77267422a197d9fxgu  return Status;
12495276127e373f2e2fb2a208ff77267422a197d9fxgu}
12595276127e373f2e2fb2a208ff77267422a197d9fxgu
126b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu/**
127a95b6045c32b8ea2c564c6848f00d785056dd56fydong   Validate variable data for the MemoryTypeInformation.
128a95b6045c32b8ea2c564c6848f00d785056dd56fydong
129a95b6045c32b8ea2c564c6848f00d785056dd56fydong   @param MemoryData       Variable data.
130a95b6045c32b8ea2c564c6848f00d785056dd56fydong   @param MemoryDataSize   Variable data length.
131a95b6045c32b8ea2c564c6848f00d785056dd56fydong
132a95b6045c32b8ea2c564c6848f00d785056dd56fydong   @return TRUE            The variable data is valid.
133a95b6045c32b8ea2c564c6848f00d785056dd56fydong   @return FALSE           The variable data is invalid.
134a95b6045c32b8ea2c564c6848f00d785056dd56fydong
135a95b6045c32b8ea2c564c6848f00d785056dd56fydong**/
136a95b6045c32b8ea2c564c6848f00d785056dd56fydongBOOLEAN
137a95b6045c32b8ea2c564c6848f00d785056dd56fydongValidateMemoryTypeInfoVariable (
138a95b6045c32b8ea2c564c6848f00d785056dd56fydong  IN EFI_MEMORY_TYPE_INFORMATION      *MemoryData,
139a95b6045c32b8ea2c564c6848f00d785056dd56fydong  IN UINTN                            MemoryDataSize
140a95b6045c32b8ea2c564c6848f00d785056dd56fydong  )
141a95b6045c32b8ea2c564c6848f00d785056dd56fydong{
142a95b6045c32b8ea2c564c6848f00d785056dd56fydong  UINTN                       Count;
143a95b6045c32b8ea2c564c6848f00d785056dd56fydong  UINTN                       Index;
144a95b6045c32b8ea2c564c6848f00d785056dd56fydong
145a95b6045c32b8ea2c564c6848f00d785056dd56fydong  // Check the input parameter.
146a95b6045c32b8ea2c564c6848f00d785056dd56fydong  if (MemoryData == NULL) {
147a95b6045c32b8ea2c564c6848f00d785056dd56fydong    return FALSE;
148a95b6045c32b8ea2c564c6848f00d785056dd56fydong  }
149a95b6045c32b8ea2c564c6848f00d785056dd56fydong
150a95b6045c32b8ea2c564c6848f00d785056dd56fydong  // Get Count
151a95b6045c32b8ea2c564c6848f00d785056dd56fydong  Count = MemoryDataSize / sizeof (*MemoryData);
152a95b6045c32b8ea2c564c6848f00d785056dd56fydong
153a95b6045c32b8ea2c564c6848f00d785056dd56fydong  // Check Size
154a95b6045c32b8ea2c564c6848f00d785056dd56fydong  if (Count * sizeof(*MemoryData) != MemoryDataSize) {
155a95b6045c32b8ea2c564c6848f00d785056dd56fydong    return FALSE;
156a95b6045c32b8ea2c564c6848f00d785056dd56fydong  }
157a95b6045c32b8ea2c564c6848f00d785056dd56fydong
158a95b6045c32b8ea2c564c6848f00d785056dd56fydong  // Check last entry type filed.
159a95b6045c32b8ea2c564c6848f00d785056dd56fydong  if (MemoryData[Count - 1].Type != EfiMaxMemoryType) {
160a95b6045c32b8ea2c564c6848f00d785056dd56fydong    return FALSE;
161a95b6045c32b8ea2c564c6848f00d785056dd56fydong  }
162a95b6045c32b8ea2c564c6848f00d785056dd56fydong
163a95b6045c32b8ea2c564c6848f00d785056dd56fydong  // Check the type filed.
164a95b6045c32b8ea2c564c6848f00d785056dd56fydong  for (Index = 0; Index < Count - 1; Index++) {
165a95b6045c32b8ea2c564c6848f00d785056dd56fydong    if (MemoryData[Index].Type >= EfiMaxMemoryType) {
166a95b6045c32b8ea2c564c6848f00d785056dd56fydong      return FALSE;
167a95b6045c32b8ea2c564c6848f00d785056dd56fydong    }
168a95b6045c32b8ea2c564c6848f00d785056dd56fydong  }
169a95b6045c32b8ea2c564c6848f00d785056dd56fydong
170a95b6045c32b8ea2c564c6848f00d785056dd56fydong  return TRUE;
171a95b6045c32b8ea2c564c6848f00d785056dd56fydong}
172a95b6045c32b8ea2c564c6848f00d785056dd56fydong
173a95b6045c32b8ea2c564c6848f00d785056dd56fydong/**
174b98da1b1f9b726f580d05f8680455122ba924da6qhuang   Main entry point to last PEIM.
17548557c6550adecf39e1e8e140b1736275d070dfbqhuang
17648557c6550adecf39e1e8e140b1736275d070dfbqhuang   This function finds DXE Core in the firmware volume and transfer the control to
17748557c6550adecf39e1e8e140b1736275d070dfbqhuang   DXE core.
178b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
179b98da1b1f9b726f580d05f8680455122ba924da6qhuang   @param This          Entry point for DXE IPL PPI.
180b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu   @param PeiServices   General purpose services available to every PEIM.
181b98da1b1f9b726f580d05f8680455122ba924da6qhuang   @param HobList       Address to the Pei HOB list.
182b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
183b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu   @return EFI_SUCCESS              DXE core was successfully loaded.
184b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu   @return EFI_OUT_OF_RESOURCES     There are not enough resources to load DXE core.
18591d92e25647e9a26392b454499d309330710a076qhuang
186b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu**/
18795276127e373f2e2fb2a208ff77267422a197d9fxguEFI_STATUS
18895276127e373f2e2fb2a208ff77267422a197d9fxguEFIAPI
18995276127e373f2e2fb2a208ff77267422a197d9fxguDxeLoadCore (
1901f3a753ee68ac1c7a620e8064fdda718cf413761xli  IN CONST EFI_DXE_IPL_PPI *This,
19195276127e373f2e2fb2a208ff77267422a197d9fxgu  IN EFI_PEI_SERVICES      **PeiServices,
19295276127e373f2e2fb2a208ff77267422a197d9fxgu  IN EFI_PEI_HOB_POINTERS  HobList
19395276127e373f2e2fb2a208ff77267422a197d9fxgu  )
19495276127e373f2e2fb2a208ff77267422a197d9fxgu{
19595276127e373f2e2fb2a208ff77267422a197d9fxgu  EFI_STATUS                                Status;
196b6b98e9133020e8e7752200b496ffe073d673883qhuang  EFI_FV_FILE_INFO                          DxeCoreFileInfo;
19795276127e373f2e2fb2a208ff77267422a197d9fxgu  EFI_PHYSICAL_ADDRESS                      DxeCoreAddress;
19895276127e373f2e2fb2a208ff77267422a197d9fxgu  UINT64                                    DxeCoreSize;
19995276127e373f2e2fb2a208ff77267422a197d9fxgu  EFI_PHYSICAL_ADDRESS                      DxeCoreEntryPoint;
20095276127e373f2e2fb2a208ff77267422a197d9fxgu  EFI_BOOT_MODE                             BootMode;
201b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  EFI_PEI_FILE_HANDLE                       FileHandle;
202b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney  EFI_PEI_READ_ONLY_VARIABLE2_PPI           *Variable;
20328efc722c49a974e8d77f4a8d4782b4e1a0a2f5fqhuang  EFI_PEI_LOAD_FILE_PPI                     *LoadFile;
20428efc722c49a974e8d77f4a8d4782b4e1a0a2f5fqhuang  UINTN                                     Instance;
20528efc722c49a974e8d77f4a8d4782b4e1a0a2f5fqhuang  UINT32                                    AuthenticationState;
206b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney  UINTN                                     DataSize;
20777215d10c065729798a2cb4734d8707cdedc0872jchen  EFI_PEI_S3_RESUME2_PPI                    *S3Resume;
20828efc722c49a974e8d77f4a8d4782b4e1a0a2f5fqhuang  EFI_PEI_RECOVERY_MODULE_PPI               *PeiRecovery;
209708919bef7fa8e0ae611173fbe7d297c74acd3d4qhuang  EFI_MEMORY_TYPE_INFORMATION               MemoryData[EfiMaxMemoryType + 1];
21095276127e373f2e2fb2a208ff77267422a197d9fxgu
21195276127e373f2e2fb2a208ff77267422a197d9fxgu  //
21295276127e373f2e2fb2a208ff77267422a197d9fxgu  // if in S3 Resume, restore configure
21395276127e373f2e2fb2a208ff77267422a197d9fxgu  //
214b98da1b1f9b726f580d05f8680455122ba924da6qhuang  BootMode = GetBootModeHob ();
21595276127e373f2e2fb2a208ff77267422a197d9fxgu
21695276127e373f2e2fb2a208ff77267422a197d9fxgu  if (BootMode == BOOT_ON_S3_RESUME) {
21728efc722c49a974e8d77f4a8d4782b4e1a0a2f5fqhuang    Status = PeiServicesLocatePpi (
21877215d10c065729798a2cb4734d8707cdedc0872jchen               &gEfiPeiS3Resume2PpiGuid,
21928efc722c49a974e8d77f4a8d4782b4e1a0a2f5fqhuang               0,
22028efc722c49a974e8d77f4a8d4782b4e1a0a2f5fqhuang               NULL,
22128efc722c49a974e8d77f4a8d4782b4e1a0a2f5fqhuang               (VOID **) &S3Resume
22228efc722c49a974e8d77f4a8d4782b4e1a0a2f5fqhuang               );
22337623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin    if (EFI_ERROR (Status)) {
22437623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin      //
22537623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin      // Report Status code that S3Resume PPI can not be found
22637623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin      //
22737623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin      REPORT_STATUS_CODE (
22837623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin        EFI_ERROR_CODE | EFI_ERROR_MAJOR,
22937623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin        (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_RESUME_PPI_NOT_FOUND)
23037623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin        );
23137623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin    }
23228efc722c49a974e8d77f4a8d4782b4e1a0a2f5fqhuang    ASSERT_EFI_ERROR (Status);
23328efc722c49a974e8d77f4a8d4782b4e1a0a2f5fqhuang
23477215d10c065729798a2cb4734d8707cdedc0872jchen    Status = S3Resume->S3RestoreConfig2 (S3Resume);
23595276127e373f2e2fb2a208ff77267422a197d9fxgu    ASSERT_EFI_ERROR (Status);
23695276127e373f2e2fb2a208ff77267422a197d9fxgu  } else if (BootMode == BOOT_IN_RECOVERY_MODE) {
23737623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin    REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_RECOVERY_BEGIN));
23828efc722c49a974e8d77f4a8d4782b4e1a0a2f5fqhuang    Status = PeiServicesLocatePpi (
23928efc722c49a974e8d77f4a8d4782b4e1a0a2f5fqhuang               &gEfiPeiRecoveryModulePpiGuid,
24028efc722c49a974e8d77f4a8d4782b4e1a0a2f5fqhuang               0,
24128efc722c49a974e8d77f4a8d4782b4e1a0a2f5fqhuang               NULL,
24228efc722c49a974e8d77f4a8d4782b4e1a0a2f5fqhuang               (VOID **) &PeiRecovery
24328efc722c49a974e8d77f4a8d4782b4e1a0a2f5fqhuang               );
24483d06ed90fdc94f94c7687bb010ad605fa94767bli-elvin
24583d06ed90fdc94f94c7687bb010ad605fa94767bli-elvin    if (EFI_ERROR (Status)) {
24683d06ed90fdc94f94c7687bb010ad605fa94767bli-elvin      DEBUG ((DEBUG_ERROR, "Locate Recovery PPI Failed.(Status = %r)\n", Status));
24783d06ed90fdc94f94c7687bb010ad605fa94767bli-elvin      //
24883d06ed90fdc94f94c7687bb010ad605fa94767bli-elvin      // Report Status code the failure of locating Recovery PPI
24983d06ed90fdc94f94c7687bb010ad605fa94767bli-elvin      //
25083d06ed90fdc94f94c7687bb010ad605fa94767bli-elvin      REPORT_STATUS_CODE (
25183d06ed90fdc94f94c7687bb010ad605fa94767bli-elvin        EFI_ERROR_CODE | EFI_ERROR_MAJOR,
25283d06ed90fdc94f94c7687bb010ad605fa94767bli-elvin        (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_RECOVERY_PPI_NOT_FOUND)
25383d06ed90fdc94f94c7687bb010ad605fa94767bli-elvin        );
25483d06ed90fdc94f94c7687bb010ad605fa94767bli-elvin      CpuDeadLoop ();
25583d06ed90fdc94f94c7687bb010ad605fa94767bli-elvin    }
25683d06ed90fdc94f94c7687bb010ad605fa94767bli-elvin
25737623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin    REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_CAPSULE_LOAD));
25828efc722c49a974e8d77f4a8d4782b4e1a0a2f5fqhuang    Status = PeiRecovery->LoadRecoveryCapsule (PeiServices, PeiRecovery);
25995276127e373f2e2fb2a208ff77267422a197d9fxgu    if (EFI_ERROR (Status)) {
26091d92e25647e9a26392b454499d309330710a076qhuang      DEBUG ((DEBUG_ERROR, "Load Recovery Capsule Failed.(Status = %r)\n", Status));
26137623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin      //
26283d06ed90fdc94f94c7687bb010ad605fa94767bli-elvin      // Report Status code that recovery image can not be found
26337623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin      //
26437623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin      REPORT_STATUS_CODE (
26537623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin        EFI_ERROR_CODE | EFI_ERROR_MAJOR,
26637623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin        (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_NO_RECOVERY_CAPSULE)
26737623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin        );
26895276127e373f2e2fb2a208ff77267422a197d9fxgu      CpuDeadLoop ();
26995276127e373f2e2fb2a208ff77267422a197d9fxgu    }
27037623a5c029e5415fe24b86bf4f6481f8fdfad94li-elvin    REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_CAPSULE_START));
27195276127e373f2e2fb2a208ff77267422a197d9fxgu    //
27248557c6550adecf39e1e8e140b1736275d070dfbqhuang    // Now should have a HOB with the DXE core
27395276127e373f2e2fb2a208ff77267422a197d9fxgu    //
27495276127e373f2e2fb2a208ff77267422a197d9fxgu  }
275288f9b382445a50278155f703ccce9a0293fceb5lgao
276d1d89e86ed786f0170848a800e1569805248cb63Liming Gao  if (GetFirstGuidHob ((CONST EFI_GUID *)&gEfiMemoryTypeInformationGuid) == NULL) {
277d1d89e86ed786f0170848a800e1569805248cb63Liming Gao    //
278d1d89e86ed786f0170848a800e1569805248cb63Liming Gao    // Don't build GuidHob if GuidHob has been installed.
279d1d89e86ed786f0170848a800e1569805248cb63Liming Gao    //
280d1d89e86ed786f0170848a800e1569805248cb63Liming Gao    Status = PeiServicesLocatePpi (
281d1d89e86ed786f0170848a800e1569805248cb63Liming Gao               &gEfiPeiReadOnlyVariable2PpiGuid,
282d1d89e86ed786f0170848a800e1569805248cb63Liming Gao               0,
283d1d89e86ed786f0170848a800e1569805248cb63Liming Gao               NULL,
284d1d89e86ed786f0170848a800e1569805248cb63Liming Gao               (VOID **)&Variable
285d1d89e86ed786f0170848a800e1569805248cb63Liming Gao               );
286d1d89e86ed786f0170848a800e1569805248cb63Liming Gao    if (!EFI_ERROR (Status)) {
287d1d89e86ed786f0170848a800e1569805248cb63Liming Gao      DataSize = sizeof (MemoryData);
288d1d89e86ed786f0170848a800e1569805248cb63Liming Gao      Status = Variable->GetVariable (
289d1d89e86ed786f0170848a800e1569805248cb63Liming Gao                           Variable,
290d1d89e86ed786f0170848a800e1569805248cb63Liming Gao                           EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,
291d1d89e86ed786f0170848a800e1569805248cb63Liming Gao                           &gEfiMemoryTypeInformationGuid,
292d1d89e86ed786f0170848a800e1569805248cb63Liming Gao                           NULL,
293d1d89e86ed786f0170848a800e1569805248cb63Liming Gao                           &DataSize,
294d1d89e86ed786f0170848a800e1569805248cb63Liming Gao                           &MemoryData
295d1d89e86ed786f0170848a800e1569805248cb63Liming Gao                           );
296d1d89e86ed786f0170848a800e1569805248cb63Liming Gao      if (!EFI_ERROR (Status) && ValidateMemoryTypeInfoVariable(MemoryData, DataSize)) {
297d1d89e86ed786f0170848a800e1569805248cb63Liming Gao        //
298d1d89e86ed786f0170848a800e1569805248cb63Liming Gao        // Build the GUID'd HOB for DXE
299d1d89e86ed786f0170848a800e1569805248cb63Liming Gao        //
300d1d89e86ed786f0170848a800e1569805248cb63Liming Gao        BuildGuidDataHob (
301d1d89e86ed786f0170848a800e1569805248cb63Liming Gao          &gEfiMemoryTypeInformationGuid,
302d1d89e86ed786f0170848a800e1569805248cb63Liming Gao          MemoryData,
303d1d89e86ed786f0170848a800e1569805248cb63Liming Gao          DataSize
304d1d89e86ed786f0170848a800e1569805248cb63Liming Gao          );
305d1d89e86ed786f0170848a800e1569805248cb63Liming Gao      }
3061ad76c3466e260a7d58ba260eddc1e87beabee79mdkinney    }
307b74350e9562f0ad4400afdbc2a157d66f55fb113mdkinney  }
308288f9b382445a50278155f703ccce9a0293fceb5lgao
30995276127e373f2e2fb2a208ff77267422a197d9fxgu  //
310b6b98e9133020e8e7752200b496ffe073d673883qhuang  // Look in all the FVs present in PEI and find the DXE Core FileHandle
31195276127e373f2e2fb2a208ff77267422a197d9fxgu  //
312b6b98e9133020e8e7752200b496ffe073d673883qhuang  FileHandle = DxeIplFindDxeCore ();
313b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
31495276127e373f2e2fb2a208ff77267422a197d9fxgu  //
31528efc722c49a974e8d77f4a8d4782b4e1a0a2f5fqhuang  // Load the DXE Core from a Firmware Volume.
31695276127e373f2e2fb2a208ff77267422a197d9fxgu  //
31728efc722c49a974e8d77f4a8d4782b4e1a0a2f5fqhuang  Instance = 0;
31828efc722c49a974e8d77f4a8d4782b4e1a0a2f5fqhuang  do {
31928efc722c49a974e8d77f4a8d4782b4e1a0a2f5fqhuang    Status = PeiServicesLocatePpi (&gEfiPeiLoadFilePpiGuid, Instance++, NULL, (VOID **) &LoadFile);
32028efc722c49a974e8d77f4a8d4782b4e1a0a2f5fqhuang    //
32128efc722c49a974e8d77f4a8d4782b4e1a0a2f5fqhuang    // These must exist an instance of EFI_PEI_LOAD_FILE_PPI to support to load DxeCore file handle successfully.
32228efc722c49a974e8d77f4a8d4782b4e1a0a2f5fqhuang    //
32328efc722c49a974e8d77f4a8d4782b4e1a0a2f5fqhuang    ASSERT_EFI_ERROR (Status);
32428efc722c49a974e8d77f4a8d4782b4e1a0a2f5fqhuang
32528efc722c49a974e8d77f4a8d4782b4e1a0a2f5fqhuang    Status = LoadFile->LoadFile (
32628efc722c49a974e8d77f4a8d4782b4e1a0a2f5fqhuang                         LoadFile,
32728efc722c49a974e8d77f4a8d4782b4e1a0a2f5fqhuang                         FileHandle,
32828efc722c49a974e8d77f4a8d4782b4e1a0a2f5fqhuang                         &DxeCoreAddress,
32928efc722c49a974e8d77f4a8d4782b4e1a0a2f5fqhuang                         &DxeCoreSize,
33028efc722c49a974e8d77f4a8d4782b4e1a0a2f5fqhuang                         &DxeCoreEntryPoint,
33128efc722c49a974e8d77f4a8d4782b4e1a0a2f5fqhuang                         &AuthenticationState
33228efc722c49a974e8d77f4a8d4782b4e1a0a2f5fqhuang                         );
33328efc722c49a974e8d77f4a8d4782b4e1a0a2f5fqhuang  } while (EFI_ERROR (Status));
33495276127e373f2e2fb2a208ff77267422a197d9fxgu
33595276127e373f2e2fb2a208ff77267422a197d9fxgu  //
336b6b98e9133020e8e7752200b496ffe073d673883qhuang  // Get the DxeCore File Info from the FileHandle for the DxeCore GUID file name.
337b6b98e9133020e8e7752200b496ffe073d673883qhuang  //
338b6b98e9133020e8e7752200b496ffe073d673883qhuang  Status = PeiServicesFfsGetFileInfo (FileHandle, &DxeCoreFileInfo);
339b6b98e9133020e8e7752200b496ffe073d673883qhuang  ASSERT_EFI_ERROR (Status);
340b6b98e9133020e8e7752200b496ffe073d673883qhuang
341b6b98e9133020e8e7752200b496ffe073d673883qhuang  //
34295276127e373f2e2fb2a208ff77267422a197d9fxgu  // Add HOB for the DXE Core
34395276127e373f2e2fb2a208ff77267422a197d9fxgu  //
34495276127e373f2e2fb2a208ff77267422a197d9fxgu  BuildModuleHob (
345b6b98e9133020e8e7752200b496ffe073d673883qhuang    &DxeCoreFileInfo.FileName,
34695276127e373f2e2fb2a208ff77267422a197d9fxgu    DxeCoreAddress,
34748557c6550adecf39e1e8e140b1736275d070dfbqhuang    ALIGN_VALUE (DxeCoreSize, EFI_PAGE_SIZE),
34895276127e373f2e2fb2a208ff77267422a197d9fxgu    DxeCoreEntryPoint
34995276127e373f2e2fb2a208ff77267422a197d9fxgu    );
35095276127e373f2e2fb2a208ff77267422a197d9fxgu
35195276127e373f2e2fb2a208ff77267422a197d9fxgu  //
35295276127e373f2e2fb2a208ff77267422a197d9fxgu  // Report Status Code EFI_SW_PEI_PC_HANDOFF_TO_NEXT
35395276127e373f2e2fb2a208ff77267422a197d9fxgu  //
354f9876ecf8a296a8e0d4ad8d22ed5ff12ecc11f65xli  REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_CORE | EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT));
35595276127e373f2e2fb2a208ff77267422a197d9fxgu
3564e2dd553a6531e04d2ceb55e1f91159188ba51ecmdkinney  DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading DXE CORE at 0x%11p EntryPoint=0x%11p\n", (VOID *)(UINTN)DxeCoreAddress, FUNCTION_ENTRY_POINT (DxeCoreEntryPoint)));
357e98cd821ebedd6472c12738bd53dc7cfd02bb4fblgao
35895276127e373f2e2fb2a208ff77267422a197d9fxgu  //
35995276127e373f2e2fb2a208ff77267422a197d9fxgu  // Transfer control to the DXE Core
36048557c6550adecf39e1e8e140b1736275d070dfbqhuang  // The hand off state is simply a pointer to the HOB list
36195276127e373f2e2fb2a208ff77267422a197d9fxgu  //
3629b937a73b079d7368cf309247585e63e6a4afbecqhuang  HandOffToDxeCore (DxeCoreEntryPoint, HobList);
36395276127e373f2e2fb2a208ff77267422a197d9fxgu  //
36495276127e373f2e2fb2a208ff77267422a197d9fxgu  // If we get here, then the DXE Core returned.  This is an error
36548557c6550adecf39e1e8e140b1736275d070dfbqhuang  // DxeCore should not return.
36695276127e373f2e2fb2a208ff77267422a197d9fxgu  //
36795276127e373f2e2fb2a208ff77267422a197d9fxgu  ASSERT (FALSE);
36895276127e373f2e2fb2a208ff77267422a197d9fxgu  CpuDeadLoop ();
36995276127e373f2e2fb2a208ff77267422a197d9fxgu
37095276127e373f2e2fb2a208ff77267422a197d9fxgu  return EFI_OUT_OF_RESOURCES;
37195276127e373f2e2fb2a208ff77267422a197d9fxgu}
37295276127e373f2e2fb2a208ff77267422a197d9fxgu
37391d92e25647e9a26392b454499d309330710a076qhuang
374b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu/**
3759b937a73b079d7368cf309247585e63e6a4afbecqhuang   Searches DxeCore in all firmware Volumes and loads the first
3769b937a73b079d7368cf309247585e63e6a4afbecqhuang   instance that contains DxeCore.
377b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
3789b937a73b079d7368cf309247585e63e6a4afbecqhuang   @return FileHandle of DxeCore to load DxeCore.
3799b937a73b079d7368cf309247585e63e6a4afbecqhuang
38091d92e25647e9a26392b454499d309330710a076qhuang**/
3819b937a73b079d7368cf309247585e63e6a4afbecqhuangEFI_PEI_FILE_HANDLE
382288f9b382445a50278155f703ccce9a0293fceb5lgaoDxeIplFindDxeCore (
383b6b98e9133020e8e7752200b496ffe073d673883qhuang  VOID
384b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  )
38595276127e373f2e2fb2a208ff77267422a197d9fxgu{
3869b937a73b079d7368cf309247585e63e6a4afbecqhuang  EFI_STATUS            Status;
3879b937a73b079d7368cf309247585e63e6a4afbecqhuang  UINTN                 Instance;
3889b937a73b079d7368cf309247585e63e6a4afbecqhuang  EFI_PEI_FV_HANDLE     VolumeHandle;
3899b937a73b079d7368cf309247585e63e6a4afbecqhuang  EFI_PEI_FILE_HANDLE   FileHandle;
390288f9b382445a50278155f703ccce9a0293fceb5lgao
391288f9b382445a50278155f703ccce9a0293fceb5lgao  Instance    = 0;
3929b937a73b079d7368cf309247585e63e6a4afbecqhuang  while (TRUE) {
3939b937a73b079d7368cf309247585e63e6a4afbecqhuang    //
3949b937a73b079d7368cf309247585e63e6a4afbecqhuang    // Traverse all firmware volume instances
3959b937a73b079d7368cf309247585e63e6a4afbecqhuang    //
3969b937a73b079d7368cf309247585e63e6a4afbecqhuang    Status = PeiServicesFfsFindNextVolume (Instance, &VolumeHandle);
3979b937a73b079d7368cf309247585e63e6a4afbecqhuang    //
3989b937a73b079d7368cf309247585e63e6a4afbecqhuang    // If some error occurs here, then we cannot find any firmware
3999b937a73b079d7368cf309247585e63e6a4afbecqhuang    // volume that may contain DxeCore.
4009b937a73b079d7368cf309247585e63e6a4afbecqhuang    //
4013d0a23854e80f952458bd74c4666f2887e79cac9li-elvin    if (EFI_ERROR (Status)) {
4023d0a23854e80f952458bd74c4666f2887e79cac9li-elvin      REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_CORE_EC_DXE_CORRUPT));
4033d0a23854e80f952458bd74c4666f2887e79cac9li-elvin    }
4049b937a73b079d7368cf309247585e63e6a4afbecqhuang    ASSERT_EFI_ERROR (Status);
4059b937a73b079d7368cf309247585e63e6a4afbecqhuang
4069b937a73b079d7368cf309247585e63e6a4afbecqhuang    //
4079b937a73b079d7368cf309247585e63e6a4afbecqhuang    // Find the DxeCore file type from the beginning in this firmware volume.
4089b937a73b079d7368cf309247585e63e6a4afbecqhuang    //
4099b937a73b079d7368cf309247585e63e6a4afbecqhuang    FileHandle = NULL;
4109b937a73b079d7368cf309247585e63e6a4afbecqhuang    Status = PeiServicesFfsFindNextFile (EFI_FV_FILETYPE_DXE_CORE, VolumeHandle, &FileHandle);
411288f9b382445a50278155f703ccce9a0293fceb5lgao    if (!EFI_ERROR (Status)) {
4129b937a73b079d7368cf309247585e63e6a4afbecqhuang      //
413b6b98e9133020e8e7752200b496ffe073d673883qhuang      // Find DxeCore FileHandle in this volume, then we skip other firmware volume and
414b6b98e9133020e8e7752200b496ffe073d673883qhuang      // return the FileHandle.
4159b937a73b079d7368cf309247585e63e6a4afbecqhuang      //
416b6b98e9133020e8e7752200b496ffe073d673883qhuang      return FileHandle;
41795276127e373f2e2fb2a208ff77267422a197d9fxgu    }
4189b937a73b079d7368cf309247585e63e6a4afbecqhuang    //
4199b937a73b079d7368cf309247585e63e6a4afbecqhuang    // We cannot find DxeCore in this firmware volume, then search the next volume.
4209b937a73b079d7368cf309247585e63e6a4afbecqhuang    //
4219b937a73b079d7368cf309247585e63e6a4afbecqhuang    Instance++;
4229b937a73b079d7368cf309247585e63e6a4afbecqhuang  }
42395276127e373f2e2fb2a208ff77267422a197d9fxgu}
42495276127e373f2e2fb2a208ff77267422a197d9fxgu
42591d92e25647e9a26392b454499d309330710a076qhuang
42691d92e25647e9a26392b454499d309330710a076qhuang
427d8c79a815f9e993b741ec38cd39498e674e1739elgao/**
428d8c79a815f9e993b741ec38cd39498e674e1739elgao  The ExtractSection() function processes the input section and
429d8c79a815f9e993b741ec38cd39498e674e1739elgao  returns a pointer to the section contents. If the section being
430d8c79a815f9e993b741ec38cd39498e674e1739elgao  extracted does not require processing (if the section
431d8c79a815f9e993b741ec38cd39498e674e1739elgao  GuidedSectionHeader.Attributes has the
432d8c79a815f9e993b741ec38cd39498e674e1739elgao  EFI_GUIDED_SECTION_PROCESSING_REQUIRED field cleared), then
433d8c79a815f9e993b741ec38cd39498e674e1739elgao  OutputBuffer is just updated to point to the start of the
434d8c79a815f9e993b741ec38cd39498e674e1739elgao  section's contents. Otherwise, *Buffer must be allocated
435d8c79a815f9e993b741ec38cd39498e674e1739elgao  from PEI permanent memory.
436d8c79a815f9e993b741ec38cd39498e674e1739elgao
437d8c79a815f9e993b741ec38cd39498e674e1739elgao  @param This                   Indicates the
438d8c79a815f9e993b741ec38cd39498e674e1739elgao                                EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI instance.
439d8c79a815f9e993b741ec38cd39498e674e1739elgao                                Buffer containing the input GUIDed section to be
440d8c79a815f9e993b741ec38cd39498e674e1739elgao                                processed. OutputBuffer OutputBuffer is
441d8c79a815f9e993b741ec38cd39498e674e1739elgao                                allocated from PEI permanent memory and contains
442d8c79a815f9e993b741ec38cd39498e674e1739elgao                                the new section stream.
44391d92e25647e9a26392b454499d309330710a076qhuang  @param InputSection           A pointer to the input buffer, which contains
44491d92e25647e9a26392b454499d309330710a076qhuang                                the input section to be processed.
44591d92e25647e9a26392b454499d309330710a076qhuang  @param OutputBuffer           A pointer to a caller-allocated buffer, whose
44691d92e25647e9a26392b454499d309330710a076qhuang                                size is specified by the contents of OutputSize.
447d8c79a815f9e993b741ec38cd39498e674e1739elgao  @param OutputSize             A pointer to a caller-allocated
448d8c79a815f9e993b741ec38cd39498e674e1739elgao                                UINTN in which the size of *OutputBuffer
449d8c79a815f9e993b741ec38cd39498e674e1739elgao                                allocation is stored. If the function
450d8c79a815f9e993b741ec38cd39498e674e1739elgao                                returns anything other than EFI_SUCCESS,
451d8c79a815f9e993b741ec38cd39498e674e1739elgao                                the value of OutputSize is undefined.
452d8c79a815f9e993b741ec38cd39498e674e1739elgao  @param AuthenticationStatus   A pointer to a caller-allocated
453d8c79a815f9e993b741ec38cd39498e674e1739elgao                                UINT32 that indicates the
454d8c79a815f9e993b741ec38cd39498e674e1739elgao                                authentication status of the
455d8c79a815f9e993b741ec38cd39498e674e1739elgao                                output buffer. If the input
456d8c79a815f9e993b741ec38cd39498e674e1739elgao                                section's GuidedSectionHeader.
457d8c79a815f9e993b741ec38cd39498e674e1739elgao                                Attributes field has the
458d8c79a815f9e993b741ec38cd39498e674e1739elgao                                EFI_GUIDED_SECTION_AUTH_STATUS_VALID
459d8c79a815f9e993b741ec38cd39498e674e1739elgao                                bit as clear,
460d8c79a815f9e993b741ec38cd39498e674e1739elgao                                AuthenticationStatus must return
461d8c79a815f9e993b741ec38cd39498e674e1739elgao                                zero. These bits reflect the
462d8c79a815f9e993b741ec38cd39498e674e1739elgao                                status of the extraction
463d8c79a815f9e993b741ec38cd39498e674e1739elgao                                operation. If the function
464d8c79a815f9e993b741ec38cd39498e674e1739elgao                                returns anything other than
465d8c79a815f9e993b741ec38cd39498e674e1739elgao                                EFI_SUCCESS, the value of
466d8c79a815f9e993b741ec38cd39498e674e1739elgao                                AuthenticationStatus is
467d8c79a815f9e993b741ec38cd39498e674e1739elgao                                undefined.
468d8c79a815f9e993b741ec38cd39498e674e1739elgao
469d8c79a815f9e993b741ec38cd39498e674e1739elgao  @retval EFI_SUCCESS           The InputSection was
470d8c79a815f9e993b741ec38cd39498e674e1739elgao                                successfully processed and the
471d8c79a815f9e993b741ec38cd39498e674e1739elgao                                section contents were returned.
472d8c79a815f9e993b741ec38cd39498e674e1739elgao
473d8c79a815f9e993b741ec38cd39498e674e1739elgao  @retval EFI_OUT_OF_RESOURCES  The system has insufficient
474d8c79a815f9e993b741ec38cd39498e674e1739elgao                                resources to process the request.
475d8c79a815f9e993b741ec38cd39498e674e1739elgao
476708919bef7fa8e0ae611173fbe7d297c74acd3d4qhuang  @retval EFI_INVALID_PARAMETER The GUID in InputSection does
477d8c79a815f9e993b741ec38cd39498e674e1739elgao                                not match this instance of the
478d8c79a815f9e993b741ec38cd39498e674e1739elgao                                GUIDed Section Extraction PPI.
47991d92e25647e9a26392b454499d309330710a076qhuang
480d8c79a815f9e993b741ec38cd39498e674e1739elgao**/
481d8c79a815f9e993b741ec38cd39498e674e1739elgaoEFI_STATUS
4826d3ea23f1183f3378a53e44d34c0a27aebec7d9ajljustenEFIAPI
48318fd8d651d7383c429cbcdf3a4262aa32268cd6clgaoCustomGuidedSectionExtract (
484d8c79a815f9e993b741ec38cd39498e674e1739elgao  IN CONST  EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *This,
485d8c79a815f9e993b741ec38cd39498e674e1739elgao  IN CONST  VOID                                  *InputSection,
486d8c79a815f9e993b741ec38cd39498e674e1739elgao  OUT       VOID                                  **OutputBuffer,
487d8c79a815f9e993b741ec38cd39498e674e1739elgao  OUT       UINTN                                 *OutputSize,
488d8c79a815f9e993b741ec38cd39498e674e1739elgao  OUT       UINT32                                *AuthenticationStatus
489d8c79a815f9e993b741ec38cd39498e674e1739elgao)
490d8c79a815f9e993b741ec38cd39498e674e1739elgao{
491d8c79a815f9e993b741ec38cd39498e674e1739elgao  EFI_STATUS      Status;
492d8c79a815f9e993b741ec38cd39498e674e1739elgao  UINT8           *ScratchBuffer;
49318fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  UINT32          ScratchBufferSize;
49418fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  UINT32          OutputBufferSize;
49518fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  UINT16          SectionAttribute;
496d8c79a815f9e993b741ec38cd39498e674e1739elgao
497d8c79a815f9e993b741ec38cd39498e674e1739elgao  //
49818fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  // Init local variable
499d8c79a815f9e993b741ec38cd39498e674e1739elgao  //
50018fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  ScratchBuffer = NULL;
50118fd8d651d7383c429cbcdf3a4262aa32268cd6clgao
502d8c79a815f9e993b741ec38cd39498e674e1739elgao  //
50318fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  // Call GetInfo to get the size and attribute of input guided section data.
504d8c79a815f9e993b741ec38cd39498e674e1739elgao  //
50518fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  Status = ExtractGuidedSectionGetInfo (
506b6b98e9133020e8e7752200b496ffe073d673883qhuang             InputSection,
507b6b98e9133020e8e7752200b496ffe073d673883qhuang             &OutputBufferSize,
508b6b98e9133020e8e7752200b496ffe073d673883qhuang             &ScratchBufferSize,
509b6b98e9133020e8e7752200b496ffe073d673883qhuang             &SectionAttribute
510b6b98e9133020e8e7752200b496ffe073d673883qhuang             );
51118fd8d651d7383c429cbcdf3a4262aa32268cd6clgao
512d8c79a815f9e993b741ec38cd39498e674e1739elgao  if (EFI_ERROR (Status)) {
51391d92e25647e9a26392b454499d309330710a076qhuang    DEBUG ((DEBUG_ERROR, "GetInfo from guided section Failed - %r\n", Status));
51418fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    return Status;
51518fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  }
51618fd8d651d7383c429cbcdf3a4262aa32268cd6clgao
51718fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  if (ScratchBufferSize != 0) {
51895276127e373f2e2fb2a208ff77267422a197d9fxgu    //
51918fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    // Allocate scratch buffer
52095276127e373f2e2fb2a208ff77267422a197d9fxgu    //
52118fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));
52218fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    if (ScratchBuffer == NULL) {
52318fd8d651d7383c429cbcdf3a4262aa32268cd6clgao      return EFI_OUT_OF_RESOURCES;
52418fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    }
525d8c79a815f9e993b741ec38cd39498e674e1739elgao  }
52695276127e373f2e2fb2a208ff77267422a197d9fxgu
527708919bef7fa8e0ae611173fbe7d297c74acd3d4qhuang  if (((SectionAttribute & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) && OutputBufferSize > 0) {
52818fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    //
52918fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    // Allocate output buffer
53018fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    //
531288f9b382445a50278155f703ccce9a0293fceb5lgao    *OutputBuffer = AllocatePages (EFI_SIZE_TO_PAGES (OutputBufferSize) + 1);
53218fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    if (*OutputBuffer == NULL) {
53318fd8d651d7383c429cbcdf3a4262aa32268cd6clgao      return EFI_OUT_OF_RESOURCES;
53418fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    }
53548557c6550adecf39e1e8e140b1736275d070dfbqhuang    DEBUG ((DEBUG_INFO, "Customized Guided section Memory Size required is 0x%x and address is 0x%p\n", OutputBufferSize, *OutputBuffer));
536288f9b382445a50278155f703ccce9a0293fceb5lgao    //
537288f9b382445a50278155f703ccce9a0293fceb5lgao    // *OutputBuffer still is one section. Adjust *OutputBuffer offset,
538288f9b382445a50278155f703ccce9a0293fceb5lgao    // skip EFI section header to make section data at page alignment.
539288f9b382445a50278155f703ccce9a0293fceb5lgao    //
540288f9b382445a50278155f703ccce9a0293fceb5lgao    *OutputBuffer = (VOID *)((UINT8 *) *OutputBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER));
54195276127e373f2e2fb2a208ff77267422a197d9fxgu  }
54218fd8d651d7383c429cbcdf3a4262aa32268cd6clgao
54318fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  Status = ExtractGuidedSectionDecode (
54418fd8d651d7383c429cbcdf3a4262aa32268cd6clgao             InputSection,
54518fd8d651d7383c429cbcdf3a4262aa32268cd6clgao             OutputBuffer,
54618fd8d651d7383c429cbcdf3a4262aa32268cd6clgao             ScratchBuffer,
54718fd8d651d7383c429cbcdf3a4262aa32268cd6clgao             AuthenticationStatus
54848557c6550adecf39e1e8e140b1736275d070dfbqhuang             );
549d8c79a815f9e993b741ec38cd39498e674e1739elgao  if (EFI_ERROR (Status)) {
550d8c79a815f9e993b741ec38cd39498e674e1739elgao    //
55118fd8d651d7383c429cbcdf3a4262aa32268cd6clgao    // Decode failed
552d8c79a815f9e993b741ec38cd39498e674e1739elgao    //
55391d92e25647e9a26392b454499d309330710a076qhuang    DEBUG ((DEBUG_ERROR, "Extract guided section Failed - %r\n", Status));
554d8c79a815f9e993b741ec38cd39498e674e1739elgao    return Status;
555d8c79a815f9e993b741ec38cd39498e674e1739elgao  }
556d8c79a815f9e993b741ec38cd39498e674e1739elgao
55718fd8d651d7383c429cbcdf3a4262aa32268cd6clgao  *OutputSize = (UINTN) OutputBufferSize;
55818fd8d651d7383c429cbcdf3a4262aa32268cd6clgao
55995276127e373f2e2fb2a208ff77267422a197d9fxgu  return EFI_SUCCESS;
56095276127e373f2e2fb2a208ff77267422a197d9fxgu}
561b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
56291d92e25647e9a26392b454499d309330710a076qhuang
56391d92e25647e9a26392b454499d309330710a076qhuang
56491d92e25647e9a26392b454499d309330710a076qhuang/**
56591d92e25647e9a26392b454499d309330710a076qhuang   Decompresses a section to the output buffer.
56691d92e25647e9a26392b454499d309330710a076qhuang
56748557c6550adecf39e1e8e140b1736275d070dfbqhuang   This function looks up the compression type field in the input section and
56891d92e25647e9a26392b454499d309330710a076qhuang   applies the appropriate compression algorithm to compress the section to a
56991d92e25647e9a26392b454499d309330710a076qhuang   callee allocated buffer.
57091d92e25647e9a26392b454499d309330710a076qhuang
57191d92e25647e9a26392b454499d309330710a076qhuang   @param  This                  Points to this instance of the
57291d92e25647e9a26392b454499d309330710a076qhuang                                 EFI_PEI_DECOMPRESS_PEI PPI.
57391d92e25647e9a26392b454499d309330710a076qhuang   @param  CompressionSection    Points to the compressed section.
57491d92e25647e9a26392b454499d309330710a076qhuang   @param  OutputBuffer          Holds the returned pointer to the decompressed
57591d92e25647e9a26392b454499d309330710a076qhuang                                 sections.
57691d92e25647e9a26392b454499d309330710a076qhuang   @param  OutputSize            Holds the returned size of the decompress
57791d92e25647e9a26392b454499d309330710a076qhuang                                 section streams.
57891d92e25647e9a26392b454499d309330710a076qhuang
57991d92e25647e9a26392b454499d309330710a076qhuang   @retval EFI_SUCCESS           The section was decompressed successfully.
58091d92e25647e9a26392b454499d309330710a076qhuang                                 OutputBuffer contains the resulting data and
58191d92e25647e9a26392b454499d309330710a076qhuang                                 OutputSize contains the resulting size.
58291d92e25647e9a26392b454499d309330710a076qhuang
58391d92e25647e9a26392b454499d309330710a076qhuang**/
584b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3kluEFI_STATUS
585b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3kluEFIAPI
586b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3kluDecompress (
587b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  IN CONST  EFI_PEI_DECOMPRESS_PPI  *This,
588b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  IN CONST  EFI_COMPRESSION_SECTION *CompressionSection,
589b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  OUT       VOID                    **OutputBuffer,
590b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  OUT       UINTN                   *OutputSize
591b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu )
592b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu{
593b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  EFI_STATUS                      Status;
594b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  UINT8                           *DstBuffer;
595b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  UINT8                           *ScratchBuffer;
596635021c59421db3d837f4e6797c5dc70bbd78b6fandrewfish  UINT32                          DstBufferSize;
597b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  UINT32                          ScratchBufferSize;
598890e54170e8f85d1357ac3614f7ad1465050ff0clzeng  VOID                            *CompressionSource;
599890e54170e8f85d1357ac3614f7ad1465050ff0clzeng  UINT32                          CompressionSourceSize;
600890e54170e8f85d1357ac3614f7ad1465050ff0clzeng  UINT32                          UncompressedLength;
601890e54170e8f85d1357ac3614f7ad1465050ff0clzeng  UINT8                           CompressionType;
602b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
603b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  if (CompressionSection->CommonHeader.Type != EFI_SECTION_COMPRESSION) {
604b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    ASSERT (FALSE);
605b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    return EFI_INVALID_PARAMETER;
606b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  }
607b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
608890e54170e8f85d1357ac3614f7ad1465050ff0clzeng  if (IS_SECTION2 (CompressionSection)) {
609890e54170e8f85d1357ac3614f7ad1465050ff0clzeng    CompressionSource = (VOID *) ((UINT8 *) CompressionSection + sizeof (EFI_COMPRESSION_SECTION2));
610890e54170e8f85d1357ac3614f7ad1465050ff0clzeng    CompressionSourceSize = (UINT32) (SECTION2_SIZE (CompressionSection) - sizeof (EFI_COMPRESSION_SECTION2));
611890e54170e8f85d1357ac3614f7ad1465050ff0clzeng    UncompressedLength = ((EFI_COMPRESSION_SECTION2 *) CompressionSection)->UncompressedLength;
612890e54170e8f85d1357ac3614f7ad1465050ff0clzeng    CompressionType = ((EFI_COMPRESSION_SECTION2 *) CompressionSection)->CompressionType;
613890e54170e8f85d1357ac3614f7ad1465050ff0clzeng  } else {
614890e54170e8f85d1357ac3614f7ad1465050ff0clzeng    CompressionSource = (VOID *) ((UINT8 *) CompressionSection + sizeof (EFI_COMPRESSION_SECTION));
615890e54170e8f85d1357ac3614f7ad1465050ff0clzeng    CompressionSourceSize = (UINT32) (SECTION_SIZE (CompressionSection) - sizeof (EFI_COMPRESSION_SECTION));
616890e54170e8f85d1357ac3614f7ad1465050ff0clzeng    UncompressedLength = CompressionSection->UncompressedLength;
617890e54170e8f85d1357ac3614f7ad1465050ff0clzeng    CompressionType = CompressionSection->CompressionType;
618890e54170e8f85d1357ac3614f7ad1465050ff0clzeng  }
619b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
620b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  //
621b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  // This is a compression set, expand it
622b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  //
623890e54170e8f85d1357ac3614f7ad1465050ff0clzeng  switch (CompressionType) {
624b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  case EFI_STANDARD_COMPRESSION:
625873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten    if (FeaturePcdGet(PcdDxeIplSupportUefiDecompress)) {
626b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      //
627873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten      // Load EFI standard compression.
628873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten      // For compressed data, decompress them to destination buffer.
629b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      //
630873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten      Status = UefiDecompressGetInfo (
631890e54170e8f85d1357ac3614f7ad1465050ff0clzeng                 CompressionSource,
632890e54170e8f85d1357ac3614f7ad1465050ff0clzeng                 CompressionSourceSize,
633635021c59421db3d837f4e6797c5dc70bbd78b6fandrewfish                 &DstBufferSize,
634873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten                 &ScratchBufferSize
635873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten                 );
636873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten      if (EFI_ERROR (Status)) {
637873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten        //
638873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten        // GetInfo failed
639873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten        //
640873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten        DEBUG ((DEBUG_ERROR, "Decompress GetInfo Failed - %r\n", Status));
641873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten        return EFI_NOT_FOUND;
642873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten      }
643873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten      //
644873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten      // Allocate scratch buffer
645b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      //
646873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten      ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));
647873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten      if (ScratchBuffer == NULL) {
648873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten        return EFI_OUT_OF_RESOURCES;
649873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten      }
650873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten      //
651873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten      // Allocate destination buffer, extra one page for adjustment
652873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten      //
653873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten      DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize) + 1);
654873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten      if (DstBuffer == NULL) {
655873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten        return EFI_OUT_OF_RESOURCES;
656873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten      }
657b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      //
658873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten      // DstBuffer still is one section. Adjust DstBuffer offset, skip EFI section header
659873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten      // to make section data at page alignment.
660873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten      //
661873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten      DstBuffer = DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER);
662873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten      //
663873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten      // Call decompress function
664873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten      //
665873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten      Status = UefiDecompress (
666890e54170e8f85d1357ac3614f7ad1465050ff0clzeng                  CompressionSource,
667873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten                  DstBuffer,
668873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten                  ScratchBuffer
669873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten                  );
670873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten      if (EFI_ERROR (Status)) {
671873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten        //
672873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten        // Decompress failed
673873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten        //
674873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten        DEBUG ((DEBUG_ERROR, "Decompress Failed - %r\n", Status));
675873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten        return EFI_NOT_FOUND;
676873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten      }
677873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten      break;
678873b7997efe978eab9b8fc9d41e6fe9baf35d127jljusten    } else {
67912b3e61ee873f395920b3397853bde50e37d7b9clgao      //
68012b3e61ee873f395920b3397853bde50e37d7b9clgao      // PcdDxeIplSupportUefiDecompress is FALSE
68112b3e61ee873f395920b3397853bde50e37d7b9clgao      // Don't support UEFI decompression algorithm.
68212b3e61ee873f395920b3397853bde50e37d7b9clgao      //
68312b3e61ee873f395920b3397853bde50e37d7b9clgao      ASSERT (FALSE);
684b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      return EFI_NOT_FOUND;
685b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    }
686b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
687b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  case EFI_NOT_COMPRESSED:
688b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
689b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    // Allocate destination buffer
690b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
691890e54170e8f85d1357ac3614f7ad1465050ff0clzeng    DstBufferSize = UncompressedLength;
692288f9b382445a50278155f703ccce9a0293fceb5lgao    DstBuffer     = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize) + 1);
693b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    if (DstBuffer == NULL) {
694b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      return EFI_OUT_OF_RESOURCES;
695b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    }
696b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
697288f9b382445a50278155f703ccce9a0293fceb5lgao    // Adjust DstBuffer offset, skip EFI section header
698288f9b382445a50278155f703ccce9a0293fceb5lgao    // to make section data at page alignment.
699288f9b382445a50278155f703ccce9a0293fceb5lgao    //
700288f9b382445a50278155f703ccce9a0293fceb5lgao    DstBuffer = DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER);
701288f9b382445a50278155f703ccce9a0293fceb5lgao    //
702b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    // stream is not actually compressed, just encapsulated.  So just copy it.
703b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
704890e54170e8f85d1357ac3614f7ad1465050ff0clzeng    CopyMem (DstBuffer, CompressionSource, DstBufferSize);
705b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    break;
706b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
707b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  default:
708b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
709b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    // Don't support other unknown compression type.
710b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    //
711b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    ASSERT (FALSE);
712b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu    return EFI_NOT_FOUND;
713b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  }
714b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
715b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  *OutputSize = DstBufferSize;
716b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  *OutputBuffer = DstBuffer;
717b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
718b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu  return EFI_SUCCESS;
719b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu}
720b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu
72191d92e25647e9a26392b454499d309330710a076qhuang
72291d92e25647e9a26392b454499d309330710a076qhuang/**
72391d92e25647e9a26392b454499d309330710a076qhuang   Updates the Stack HOB passed to DXE phase.
72491d92e25647e9a26392b454499d309330710a076qhuang
72591d92e25647e9a26392b454499d309330710a076qhuang   This function traverses the whole HOB list and update the stack HOB to
72691d92e25647e9a26392b454499d309330710a076qhuang   reflect the real stack that is used by DXE core.
72791d92e25647e9a26392b454499d309330710a076qhuang
72891d92e25647e9a26392b454499d309330710a076qhuang   @param BaseAddress           The lower address of stack used by DxeCore.
72991d92e25647e9a26392b454499d309330710a076qhuang   @param Length                The length of stack used by DxeCore.
73091d92e25647e9a26392b454499d309330710a076qhuang
73191d92e25647e9a26392b454499d309330710a076qhuang**/
73230c8f8616d9f2c764e4b8c3566bef4f562115005qhuangVOID
73330c8f8616d9f2c764e4b8c3566bef4f562115005qhuangUpdateStackHob (
73430c8f8616d9f2c764e4b8c3566bef4f562115005qhuang  IN EFI_PHYSICAL_ADDRESS        BaseAddress,
73530c8f8616d9f2c764e4b8c3566bef4f562115005qhuang  IN UINT64                      Length
73630c8f8616d9f2c764e4b8c3566bef4f562115005qhuang  )
73730c8f8616d9f2c764e4b8c3566bef4f562115005qhuang{
73830c8f8616d9f2c764e4b8c3566bef4f562115005qhuang  EFI_PEI_HOB_POINTERS           Hob;
73930c8f8616d9f2c764e4b8c3566bef4f562115005qhuang
74030c8f8616d9f2c764e4b8c3566bef4f562115005qhuang  Hob.Raw = GetHobList ();
74130c8f8616d9f2c764e4b8c3566bef4f562115005qhuang  while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) {
74230c8f8616d9f2c764e4b8c3566bef4f562115005qhuang    if (CompareGuid (&gEfiHobMemoryAllocStackGuid, &(Hob.MemoryAllocationStack->AllocDescriptor.Name))) {
74330c8f8616d9f2c764e4b8c3566bef4f562115005qhuang      //
7449a43bc39a9b038523a9c5678f05cc31c62640bf0pgao      // Build a new memory allocation HOB with old stack info with EfiBootServicesData type. Need to
7459a43bc39a9b038523a9c5678f05cc31c62640bf0pgao      // avoid this region be reclaimed by DXE core as the IDT built in SEC might be on stack, and some
7469a43bc39a9b038523a9c5678f05cc31c62640bf0pgao      // PEIMs may also keep key information on stack
74730c8f8616d9f2c764e4b8c3566bef4f562115005qhuang      //
74830c8f8616d9f2c764e4b8c3566bef4f562115005qhuang      BuildMemoryAllocationHob (
74930c8f8616d9f2c764e4b8c3566bef4f562115005qhuang        Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress,
75030c8f8616d9f2c764e4b8c3566bef4f562115005qhuang        Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength,
7519a43bc39a9b038523a9c5678f05cc31c62640bf0pgao        EfiBootServicesData
75230c8f8616d9f2c764e4b8c3566bef4f562115005qhuang        );
75330c8f8616d9f2c764e4b8c3566bef4f562115005qhuang      //
75430c8f8616d9f2c764e4b8c3566bef4f562115005qhuang      // Update the BSP Stack Hob to reflect the new stack info.
75530c8f8616d9f2c764e4b8c3566bef4f562115005qhuang      //
75630c8f8616d9f2c764e4b8c3566bef4f562115005qhuang      Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress = BaseAddress;
75730c8f8616d9f2c764e4b8c3566bef4f562115005qhuang      Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength = Length;
75830c8f8616d9f2c764e4b8c3566bef4f562115005qhuang      break;
75930c8f8616d9f2c764e4b8c3566bef4f562115005qhuang    }
76030c8f8616d9f2c764e4b8c3566bef4f562115005qhuang    Hob.Raw = GET_NEXT_HOB (Hob);
76130c8f8616d9f2c764e4b8c3566bef4f562115005qhuang  }
76230c8f8616d9f2c764e4b8c3566bef4f562115005qhuang}
763