]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Core/DxeIplPeim/DxeLoad.c
Print real entry point for IPF image.
[mirror_edk2.git] / MdeModulePkg / Core / DxeIplPeim / DxeLoad.c
CommitLineData
b0d803fe 1/**@file\r
2 Last PEIM.\r
3 Responsibility of this module is to load the DXE Core from a Firmware Volume.\r
95276127 4\r
b0d803fe 5Copyright (c) 2006 - 2007 Intel Corporation\r
95276127 6All rights reserved. This 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
b0d803fe 14**/\r
95276127 15\r
95276127 16#include "DxeIpl.h"\r
d8c79a81 17#include <Ppi/GuidedSectionExtraction.h>\r
b0d803fe 18#include <FrameworkPei.h>\r
95276127 19\r
d8c79a81 20EFI_STATUS\r
18fd8d65 21CustomGuidedSectionExtract (\r
d8c79a81
LG
22 IN CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *This,\r
23 IN CONST VOID *InputSection,\r
24 OUT VOID **OutputBuffer,\r
25 OUT UINTN *OutputSize,\r
26 OUT UINT32 *AuthenticationStatus\r
27);\r
28\r
b0d803fe 29STATIC\r
30EFI_STATUS\r
31EFIAPI \r
32Decompress (\r
33 IN CONST EFI_PEI_DECOMPRESS_PPI *This,\r
34 IN CONST EFI_COMPRESSION_SECTION *InputSection,\r
35 OUT VOID **OutputBuffer,\r
36 OUT UINTN *OutputSize\r
37);\r
38\r
39\r
95276127 40BOOLEAN gInMemory = FALSE;\r
41\r
42//\r
43// Module Globals used in the DXE to PEI handoff\r
44// These must be module globals, so the stack can be switched\r
45//\r
46static EFI_DXE_IPL_PPI mDxeIplPpi = {\r
47 DxeLoadCore\r
48};\r
49\r
18fd8d65
LG
50STATIC EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI mCustomGuidedSectionExtractionPpi = {\r
51 CustomGuidedSectionExtract\r
95276127 52};\r
53\r
b0d803fe 54STATIC EFI_PEI_DECOMPRESS_PPI mDecompressPpi = {\r
55 Decompress\r
d8c79a81
LG
56};\r
57\r
95276127 58static EFI_PEI_PPI_DESCRIPTOR mPpiList[] = {\r
59 {\r
b0d803fe 60 EFI_PEI_PPI_DESCRIPTOR_PPI,\r
61 &gEfiDxeIplPpiGuid,\r
62 &mDxeIplPpi\r
95276127 63 },\r
64 {\r
b0d803fe 65 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
66 &gEfiPeiDecompressPpiGuid,\r
67 &mDecompressPpi\r
95276127 68 }\r
69};\r
70\r
71static EFI_PEI_PPI_DESCRIPTOR mPpiSignal = {\r
72 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
73 &gEfiEndOfPeiSignalPpiGuid,\r
74 NULL\r
75};\r
76\r
b0d803fe 77/**\r
78 Initializes the Dxe Ipl PPI\r
79\r
80 @param FfsHandle The handle of FFS file.\r
81 @param PeiServices General purpose services available to\r
82 every PEIM.\r
83 @return EFI_SUCESS \r
84*/ \r
95276127 85EFI_STATUS\r
86EFIAPI\r
87PeimInitializeDxeIpl (\r
b0d803fe 88 IN EFI_PEI_FILE_HANDLE FfsHandle,\r
95276127 89 IN EFI_PEI_SERVICES **PeiServices\r
90 )\r
95276127 91{\r
92 EFI_STATUS Status;\r
95276127 93 EFI_BOOT_MODE BootMode;\r
18fd8d65
LG
94 EFI_GUID *ExtractHandlerGuidTable;\r
95 UINTN ExtractHandlerNumber;\r
d8c79a81
LG
96 EFI_PEI_PPI_DESCRIPTOR *GuidPpi;\r
97 \r
95276127 98 Status = PeiServicesGetBootMode (&BootMode);\r
99 ASSERT_EFI_ERROR (Status);\r
100\r
b0d803fe 101 if (BootMode != BOOT_ON_S3_RESUME) {\r
102 Status = PeiServicesRegisterForShadow (FfsHandle);\r
103 if (Status == EFI_SUCCESS) {\r
b0d803fe 104 //\r
105 // EFI_SUCESS means the first time call register for shadow \r
106 // \r
107 return Status;\r
108 } else if (Status == EFI_ALREADY_STARTED) {\r
5516d05a 109 \r
110 gInMemory = TRUE;\r
111 \r
b0d803fe 112 //\r
18fd8d65 113 // Get custom extract guided section method guid list \r
b0d803fe 114 //\r
18fd8d65 115 ExtractHandlerNumber = ExtractGuidedSectionGetGuidList (&ExtractHandlerGuidTable);\r
b0d803fe 116 \r
117 //\r
18fd8d65 118 // Install custom extraction guid ppi\r
b0d803fe 119 //\r
18fd8d65 120 if (ExtractHandlerNumber > 0) {\r
b0d803fe 121 GuidPpi = NULL;\r
18fd8d65 122 GuidPpi = (EFI_PEI_PPI_DESCRIPTOR *) AllocatePool (ExtractHandlerNumber * sizeof (EFI_PEI_PPI_DESCRIPTOR));\r
b0d803fe 123 ASSERT (GuidPpi != NULL);\r
18fd8d65 124 while (ExtractHandlerNumber-- > 0) {\r
b0d803fe 125 GuidPpi->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;\r
18fd8d65
LG
126 GuidPpi->Ppi = &mCustomGuidedSectionExtractionPpi;\r
127 GuidPpi->Guid = &(ExtractHandlerGuidTable [ExtractHandlerNumber]);\r
b0d803fe 128 Status = PeiServicesInstallPpi (GuidPpi++);\r
129 ASSERT_EFI_ERROR(Status);\r
130 }\r
131 }\r
132 } else {\r
fb8749d0 133 ASSERT (FALSE);\r
d8c79a81 134 }\r
95276127 135 }\r
136 \r
b0d803fe 137 //\r
138 // Install FvFileLoader and DxeIpl PPIs.\r
139 //\r
140 Status = PeiServicesInstallPpi (mPpiList);\r
141 ASSERT_EFI_ERROR(Status); \r
142 \r
95276127 143 return Status;\r
144}\r
145\r
b0d803fe 146/**\r
147 Main entry point to last PEIM \r
148 \r
149 @param This Entry point for DXE IPL PPI\r
150 @param PeiServices General purpose services available to every PEIM.\r
151 @param HobList Address to the Pei HOB list\r
152 \r
153 @return EFI_SUCCESS DXE core was successfully loaded. \r
154 @return EFI_OUT_OF_RESOURCES There are not enough resources to load DXE core.\r
155**/\r
95276127 156EFI_STATUS\r
157EFIAPI\r
158DxeLoadCore (\r
159 IN EFI_DXE_IPL_PPI *This,\r
160 IN EFI_PEI_SERVICES **PeiServices,\r
161 IN EFI_PEI_HOB_POINTERS HobList\r
162 )\r
95276127 163{\r
164 EFI_STATUS Status;\r
165 EFI_GUID DxeCoreFileName;\r
95276127 166 EFI_PHYSICAL_ADDRESS DxeCoreAddress;\r
167 UINT64 DxeCoreSize;\r
168 EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint;\r
95276127 169 EFI_BOOT_MODE BootMode;\r
b0d803fe 170 EFI_PEI_FV_HANDLE VolumeHandle;\r
171 EFI_PEI_FILE_HANDLE FileHandle;\r
172 UINTN Instance;\r
95276127 173\r
174 //\r
175 // if in S3 Resume, restore configure\r
176 //\r
177 Status = PeiServicesGetBootMode (&BootMode);\r
178 ASSERT_EFI_ERROR(Status);\r
179\r
180 if (BootMode == BOOT_ON_S3_RESUME) {\r
e8da1266 181 Status = AcpiS3ResumeOs();\r
95276127 182 ASSERT_EFI_ERROR (Status);\r
183 } else if (BootMode == BOOT_IN_RECOVERY_MODE) {\r
e8da1266 184 Status = PeiRecoverFirmware ();\r
95276127 185 if (EFI_ERROR (Status)) {\r
186 DEBUG ((EFI_D_ERROR, "Load Recovery Capsule Failed.(Status = %r)\n", Status));\r
187 CpuDeadLoop ();\r
188 }\r
189\r
190 //\r
191 // Now should have a HOB with the DXE core w/ the old HOB destroyed\r
192 //\r
193 }\r
b0d803fe 194 \r
95276127 195 //\r
b0d803fe 196 // If any FV contains an encapsulated FV extract that FV\r
95276127 197 //\r
b0d803fe 198 DxeIplAddEncapsulatedFirmwareVolumes ();\r
199 \r
95276127 200 //\r
b0d803fe 201 // Look in all the FVs present in PEI and find the DXE Core\r
95276127 202 //\r
b0d803fe 203 Instance = 0;\r
204 Status = DxeIplFindFirmwareVolumeInstance (&Instance, EFI_FV_FILETYPE_DXE_CORE, &VolumeHandle, &FileHandle);\r
95276127 205 ASSERT_EFI_ERROR (Status);\r
206\r
b0d803fe 207 CopyMem(&DxeCoreFileName, &(((EFI_FFS_FILE_HEADER*)FileHandle)->Name), sizeof (EFI_GUID));\r
208\r
95276127 209 //\r
210 // Load the DXE Core from a Firmware Volume\r
211 //\r
212 Status = PeiLoadFile (\r
b0d803fe 213 FileHandle,\r
214 &DxeCoreAddress,\r
215 &DxeCoreSize,\r
216 &DxeCoreEntryPoint\r
217 );\r
218\r
95276127 219 ASSERT_EFI_ERROR (Status);\r
220\r
221 //\r
222 // Add HOB for the DXE Core\r
223 //\r
224 BuildModuleHob (\r
225 &DxeCoreFileName,\r
226 DxeCoreAddress,\r
0a7d0741 227 EFI_SIZE_TO_PAGES ((UINT32) DxeCoreSize) * EFI_PAGE_SIZE,\r
95276127 228 DxeCoreEntryPoint\r
229 );\r
230\r
231 //\r
232 // Report Status Code EFI_SW_PEI_PC_HANDOFF_TO_NEXT\r
233 //\r
234 REPORT_STATUS_CODE (\r
235 EFI_PROGRESS_CODE,\r
236 EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT\r
237 );\r
238\r
e98cd821
LG
239 DEBUG_CODE_BEGIN ();\r
240\r
241 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION PtrPeImage;\r
242 PtrPeImage.Pe32 = (EFI_IMAGE_NT_HEADERS32 *) ((UINTN) DxeCoreAddress + ((EFI_IMAGE_DOS_HEADER *) (UINTN) DxeCoreAddress)->e_lfanew);\r
243 \r
244 if (PtrPeImage.Pe32->FileHeader.Machine != IMAGE_FILE_MACHINE_IA64) {\r
245 DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Loading DXE CORE at 0x%08x EntryPoint=0x%08x\n", (UINTN) DxeCoreAddress, (UINTN) DxeCoreEntryPoint));\r
246 } else {\r
247 //\r
248 // For IPF Image, the real entry point should be print.\r
249 //\r
250 DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Loading DXE CORE at 0x%08x EntryPoint=0x%08x\n", (UINTN) DxeCoreAddress, (UINTN) (*(UINT64 *)(UINTN)DxeCoreEntryPoint)));\r
251 }\r
252\r
253 DEBUG_CODE_END ();\r
95276127 254 //\r
255 // Transfer control to the DXE Core\r
256 // The handoff state is simply a pointer to the HOB list\r
257 //\r
95276127 258 HandOffToDxeCore (DxeCoreEntryPoint, HobList, &mPpiSignal);\r
259 //\r
260 // If we get here, then the DXE Core returned. This is an error\r
261 // Dxe Core should not return.\r
262 //\r
263 ASSERT (FALSE);\r
264 CpuDeadLoop ();\r
265\r
266 return EFI_OUT_OF_RESOURCES;\r
267}\r
268\r
b0d803fe 269\r
270STATIC\r
95276127 271EFI_STATUS\r
b0d803fe 272GetFvAlignment (\r
273 IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader,\r
274 OUT UINT32 *FvAlignment\r
95276127 275 )\r
b0d803fe 276{\r
277 //\r
278 // Because FvLength in FvHeader is UINT64 type, \r
279 // so FvHeader must meed at least 8 bytes alignment.\r
280 // Get the appropriate alignment requirement.\r
281 // \r
282 if ((FvHeader->Attributes & EFI_FVB2_ALIGNMENT) < EFI_FVB2_ALIGNMENT_8) {\r
283 return EFI_UNSUPPORTED;\r
284 }\r
285 \r
286 *FvAlignment = 1 << ((FvHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16);\r
287 return EFI_SUCCESS;\r
288}\r
95276127 289\r
b0d803fe 290/**\r
291 Search EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE image and expand \r
292 as memory FV \r
293 \r
294 @return EFI_OUT_OF_RESOURCES There are no memory space to exstract FV\r
295 @return EFI_SUCESS Sucess to find the FV \r
296**/\r
297EFI_STATUS\r
298DxeIplAddEncapsulatedFirmwareVolumes (\r
299 VOID\r
300 )\r
301{\r
302 EFI_STATUS Status;\r
303 EFI_STATUS VolumeStatus;\r
304 UINTN Index;\r
305 EFI_FV_INFO VolumeInfo; \r
306 EFI_PEI_FV_HANDLE VolumeHandle;\r
307 EFI_PEI_FILE_HANDLE FileHandle;\r
308 UINT32 SectionLength;\r
309 EFI_FIRMWARE_VOLUME_HEADER *FvHeader;\r
310 EFI_FIRMWARE_VOLUME_IMAGE_SECTION *SectionHeader;\r
311 VOID *DstBuffer;\r
312 UINT32 FvAlignment;\r
b0d803fe 313\r
314 Status = EFI_NOT_FOUND;\r
315 Index = 0;\r
95276127 316\r
b0d803fe 317 do {\r
318 VolumeStatus = DxeIplFindFirmwareVolumeInstance (\r
319 &Index, \r
320 EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, \r
321 &VolumeHandle, \r
322 &FileHandle\r
323 );\r
324 \r
325 if (!EFI_ERROR (VolumeStatus)) {\r
326 Status = PeiServicesFfsFindSectionData (\r
327 EFI_SECTION_FIRMWARE_VOLUME_IMAGE, \r
328 (EFI_FFS_FILE_HEADER *)FileHandle, \r
329 (VOID **)&FvHeader\r
330 );\r
331 \r
332 if (!EFI_ERROR (Status)) {\r
333 if (FvHeader->Signature == EFI_FVH_SIGNATURE) {\r
334 //\r
335 // Because FvLength in FvHeader is UINT64 type, \r
336 // so FvHeader must meed at least 8 bytes alignment.\r
337 // If current FvImage base address doesn't meet its alignment,\r
338 // we need to reload this FvImage to another correct memory address.\r
339 //\r
340 Status = GetFvAlignment(FvHeader, &FvAlignment); \r
341 if (EFI_ERROR(Status)) {\r
342 return Status;\r
343 }\r
344 if (((UINTN) FvHeader % FvAlignment) != 0) {\r
345 SectionHeader = (EFI_FIRMWARE_VOLUME_IMAGE_SECTION*)((UINTN)FvHeader - sizeof(EFI_FIRMWARE_VOLUME_IMAGE_SECTION));\r
346 SectionLength = *(UINT32 *)SectionHeader->Size & 0x00FFFFFF;\r
347 \r
348 DstBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINTN) SectionLength - sizeof (EFI_COMMON_SECTION_HEADER)), FvAlignment);\r
349 if (DstBuffer == NULL) {\r
350 return EFI_OUT_OF_RESOURCES;\r
351 }\r
352 CopyMem (DstBuffer, FvHeader, (UINTN) SectionLength - sizeof (EFI_COMMON_SECTION_HEADER));\r
353 FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) DstBuffer; \r
354 }\r
95276127 355\r
b0d803fe 356 //\r
357 // This new Firmware Volume comes from a firmware file within a firmware volume.\r
358 // Record the original Firmware Volume Name.\r
359 //\r
360 PeiServicesFfsGetVolumeInfo (&VolumeHandle, &VolumeInfo);\r
95276127 361\r
10dde96f 362 PiLibInstallFvInfoPpi (\r
363 NULL,\r
364 FvHeader,\r
365 (UINT32) FvHeader->FvLength,\r
b0d803fe 366 &(VolumeInfo.FvName),\r
64253026 367 &(((EFI_FFS_FILE_HEADER*)FileHandle)->Name)\r
b0d803fe 368 );\r
10dde96f 369\r
370 //\r
371 // Inform HOB consumer phase, i.e. DXE core, the existance of this FV\r
372 //\r
373 BuildFvHob (\r
374 (EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader,\r
375 FvHeader->FvLength\r
376 );\r
64253026 377 \r
b0d803fe 378 ASSERT_EFI_ERROR (Status);\r
95276127 379\r
b0d803fe 380 //\r
381 // Makes the encapsulated volume show up in DXE phase to skip processing of\r
382 // encapsulated file again.\r
383 //\r
384 BuildFv2Hob (\r
385 (EFI_PHYSICAL_ADDRESS)(UINTN)FvHeader,\r
386 FvHeader->FvLength, \r
387 &VolumeInfo.FvName,\r
388 &(((EFI_FFS_FILE_HEADER *)FileHandle)->Name)\r
389 );\r
390 return Status;\r
391 }\r
392 }\r
393 }\r
394 } while (!EFI_ERROR (VolumeStatus));\r
395 \r
396 return Status;\r
397}\r
95276127 398\r
b0d803fe 399/**\r
400 Find the First Volume that contains the first FileType.\r
401\r
402 @param Instance The Fv instance.\r
403 @param SeachType The type of file to search.\r
404 @param VolumeHandle Pointer to Fv which contains the file to search. \r
405 @param FileHandle Pointer to FFS file to search.\r
406 \r
407 @return EFI_SUCESS Success to find the FFS in specificed FV\r
408 @return others Fail to find the FFS in specificed FV\r
409 */\r
410EFI_STATUS\r
411DxeIplFindFirmwareVolumeInstance (\r
412 IN OUT UINTN *Instance,\r
413 IN EFI_FV_FILETYPE SeachType,\r
414 OUT EFI_PEI_FV_HANDLE *VolumeHandle,\r
415 OUT EFI_PEI_FILE_HANDLE *FileHandle\r
416 )\r
95276127 417{\r
b0d803fe 418 EFI_STATUS Status;\r
419 EFI_STATUS VolumeStatus;\r
95276127 420\r
b0d803fe 421 do {\r
422 VolumeStatus = PeiServicesFfsFindNextVolume (*Instance, VolumeHandle);\r
423 if (!EFI_ERROR (VolumeStatus)) {\r
424 *FileHandle = NULL;\r
425 Status = PeiServicesFfsFindNextFile (SeachType, *VolumeHandle, FileHandle);\r
426 if (!EFI_ERROR (Status)) {\r
427 return Status;\r
95276127 428 }\r
429 }\r
b0d803fe 430 *Instance += 1;\r
431 } while (!EFI_ERROR (VolumeStatus));\r
432\r
433 return VolumeStatus;\r
95276127 434}\r
435\r
b0d803fe 436/**\r
437 Loads and relocates a PE/COFF image into memory.\r
438\r
439 @param FileHandle The image file handle\r
440 @param ImageAddress The base address of the relocated PE/COFF image\r
441 @param ImageSize The size of the relocated PE/COFF image\r
442 @param EntryPoint The entry point of the relocated PE/COFF image\r
443 \r
444 @return EFI_SUCCESS The file was loaded and relocated\r
445 @return EFI_OUT_OF_RESOURCES There was not enough memory to load and relocate the PE/COFF file\r
446**/\r
95276127 447EFI_STATUS\r
448PeiLoadFile (\r
b0d803fe 449 IN EFI_PEI_FILE_HANDLE FileHandle,\r
95276127 450 OUT EFI_PHYSICAL_ADDRESS *ImageAddress,\r
451 OUT UINT64 *ImageSize,\r
452 OUT EFI_PHYSICAL_ADDRESS *EntryPoint\r
453 )\r
b0d803fe 454{\r
95276127 455\r
b0d803fe 456 EFI_STATUS Status;\r
457 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
458 VOID *Pe32Data;\r
b0d803fe 459 //\r
460 // First try to find the required section in this ffs file.\r
461 //\r
462 Status = PeiServicesFfsFindSectionData (\r
463 EFI_SECTION_PE32,\r
464 FileHandle,\r
465 &Pe32Data\r
466 );\r
95276127 467\r
b0d803fe 468 if (EFI_ERROR (Status)) {\r
469 Status = PeiServicesFfsFindSectionData (\r
470 EFI_SECTION_TE,\r
471 FileHandle,\r
472 &Pe32Data\r
473 );\r
474 }\r
475 \r
476 if (EFI_ERROR (Status)) {\r
477 //\r
478 // NO image types we support so exit.\r
479 //\r
480 return Status;\r
481 }\r
95276127 482\r
483 ZeroMem (&ImageContext, sizeof (ImageContext));\r
484 ImageContext.Handle = Pe32Data;\r
485 Status = GetImageReadFunction (&ImageContext);\r
486\r
487 ASSERT_EFI_ERROR (Status);\r
488\r
3d7b0992 489 Status = PeCoffLoaderGetImageInfo (&ImageContext);\r
95276127 490 if (EFI_ERROR (Status)) {\r
491 return Status;\r
492 }\r
493 //\r
494 // Allocate Memory for the image\r
495 //\r
496 ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) AllocatePages (EFI_SIZE_TO_PAGES ((UINT32) ImageContext.ImageSize));\r
497 ASSERT (ImageContext.ImageAddress != 0);\r
498\r
4e844595
LG
499 //\r
500 // Skip the reserved space for the stripped PeHeader when load TeImage into memory.\r
501 //\r
502 if (ImageContext.IsTeImage) {\r
503 ImageContext.ImageAddress = ImageContext.ImageAddress + \r
504 ((EFI_TE_IMAGE_HEADER *) Pe32Data)->StrippedSize -\r
505 sizeof (EFI_TE_IMAGE_HEADER);\r
506 }\r
507\r
95276127 508 //\r
509 // Load the image to our new buffer\r
510 //\r
3d7b0992 511 Status = PeCoffLoaderLoadImage (&ImageContext);\r
95276127 512 if (EFI_ERROR (Status)) {\r
513 return Status;\r
514 }\r
515 //\r
516 // Relocate the image in our new buffer\r
517 //\r
3d7b0992 518 Status = PeCoffLoaderRelocateImage (&ImageContext);\r
95276127 519 if (EFI_ERROR (Status)) {\r
520 return Status;\r
521 }\r
522\r
523 //\r
524 // Flush the instruction cache so the image data is written before we execute it\r
525 //\r
526 InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);\r
527\r
528 *ImageAddress = ImageContext.ImageAddress;\r
529 *ImageSize = ImageContext.ImageSize;\r
530 *EntryPoint = ImageContext.EntryPoint;\r
531\r
532 return EFI_SUCCESS;\r
533}\r
534\r
d8c79a81
LG
535/**\r
536 The ExtractSection() function processes the input section and\r
537 returns a pointer to the section contents. If the section being\r
538 extracted does not require processing (if the section\r
539 GuidedSectionHeader.Attributes has the\r
540 EFI_GUIDED_SECTION_PROCESSING_REQUIRED field cleared), then\r
541 OutputBuffer is just updated to point to the start of the\r
542 section's contents. Otherwise, *Buffer must be allocated\r
543 from PEI permanent memory.\r
544\r
545 @param This Indicates the\r
546 EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI instance.\r
547 Buffer containing the input GUIDed section to be\r
548 processed. OutputBuffer OutputBuffer is\r
549 allocated from PEI permanent memory and contains\r
550 the new section stream.\r
551 \r
552 @param OutputSize A pointer to a caller-allocated\r
553 UINTN in which the size of *OutputBuffer\r
554 allocation is stored. If the function\r
555 returns anything other than EFI_SUCCESS,\r
556 the value of OutputSize is undefined.\r
557 \r
558 @param AuthenticationStatus A pointer to a caller-allocated\r
559 UINT32 that indicates the\r
560 authentication status of the\r
561 output buffer. If the input\r
562 section's GuidedSectionHeader.\r
563 Attributes field has the\r
564 EFI_GUIDED_SECTION_AUTH_STATUS_VALID \r
565 bit as clear,\r
566 AuthenticationStatus must return\r
567 zero. These bits reflect the\r
568 status of the extraction\r
569 operation. If the function\r
570 returns anything other than\r
571 EFI_SUCCESS, the value of\r
572 AuthenticationStatus is\r
573 undefined.\r
574 \r
575 @retval EFI_SUCCESS The InputSection was\r
576 successfully processed and the\r
577 section contents were returned.\r
578 \r
579 @retval EFI_OUT_OF_RESOURCES The system has insufficient\r
580 resources to process the request.\r
581 \r
582 @reteval EFI_INVALID_PARAMETER The GUID in InputSection does\r
583 not match this instance of the\r
584 GUIDed Section Extraction PPI.\r
585**/\r
586EFI_STATUS\r
18fd8d65 587CustomGuidedSectionExtract (\r
d8c79a81
LG
588 IN CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *This,\r
589 IN CONST VOID *InputSection,\r
590 OUT VOID **OutputBuffer,\r
591 OUT UINTN *OutputSize,\r
592 OUT UINT32 *AuthenticationStatus\r
593)\r
594{\r
595 EFI_STATUS Status;\r
596 UINT8 *ScratchBuffer;\r
18fd8d65
LG
597 UINT32 ScratchBufferSize;\r
598 UINT32 OutputBufferSize;\r
599 UINT16 SectionAttribute;\r
d8c79a81
LG
600 \r
601 //\r
18fd8d65 602 // Init local variable\r
d8c79a81 603 //\r
18fd8d65
LG
604 ScratchBuffer = NULL;\r
605\r
d8c79a81 606 //\r
18fd8d65 607 // Call GetInfo to get the size and attribute of input guided section data.\r
d8c79a81 608 //\r
18fd8d65
LG
609 Status = ExtractGuidedSectionGetInfo (\r
610 InputSection,\r
611 &OutputBufferSize,\r
612 &ScratchBufferSize,\r
613 &SectionAttribute\r
614 );\r
615 \r
d8c79a81 616 if (EFI_ERROR (Status)) {\r
18fd8d65
LG
617 DEBUG ((EFI_D_ERROR, "GetInfo from guided section Failed - %r\n", Status));\r
618 return Status;\r
619 }\r
620 \r
621 if (ScratchBufferSize != 0) {\r
95276127 622 //\r
18fd8d65 623 // Allocate scratch buffer\r
95276127 624 //\r
18fd8d65
LG
625 ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));\r
626 if (ScratchBuffer == NULL) {\r
627 return EFI_OUT_OF_RESOURCES;\r
628 }\r
d8c79a81 629 }\r
95276127 630\r
18fd8d65
LG
631 if ((SectionAttribute & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) && OutputBufferSize > 0) { \r
632 //\r
633 // Allocate output buffer\r
634 //\r
635 *OutputBuffer = AllocatePages (EFI_SIZE_TO_PAGES (OutputBufferSize));\r
636 if (*OutputBuffer == NULL) {\r
637 return EFI_OUT_OF_RESOURCES;\r
638 }\r
95276127 639 }\r
18fd8d65
LG
640 \r
641 Status = ExtractGuidedSectionDecode (\r
642 InputSection, \r
643 OutputBuffer,\r
644 ScratchBuffer,\r
645 AuthenticationStatus\r
646 );\r
95276127 647\r
d8c79a81
LG
648 if (EFI_ERROR (Status)) {\r
649 //\r
18fd8d65 650 // Decode failed\r
d8c79a81
LG
651 //\r
652 DEBUG ((EFI_D_ERROR, "Extract guided section Failed - %r\n", Status));\r
653 return Status;\r
654 }\r
655 \r
18fd8d65
LG
656 *OutputSize = (UINTN) OutputBufferSize;\r
657 \r
95276127 658 return EFI_SUCCESS;\r
659}\r
b0d803fe 660\r
661STATIC\r
662EFI_STATUS\r
663EFIAPI \r
664Decompress (\r
665 IN CONST EFI_PEI_DECOMPRESS_PPI *This,\r
666 IN CONST EFI_COMPRESSION_SECTION *CompressionSection,\r
667 OUT VOID **OutputBuffer,\r
668 OUT UINTN *OutputSize\r
669 )\r
670{\r
671 EFI_STATUS Status;\r
672 UINT8 *DstBuffer;\r
673 UINT8 *ScratchBuffer;\r
674 UINTN DstBufferSize;\r
675 UINT32 ScratchBufferSize;\r
676 EFI_COMMON_SECTION_HEADER *Section;\r
677 UINTN SectionLength;\r
678\r
679 if (CompressionSection->CommonHeader.Type != EFI_SECTION_COMPRESSION) {\r
680 ASSERT (FALSE);\r
681 return EFI_INVALID_PARAMETER;\r
682 }\r
683\r
684 Section = (EFI_COMMON_SECTION_HEADER *) CompressionSection;\r
685 SectionLength = *(UINT32 *) (Section->Size) & 0x00ffffff;\r
686 \r
687 //\r
688 // This is a compression set, expand it\r
689 //\r
690 switch (CompressionSection->CompressionType) {\r
691 case EFI_STANDARD_COMPRESSION:\r
692 //\r
693 // Load EFI standard compression.\r
694 // For compressed data, decompress them to dstbuffer.\r
695 //\r
696 Status = UefiDecompressGetInfo (\r
697 (UINT8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),\r
698 (UINT32) SectionLength - sizeof (EFI_COMPRESSION_SECTION),\r
699 (UINT32 *) &DstBufferSize,\r
700 &ScratchBufferSize\r
701 );\r
702 if (EFI_ERROR (Status)) {\r
703 //\r
704 // GetInfo failed\r
705 //\r
706 DEBUG ((EFI_D_ERROR, "Decompress GetInfo Failed - %r\n", Status));\r
707 return EFI_NOT_FOUND;\r
708 }\r
709 //\r
710 // Allocate scratch buffer\r
711 //\r
712 ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));\r
713 if (ScratchBuffer == NULL) {\r
714 return EFI_OUT_OF_RESOURCES;\r
715 }\r
716 //\r
717 // Allocate destination buffer\r
718 //\r
719 DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));\r
720 if (DstBuffer == NULL) {\r
721 return EFI_OUT_OF_RESOURCES;\r
722 }\r
723 //\r
724 // Call decompress function\r
725 //\r
726 Status = UefiDecompress (\r
727 (CHAR8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),\r
728 DstBuffer,\r
729 ScratchBuffer\r
730 );\r
731 if (EFI_ERROR (Status)) {\r
732 //\r
733 // Decompress failed\r
734 //\r
735 DEBUG ((EFI_D_ERROR, "Decompress Failed - %r\n", Status));\r
736 return EFI_NOT_FOUND;\r
737 }\r
738 break;\r
739\r
740 // porting note the original branch for customized compress is removed, it should be change to use GUID compress\r
741\r
742 case EFI_NOT_COMPRESSED:\r
743 //\r
744 // Allocate destination buffer\r
745 //\r
746 DstBufferSize = CompressionSection->UncompressedLength;\r
747 DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));\r
748 if (DstBuffer == NULL) {\r
749 return EFI_OUT_OF_RESOURCES;\r
750 }\r
751 //\r
752 // stream is not actually compressed, just encapsulated. So just copy it.\r
753 //\r
754 CopyMem (DstBuffer, CompressionSection + 1, DstBufferSize);\r
755 break;\r
756\r
757 default:\r
758 //\r
759 // Don't support other unknown compression type.\r
760 //\r
761 ASSERT (FALSE);\r
762 return EFI_NOT_FOUND;\r
763 }\r
764\r
765 *OutputSize = DstBufferSize;\r
766 *OutputBuffer = DstBuffer;\r
767\r
768 return EFI_SUCCESS;\r
769}\r
770\r