]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - MdeModulePkg/Core/DxeIplPeim/DxeLoad.c
Add more status code in drivers.
[mirror_edk2.git] / MdeModulePkg / Core / DxeIplPeim / DxeLoad.c
... / ...
CommitLineData
1/** @file\r
2 Last PEIM.\r
3 Responsibility of this module is to load the DXE Core from a Firmware Volume.\r
4\r
5Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
6This program and the accompanying materials\r
7are licensed and made available under the terms and conditions of the BSD License\r
8which accompanies this distribution. The full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include "DxeIpl.h"\r
17\r
18\r
19//\r
20// Module Globals used in the DXE to PEI hand off\r
21// These must be module globals, so the stack can be switched\r
22//\r
23CONST EFI_DXE_IPL_PPI mDxeIplPpi = {\r
24 DxeLoadCore\r
25};\r
26\r
27CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI mCustomGuidedSectionExtractionPpi = {\r
28 CustomGuidedSectionExtract\r
29};\r
30\r
31CONST EFI_PEI_DECOMPRESS_PPI mDecompressPpi = {\r
32 Decompress\r
33};\r
34\r
35CONST EFI_PEI_PPI_DESCRIPTOR mPpiList[] = {\r
36 {\r
37 EFI_PEI_PPI_DESCRIPTOR_PPI,\r
38 &gEfiDxeIplPpiGuid,\r
39 (VOID *) &mDxeIplPpi\r
40 },\r
41 {\r
42 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
43 &gEfiPeiDecompressPpiGuid,\r
44 (VOID *) &mDecompressPpi\r
45 }\r
46};\r
47\r
48CONST EFI_PEI_PPI_DESCRIPTOR gEndOfPeiSignalPpi = {\r
49 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
50 &gEfiEndOfPeiSignalPpiGuid,\r
51 NULL\r
52};\r
53\r
54/**\r
55 Entry point of DXE IPL PEIM.\r
56 \r
57 This function installs DXE IPL PPI and Decompress PPI. It also reloads\r
58 itself to memory on non-S3 resume boot path.\r
59\r
60 @param FileHandle Handle of the file being invoked.\r
61 @param PeiServices Describes the list of possible PEI Services.\r
62\r
63 @retval EFI_SUCESS The entry point of DXE IPL PEIM executes successfully.\r
64 @retval Others Some error occurs during the execution of this function. \r
65\r
66**/\r
67EFI_STATUS\r
68EFIAPI\r
69PeimInitializeDxeIpl (\r
70 IN EFI_PEI_FILE_HANDLE FileHandle,\r
71 IN CONST EFI_PEI_SERVICES **PeiServices\r
72 )\r
73{\r
74 EFI_STATUS Status;\r
75 EFI_BOOT_MODE BootMode;\r
76 EFI_GUID *ExtractHandlerGuidTable;\r
77 UINTN ExtractHandlerNumber;\r
78 EFI_PEI_PPI_DESCRIPTOR *GuidPpi;\r
79 \r
80 BootMode = GetBootModeHob ();\r
81\r
82 if (BootMode != BOOT_ON_S3_RESUME) {\r
83 Status = PeiServicesRegisterForShadow (FileHandle);\r
84 if (Status == EFI_SUCCESS) {\r
85 //\r
86 // EFI_SUCESS means it is the first time to call register for shadow. \r
87 // \r
88 return Status;\r
89 }\r
90 \r
91 //\r
92 // Ensure that DXE IPL is shadowed to permanent memory.\r
93 //\r
94 ASSERT (Status == EFI_ALREADY_STARTED);\r
95 \r
96 //\r
97 // Get custom extract guided section method guid list \r
98 //\r
99 ExtractHandlerNumber = ExtractGuidedSectionGetGuidList (&ExtractHandlerGuidTable);\r
100 \r
101 //\r
102 // Install custom extraction guid PPI\r
103 //\r
104 if (ExtractHandlerNumber > 0) {\r
105 GuidPpi = (EFI_PEI_PPI_DESCRIPTOR *) AllocatePool (ExtractHandlerNumber * sizeof (EFI_PEI_PPI_DESCRIPTOR));\r
106 ASSERT (GuidPpi != NULL);\r
107 while (ExtractHandlerNumber-- > 0) {\r
108 GuidPpi->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;\r
109 GuidPpi->Ppi = (VOID *) &mCustomGuidedSectionExtractionPpi;\r
110 GuidPpi->Guid = &ExtractHandlerGuidTable[ExtractHandlerNumber];\r
111 Status = PeiServicesInstallPpi (GuidPpi++);\r
112 ASSERT_EFI_ERROR(Status);\r
113 }\r
114 }\r
115 \r
116 }\r
117 \r
118 //\r
119 // Install DxeIpl and Decompress PPIs.\r
120 //\r
121 Status = PeiServicesInstallPpi (mPpiList);\r
122 ASSERT_EFI_ERROR(Status);\r
123\r
124 return Status;\r
125}\r
126\r
127/**\r
128 Main entry point to last PEIM. \r
129\r
130 This function finds DXE Core in the firmware volume and transfer the control to\r
131 DXE core.\r
132 \r
133 @param This Entry point for DXE IPL PPI.\r
134 @param PeiServices General purpose services available to every PEIM.\r
135 @param HobList Address to the Pei HOB list.\r
136 \r
137 @return EFI_SUCCESS DXE core was successfully loaded. \r
138 @return EFI_OUT_OF_RESOURCES There are not enough resources to load DXE core.\r
139\r
140**/\r
141EFI_STATUS\r
142EFIAPI\r
143DxeLoadCore (\r
144 IN CONST EFI_DXE_IPL_PPI *This,\r
145 IN EFI_PEI_SERVICES **PeiServices,\r
146 IN EFI_PEI_HOB_POINTERS HobList\r
147 )\r
148{\r
149 EFI_STATUS Status;\r
150 EFI_FV_FILE_INFO DxeCoreFileInfo;\r
151 EFI_PHYSICAL_ADDRESS DxeCoreAddress;\r
152 UINT64 DxeCoreSize;\r
153 EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint;\r
154 EFI_BOOT_MODE BootMode;\r
155 EFI_PEI_FILE_HANDLE FileHandle;\r
156 EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable;\r
157 EFI_PEI_LOAD_FILE_PPI *LoadFile;\r
158 UINTN Instance;\r
159 UINT32 AuthenticationState;\r
160 UINTN DataSize;\r
161 EFI_PEI_S3_RESUME2_PPI *S3Resume;\r
162 EFI_PEI_RECOVERY_MODULE_PPI *PeiRecovery;\r
163 EFI_MEMORY_TYPE_INFORMATION MemoryData[EfiMaxMemoryType + 1];\r
164\r
165 //\r
166 // if in S3 Resume, restore configure\r
167 //\r
168 BootMode = GetBootModeHob ();\r
169\r
170 if (BootMode == BOOT_ON_S3_RESUME) {\r
171 Status = PeiServicesLocatePpi (\r
172 &gEfiPeiS3Resume2PpiGuid,\r
173 0,\r
174 NULL,\r
175 (VOID **) &S3Resume\r
176 );\r
177 ASSERT_EFI_ERROR (Status);\r
178 \r
179 Status = S3Resume->S3RestoreConfig2 (S3Resume);\r
180 ASSERT_EFI_ERROR (Status);\r
181 } else if (BootMode == BOOT_IN_RECOVERY_MODE) {\r
182 Status = PeiServicesLocatePpi (\r
183 &gEfiPeiRecoveryModulePpiGuid,\r
184 0,\r
185 NULL,\r
186 (VOID **) &PeiRecovery\r
187 );\r
188 ASSERT_EFI_ERROR (Status);\r
189 \r
190 Status = PeiRecovery->LoadRecoveryCapsule (PeiServices, PeiRecovery);\r
191 if (EFI_ERROR (Status)) {\r
192 DEBUG ((DEBUG_ERROR, "Load Recovery Capsule Failed.(Status = %r)\n", Status));\r
193 CpuDeadLoop ();\r
194 }\r
195\r
196 //\r
197 // Now should have a HOB with the DXE core\r
198 //\r
199 }\r
200\r
201 Status = PeiServicesLocatePpi (\r
202 &gEfiPeiReadOnlyVariable2PpiGuid,\r
203 0,\r
204 NULL,\r
205 (VOID **)&Variable\r
206 );\r
207 if (!EFI_ERROR (Status)) {\r
208 DataSize = sizeof (MemoryData);\r
209 Status = Variable->GetVariable ( \r
210 Variable, \r
211 EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,\r
212 &gEfiMemoryTypeInformationGuid,\r
213 NULL,\r
214 &DataSize,\r
215 &MemoryData\r
216 );\r
217 if (!EFI_ERROR (Status)) {\r
218 //\r
219 // Build the GUID'd HOB for DXE\r
220 //\r
221 BuildGuidDataHob (\r
222 &gEfiMemoryTypeInformationGuid,\r
223 MemoryData,\r
224 DataSize\r
225 );\r
226 }\r
227 }\r
228\r
229 //\r
230 // Look in all the FVs present in PEI and find the DXE Core FileHandle\r
231 //\r
232 FileHandle = DxeIplFindDxeCore ();\r
233\r
234 //\r
235 // Load the DXE Core from a Firmware Volume.\r
236 //\r
237 Instance = 0;\r
238 do {\r
239 Status = PeiServicesLocatePpi (&gEfiPeiLoadFilePpiGuid, Instance++, NULL, (VOID **) &LoadFile);\r
240 //\r
241 // These must exist an instance of EFI_PEI_LOAD_FILE_PPI to support to load DxeCore file handle successfully.\r
242 //\r
243 ASSERT_EFI_ERROR (Status);\r
244\r
245 Status = LoadFile->LoadFile (\r
246 LoadFile,\r
247 FileHandle,\r
248 &DxeCoreAddress,\r
249 &DxeCoreSize,\r
250 &DxeCoreEntryPoint,\r
251 &AuthenticationState\r
252 );\r
253 } while (EFI_ERROR (Status));\r
254\r
255 //\r
256 // Get the DxeCore File Info from the FileHandle for the DxeCore GUID file name.\r
257 //\r
258 Status = PeiServicesFfsGetFileInfo (FileHandle, &DxeCoreFileInfo);\r
259 ASSERT_EFI_ERROR (Status);\r
260\r
261 //\r
262 // Add HOB for the DXE Core\r
263 //\r
264 BuildModuleHob (\r
265 &DxeCoreFileInfo.FileName,\r
266 DxeCoreAddress,\r
267 ALIGN_VALUE (DxeCoreSize, EFI_PAGE_SIZE),\r
268 DxeCoreEntryPoint\r
269 );\r
270\r
271 //\r
272 // Report Status Code EFI_SW_PEI_PC_HANDOFF_TO_NEXT\r
273 //\r
274 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_CORE | EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT));\r
275\r
276 DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading DXE CORE at 0x%11p EntryPoint=0x%11p\n", (VOID *)(UINTN)DxeCoreAddress, FUNCTION_ENTRY_POINT (DxeCoreEntryPoint)));\r
277\r
278 //\r
279 // Transfer control to the DXE Core\r
280 // The hand off state is simply a pointer to the HOB list\r
281 //\r
282 HandOffToDxeCore (DxeCoreEntryPoint, HobList);\r
283 //\r
284 // If we get here, then the DXE Core returned. This is an error\r
285 // DxeCore should not return.\r
286 //\r
287 ASSERT (FALSE);\r
288 CpuDeadLoop ();\r
289\r
290 return EFI_OUT_OF_RESOURCES;\r
291}\r
292\r
293\r
294/**\r
295 Searches DxeCore in all firmware Volumes and loads the first\r
296 instance that contains DxeCore.\r
297\r
298 @return FileHandle of DxeCore to load DxeCore.\r
299 \r
300**/\r
301EFI_PEI_FILE_HANDLE\r
302DxeIplFindDxeCore (\r
303 VOID\r
304 )\r
305{\r
306 EFI_STATUS Status;\r
307 UINTN Instance;\r
308 EFI_PEI_FV_HANDLE VolumeHandle;\r
309 EFI_PEI_FILE_HANDLE FileHandle;\r
310 \r
311 Instance = 0;\r
312 while (TRUE) {\r
313 //\r
314 // Traverse all firmware volume instances\r
315 //\r
316 Status = PeiServicesFfsFindNextVolume (Instance, &VolumeHandle);\r
317 //\r
318 // If some error occurs here, then we cannot find any firmware\r
319 // volume that may contain DxeCore.\r
320 //\r
321 if (EFI_ERROR (Status)) {\r
322 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_CORE_EC_DXE_CORRUPT));\r
323 }\r
324 ASSERT_EFI_ERROR (Status);\r
325 \r
326 //\r
327 // Find the DxeCore file type from the beginning in this firmware volume.\r
328 //\r
329 FileHandle = NULL;\r
330 Status = PeiServicesFfsFindNextFile (EFI_FV_FILETYPE_DXE_CORE, VolumeHandle, &FileHandle);\r
331 if (!EFI_ERROR (Status)) {\r
332 //\r
333 // Find DxeCore FileHandle in this volume, then we skip other firmware volume and\r
334 // return the FileHandle.\r
335 //\r
336 return FileHandle;\r
337 }\r
338 //\r
339 // We cannot find DxeCore in this firmware volume, then search the next volume.\r
340 //\r
341 Instance++;\r
342 }\r
343}\r
344\r
345\r
346\r
347/**\r
348 The ExtractSection() function processes the input section and\r
349 returns a pointer to the section contents. If the section being\r
350 extracted does not require processing (if the section\r
351 GuidedSectionHeader.Attributes has the\r
352 EFI_GUIDED_SECTION_PROCESSING_REQUIRED field cleared), then\r
353 OutputBuffer is just updated to point to the start of the\r
354 section's contents. Otherwise, *Buffer must be allocated\r
355 from PEI permanent memory.\r
356\r
357 @param This Indicates the\r
358 EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI instance.\r
359 Buffer containing the input GUIDed section to be\r
360 processed. OutputBuffer OutputBuffer is\r
361 allocated from PEI permanent memory and contains\r
362 the new section stream.\r
363 @param InputSection A pointer to the input buffer, which contains\r
364 the input section to be processed.\r
365 @param OutputBuffer A pointer to a caller-allocated buffer, whose\r
366 size is specified by the contents of OutputSize.\r
367 @param OutputSize A pointer to a caller-allocated\r
368 UINTN in which the size of *OutputBuffer\r
369 allocation is stored. If the function\r
370 returns anything other than EFI_SUCCESS,\r
371 the value of OutputSize is undefined.\r
372 @param AuthenticationStatus A pointer to a caller-allocated\r
373 UINT32 that indicates the\r
374 authentication status of the\r
375 output buffer. If the input\r
376 section's GuidedSectionHeader.\r
377 Attributes field has the\r
378 EFI_GUIDED_SECTION_AUTH_STATUS_VALID \r
379 bit as clear,\r
380 AuthenticationStatus must return\r
381 zero. These bits reflect the\r
382 status of the extraction\r
383 operation. If the function\r
384 returns anything other than\r
385 EFI_SUCCESS, the value of\r
386 AuthenticationStatus is\r
387 undefined.\r
388 \r
389 @retval EFI_SUCCESS The InputSection was\r
390 successfully processed and the\r
391 section contents were returned.\r
392 \r
393 @retval EFI_OUT_OF_RESOURCES The system has insufficient\r
394 resources to process the request.\r
395 \r
396 @retval EFI_INVALID_PARAMETER The GUID in InputSection does\r
397 not match this instance of the\r
398 GUIDed Section Extraction PPI.\r
399\r
400**/\r
401EFI_STATUS\r
402EFIAPI\r
403CustomGuidedSectionExtract (\r
404 IN CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *This,\r
405 IN CONST VOID *InputSection,\r
406 OUT VOID **OutputBuffer,\r
407 OUT UINTN *OutputSize,\r
408 OUT UINT32 *AuthenticationStatus\r
409)\r
410{\r
411 EFI_STATUS Status;\r
412 UINT8 *ScratchBuffer;\r
413 UINT32 ScratchBufferSize;\r
414 UINT32 OutputBufferSize;\r
415 UINT16 SectionAttribute;\r
416 \r
417 //\r
418 // Init local variable\r
419 //\r
420 ScratchBuffer = NULL;\r
421\r
422 //\r
423 // Call GetInfo to get the size and attribute of input guided section data.\r
424 //\r
425 Status = ExtractGuidedSectionGetInfo (\r
426 InputSection,\r
427 &OutputBufferSize,\r
428 &ScratchBufferSize,\r
429 &SectionAttribute\r
430 );\r
431 \r
432 if (EFI_ERROR (Status)) {\r
433 DEBUG ((DEBUG_ERROR, "GetInfo from guided section Failed - %r\n", Status));\r
434 return Status;\r
435 }\r
436 \r
437 if (ScratchBufferSize != 0) {\r
438 //\r
439 // Allocate scratch buffer\r
440 //\r
441 ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));\r
442 if (ScratchBuffer == NULL) {\r
443 return EFI_OUT_OF_RESOURCES;\r
444 }\r
445 }\r
446\r
447 if (((SectionAttribute & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) && OutputBufferSize > 0) { \r
448 //\r
449 // Allocate output buffer\r
450 //\r
451 *OutputBuffer = AllocatePages (EFI_SIZE_TO_PAGES (OutputBufferSize) + 1);\r
452 if (*OutputBuffer == NULL) {\r
453 return EFI_OUT_OF_RESOURCES;\r
454 }\r
455 DEBUG ((DEBUG_INFO, "Customized Guided section Memory Size required is 0x%x and address is 0x%p\n", OutputBufferSize, *OutputBuffer));\r
456 //\r
457 // *OutputBuffer still is one section. Adjust *OutputBuffer offset, \r
458 // skip EFI section header to make section data at page alignment.\r
459 //\r
460 *OutputBuffer = (VOID *)((UINT8 *) *OutputBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER));\r
461 }\r
462 \r
463 Status = ExtractGuidedSectionDecode (\r
464 InputSection, \r
465 OutputBuffer,\r
466 ScratchBuffer,\r
467 AuthenticationStatus\r
468 );\r
469 if (EFI_ERROR (Status)) {\r
470 //\r
471 // Decode failed\r
472 //\r
473 DEBUG ((DEBUG_ERROR, "Extract guided section Failed - %r\n", Status));\r
474 return Status;\r
475 }\r
476 \r
477 *OutputSize = (UINTN) OutputBufferSize;\r
478 \r
479 return EFI_SUCCESS;\r
480}\r
481\r
482\r
483\r
484/**\r
485 Decompresses a section to the output buffer.\r
486\r
487 This function looks up the compression type field in the input section and\r
488 applies the appropriate compression algorithm to compress the section to a\r
489 callee allocated buffer.\r
490 \r
491 @param This Points to this instance of the\r
492 EFI_PEI_DECOMPRESS_PEI PPI.\r
493 @param CompressionSection Points to the compressed section.\r
494 @param OutputBuffer Holds the returned pointer to the decompressed\r
495 sections.\r
496 @param OutputSize Holds the returned size of the decompress\r
497 section streams.\r
498 \r
499 @retval EFI_SUCCESS The section was decompressed successfully.\r
500 OutputBuffer contains the resulting data and\r
501 OutputSize contains the resulting size.\r
502\r
503**/\r
504EFI_STATUS\r
505EFIAPI \r
506Decompress (\r
507 IN CONST EFI_PEI_DECOMPRESS_PPI *This,\r
508 IN CONST EFI_COMPRESSION_SECTION *CompressionSection,\r
509 OUT VOID **OutputBuffer,\r
510 OUT UINTN *OutputSize\r
511 )\r
512{\r
513 EFI_STATUS Status;\r
514 UINT8 *DstBuffer;\r
515 UINT8 *ScratchBuffer;\r
516 UINT32 DstBufferSize;\r
517 UINT32 ScratchBufferSize;\r
518 EFI_COMMON_SECTION_HEADER *Section;\r
519 UINT32 SectionLength;\r
520\r
521 if (CompressionSection->CommonHeader.Type != EFI_SECTION_COMPRESSION) {\r
522 ASSERT (FALSE);\r
523 return EFI_INVALID_PARAMETER;\r
524 }\r
525\r
526 Section = (EFI_COMMON_SECTION_HEADER *) CompressionSection;\r
527 SectionLength = *(UINT32 *) (Section->Size) & 0x00ffffff;\r
528 \r
529 //\r
530 // This is a compression set, expand it\r
531 //\r
532 switch (CompressionSection->CompressionType) {\r
533 case EFI_STANDARD_COMPRESSION:\r
534 if (FeaturePcdGet(PcdDxeIplSupportUefiDecompress)) {\r
535 //\r
536 // Load EFI standard compression.\r
537 // For compressed data, decompress them to destination buffer.\r
538 //\r
539 Status = UefiDecompressGetInfo (\r
540 (UINT8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),\r
541 SectionLength - sizeof (EFI_COMPRESSION_SECTION),\r
542 &DstBufferSize,\r
543 &ScratchBufferSize\r
544 );\r
545 if (EFI_ERROR (Status)) {\r
546 //\r
547 // GetInfo failed\r
548 //\r
549 DEBUG ((DEBUG_ERROR, "Decompress GetInfo Failed - %r\n", Status));\r
550 return EFI_NOT_FOUND;\r
551 }\r
552 //\r
553 // Allocate scratch buffer\r
554 //\r
555 ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));\r
556 if (ScratchBuffer == NULL) {\r
557 return EFI_OUT_OF_RESOURCES;\r
558 }\r
559 //\r
560 // Allocate destination buffer, extra one page for adjustment \r
561 //\r
562 DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize) + 1);\r
563 if (DstBuffer == NULL) {\r
564 return EFI_OUT_OF_RESOURCES;\r
565 }\r
566 //\r
567 // DstBuffer still is one section. Adjust DstBuffer offset, skip EFI section header\r
568 // to make section data at page alignment.\r
569 //\r
570 DstBuffer = DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER);\r
571 //\r
572 // Call decompress function\r
573 //\r
574 Status = UefiDecompress (\r
575 (CHAR8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),\r
576 DstBuffer,\r
577 ScratchBuffer\r
578 );\r
579 if (EFI_ERROR (Status)) {\r
580 //\r
581 // Decompress failed\r
582 //\r
583 DEBUG ((DEBUG_ERROR, "Decompress Failed - %r\n", Status));\r
584 return EFI_NOT_FOUND;\r
585 }\r
586 break;\r
587 } else {\r
588 //\r
589 // PcdDxeIplSupportUefiDecompress is FALSE\r
590 // Don't support UEFI decompression algorithm.\r
591 //\r
592 ASSERT (FALSE);\r
593 return EFI_NOT_FOUND;\r
594 }\r
595\r
596 case EFI_NOT_COMPRESSED:\r
597 //\r
598 // Allocate destination buffer\r
599 //\r
600 DstBufferSize = CompressionSection->UncompressedLength;\r
601 DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize) + 1);\r
602 if (DstBuffer == NULL) {\r
603 return EFI_OUT_OF_RESOURCES;\r
604 }\r
605 //\r
606 // Adjust DstBuffer offset, skip EFI section header\r
607 // to make section data at page alignment.\r
608 //\r
609 DstBuffer = DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER);\r
610 //\r
611 // stream is not actually compressed, just encapsulated. So just copy it.\r
612 //\r
613 CopyMem (DstBuffer, CompressionSection + 1, DstBufferSize);\r
614 break;\r
615\r
616 default:\r
617 //\r
618 // Don't support other unknown compression type.\r
619 //\r
620 ASSERT (FALSE);\r
621 return EFI_NOT_FOUND;\r
622 }\r
623\r
624 *OutputSize = DstBufferSize;\r
625 *OutputBuffer = DstBuffer;\r
626\r
627 return EFI_SUCCESS;\r
628}\r
629\r
630\r
631/**\r
632 Updates the Stack HOB passed to DXE phase.\r
633\r
634 This function traverses the whole HOB list and update the stack HOB to\r
635 reflect the real stack that is used by DXE core.\r
636\r
637 @param BaseAddress The lower address of stack used by DxeCore.\r
638 @param Length The length of stack used by DxeCore.\r
639\r
640**/\r
641VOID\r
642UpdateStackHob (\r
643 IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
644 IN UINT64 Length\r
645 )\r
646{\r
647 EFI_PEI_HOB_POINTERS Hob;\r
648\r
649 Hob.Raw = GetHobList ();\r
650 while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) {\r
651 if (CompareGuid (&gEfiHobMemoryAllocStackGuid, &(Hob.MemoryAllocationStack->AllocDescriptor.Name))) {\r
652 //\r
653 // Build a new memory allocation HOB with old stack info with EfiBootServicesData type. Need to \r
654 // avoid this region be reclaimed by DXE core as the IDT built in SEC might be on stack, and some \r
655 // PEIMs may also keep key information on stack\r
656 //\r
657 BuildMemoryAllocationHob (\r
658 Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress,\r
659 Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength,\r
660 EfiBootServicesData\r
661 );\r
662 //\r
663 // Update the BSP Stack Hob to reflect the new stack info.\r
664 //\r
665 Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress = BaseAddress;\r
666 Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength = Length;\r
667 break;\r
668 }\r
669 Hob.Raw = GET_NEXT_HOB (Hob);\r
670 }\r
671}\r