TianoCore EDK2 master
Loading...
Searching...
No Matches
FwVol.c
Go to the documentation of this file.
1
12#include <PrePi.h>
14
15#define GET_OCCUPIED_SIZE(ActualSize, Alignment) \
16 (ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1))
17
30EFI_FFS_FILE_STATE
32 IN UINT8 ErasePolarity,
33 IN EFI_FFS_FILE_HEADER *FfsHeader
34 )
35{
36 EFI_FFS_FILE_STATE FileState;
37 EFI_FFS_FILE_STATE HighestBit;
38
39 FileState = FfsHeader->State;
40
41 if (ErasePolarity != 0) {
42 FileState = (EFI_FFS_FILE_STATE) ~FileState;
43 }
44
45 HighestBit = 0x80;
46 while (HighestBit != 0 && (HighestBit & FileState) == 0) {
47 HighestBit >>= 1;
48 }
49
50 return HighestBit;
51}
52
63UINT8
65 IN EFI_FFS_FILE_HEADER *FileHeader
66 )
67{
68 UINT8 *Ptr;
69 UINTN Index;
70 UINT8 Sum;
71
72 Sum = 0;
73 Ptr = (UINT8 *)FileHeader;
74
75 for (Index = 0; Index < sizeof (EFI_FFS_FILE_HEADER) - 3; Index += 4) {
76 Sum = (UINT8)(Sum + Ptr[Index]);
77 Sum = (UINT8)(Sum + Ptr[Index+1]);
78 Sum = (UINT8)(Sum + Ptr[Index+2]);
79 Sum = (UINT8)(Sum + Ptr[Index+3]);
80 }
81
82 for ( ; Index < sizeof (EFI_FFS_FILE_HEADER); Index++) {
83 Sum = (UINT8)(Sum + Ptr[Index]);
84 }
85
86 //
87 // State field (since this indicates the different state of file).
88 //
89 Sum = (UINT8)(Sum - FileHeader->State);
90 //
91 // Checksum field of the file is not part of the header checksum.
92 //
93 Sum = (UINT8)(Sum - FileHeader->IntegrityCheck.Checksum.File);
94
95 return Sum;
96}
97
107STATIC
108BOOLEAN
109EFIAPI
111 IN EFI_PEI_FILE_HANDLE FileHandle,
112 OUT EFI_PEI_FV_HANDLE *VolumeHandle
113 )
114{
115 EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
117
118 Hob.Raw = GetHobList ();
119 if (Hob.Raw == NULL) {
120 return FALSE;
121 }
122
123 do {
124 Hob.Raw = GetNextHob (EFI_HOB_TYPE_FV, Hob.Raw);
125 if (Hob.Raw != NULL) {
126 FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)(Hob.FirmwareVolume->BaseAddress);
127 if (((UINT64)(UINTN)FileHandle > (UINT64)(UINTN)FwVolHeader) && \
128 ((UINT64)(UINTN)FileHandle <= ((UINT64)(UINTN)FwVolHeader + FwVolHeader->FvLength - 1)))
129 {
130 *VolumeHandle = (EFI_PEI_FV_HANDLE)FwVolHeader;
131 return TRUE;
132 }
133
134 Hob.Raw = GetNextHob (EFI_HOB_TYPE_FV, GET_NEXT_HOB (Hob));
135 }
136 } while (Hob.Raw != NULL);
137
138 return FALSE;
139}
140
153 IN CONST EFI_PEI_FV_HANDLE FvHandle,
154 IN CONST EFI_GUID *FileName OPTIONAL,
155 IN EFI_FV_FILETYPE SearchType,
156 IN OUT EFI_PEI_FILE_HANDLE *FileHandle
157 )
158{
159 EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
160 EFI_FFS_FILE_HEADER **FileHeader;
161 EFI_FFS_FILE_HEADER *FfsFileHeader;
162 EFI_FIRMWARE_VOLUME_EXT_HEADER *FwVolExHeaderInfo;
163 UINT32 FileLength;
164 UINT32 FileOccupiedSize;
165 UINT32 FileOffset;
166 UINT64 FvLength;
167 UINT8 ErasePolarity;
168 UINT8 FileState;
169
170 FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)FvHandle;
171 FileHeader = (EFI_FFS_FILE_HEADER **)FileHandle;
172
173 FvLength = FwVolHeader->FvLength;
174 if (FwVolHeader->Attributes & EFI_FVB2_ERASE_POLARITY) {
175 ErasePolarity = 1;
176 } else {
177 ErasePolarity = 0;
178 }
179
180 //
181 // If FileHeader is not specified (NULL) or FileName is not NULL,
182 // start with the first file in the firmware volume. Otherwise,
183 // start from the FileHeader.
184 //
185 if ((*FileHeader == NULL) || (FileName != NULL)) {
186 FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FwVolHeader + FwVolHeader->HeaderLength);
187 if (FwVolHeader->ExtHeaderOffset != 0) {
188 FwVolExHeaderInfo = (EFI_FIRMWARE_VOLUME_EXT_HEADER *)(((UINT8 *)FwVolHeader) + FwVolHeader->ExtHeaderOffset);
189 FfsFileHeader = (EFI_FFS_FILE_HEADER *)(((UINT8 *)FwVolExHeaderInfo) + FwVolExHeaderInfo->ExtHeaderSize);
190 }
191 } else {
192 //
193 // Length is 24 bits wide so mask upper 8 bits
194 // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned.
195 //
196 FileLength = *(UINT32 *)(*FileHeader)->Size & 0x00FFFFFF;
197 FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);
198 FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)*FileHeader + FileOccupiedSize);
199 }
200
201 // FFS files begin with a header that is aligned on an 8-byte boundary
202 FfsFileHeader = ALIGN_POINTER (FfsFileHeader, 8);
203
204 FileOffset = (UINT32)((UINT8 *)FfsFileHeader - (UINT8 *)FwVolHeader);
205 ASSERT (FileOffset <= 0xFFFFFFFF);
206
207 while (FileOffset < (FvLength - sizeof (EFI_FFS_FILE_HEADER))) {
208 //
209 // Get FileState which is the highest bit of the State
210 //
211 FileState = GetFileState (ErasePolarity, FfsFileHeader);
212
213 switch (FileState) {
214 case EFI_FILE_HEADER_INVALID:
215 FileOffset += sizeof (EFI_FFS_FILE_HEADER);
216 FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER));
217 break;
218
219 case EFI_FILE_DATA_VALID:
220 case EFI_FILE_MARKED_FOR_UPDATE:
221 if (CalculateHeaderChecksum (FfsFileHeader) != 0) {
222 ASSERT (FALSE);
223 *FileHeader = NULL;
224 return EFI_NOT_FOUND;
225 }
226
227 FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;
228 FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);
229
230 if (FileName != NULL) {
231 if (CompareGuid (&FfsFileHeader->Name, (EFI_GUID *)FileName)) {
232 *FileHeader = FfsFileHeader;
233 return EFI_SUCCESS;
234 }
235 } else if (((SearchType == FfsFileHeader->Type) || (SearchType == EFI_FV_FILETYPE_ALL)) &&
236 (FfsFileHeader->Type != EFI_FV_FILETYPE_FFS_PAD))
237 {
238 *FileHeader = FfsFileHeader;
239 return EFI_SUCCESS;
240 }
241
242 FileOffset += FileOccupiedSize;
243 FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);
244 break;
245
246 case EFI_FILE_DELETED:
247 FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;
248 FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);
249 FileOffset += FileOccupiedSize;
250 FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);
251 break;
252
253 default:
254 *FileHeader = NULL;
255 return EFI_NOT_FOUND;
256 }
257 }
258
259 *FileHeader = NULL;
260 return EFI_NOT_FOUND;
261}
262
277 IN EFI_SECTION_TYPE SectionType,
278 IN FFS_CHECK_SECTION_HOOK SectionCheckHook,
280 IN UINTN SectionSize,
281 OUT VOID **OutputBuffer
282 )
283{
284 EFI_STATUS Status;
285 UINT32 SectionLength;
286 UINT32 ParsedLength;
287 EFI_COMPRESSION_SECTION *CompressionSection;
288 EFI_COMPRESSION_SECTION2 *CompressionSection2;
289 UINT32 DstBufferSize;
290 VOID *ScratchBuffer;
291 UINT32 ScratchBufferSize;
292 VOID *DstBuffer;
293 UINT16 SectionAttribute;
294 UINT32 AuthenticationStatus;
295 CHAR8 *CompressedData;
296 UINT32 CompressedDataLength;
297 BOOLEAN Found;
298
299 Found = FALSE;
300 *OutputBuffer = NULL;
301 ParsedLength = 0;
302 Status = EFI_NOT_FOUND;
303 while (ParsedLength < SectionSize) {
304 if (IS_SECTION2 (Section)) {
305 ASSERT (SECTION2_SIZE (Section) > 0x00FFFFFF);
306 }
307
308 if (Section->Type == SectionType) {
309 if (SectionCheckHook != NULL) {
310 Found = SectionCheckHook (Section) == EFI_SUCCESS;
311 } else {
312 Found = TRUE;
313 }
314
315 if (Found) {
316 if (IS_SECTION2 (Section)) {
317 *OutputBuffer = (VOID *)((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER2));
318 } else {
319 *OutputBuffer = (VOID *)((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER));
320 }
321
322 return EFI_SUCCESS;
323 } else {
324 goto CheckNextSection;
325 }
326 } else if ((Section->Type == EFI_SECTION_COMPRESSION) || (Section->Type == EFI_SECTION_GUID_DEFINED)) {
327 if (Section->Type == EFI_SECTION_COMPRESSION) {
328 if (IS_SECTION2 (Section)) {
329 CompressionSection2 = (EFI_COMPRESSION_SECTION2 *)Section;
330 SectionLength = SECTION2_SIZE (Section);
331
332 if (CompressionSection2->CompressionType != EFI_STANDARD_COMPRESSION) {
333 return EFI_UNSUPPORTED;
334 }
335
336 CompressedData = (CHAR8 *)((EFI_COMPRESSION_SECTION2 *)Section + 1);
337 CompressedDataLength = SectionLength - sizeof (EFI_COMPRESSION_SECTION2);
338 } else {
339 CompressionSection = (EFI_COMPRESSION_SECTION *)Section;
340 SectionLength = SECTION_SIZE (Section);
341
342 if (CompressionSection->CompressionType != EFI_STANDARD_COMPRESSION) {
343 return EFI_UNSUPPORTED;
344 }
345
346 CompressedData = (CHAR8 *)((EFI_COMPRESSION_SECTION *)Section + 1);
347 CompressedDataLength = SectionLength - sizeof (EFI_COMPRESSION_SECTION);
348 }
349
350 Status = UefiDecompressGetInfo (
351 CompressedData,
352 CompressedDataLength,
353 &DstBufferSize,
354 &ScratchBufferSize
355 );
356 } else if (Section->Type == EFI_SECTION_GUID_DEFINED) {
358 Section,
359 &DstBufferSize,
360 &ScratchBufferSize,
361 &SectionAttribute
362 );
363 }
364
365 if (EFI_ERROR (Status)) {
366 //
367 // GetInfo failed
368 //
369 DEBUG ((DEBUG_ERROR, "Decompress GetInfo Failed - %r\n", Status));
370 return EFI_NOT_FOUND;
371 }
372
373 //
374 // Allocate scratch buffer
375 //
376 ScratchBuffer = (VOID *)(UINTN)AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));
377 if (ScratchBuffer == NULL) {
378 return EFI_OUT_OF_RESOURCES;
379 }
380
381 //
382 // Allocate destination buffer, extra one page for adjustment
383 //
384 DstBuffer = (VOID *)(UINTN)AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize) + 1);
385 if (DstBuffer == NULL) {
386 return EFI_OUT_OF_RESOURCES;
387 }
388
389 //
390 // DstBuffer still is one section. Adjust DstBuffer offset, skip EFI section header
391 // to make section data at page alignment.
392 //
393 if (IS_SECTION2 (Section)) {
394 DstBuffer = (UINT8 *)DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER2);
395 } else {
396 DstBuffer = (UINT8 *)DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER);
397 }
398
399 //
400 // Call decompress function
401 //
402 if (Section->Type == EFI_SECTION_COMPRESSION) {
403 if (IS_SECTION2 (Section)) {
404 CompressedData = (CHAR8 *)((EFI_COMPRESSION_SECTION2 *)Section + 1);
405 } else {
406 CompressedData = (CHAR8 *)((EFI_COMPRESSION_SECTION *)Section + 1);
407 }
408
409 Status = UefiDecompress (
410 CompressedData,
411 DstBuffer,
412 ScratchBuffer
413 );
414 } else if (Section->Type == EFI_SECTION_GUID_DEFINED) {
415 Status = ExtractGuidedSectionDecode (
416 Section,
417 &DstBuffer,
418 ScratchBuffer,
419 &AuthenticationStatus
420 );
421 }
422
423 if (EFI_ERROR (Status)) {
424 //
425 // Decompress failed
426 //
427 DEBUG ((DEBUG_ERROR, "Decompress Failed - %r\n", Status));
428 return EFI_NOT_FOUND;
429 } else {
430 return FfsProcessSection (
431 SectionType,
432 SectionCheckHook,
433 DstBuffer,
434 DstBufferSize,
435 OutputBuffer
436 );
437 }
438 }
439
440CheckNextSection:
441 if (IS_SECTION2 (Section)) {
442 SectionLength = SECTION2_SIZE (Section);
443 } else {
444 SectionLength = SECTION_SIZE (Section);
445 }
446
447 //
448 // SectionLength is adjusted it is 4 byte aligned.
449 // Go to the next section
450 //
451 SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);
452 ASSERT (SectionLength != 0);
453 ParsedLength += SectionLength;
454 Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength);
455 }
456
457 return EFI_NOT_FOUND;
458}
459
475EFIAPI
477 IN EFI_SECTION_TYPE SectionType,
478 IN FFS_CHECK_SECTION_HOOK SectionCheckHook,
479 IN EFI_PEI_FILE_HANDLE FileHandle,
480 OUT VOID **SectionData
481 )
482{
483 EFI_FFS_FILE_HEADER *FfsFileHeader;
484 UINT32 FileSize;
486
487 FfsFileHeader = (EFI_FFS_FILE_HEADER *)(FileHandle);
488
489 //
490 // Size is 24 bits wide so mask upper 8 bits.
491 // Does not include FfsFileHeader header size
492 // FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned.
493 //
494 Section = (EFI_COMMON_SECTION_HEADER *)(FfsFileHeader + 1);
495 FileSize = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;
496 FileSize -= sizeof (EFI_FFS_FILE_HEADER);
497
498 return FfsProcessSection (
499 SectionType,
500 SectionCheckHook,
501 Section,
502 FileSize,
503 SectionData
504 );
505}
506
520EFIAPI
522 IN EFI_SECTION_TYPE SectionType,
523 IN EFI_PEI_FILE_HANDLE FileHandle,
524 OUT VOID **SectionData
525 )
526{
527 return FfsFindSectionDataWithHook (SectionType, NULL, FileHandle, SectionData);
528}
529
544EFIAPI
546 IN UINT8 SearchType,
547 IN EFI_PEI_FV_HANDLE VolumeHandle,
548 IN OUT EFI_PEI_FILE_HANDLE *FileHandle
549 )
550{
551 return FindFileEx (VolumeHandle, NULL, SearchType, FileHandle);
552}
553
566EFIAPI
568 IN UINTN Instance,
569 IN OUT EFI_PEI_FV_HANDLE *VolumeHandle
570 )
571{
573
574 Hob.Raw = GetHobList ();
575 if (Hob.Raw == NULL) {
576 return EFI_NOT_FOUND;
577 }
578
579 do {
580 Hob.Raw = GetNextHob (EFI_HOB_TYPE_FV, Hob.Raw);
581 if (Hob.Raw != NULL) {
582 if (Instance-- == 0) {
583 *VolumeHandle = (EFI_PEI_FV_HANDLE)(UINTN)(Hob.FirmwareVolume->BaseAddress);
584 return EFI_SUCCESS;
585 }
586
587 Hob.Raw = GetNextHob (EFI_HOB_TYPE_FV, GET_NEXT_HOB (Hob));
588 }
589 } while (Hob.Raw != NULL);
590
591 return EFI_NOT_FOUND;
592}
593
613EFIAPI
615 IN CONST EFI_GUID *FileName,
616 IN EFI_PEI_FV_HANDLE VolumeHandle,
617 OUT EFI_PEI_FILE_HANDLE *FileHandle
618 )
619{
620 EFI_STATUS Status;
621
622 if ((VolumeHandle == NULL) || (FileName == NULL) || (FileHandle == NULL)) {
623 return EFI_INVALID_PARAMETER;
624 }
625
626 Status = FindFileEx (VolumeHandle, FileName, 0, FileHandle);
627 if (Status == EFI_NOT_FOUND) {
628 *FileHandle = NULL;
629 }
630
631 return Status;
632}
633
651EFIAPI
653 IN EFI_PEI_FILE_HANDLE FileHandle,
655 )
656{
657 UINT8 FileState;
658 UINT8 ErasePolarity;
659 EFI_FFS_FILE_HEADER *FileHeader;
660 EFI_PEI_FV_HANDLE VolumeHandle;
661
662 if ((FileHandle == NULL) || (FileInfo == NULL)) {
663 return EFI_INVALID_PARAMETER;
664 }
665
666 VolumeHandle = 0;
667 //
668 // Retrieve the FirmwareVolume which the file resides in.
669 //
670 if (!FileHandleToVolume (FileHandle, &VolumeHandle)) {
671 return EFI_INVALID_PARAMETER;
672 }
673
674 if (((EFI_FIRMWARE_VOLUME_HEADER *)VolumeHandle)->Attributes & EFI_FVB2_ERASE_POLARITY) {
675 ErasePolarity = 1;
676 } else {
677 ErasePolarity = 0;
678 }
679
680 //
681 // Get FileState which is the highest bit of the State
682 //
683 FileState = GetFileState (ErasePolarity, (EFI_FFS_FILE_HEADER *)FileHandle);
684
685 switch (FileState) {
686 case EFI_FILE_DATA_VALID:
687 case EFI_FILE_MARKED_FOR_UPDATE:
688 break;
689 default:
690 return EFI_INVALID_PARAMETER;
691 }
692
693 FileHeader = (EFI_FFS_FILE_HEADER *)FileHandle;
694 CopyMem (&FileInfo->FileName, &FileHeader->Name, sizeof (EFI_GUID));
695 FileInfo->FileType = FileHeader->Type;
696 FileInfo->FileAttributes = FileHeader->Attributes;
697 FileInfo->BufferSize = ((*(UINT32 *)FileHeader->Size) & 0x00FFFFFF) - sizeof (EFI_FFS_FILE_HEADER);
698 FileInfo->Buffer = (FileHeader + 1);
699 return EFI_SUCCESS;
700}
701
719EFIAPI
721 IN EFI_PEI_FV_HANDLE VolumeHandle,
722 OUT EFI_FV_INFO *VolumeInfo
723 )
724{
725 EFI_FIRMWARE_VOLUME_HEADER FwVolHeader;
726 EFI_FIRMWARE_VOLUME_EXT_HEADER *FwVolExHeaderInfo;
727
728 if (VolumeInfo == NULL) {
729 return EFI_INVALID_PARAMETER;
730 }
731
732 //
733 // VolumeHandle may not align at 8 byte,
734 // but FvLength is UINT64 type, which requires FvHeader align at least 8 byte.
735 // So, Copy FvHeader into the local FvHeader structure.
736 //
737 CopyMem (&FwVolHeader, VolumeHandle, sizeof (EFI_FIRMWARE_VOLUME_HEADER));
738 //
739 // Check Fv Image Signature
740 //
741 if (FwVolHeader.Signature != EFI_FVH_SIGNATURE) {
742 return EFI_INVALID_PARAMETER;
743 }
744
745 VolumeInfo->FvAttributes = FwVolHeader.Attributes;
746 VolumeInfo->FvStart = (VOID *)VolumeHandle;
747 VolumeInfo->FvSize = FwVolHeader.FvLength;
748 CopyMem (&VolumeInfo->FvFormat, &FwVolHeader.FileSystemGuid, sizeof (EFI_GUID));
749
750 if (FwVolHeader.ExtHeaderOffset != 0) {
751 FwVolExHeaderInfo = (EFI_FIRMWARE_VOLUME_EXT_HEADER *)(((UINT8 *)VolumeHandle) + FwVolHeader.ExtHeaderOffset);
752 CopyMem (&VolumeInfo->FvName, &FwVolExHeaderInfo->FvName, sizeof (EFI_GUID));
753 }
754
755 return EFI_SUCCESS;
756}
757
770EFIAPI
772 IN EFI_FV_FILETYPE FileType,
773 OUT EFI_PEI_FV_HANDLE *VolumeHandle,
774 OUT EFI_PEI_FILE_HANDLE *FileHandle
775 )
776{
777 EFI_STATUS Status;
778 UINTN Instance;
779
780 //
781 // Search every FV for the DXE Core
782 //
783 Instance = 0;
784 *FileHandle = NULL;
785
786 while (1) {
787 Status = FfsFindNextVolume (Instance++, VolumeHandle);
788 if (EFI_ERROR (Status)) {
789 break;
790 }
791
792 Status = FfsFindNextFile (FileType, *VolumeHandle, FileHandle);
793 if (!EFI_ERROR (Status)) {
794 break;
795 }
796 }
797
798 return Status;
799}
800
812EFIAPI
814 IN EFI_PEI_FILE_HANDLE FvFileHandle
815 )
816{
817 EFI_STATUS Status;
818 EFI_PEI_FV_HANDLE FvImageHandle;
819 EFI_FV_INFO FvImageInfo;
820 UINT32 FvAlignment;
821 VOID *FvBuffer;
823
824 FvBuffer = NULL;
825
826 //
827 // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already
828 // been extracted.
829 //
830 HobFv2.Raw = GetHobList ();
831 while ((HobFv2.Raw = GetNextHob (EFI_HOB_TYPE_FV2, HobFv2.Raw)) != NULL) {
832 if (CompareGuid (&(((EFI_FFS_FILE_HEADER *)FvFileHandle)->Name), &HobFv2.FirmwareVolume2->FileName)) {
833 //
834 // this FILE has been dispatched, it will not be dispatched again.
835 //
836 return EFI_SUCCESS;
837 }
838
839 HobFv2.Raw = GET_NEXT_HOB (HobFv2);
840 }
841
842 //
843 // Find FvImage in FvFile
844 //
845 Status = FfsFindSectionDataWithHook (EFI_SECTION_FIRMWARE_VOLUME_IMAGE, NULL, FvFileHandle, (VOID **)&FvImageHandle);
846 if (EFI_ERROR (Status)) {
847 return Status;
848 }
849
850 //
851 // Collect FvImage Info.
852 //
853 ZeroMem (&FvImageInfo, sizeof (FvImageInfo));
854 Status = FfsGetVolumeInfo (FvImageHandle, &FvImageInfo);
855 ASSERT_EFI_ERROR (Status);
856
857 //
858 // FvAlignment must be more than 8 bytes required by FvHeader structure.
859 //
860 FvAlignment = 1 << ((FvImageInfo.FvAttributes & EFI_FVB2_ALIGNMENT) >> 16);
861 if (FvAlignment < 8) {
862 FvAlignment = 8;
863 }
864
865 //
866 // Check FvImage
867 //
868 if ((UINTN)FvImageInfo.FvStart % FvAlignment != 0) {
869 FvBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINT32)FvImageInfo.FvSize), FvAlignment);
870 if (FvBuffer == NULL) {
871 return EFI_OUT_OF_RESOURCES;
872 }
873
874 CopyMem (FvBuffer, FvImageInfo.FvStart, (UINTN)FvImageInfo.FvSize);
875 //
876 // Update FvImageInfo after reload FvImage to new aligned memory
877 //
878 FfsGetVolumeInfo ((EFI_PEI_FV_HANDLE)FvBuffer, &FvImageInfo);
879 }
880
881 //
882 // Inform HOB consumer phase, i.e. DXE core, the existence of this FV
883 //
884 BuildFvHob ((EFI_PHYSICAL_ADDRESS)(UINTN)FvImageInfo.FvStart, FvImageInfo.FvSize);
885
886 //
887 // Makes the encapsulated volume show up in DXE phase to skip processing of
888 // encapsulated file again.
889 //
891 (EFI_PHYSICAL_ADDRESS)(UINTN)FvImageInfo.FvStart,
892 FvImageInfo.FvSize,
893 &FvImageInfo.FvName,
894 &(((EFI_FFS_FILE_HEADER *)FvFileHandle)->Name)
895 );
896
897 return EFI_SUCCESS;
898}
UINT64 UINTN
VOID EFIAPI BuildFv2Hob(IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN CONST EFI_GUID *FvName, IN CONST EFI_GUID *FileName)
Definition: HobLib.c:433
VOID EFIAPI BuildFvHob(IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length)
Definition: HobLib.c:404
VOID *EFIAPI GetNextHob(IN UINT16 Type, IN CONST VOID *HobStart)
Definition: HobLib.c:103
VOID *EFIAPI GetHobList(VOID)
Definition: HobLib.c:76
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_STATUS EFIAPI FfsFindSectionDataWithHook(IN EFI_SECTION_TYPE SectionType, IN FFS_CHECK_SECTION_HOOK SectionCheckHook, IN EFI_PEI_FILE_HANDLE FileHandle, OUT VOID **SectionData)
Definition: FwVol.c:476
EFI_STATUS EFIAPI FfsFindFileByName(IN CONST EFI_GUID *FileName, IN EFI_PEI_FV_HANDLE VolumeHandle, OUT EFI_PEI_FILE_HANDLE *FileHandle)
Definition: FwVol.c:614
EFI_STATUS EFIAPI FfsFindSectionData(IN EFI_SECTION_TYPE SectionType, IN EFI_PEI_FILE_HANDLE FileHandle, OUT VOID **SectionData)
Definition: FwVol.c:521
STATIC BOOLEAN EFIAPI FileHandleToVolume(IN EFI_PEI_FILE_HANDLE FileHandle, OUT EFI_PEI_FV_HANDLE *VolumeHandle)
Definition: FwVol.c:110
EFI_STATUS EFIAPI FfsGetFileInfo(IN EFI_PEI_FILE_HANDLE FileHandle, OUT EFI_FV_FILE_INFO *FileInfo)
Definition: FwVol.c:652
EFI_STATUS EFIAPI FfsFindNextVolume(IN UINTN Instance, IN OUT EFI_PEI_FV_HANDLE *VolumeHandle)
Definition: FwVol.c:567
STATIC EFI_FFS_FILE_STATE GetFileState(IN UINT8 ErasePolarity, IN EFI_FFS_FILE_HEADER *FfsHeader)
Definition: FwVol.c:31
EFI_STATUS EFIAPI FfsAnyFvFindFirstFile(IN EFI_FV_FILETYPE FileType, OUT EFI_PEI_FV_HANDLE *VolumeHandle, OUT EFI_PEI_FILE_HANDLE *FileHandle)
Definition: FwVol.c:771
EFI_STATUS EFIAPI FfsProcessFvFile(IN EFI_PEI_FILE_HANDLE FvFileHandle)
Definition: FwVol.c:813
EFI_STATUS EFIAPI FfsFindNextFile(IN UINT8 SearchType, IN EFI_PEI_FV_HANDLE VolumeHandle, IN OUT EFI_PEI_FILE_HANDLE *FileHandle)
Definition: FwVol.c:545
EFI_STATUS EFIAPI FfsGetVolumeInfo(IN EFI_PEI_FV_HANDLE VolumeHandle, OUT EFI_FV_INFO *VolumeInfo)
Definition: FwVol.c:720
EFI_STATUS FfsProcessSection(IN EFI_SECTION_TYPE SectionType, IN FFS_CHECK_SECTION_HOOK SectionCheckHook, IN EFI_COMMON_SECTION_HEADER *Section, IN UINTN SectionSize, OUT VOID **OutputBuffer)
Definition: FwVol.c:276
EFI_STATUS FindFileEx(IN CONST EFI_PEI_FV_HANDLE FvHandle, IN CONST EFI_GUID *FileName OPTIONAL, IN EFI_FV_FILETYPE SearchType, IN OUT EFI_PEI_FILE_HANDLE *FileHandle)
Definition: FwVol.c:152
STATIC UINT8 CalculateHeaderChecksum(IN EFI_FFS_FILE_HEADER *FileHeader)
Definition: FwVol.c:64
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define ALIGN_POINTER(Pointer, Alignment)
Definition: Base.h:963
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define EFI_FV_FILETYPE_ALL
#define EFI_SECTION_COMPRESSION
#define SECTION_SIZE(SectionHeaderPtr)
VOID * EFI_PEI_FILE_HANDLE
Definition: PiPeiCis.h:26
VOID * EFI_PEI_FV_HANDLE
Definition: PiPeiCis.h:21
RETURN_STATUS EFIAPI ExtractGuidedSectionGetInfo(IN CONST VOID *InputSection, OUT UINT32 *OutputBufferSize, OUT UINT32 *ScratchBufferSize, OUT UINT16 *SectionAttribute)
VOID *EFIAPI AllocateAlignedPages(IN UINTN Pages, IN UINTN Alignment)
VOID *EFIAPI AllocatePages(IN UINTN Pages)
EFI_STATUS(EFIAPI * FFS_CHECK_SECTION_HOOK)(IN EFI_COMMON_SECTION_HEADER *Section)
Definition: PrePiLib.h:61
EFI_FILE_INFO * FileInfo(IN EFI_FILE_HANDLE FHand)
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:200
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
RETURN_STATUS EFIAPI UefiDecompress(IN CONST VOID *Source, IN OUT VOID *Destination, IN OUT VOID *Scratch OPTIONAL)
RETURN_STATUS EFIAPI UefiDecompressGetInfo(IN CONST VOID *Source, IN UINT32 SourceSize, OUT UINT32 *DestinationSize, OUT UINT32 *ScratchSize)
EFI_FV_FILETYPE Type
EFI_FFS_FILE_ATTRIBUTES Attributes
CHAR16 FileName[1]
Definition: FileInfo.h:52
EFI_FVB_ATTRIBUTES_2 Attributes
UINT64 FvSize
Definition: PiPeiCis.h:789
EFI_GUID FvName
Definition: PiPeiCis.h:779
EFI_FVB_ATTRIBUTES_2 FvAttributes
Definition: PiPeiCis.h:771
VOID * FvStart
Definition: PiPeiCis.h:785
EFI_PHYSICAL_ADDRESS BaseAddress
Definition: PiHob.h:364
Definition: Base.h:213