]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Core/DxeIplPeim/DxeLoad.c
Revert "Capsule-on-Disk entire Patch
[mirror_edk2.git] / MdeModulePkg / Core / DxeIplPeim / DxeLoad.c
CommitLineData
96226baa 1/** @file\r
b0d803fe 2 Last PEIM.\r
3 Responsibility of this module is to load the DXE Core from a Firmware Volume.\r
95276127 4\r
ebaafbe6 5Copyright (c) 2016 HP Development Company, L.P.\r
57ec204e 6Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
9d510e61 7SPDX-License-Identifier: BSD-2-Clause-Patent\r
95276127 8\r
b0d803fe 9**/\r
95276127 10\r
95276127 11#include "DxeIpl.h"\r
b0d803fe 12\r
95276127 13\r
14//\r
48557c65 15// Module Globals used in the DXE to PEI hand off\r
95276127 16// These must be module globals, so the stack can be switched\r
17//\r
9b937a73 18CONST EFI_DXE_IPL_PPI mDxeIplPpi = {\r
95276127 19 DxeLoadCore\r
20};\r
21\r
ebaafbe6
EC
22CONST EFI_PEI_PPI_DESCRIPTOR mDxeIplPpiList = {\r
23 EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
24 &gEfiDxeIplPpiGuid,\r
25 (VOID *) &mDxeIplPpi\r
26};\r
27\r
9b937a73 28CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI mCustomGuidedSectionExtractionPpi = {\r
18fd8d65 29 CustomGuidedSectionExtract\r
95276127 30};\r
31\r
9b937a73 32CONST EFI_PEI_DECOMPRESS_PPI mDecompressPpi = {\r
b0d803fe 33 Decompress\r
d8c79a81
LG
34};\r
35\r
ebaafbe6
EC
36CONST EFI_PEI_PPI_DESCRIPTOR mDecompressPpiList = {\r
37 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
38 &gEfiPeiDecompressPpiGuid,\r
39 (VOID *) &mDecompressPpi\r
95276127 40};\r
41\r
48557c65 42CONST EFI_PEI_PPI_DESCRIPTOR gEndOfPeiSignalPpi = {\r
95276127 43 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
44 &gEfiEndOfPeiSignalPpiGuid,\r
45 NULL\r
46};\r
47\r
ebaafbe6
EC
48CONST EFI_PEI_NOTIFY_DESCRIPTOR mMemoryDiscoveredNotifyList = {\r
49 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
50 &gEfiPeiMemoryDiscoveredPpiGuid,\r
51 InstallIplPermanentMemoryPpis\r
52};\r
53\r
b0d803fe 54/**\r
48557c65 55 Entry point of DXE IPL PEIM.\r
ebaafbe6
EC
56\r
57 This function installs DXE IPL PPI. It also reloads\r
48557c65 58 itself to memory on non-S3 resume boot path.\r
b0d803fe 59\r
a55caa53
LG
60 @param FileHandle Handle of the file being invoked.\r
61 @param PeiServices Describes the list of possible PEI Services.\r
91d92e25 62\r
48557c65 63 @retval EFI_SUCESS The entry point of DXE IPL PEIM executes successfully.\r
d1102dba 64 @retval Others Some error occurs during the execution of this function.\r
48557c65 65\r
91d92e25 66**/\r
95276127 67EFI_STATUS\r
68EFIAPI\r
69PeimInitializeDxeIpl (\r
a55caa53
LG
70 IN EFI_PEI_FILE_HANDLE FileHandle,\r
71 IN CONST EFI_PEI_SERVICES **PeiServices\r
95276127 72 )\r
95276127 73{\r
74 EFI_STATUS Status;\r
95276127 75 EFI_BOOT_MODE BootMode;\r
ebaafbe6
EC
76 VOID *Dummy;\r
77\r
b98da1b1 78 BootMode = GetBootModeHob ();\r
95276127 79\r
b0d803fe 80 if (BootMode != BOOT_ON_S3_RESUME) {\r
a55caa53 81 Status = PeiServicesRegisterForShadow (FileHandle);\r
b0d803fe 82 if (Status == EFI_SUCCESS) {\r
b0d803fe 83 //\r
d1102dba
LG
84 // EFI_SUCESS means it is the first time to call register for shadow.\r
85 //\r
b0d803fe 86 return Status;\r
48557c65 87 }\r
ebaafbe6 88\r
48557c65 89 //\r
90 // Ensure that DXE IPL is shadowed to permanent memory.\r
91 //\r
92 ASSERT (Status == EFI_ALREADY_STARTED);\r
ebaafbe6
EC
93\r
94 //\r
95 // DXE core load requires permanent memory.\r
96 //\r
97 Status = PeiServicesLocatePpi (\r
98 &gEfiPeiMemoryDiscoveredPpiGuid,\r
99 0,\r
100 NULL,\r
101 (VOID **) &Dummy\r
102 );\r
103 ASSERT_EFI_ERROR (Status);\r
104 if (EFI_ERROR (Status)) {\r
105 return Status;\r
106 }\r
107\r
108 //\r
109 // Now the permanent memory exists, install the PPIs for decompression\r
110 // and section extraction.\r
111 //\r
112 Status = InstallIplPermanentMemoryPpis (NULL, NULL, NULL);\r
d1102dba 113 ASSERT_EFI_ERROR (Status);\r
ebaafbe6
EC
114 } else {\r
115 //\r
116 // Install memory discovered PPI notification to install PPIs for\r
117 // decompression and section extraction.\r
118 //\r
119 Status = PeiServicesNotifyPpi (&mMemoryDiscoveredNotifyList);\r
120 ASSERT_EFI_ERROR (Status);\r
25bc8326 121 }\r
ebaafbe6
EC
122\r
123 //\r
124 // Install DxeIpl PPI.\r
125 //\r
126 Status = PeiServicesInstallPpi (&mDxeIplPpiList);\r
127 ASSERT_EFI_ERROR(Status);\r
128\r
129 return Status;\r
130}\r
131\r
132/**\r
133 This function installs the PPIs that require permanent memory.\r
134\r
135 @param PeiServices Indirect reference to the PEI Services Table.\r
136 @param NotifyDescriptor Address of the notification descriptor data structure.\r
137 @param Ppi Address of the PPI that was installed.\r
138\r
139 @return EFI_SUCCESS The PPIs were installed successfully.\r
140 @return Others Some error occurs during the execution of this function.\r
141\r
142**/\r
143EFI_STATUS\r
144EFIAPI\r
145InstallIplPermanentMemoryPpis (\r
146 IN EFI_PEI_SERVICES **PeiServices,\r
147 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
148 IN VOID *Ppi\r
149 )\r
150{\r
151 EFI_STATUS Status;\r
152 EFI_GUID *ExtractHandlerGuidTable;\r
153 UINTN ExtractHandlerNumber;\r
154 EFI_PEI_PPI_DESCRIPTOR *GuidPpi;\r
155\r
25bc8326 156 //\r
d1102dba 157 // Get custom extract guided section method guid list\r
25bc8326
LG
158 //\r
159 ExtractHandlerNumber = ExtractGuidedSectionGetGuidList (&ExtractHandlerGuidTable);\r
ebaafbe6 160\r
25bc8326 161 //\r
ebaafbe6 162 // Install custom guided section extraction PPI\r
25bc8326
LG
163 //\r
164 if (ExtractHandlerNumber > 0) {\r
165 GuidPpi = (EFI_PEI_PPI_DESCRIPTOR *) AllocatePool (ExtractHandlerNumber * sizeof (EFI_PEI_PPI_DESCRIPTOR));\r
166 ASSERT (GuidPpi != NULL);\r
167 while (ExtractHandlerNumber-- > 0) {\r
168 GuidPpi->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;\r
169 GuidPpi->Ppi = (VOID *) &mCustomGuidedSectionExtractionPpi;\r
170 GuidPpi->Guid = &ExtractHandlerGuidTable[ExtractHandlerNumber];\r
171 Status = PeiServicesInstallPpi (GuidPpi++);\r
172 ASSERT_EFI_ERROR(Status);\r
d8c79a81 173 }\r
95276127 174 }\r
ebaafbe6 175\r
b0d803fe 176 //\r
ebaafbe6 177 // Install Decompress PPI.\r
b0d803fe 178 //\r
ebaafbe6 179 Status = PeiServicesInstallPpi (&mDecompressPpiList);\r
288f9b38
LG
180 ASSERT_EFI_ERROR(Status);\r
181\r
95276127 182 return Status;\r
183}\r
184\r
a95b6045 185/**\r
d1102dba 186 Validate variable data for the MemoryTypeInformation.\r
a95b6045
ED
187\r
188 @param MemoryData Variable data.\r
189 @param MemoryDataSize Variable data length.\r
190\r
191 @return TRUE The variable data is valid.\r
192 @return FALSE The variable data is invalid.\r
193\r
194**/\r
195BOOLEAN\r
196ValidateMemoryTypeInfoVariable (\r
197 IN EFI_MEMORY_TYPE_INFORMATION *MemoryData,\r
198 IN UINTN MemoryDataSize\r
199 )\r
200{\r
201 UINTN Count;\r
202 UINTN Index;\r
203\r
204 // Check the input parameter.\r
205 if (MemoryData == NULL) {\r
206 return FALSE;\r
207 }\r
208\r
209 // Get Count\r
210 Count = MemoryDataSize / sizeof (*MemoryData);\r
211\r
212 // Check Size\r
213 if (Count * sizeof(*MemoryData) != MemoryDataSize) {\r
214 return FALSE;\r
215 }\r
216\r
217 // Check last entry type filed.\r
218 if (MemoryData[Count - 1].Type != EfiMaxMemoryType) {\r
219 return FALSE;\r
220 }\r
221\r
222 // Check the type filed.\r
223 for (Index = 0; Index < Count - 1; Index++) {\r
224 if (MemoryData[Index].Type >= EfiMaxMemoryType) {\r
225 return FALSE;\r
226 }\r
227 }\r
228\r
229 return TRUE;\r
230}\r
231\r
b0d803fe 232/**\r
d1102dba 233 Main entry point to last PEIM.\r
48557c65 234\r
235 This function finds DXE Core in the firmware volume and transfer the control to\r
236 DXE core.\r
d1102dba 237\r
b98da1b1 238 @param This Entry point for DXE IPL PPI.\r
b0d803fe 239 @param PeiServices General purpose services available to every PEIM.\r
b98da1b1 240 @param HobList Address to the Pei HOB list.\r
d1102dba
LG
241\r
242 @return EFI_SUCCESS DXE core was successfully loaded.\r
b0d803fe 243 @return EFI_OUT_OF_RESOURCES There are not enough resources to load DXE core.\r
91d92e25 244\r
b0d803fe 245**/\r
95276127 246EFI_STATUS\r
247EFIAPI\r
248DxeLoadCore (\r
1f3a753e 249 IN CONST EFI_DXE_IPL_PPI *This,\r
95276127 250 IN EFI_PEI_SERVICES **PeiServices,\r
251 IN EFI_PEI_HOB_POINTERS HobList\r
252 )\r
95276127 253{\r
254 EFI_STATUS Status;\r
b6b98e91 255 EFI_FV_FILE_INFO DxeCoreFileInfo;\r
95276127 256 EFI_PHYSICAL_ADDRESS DxeCoreAddress;\r
257 UINT64 DxeCoreSize;\r
258 EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint;\r
95276127 259 EFI_BOOT_MODE BootMode;\r
b0d803fe 260 EFI_PEI_FILE_HANDLE FileHandle;\r
b74350e9 261 EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable;\r
28efc722 262 EFI_PEI_LOAD_FILE_PPI *LoadFile;\r
263 UINTN Instance;\r
264 UINT32 AuthenticationState;\r
b74350e9 265 UINTN DataSize;\r
77215d10 266 EFI_PEI_S3_RESUME2_PPI *S3Resume;\r
28efc722 267 EFI_PEI_RECOVERY_MODULE_PPI *PeiRecovery;\r
708919be 268 EFI_MEMORY_TYPE_INFORMATION MemoryData[EfiMaxMemoryType + 1];\r
95276127 269\r
270 //\r
271 // if in S3 Resume, restore configure\r
272 //\r
b98da1b1 273 BootMode = GetBootModeHob ();\r
95276127 274\r
275 if (BootMode == BOOT_ON_S3_RESUME) {\r
28efc722 276 Status = PeiServicesLocatePpi (\r
77215d10 277 &gEfiPeiS3Resume2PpiGuid,\r
28efc722 278 0,\r
279 NULL,\r
280 (VOID **) &S3Resume\r
281 );\r
37623a5c 282 if (EFI_ERROR (Status)) {\r
283 //\r
284 // Report Status code that S3Resume PPI can not be found\r
285 //\r
286 REPORT_STATUS_CODE (\r
287 EFI_ERROR_CODE | EFI_ERROR_MAJOR,\r
288 (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_RESUME_PPI_NOT_FOUND)\r
289 );\r
290 }\r
28efc722 291 ASSERT_EFI_ERROR (Status);\r
d1102dba 292\r
77215d10 293 Status = S3Resume->S3RestoreConfig2 (S3Resume);\r
95276127 294 ASSERT_EFI_ERROR (Status);\r
295 } else if (BootMode == BOOT_IN_RECOVERY_MODE) {\r
37623a5c 296 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_RECOVERY_BEGIN));\r
28efc722 297 Status = PeiServicesLocatePpi (\r
298 &gEfiPeiRecoveryModulePpiGuid,\r
299 0,\r
300 NULL,\r
301 (VOID **) &PeiRecovery\r
302 );\r
83d06ed9 303\r
304 if (EFI_ERROR (Status)) {\r
305 DEBUG ((DEBUG_ERROR, "Locate Recovery PPI Failed.(Status = %r)\n", Status));\r
306 //\r
d1102dba 307 // Report Status code the failure of locating Recovery PPI\r
83d06ed9 308 //\r
309 REPORT_STATUS_CODE (\r
310 EFI_ERROR_CODE | EFI_ERROR_MAJOR,\r
311 (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_RECOVERY_PPI_NOT_FOUND)\r
312 );\r
313 CpuDeadLoop ();\r
314 }\r
315\r
37623a5c 316 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_CAPSULE_LOAD));\r
28efc722 317 Status = PeiRecovery->LoadRecoveryCapsule (PeiServices, PeiRecovery);\r
95276127 318 if (EFI_ERROR (Status)) {\r
91d92e25 319 DEBUG ((DEBUG_ERROR, "Load Recovery Capsule Failed.(Status = %r)\n", Status));\r
37623a5c 320 //\r
83d06ed9 321 // Report Status code that recovery image can not be found\r
37623a5c 322 //\r
323 REPORT_STATUS_CODE (\r
324 EFI_ERROR_CODE | EFI_ERROR_MAJOR,\r
325 (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_NO_RECOVERY_CAPSULE)\r
326 );\r
95276127 327 CpuDeadLoop ();\r
328 }\r
37623a5c 329 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_CAPSULE_START));\r
95276127 330 //\r
48557c65 331 // Now should have a HOB with the DXE core\r
95276127 332 //\r
333 }\r
288f9b38 334\r
d1d89e86
LG
335 if (GetFirstGuidHob ((CONST EFI_GUID *)&gEfiMemoryTypeInformationGuid) == NULL) {\r
336 //\r
337 // Don't build GuidHob if GuidHob has been installed.\r
338 //\r
339 Status = PeiServicesLocatePpi (\r
340 &gEfiPeiReadOnlyVariable2PpiGuid,\r
341 0,\r
342 NULL,\r
343 (VOID **)&Variable\r
344 );\r
345 if (!EFI_ERROR (Status)) {\r
346 DataSize = sizeof (MemoryData);\r
d1102dba
LG
347 Status = Variable->GetVariable (\r
348 Variable,\r
d1d89e86
LG
349 EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,\r
350 &gEfiMemoryTypeInformationGuid,\r
351 NULL,\r
352 &DataSize,\r
353 &MemoryData\r
354 );\r
355 if (!EFI_ERROR (Status) && ValidateMemoryTypeInfoVariable(MemoryData, DataSize)) {\r
356 //\r
357 // Build the GUID'd HOB for DXE\r
358 //\r
359 BuildGuidDataHob (\r
360 &gEfiMemoryTypeInformationGuid,\r
361 MemoryData,\r
362 DataSize\r
363 );\r
364 }\r
1ad76c34 365 }\r
b74350e9 366 }\r
288f9b38 367\r
95276127 368 //\r
b6b98e91 369 // Look in all the FVs present in PEI and find the DXE Core FileHandle\r
95276127 370 //\r
b6b98e91 371 FileHandle = DxeIplFindDxeCore ();\r
b0d803fe 372\r
95276127 373 //\r
28efc722 374 // Load the DXE Core from a Firmware Volume.\r
95276127 375 //\r
28efc722 376 Instance = 0;\r
377 do {\r
378 Status = PeiServicesLocatePpi (&gEfiPeiLoadFilePpiGuid, Instance++, NULL, (VOID **) &LoadFile);\r
379 //\r
380 // These must exist an instance of EFI_PEI_LOAD_FILE_PPI to support to load DxeCore file handle successfully.\r
381 //\r
382 ASSERT_EFI_ERROR (Status);\r
383\r
384 Status = LoadFile->LoadFile (\r
385 LoadFile,\r
386 FileHandle,\r
387 &DxeCoreAddress,\r
388 &DxeCoreSize,\r
389 &DxeCoreEntryPoint,\r
390 &AuthenticationState\r
391 );\r
392 } while (EFI_ERROR (Status));\r
95276127 393\r
b6b98e91 394 //\r
395 // Get the DxeCore File Info from the FileHandle for the DxeCore GUID file name.\r
396 //\r
397 Status = PeiServicesFfsGetFileInfo (FileHandle, &DxeCoreFileInfo);\r
398 ASSERT_EFI_ERROR (Status);\r
399\r
95276127 400 //\r
401 // Add HOB for the DXE Core\r
402 //\r
403 BuildModuleHob (\r
b6b98e91 404 &DxeCoreFileInfo.FileName,\r
95276127 405 DxeCoreAddress,\r
48557c65 406 ALIGN_VALUE (DxeCoreSize, EFI_PAGE_SIZE),\r
95276127 407 DxeCoreEntryPoint\r
408 );\r
409\r
410 //\r
411 // Report Status Code EFI_SW_PEI_PC_HANDOFF_TO_NEXT\r
412 //\r
f9876ecf 413 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_CORE | EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT));\r
95276127 414\r
4e2dd553 415 DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading DXE CORE at 0x%11p EntryPoint=0x%11p\n", (VOID *)(UINTN)DxeCoreAddress, FUNCTION_ENTRY_POINT (DxeCoreEntryPoint)));\r
e98cd821 416\r
95276127 417 //\r
418 // Transfer control to the DXE Core\r
48557c65 419 // The hand off state is simply a pointer to the HOB list\r
95276127 420 //\r
9b937a73 421 HandOffToDxeCore (DxeCoreEntryPoint, HobList);\r
95276127 422 //\r
423 // If we get here, then the DXE Core returned. This is an error\r
48557c65 424 // DxeCore should not return.\r
95276127 425 //\r
426 ASSERT (FALSE);\r
427 CpuDeadLoop ();\r
428\r
429 return EFI_OUT_OF_RESOURCES;\r
430}\r
431\r
91d92e25 432\r
b0d803fe 433/**\r
9b937a73 434 Searches DxeCore in all firmware Volumes and loads the first\r
435 instance that contains DxeCore.\r
b0d803fe 436\r
9b937a73 437 @return FileHandle of DxeCore to load DxeCore.\r
d1102dba 438\r
91d92e25 439**/\r
9b937a73 440EFI_PEI_FILE_HANDLE\r
288f9b38 441DxeIplFindDxeCore (\r
b6b98e91 442 VOID\r
b0d803fe 443 )\r
95276127 444{\r
9b937a73 445 EFI_STATUS Status;\r
446 UINTN Instance;\r
447 EFI_PEI_FV_HANDLE VolumeHandle;\r
448 EFI_PEI_FILE_HANDLE FileHandle;\r
d1102dba 449\r
288f9b38 450 Instance = 0;\r
9b937a73 451 while (TRUE) {\r
452 //\r
453 // Traverse all firmware volume instances\r
454 //\r
455 Status = PeiServicesFfsFindNextVolume (Instance, &VolumeHandle);\r
456 //\r
457 // If some error occurs here, then we cannot find any firmware\r
458 // volume that may contain DxeCore.\r
459 //\r
3d0a2385 460 if (EFI_ERROR (Status)) {\r
461 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_CORE_EC_DXE_CORRUPT));\r
462 }\r
9b937a73 463 ASSERT_EFI_ERROR (Status);\r
d1102dba 464\r
9b937a73 465 //\r
466 // Find the DxeCore file type from the beginning in this firmware volume.\r
467 //\r
468 FileHandle = NULL;\r
469 Status = PeiServicesFfsFindNextFile (EFI_FV_FILETYPE_DXE_CORE, VolumeHandle, &FileHandle);\r
288f9b38 470 if (!EFI_ERROR (Status)) {\r
9b937a73 471 //\r
b6b98e91 472 // Find DxeCore FileHandle in this volume, then we skip other firmware volume and\r
473 // return the FileHandle.\r
9b937a73 474 //\r
b6b98e91 475 return FileHandle;\r
95276127 476 }\r
9b937a73 477 //\r
478 // We cannot find DxeCore in this firmware volume, then search the next volume.\r
479 //\r
480 Instance++;\r
481 }\r
95276127 482}\r
483\r
91d92e25 484\r
91d92e25 485\r
d8c79a81
LG
486/**\r
487 The ExtractSection() function processes the input section and\r
488 returns a pointer to the section contents. If the section being\r
489 extracted does not require processing (if the section\r
490 GuidedSectionHeader.Attributes has the\r
491 EFI_GUIDED_SECTION_PROCESSING_REQUIRED field cleared), then\r
492 OutputBuffer is just updated to point to the start of the\r
493 section's contents. Otherwise, *Buffer must be allocated\r
494 from PEI permanent memory.\r
495\r
496 @param This Indicates the\r
497 EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI instance.\r
498 Buffer containing the input GUIDed section to be\r
499 processed. OutputBuffer OutputBuffer is\r
500 allocated from PEI permanent memory and contains\r
501 the new section stream.\r
91d92e25 502 @param InputSection A pointer to the input buffer, which contains\r
503 the input section to be processed.\r
504 @param OutputBuffer A pointer to a caller-allocated buffer, whose\r
505 size is specified by the contents of OutputSize.\r
d8c79a81
LG
506 @param OutputSize A pointer to a caller-allocated\r
507 UINTN in which the size of *OutputBuffer\r
508 allocation is stored. If the function\r
509 returns anything other than EFI_SUCCESS,\r
510 the value of OutputSize is undefined.\r
d8c79a81
LG
511 @param AuthenticationStatus A pointer to a caller-allocated\r
512 UINT32 that indicates the\r
513 authentication status of the\r
514 output buffer. If the input\r
515 section's GuidedSectionHeader.\r
516 Attributes field has the\r
d1102dba 517 EFI_GUIDED_SECTION_AUTH_STATUS_VALID\r
d8c79a81
LG
518 bit as clear,\r
519 AuthenticationStatus must return\r
520 zero. These bits reflect the\r
521 status of the extraction\r
522 operation. If the function\r
523 returns anything other than\r
524 EFI_SUCCESS, the value of\r
525 AuthenticationStatus is\r
526 undefined.\r
d1102dba 527\r
d8c79a81
LG
528 @retval EFI_SUCCESS The InputSection was\r
529 successfully processed and the\r
530 section contents were returned.\r
d1102dba 531\r
d8c79a81
LG
532 @retval EFI_OUT_OF_RESOURCES The system has insufficient\r
533 resources to process the request.\r
d1102dba 534\r
708919be 535 @retval EFI_INVALID_PARAMETER The GUID in InputSection does\r
d8c79a81
LG
536 not match this instance of the\r
537 GUIDed Section Extraction PPI.\r
91d92e25 538\r
d8c79a81
LG
539**/\r
540EFI_STATUS\r
6d3ea23f 541EFIAPI\r
18fd8d65 542CustomGuidedSectionExtract (\r
d8c79a81
LG
543 IN CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *This,\r
544 IN CONST VOID *InputSection,\r
545 OUT VOID **OutputBuffer,\r
546 OUT UINTN *OutputSize,\r
547 OUT UINT32 *AuthenticationStatus\r
548)\r
549{\r
550 EFI_STATUS Status;\r
551 UINT8 *ScratchBuffer;\r
18fd8d65
LG
552 UINT32 ScratchBufferSize;\r
553 UINT32 OutputBufferSize;\r
554 UINT16 SectionAttribute;\r
d1102dba 555\r
d8c79a81 556 //\r
18fd8d65 557 // Init local variable\r
d8c79a81 558 //\r
18fd8d65
LG
559 ScratchBuffer = NULL;\r
560\r
d8c79a81 561 //\r
18fd8d65 562 // Call GetInfo to get the size and attribute of input guided section data.\r
d8c79a81 563 //\r
18fd8d65 564 Status = ExtractGuidedSectionGetInfo (\r
b6b98e91 565 InputSection,\r
566 &OutputBufferSize,\r
567 &ScratchBufferSize,\r
568 &SectionAttribute\r
569 );\r
d1102dba 570\r
d8c79a81 571 if (EFI_ERROR (Status)) {\r
91d92e25 572 DEBUG ((DEBUG_ERROR, "GetInfo from guided section Failed - %r\n", Status));\r
18fd8d65
LG
573 return Status;\r
574 }\r
d1102dba 575\r
18fd8d65 576 if (ScratchBufferSize != 0) {\r
95276127 577 //\r
18fd8d65 578 // Allocate scratch buffer\r
95276127 579 //\r
18fd8d65
LG
580 ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));\r
581 if (ScratchBuffer == NULL) {\r
582 return EFI_OUT_OF_RESOURCES;\r
583 }\r
d8c79a81 584 }\r
95276127 585\r
d1102dba 586 if (((SectionAttribute & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) && OutputBufferSize > 0) {\r
18fd8d65
LG
587 //\r
588 // Allocate output buffer\r
589 //\r
5367f17d 590 *OutputBuffer = AllocatePages (EFI_SIZE_TO_PAGES (OutputBufferSize));\r
18fd8d65
LG
591 if (*OutputBuffer == NULL) {\r
592 return EFI_OUT_OF_RESOURCES;\r
593 }\r
48557c65 594 DEBUG ((DEBUG_INFO, "Customized Guided section Memory Size required is 0x%x and address is 0x%p\n", OutputBufferSize, *OutputBuffer));\r
95276127 595 }\r
d1102dba 596\r
18fd8d65 597 Status = ExtractGuidedSectionDecode (\r
d1102dba 598 InputSection,\r
18fd8d65
LG
599 OutputBuffer,\r
600 ScratchBuffer,\r
601 AuthenticationStatus\r
48557c65 602 );\r
d8c79a81
LG
603 if (EFI_ERROR (Status)) {\r
604 //\r
18fd8d65 605 // Decode failed\r
d8c79a81 606 //\r
91d92e25 607 DEBUG ((DEBUG_ERROR, "Extract guided section Failed - %r\n", Status));\r
d8c79a81
LG
608 return Status;\r
609 }\r
d1102dba 610\r
18fd8d65 611 *OutputSize = (UINTN) OutputBufferSize;\r
d1102dba 612\r
95276127 613 return EFI_SUCCESS;\r
614}\r
b0d803fe 615\r
91d92e25 616\r
617\r
618/**\r
619 Decompresses a section to the output buffer.\r
620\r
48557c65 621 This function looks up the compression type field in the input section and\r
91d92e25 622 applies the appropriate compression algorithm to compress the section to a\r
623 callee allocated buffer.\r
d1102dba 624\r
91d92e25 625 @param This Points to this instance of the\r
626 EFI_PEI_DECOMPRESS_PEI PPI.\r
627 @param CompressionSection Points to the compressed section.\r
628 @param OutputBuffer Holds the returned pointer to the decompressed\r
629 sections.\r
630 @param OutputSize Holds the returned size of the decompress\r
631 section streams.\r
d1102dba 632\r
91d92e25 633 @retval EFI_SUCCESS The section was decompressed successfully.\r
634 OutputBuffer contains the resulting data and\r
635 OutputSize contains the resulting size.\r
636\r
637**/\r
b0d803fe 638EFI_STATUS\r
d1102dba 639EFIAPI\r
b0d803fe 640Decompress (\r
641 IN CONST EFI_PEI_DECOMPRESS_PPI *This,\r
642 IN CONST EFI_COMPRESSION_SECTION *CompressionSection,\r
643 OUT VOID **OutputBuffer,\r
644 OUT UINTN *OutputSize\r
645 )\r
646{\r
647 EFI_STATUS Status;\r
648 UINT8 *DstBuffer;\r
649 UINT8 *ScratchBuffer;\r
635021c5 650 UINT32 DstBufferSize;\r
b0d803fe 651 UINT32 ScratchBufferSize;\r
890e5417
SZ
652 VOID *CompressionSource;\r
653 UINT32 CompressionSourceSize;\r
654 UINT32 UncompressedLength;\r
655 UINT8 CompressionType;\r
b0d803fe 656\r
657 if (CompressionSection->CommonHeader.Type != EFI_SECTION_COMPRESSION) {\r
658 ASSERT (FALSE);\r
659 return EFI_INVALID_PARAMETER;\r
660 }\r
661\r
890e5417
SZ
662 if (IS_SECTION2 (CompressionSection)) {\r
663 CompressionSource = (VOID *) ((UINT8 *) CompressionSection + sizeof (EFI_COMPRESSION_SECTION2));\r
664 CompressionSourceSize = (UINT32) (SECTION2_SIZE (CompressionSection) - sizeof (EFI_COMPRESSION_SECTION2));\r
665 UncompressedLength = ((EFI_COMPRESSION_SECTION2 *) CompressionSection)->UncompressedLength;\r
666 CompressionType = ((EFI_COMPRESSION_SECTION2 *) CompressionSection)->CompressionType;\r
667 } else {\r
668 CompressionSource = (VOID *) ((UINT8 *) CompressionSection + sizeof (EFI_COMPRESSION_SECTION));\r
669 CompressionSourceSize = (UINT32) (SECTION_SIZE (CompressionSection) - sizeof (EFI_COMPRESSION_SECTION));\r
670 UncompressedLength = CompressionSection->UncompressedLength;\r
671 CompressionType = CompressionSection->CompressionType;\r
672 }\r
d1102dba 673\r
b0d803fe 674 //\r
675 // This is a compression set, expand it\r
676 //\r
890e5417 677 switch (CompressionType) {\r
b0d803fe 678 case EFI_STANDARD_COMPRESSION:\r
873b7997 679 if (FeaturePcdGet(PcdDxeIplSupportUefiDecompress)) {\r
b0d803fe 680 //\r
873b7997 681 // Load EFI standard compression.\r
682 // For compressed data, decompress them to destination buffer.\r
b0d803fe 683 //\r
873b7997 684 Status = UefiDecompressGetInfo (\r
890e5417
SZ
685 CompressionSource,\r
686 CompressionSourceSize,\r
635021c5 687 &DstBufferSize,\r
873b7997 688 &ScratchBufferSize\r
689 );\r
690 if (EFI_ERROR (Status)) {\r
691 //\r
692 // GetInfo failed\r
693 //\r
694 DEBUG ((DEBUG_ERROR, "Decompress GetInfo Failed - %r\n", Status));\r
695 return EFI_NOT_FOUND;\r
696 }\r
697 //\r
698 // Allocate scratch buffer\r
b0d803fe 699 //\r
873b7997 700 ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));\r
701 if (ScratchBuffer == NULL) {\r
702 return EFI_OUT_OF_RESOURCES;\r
703 }\r
704 //\r
d40695ad 705 // Allocate destination buffer\r
873b7997 706 //\r
d40695ad 707 DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));\r
873b7997 708 if (DstBuffer == NULL) {\r
709 return EFI_OUT_OF_RESOURCES;\r
710 }\r
b0d803fe 711 //\r
873b7997 712 // Call decompress function\r
713 //\r
714 Status = UefiDecompress (\r
890e5417 715 CompressionSource,\r
873b7997 716 DstBuffer,\r
717 ScratchBuffer\r
718 );\r
719 if (EFI_ERROR (Status)) {\r
720 //\r
721 // Decompress failed\r
722 //\r
723 DEBUG ((DEBUG_ERROR, "Decompress Failed - %r\n", Status));\r
724 return EFI_NOT_FOUND;\r
725 }\r
726 break;\r
727 } else {\r
12b3e61e
LG
728 //\r
729 // PcdDxeIplSupportUefiDecompress is FALSE\r
730 // Don't support UEFI decompression algorithm.\r
731 //\r
732 ASSERT (FALSE);\r
b0d803fe 733 return EFI_NOT_FOUND;\r
734 }\r
b0d803fe 735\r
b0d803fe 736 case EFI_NOT_COMPRESSED:\r
737 //\r
738 // Allocate destination buffer\r
739 //\r
890e5417 740 DstBufferSize = UncompressedLength;\r
d40695ad 741 DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));\r
b0d803fe 742 if (DstBuffer == NULL) {\r
743 return EFI_OUT_OF_RESOURCES;\r
744 }\r
745 //\r
746 // stream is not actually compressed, just encapsulated. So just copy it.\r
747 //\r
890e5417 748 CopyMem (DstBuffer, CompressionSource, DstBufferSize);\r
b0d803fe 749 break;\r
750\r
751 default:\r
752 //\r
753 // Don't support other unknown compression type.\r
754 //\r
755 ASSERT (FALSE);\r
756 return EFI_NOT_FOUND;\r
757 }\r
758\r
759 *OutputSize = DstBufferSize;\r
760 *OutputBuffer = DstBuffer;\r
761\r
762 return EFI_SUCCESS;\r
763}\r
764\r
91d92e25 765\r
91d92e25 766/**\r
767 Updates the Stack HOB passed to DXE phase.\r
768\r
769 This function traverses the whole HOB list and update the stack HOB to\r
770 reflect the real stack that is used by DXE core.\r
771\r
772 @param BaseAddress The lower address of stack used by DxeCore.\r
773 @param Length The length of stack used by DxeCore.\r
774\r
775**/\r
30c8f861 776VOID\r
777UpdateStackHob (\r
778 IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
779 IN UINT64 Length\r
780 )\r
781{\r
782 EFI_PEI_HOB_POINTERS Hob;\r
783\r
784 Hob.Raw = GetHobList ();\r
785 while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) {\r
786 if (CompareGuid (&gEfiHobMemoryAllocStackGuid, &(Hob.MemoryAllocationStack->AllocDescriptor.Name))) {\r
787 //\r
d1102dba
LG
788 // Build a new memory allocation HOB with old stack info with EfiBootServicesData type. Need to\r
789 // avoid this region be reclaimed by DXE core as the IDT built in SEC might be on stack, and some\r
9a43bc39 790 // PEIMs may also keep key information on stack\r
30c8f861 791 //\r
792 BuildMemoryAllocationHob (\r
793 Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress,\r
794 Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength,\r
9a43bc39 795 EfiBootServicesData\r
30c8f861 796 );\r
797 //\r
798 // Update the BSP Stack Hob to reflect the new stack info.\r
799 //\r
800 Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress = BaseAddress;\r
801 Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength = Length;\r
802 break;\r
803 }\r
804 Hob.Raw = GET_NEXT_HOB (Hob);\r
805 }\r
806}\r
9189ec20 807\r