TianoCore EDK2 master
Loading...
Searching...
No Matches
FwVol.c
Go to the documentation of this file.
1
10#include "FwVol.h"
11
12EFI_PEI_NOTIFY_DESCRIPTOR mNotifyOnFvInfoList[] = {
13 {
14 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
15 &gEfiPeiFirmwareVolumeInfoPpiGuid,
17 },
18 {
19 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
20 &gEfiPeiFirmwareVolumeInfo2PpiGuid,
22 }
23};
24
25PEI_FW_VOL_INSTANCE mPeiFfs2FwVol = {
26 PEI_FW_VOL_SIGNATURE,
27 FALSE,
28 {
37 EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE,
38 EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION
39 }
40};
41
42PEI_FW_VOL_INSTANCE mPeiFfs3FwVol = {
43 PEI_FW_VOL_SIGNATURE,
44 TRUE,
45 {
54 EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE,
55 EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION
56 }
57};
58
59EFI_PEI_PPI_DESCRIPTOR mPeiFfs2FvPpiList = {
60 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
61 &gEfiFirmwareFileSystem2Guid,
62 &mPeiFfs2FwVol.Fv
63};
64
65EFI_PEI_PPI_DESCRIPTOR mPeiFfs3FvPpiList = {
66 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
67 &gEfiFirmwareFileSystem3Guid,
68 &mPeiFfs3FwVol.Fv
69};
70
91UINT8 mFvAttributes[] = { 0, 4, 7, 9, 10, 12, 15, 16 };
92UINT8 mFvAttributes2[] = { 17, 18, 19, 20, 21, 22, 23, 24 };
93
104 IN EFI_FFS_FILE_ATTRIBUTES FfsAttributes
105 )
106{
107 UINT8 DataAlignment;
108 EFI_FV_FILE_ATTRIBUTES FileAttribute;
109
110 DataAlignment = (UINT8)((FfsAttributes & FFS_ATTRIB_DATA_ALIGNMENT) >> 3);
111 ASSERT (DataAlignment < 8);
112
113 if ((FfsAttributes & FFS_ATTRIB_DATA_ALIGNMENT_2) != 0) {
114 FileAttribute = (EFI_FV_FILE_ATTRIBUTES)mFvAttributes2[DataAlignment];
115 } else {
116 FileAttribute = (EFI_FV_FILE_ATTRIBUTES)mFvAttributes[DataAlignment];
117 }
118
119 if ((FfsAttributes & FFS_ATTRIB_FIXED) == FFS_ATTRIB_FIXED) {
120 FileAttribute |= EFI_FV_FILE_ATTRIB_FIXED;
121 }
122
123 return FileAttribute;
124}
125
136EFI_FFS_FILE_STATE
138 IN UINT8 ErasePolarity,
139 IN EFI_FFS_FILE_HEADER *FfsHeader
140 )
141{
142 EFI_FFS_FILE_STATE FileState;
143 EFI_FFS_FILE_STATE HighestBit;
144
145 FileState = FfsHeader->State;
146
147 if (ErasePolarity != 0) {
148 FileState = (EFI_FFS_FILE_STATE) ~FileState;
149 }
150
151 //
152 // Get file state set by its highest none zero bit.
153 //
154 HighestBit = 0x80;
155 while (HighestBit != 0 && (HighestBit & FileState) == 0) {
156 HighestBit >>= 1;
157 }
158
159 return HighestBit;
160}
161
171UINT8
173 IN EFI_FFS_FILE_HEADER *FileHeader
174 )
175{
176 EFI_FFS_FILE_HEADER2 TestFileHeader;
177
178 if (IS_FFS_FILE2 (FileHeader)) {
179 CopyMem (&TestFileHeader, FileHeader, sizeof (EFI_FFS_FILE_HEADER2));
180 //
181 // Ignore State and File field in FFS header.
182 //
183 TestFileHeader.State = 0;
184 TestFileHeader.IntegrityCheck.Checksum.File = 0;
185
186 return CalculateSum8 ((CONST UINT8 *)&TestFileHeader, sizeof (EFI_FFS_FILE_HEADER2));
187 } else {
188 CopyMem (&TestFileHeader, FileHeader, sizeof (EFI_FFS_FILE_HEADER));
189 //
190 // Ignore State and File field in FFS header.
191 //
192 TestFileHeader.State = 0;
193 TestFileHeader.IntegrityCheck.Checksum.File = 0;
194
195 return CalculateSum8 ((CONST UINT8 *)&TestFileHeader, sizeof (EFI_FFS_FILE_HEADER));
196 }
197}
198
208 IN EFI_PEI_FILE_HANDLE FileHandle
209 )
210{
211 UINTN Index;
212 PEI_CORE_INSTANCE *PrivateData;
213 EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
214 UINTN BestIndex;
215
217 BestIndex = PrivateData->FvCount;
218
219 //
220 // Find the best matched FV image that includes this FileHandle.
221 // FV may include the child FV, and they are in the same continuous space.
222 // If FileHandle is from the child FV, the updated logic can find its matched FV.
223 //
224 for (Index = 0; Index < PrivateData->FvCount; Index++) {
225 FwVolHeader = PrivateData->Fv[Index].FvHeader;
226 if (((UINT64)(UINTN)FileHandle > (UINT64)(UINTN)FwVolHeader) && \
227 ((UINT64)(UINTN)FileHandle <= ((UINT64)(UINTN)FwVolHeader + FwVolHeader->FvLength - 1)))
228 {
229 if (BestIndex == PrivateData->FvCount) {
230 BestIndex = Index;
231 } else {
232 if ((UINT64)(UINTN)PrivateData->Fv[BestIndex].FvHeader < (UINT64)(UINTN)FwVolHeader) {
233 BestIndex = Index;
234 }
235 }
236 }
237 }
238
239 if (BestIndex < PrivateData->FvCount) {
240 return &PrivateData->Fv[BestIndex];
241 }
242
243 return NULL;
244}
245
267 IN CONST EFI_PEI_FV_HANDLE FvHandle,
268 IN CONST EFI_GUID *FileName OPTIONAL,
269 IN EFI_FV_FILETYPE SearchType,
270 IN OUT EFI_PEI_FILE_HANDLE *FileHandle,
271 IN OUT EFI_PEI_FILE_HANDLE *AprioriFile OPTIONAL
272 )
273{
274 EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
275 EFI_FIRMWARE_VOLUME_EXT_HEADER *FwVolExtHeader;
276 EFI_FFS_FILE_HEADER **FileHeader;
277 EFI_FFS_FILE_HEADER *FfsFileHeader;
278 UINT32 FileLength;
279 UINT32 FileOccupiedSize;
280 UINT64 FileOffset;
281 UINT64 FvLength;
282 UINT8 ErasePolarity;
283 UINT8 FileState;
284 UINT8 DataCheckSum;
285 BOOLEAN IsFfs3Fv;
286
287 //
288 // Convert the handle of FV to FV header for memory-mapped firmware volume
289 //
290 FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)FvHandle;
291 FileHeader = (EFI_FFS_FILE_HEADER **)FileHandle;
292
293 IsFfs3Fv = CompareGuid (&FwVolHeader->FileSystemGuid, &gEfiFirmwareFileSystem3Guid);
294
295 FvLength = FwVolHeader->FvLength;
296 if ((FwVolHeader->Attributes & EFI_FVB2_ERASE_POLARITY) != 0) {
297 ErasePolarity = 1;
298 } else {
299 ErasePolarity = 0;
300 }
301
302 //
303 // If FileHeader is not specified (NULL) or FileName is not NULL,
304 // start with the first file in the firmware volume. Otherwise,
305 // start from the FileHeader.
306 //
307 if ((*FileHeader == NULL) || (FileName != NULL)) {
308 if (FwVolHeader->ExtHeaderOffset != 0) {
309 //
310 // Searching for files starts on an 8 byte aligned boundary after the end of the Extended Header if it exists.
311 //
312 FwVolExtHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER *)((UINT8 *)FwVolHeader + FwVolHeader->ExtHeaderOffset);
313 FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FwVolExtHeader + FwVolExtHeader->ExtHeaderSize);
314 } else {
315 FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FwVolHeader + FwVolHeader->HeaderLength);
316 }
317
318 FfsFileHeader = (EFI_FFS_FILE_HEADER *)ALIGN_POINTER (FfsFileHeader, 8);
319 } else {
320 if (IS_FFS_FILE2 (*FileHeader)) {
321 if (!IsFfs3Fv) {
322 DEBUG ((DEBUG_ERROR, "It is a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &(*FileHeader)->Name));
323 }
324
325 FileLength = FFS_FILE2_SIZE (*FileHeader);
326 ASSERT (FileLength > 0x00FFFFFF);
327 } else {
328 FileLength = FFS_FILE_SIZE (*FileHeader);
329 }
330
331 //
332 // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned.
333 //
334 FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);
335 FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)*FileHeader + FileOccupiedSize);
336 }
337
338 FileOffset = ((UINT8 *)FfsFileHeader - (UINT8 *)FwVolHeader);
339 ASSERT (FileOffset <= MAX_UINT32);
340
341 while (FileOffset < (FvLength - sizeof (EFI_FFS_FILE_HEADER))) {
342 //
343 // Get FileState which is the highest bit of the State
344 //
345 FileState = GetFileState (ErasePolarity, FfsFileHeader);
346 switch (FileState) {
348 case EFI_FILE_HEADER_INVALID:
349 if (IS_FFS_FILE2 (FfsFileHeader)) {
350 if (!IsFfs3Fv) {
351 DEBUG ((DEBUG_ERROR, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader->Name));
352 }
353
354 FileOffset += sizeof (EFI_FFS_FILE_HEADER2);
355 FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER2));
356 } else {
357 FileOffset += sizeof (EFI_FFS_FILE_HEADER);
358 FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER));
359 }
360
361 break;
362
363 case EFI_FILE_DATA_VALID:
364 case EFI_FILE_MARKED_FOR_UPDATE:
365 if (CalculateHeaderChecksum (FfsFileHeader) != 0) {
366 ASSERT (FALSE);
367 *FileHeader = NULL;
368 return EFI_NOT_FOUND;
369 }
370
371 if (IS_FFS_FILE2 (FfsFileHeader)) {
372 FileLength = FFS_FILE2_SIZE (FfsFileHeader);
373 ASSERT (FileLength > 0x00FFFFFF);
374 FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);
375 if (!IsFfs3Fv) {
376 DEBUG ((DEBUG_ERROR, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader->Name));
377 FileOffset += FileOccupiedSize;
378 FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);
379 break;
380 }
381 } else {
382 FileLength = FFS_FILE_SIZE (FfsFileHeader);
383 FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);
384 }
385
386 DataCheckSum = FFS_FIXED_CHECKSUM;
387 if ((FfsFileHeader->Attributes & FFS_ATTRIB_CHECKSUM) == FFS_ATTRIB_CHECKSUM) {
388 if (IS_FFS_FILE2 (FfsFileHeader)) {
389 DataCheckSum = CalculateCheckSum8 ((CONST UINT8 *)FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER2), FileLength - sizeof (EFI_FFS_FILE_HEADER2));
390 } else {
391 DataCheckSum = CalculateCheckSum8 ((CONST UINT8 *)FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER), FileLength - sizeof (EFI_FFS_FILE_HEADER));
392 }
393 }
394
395 if (FfsFileHeader->IntegrityCheck.Checksum.File != DataCheckSum) {
396 ASSERT (FALSE);
397 *FileHeader = NULL;
398 return EFI_NOT_FOUND;
399 }
400
401 if (FileName != NULL) {
402 if (CompareGuid (&FfsFileHeader->Name, (EFI_GUID *)FileName)) {
403 *FileHeader = FfsFileHeader;
404 return EFI_SUCCESS;
405 }
406 } else if (SearchType == PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE) {
407 if ((FfsFileHeader->Type == EFI_FV_FILETYPE_PEIM) ||
408 (FfsFileHeader->Type == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER) ||
409 (FfsFileHeader->Type == EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE))
410 {
411 *FileHeader = FfsFileHeader;
412 return EFI_SUCCESS;
413 } else if (AprioriFile != NULL) {
414 if (FfsFileHeader->Type == EFI_FV_FILETYPE_FREEFORM) {
415 if (CompareGuid (&FfsFileHeader->Name, &gPeiAprioriFileNameGuid)) {
416 *AprioriFile = (EFI_PEI_FILE_HANDLE)FfsFileHeader;
417 }
418 }
419 }
420 } else if (((SearchType == FfsFileHeader->Type) || (SearchType == EFI_FV_FILETYPE_ALL)) &&
421 (FfsFileHeader->Type != EFI_FV_FILETYPE_FFS_PAD))
422 {
423 *FileHeader = FfsFileHeader;
424 return EFI_SUCCESS;
425 }
426
427 FileOffset += FileOccupiedSize;
428 FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);
429 break;
430
431 case EFI_FILE_DELETED:
432 if (IS_FFS_FILE2 (FfsFileHeader)) {
433 if (!IsFfs3Fv) {
434 DEBUG ((DEBUG_ERROR, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader->Name));
435 }
436
437 FileLength = FFS_FILE2_SIZE (FfsFileHeader);
438 ASSERT (FileLength > 0x00FFFFFF);
439 } else {
440 FileLength = FFS_FILE_SIZE (FfsFileHeader);
441 }
442
443 FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);
444 FileOffset += FileOccupiedSize;
445 FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);
446 break;
447
448 default:
449 *FileHeader = NULL;
450 return EFI_NOT_FOUND;
451 }
452 }
453
454 *FileHeader = NULL;
455 return EFI_NOT_FOUND;
456}
457
466EFI_GUID *
469 )
470{
472
473 if (FvHeader->ExtHeaderOffset == 0) {
474 return NULL;
475 }
476
477 FvExtHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER *)((UINT8 *)FvHeader + FvHeader->ExtHeaderOffset);
478 return &FvExtHeader->FvName;
479}
480
487VOID
489 IN PEI_CORE_INSTANCE *PrivateData,
490 IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData
491 )
492{
493 EFI_STATUS Status;
495 EFI_PEI_FV_HANDLE FvHandle;
497
498 //
499 // Install FV_PPI for FFS2 file system.
500 //
501 PeiServicesInstallPpi (&mPeiFfs2FvPpiList);
502
503 //
504 // Install FV_PPI for FFS3 file system.
505 //
506 PeiServicesInstallPpi (&mPeiFfs3FvPpiList);
507
508 BfvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)SecCoreData->BootFirmwareVolumeBase;
509
510 //
511 // The FV_PPI in BFV's format should be installed.
512 //
513 Status = PeiServicesLocatePpi (
514 &BfvHeader->FileSystemGuid,
515 0,
516 NULL,
517 (VOID **)&FvPpi
518 );
519 ASSERT_EFI_ERROR (Status);
520
521 //
522 // Get handle of BFV
523 //
524 Status = FvPpi->ProcessVolume (
525 FvPpi,
526 SecCoreData->BootFirmwareVolumeBase,
527 (UINTN)BfvHeader->FvLength,
528 &FvHandle
529 );
530 ASSERT_EFI_ERROR (Status);
531
532 PrivateData->Fv = AllocateZeroPool (sizeof (PEI_CORE_FV_HANDLE) * FV_GROWTH_STEP);
533 ASSERT (PrivateData->Fv != NULL);
534 PrivateData->MaxFvCount = FV_GROWTH_STEP;
535
536 //
537 // Update internal PEI_CORE_FV array.
538 //
539 PrivateData->Fv[PrivateData->FvCount].FvHeader = BfvHeader;
540 PrivateData->Fv[PrivateData->FvCount].FvPpi = FvPpi;
541 PrivateData->Fv[PrivateData->FvCount].FvHandle = FvHandle;
542 PrivateData->Fv[PrivateData->FvCount].AuthenticationStatus = 0;
543 DEBUG ((
544 DEBUG_INFO,
545 "The %dth FV[%g] start address is 0x%11p, size is 0x%08x, handle is 0x%p\n",
546 (UINT32)PrivateData->FvCount,
547 GetFvName (BfvHeader),
548 (VOID *)BfvHeader,
549 (UINT32)BfvHeader->FvLength,
550 FvHandle
551 ));
552 PrivateData->FvCount++;
553
554 //
555 // Post a call-back for the FvInfoPPI and FvInfo2PPI services to expose
556 // additional FVs to PeiCore.
557 //
558 Status = PeiServicesNotifyPpi (mNotifyOnFvInfoList);
559 ASSERT_EFI_ERROR (Status);
560}
561
576EFIAPI
578 IN EFI_PEI_SERVICES **PeiServices,
579 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
580 IN VOID *Ppi
581 )
582{
585 PEI_CORE_INSTANCE *PrivateData;
586 EFI_STATUS Status;
587 EFI_PEI_FV_HANDLE FvHandle;
588 UINTN FvIndex;
589 EFI_PEI_FILE_HANDLE FileHandle;
590 VOID *DepexData;
591 BOOLEAN IsFvInfo2;
592 UINTN CurFvCount;
593 VOID *TempPtr;
594
595 Status = EFI_SUCCESS;
596 PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
597
598 if (CompareGuid (NotifyDescriptor->Guid, &gEfiPeiFirmwareVolumeInfo2PpiGuid)) {
599 //
600 // It is FvInfo2PPI.
601 //
602 CopyMem (&FvInfo2Ppi, Ppi, sizeof (EFI_PEI_FIRMWARE_VOLUME_INFO2_PPI));
603 IsFvInfo2 = TRUE;
604 } else {
605 //
606 // It is FvInfoPPI.
607 //
608 CopyMem (&FvInfo2Ppi, Ppi, sizeof (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI));
609 FvInfo2Ppi.AuthenticationStatus = 0;
610 IsFvInfo2 = FALSE;
611 }
612
613 if (CompareGuid (&FvInfo2Ppi.FvFormat, &gEfiFirmwareFileSystem2Guid)) {
614 //
615 // gEfiFirmwareFileSystem2Guid is specified for FvFormat, then here to check the
616 // FileSystemGuid pointed by FvInfo against gEfiFirmwareFileSystem2Guid to make sure
617 // FvInfo has the firmware file system 2 format.
618 //
619 // If the ASSERT really appears, FvFormat needs to be specified correctly, for example,
620 // gEfiFirmwareFileSystem3Guid can be used for firmware file system 3 format, or
621 // ((EFI_FIRMWARE_VOLUME_HEADER *) FvInfo)->FileSystemGuid can be just used for both
622 // firmware file system 2 and 3 format.
623 //
624 ASSERT (CompareGuid (&(((EFI_FIRMWARE_VOLUME_HEADER *)FvInfo2Ppi.FvInfo)->FileSystemGuid), &gEfiFirmwareFileSystem2Guid));
625 }
626
627 //
628 // Locate the corresponding FV_PPI according to the format GUID of the FV found
629 //
630 Status = PeiServicesLocatePpi (
631 &FvInfo2Ppi.FvFormat,
632 0,
633 NULL,
634 (VOID **)&FvPpi
635 );
636 if (!EFI_ERROR (Status)) {
637 //
638 // Process new found FV and get FV handle.
639 //
640 Status = FvPpi->ProcessVolume (FvPpi, FvInfo2Ppi.FvInfo, FvInfo2Ppi.FvInfoSize, &FvHandle);
641 if (EFI_ERROR (Status)) {
642 DEBUG ((DEBUG_ERROR, "Fail to process new found FV, FV may be corrupted!\n"));
643 return Status;
644 }
645
646 //
647 // Check whether the FV has already been processed.
648 //
649 for (FvIndex = 0; FvIndex < PrivateData->FvCount; FvIndex++) {
650 if (PrivateData->Fv[FvIndex].FvHandle == FvHandle) {
651 if (IsFvInfo2 && (FvInfo2Ppi.AuthenticationStatus != PrivateData->Fv[FvIndex].AuthenticationStatus)) {
652 PrivateData->Fv[FvIndex].AuthenticationStatus = FvInfo2Ppi.AuthenticationStatus;
653 DEBUG ((DEBUG_INFO, "Update AuthenticationStatus of the %dth FV to 0x%x!\n", FvIndex, FvInfo2Ppi.AuthenticationStatus));
654 }
655
656 DEBUG ((DEBUG_INFO, "The FV %p has already been processed!\n", FvInfo2Ppi.FvInfo));
657 return EFI_SUCCESS;
658 }
659 }
660
661 if (PrivateData->FvCount >= PrivateData->MaxFvCount) {
662 //
663 // Run out of room, grow the buffer.
664 //
665 TempPtr = AllocateZeroPool (
666 sizeof (PEI_CORE_FV_HANDLE) * (PrivateData->MaxFvCount + FV_GROWTH_STEP)
667 );
668 ASSERT (TempPtr != NULL);
669 CopyMem (
670 TempPtr,
671 PrivateData->Fv,
672 sizeof (PEI_CORE_FV_HANDLE) * PrivateData->MaxFvCount
673 );
674 PrivateData->Fv = TempPtr;
675 PrivateData->MaxFvCount = PrivateData->MaxFvCount + FV_GROWTH_STEP;
676 }
677
678 //
679 // Update internal PEI_CORE_FV array.
680 //
681 PrivateData->Fv[PrivateData->FvCount].FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)FvInfo2Ppi.FvInfo;
682 PrivateData->Fv[PrivateData->FvCount].FvPpi = FvPpi;
683 PrivateData->Fv[PrivateData->FvCount].FvHandle = FvHandle;
684 PrivateData->Fv[PrivateData->FvCount].AuthenticationStatus = FvInfo2Ppi.AuthenticationStatus;
685 CurFvCount = PrivateData->FvCount;
686 DEBUG ((
687 DEBUG_INFO,
688 "The %dth FV[%g] start address is 0x%11p, size is 0x%08x, handle is 0x%p\n",
689 (UINT32)CurFvCount,
691 (VOID *)FvInfo2Ppi.FvInfo,
692 FvInfo2Ppi.FvInfoSize,
693 FvHandle
694 ));
695 PrivateData->FvCount++;
696
697 //
698 // Scan and process the new discovered FV for EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
699 //
700 FileHandle = NULL;
701 do {
702 Status = FvPpi->FindFileByType (
703 FvPpi,
704 EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE,
705 FvHandle,
706 &FileHandle
707 );
708 if (!EFI_ERROR (Status)) {
709 Status = FvPpi->FindSectionByType (
710 FvPpi,
711 EFI_SECTION_PEI_DEPEX,
712 FileHandle,
713 (VOID **)&DepexData
714 );
715 if (!EFI_ERROR (Status)) {
716 if (!PeimDispatchReadiness (PeiServices, DepexData)) {
717 //
718 // Dependency is not satisfied.
719 //
720 continue;
721 }
722 }
723
724 DEBUG ((DEBUG_INFO, "Found firmware volume Image File[%g] %p in FV[%d] %p\n", FileHandle, FileHandle, CurFvCount, FvHandle));
725 ProcessFvFile (PrivateData, &PrivateData->Fv[CurFvCount], FileHandle);
726 }
727 } while (FileHandle != NULL);
728 } else {
729 DEBUG ((DEBUG_ERROR, "Fail to process FV %p because no corresponding EFI_FIRMWARE_VOLUME_PPI is found!\n", FvInfo2Ppi.FvInfo));
730
731 AddUnknownFormatFvInfo (PrivateData, &FvInfo2Ppi);
732 }
733
734 return EFI_SUCCESS;
735}
736
750BOOLEAN
752 IN EFI_GUID *GuidedSectionGuid,
753 OUT EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI **GuidedSectionExtraction
754 )
755{
757 EFI_GUID *GuidRecorded;
758 VOID *Interface;
759 EFI_STATUS Status;
760
761 //
762 // Check if there is the Guided Section GUID HOB recorded the GUID itself.
763 //
764 Hob.Raw = GetFirstGuidHob (GuidedSectionGuid);
765 if (Hob.Raw != NULL) {
766 GuidRecorded = (EFI_GUID *)GET_GUID_HOB_DATA (Hob);
767 if (CompareGuid (GuidRecorded, GuidedSectionGuid)) {
768 //
769 // Found the recorded GuidedSectionGuid.
770 //
771 Status = PeiServicesLocatePpi (GuidedSectionGuid, 0, NULL, (VOID **)&Interface);
772 if (!EFI_ERROR (Status) && (Interface != NULL)) {
773 //
774 // Found the supported Guided Section Extraction Ppi for the Guided Section.
775 //
776 *GuidedSectionExtraction = (EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *)Interface;
777 return TRUE;
778 }
779
780 return FALSE;
781 }
782 }
783
784 return FALSE;
785}
786
808 IN CONST EFI_PEI_SERVICES **PeiServices,
809 IN EFI_SECTION_TYPE SectionType,
810 IN OUT UINTN *SectionInstance,
812 IN UINTN SectionSize,
813 OUT VOID **OutputBuffer,
814 OUT UINT32 *AuthenticationStatus,
815 IN BOOLEAN IsFfs3Fv
816 )
817{
818 EFI_STATUS Status;
819 UINT32 SectionLength;
820 UINTN ParsedLength;
822 EFI_PEI_DECOMPRESS_PPI *DecompressPpi;
823 VOID *PpiOutput;
824 UINTN PpiOutputSize;
825 UINTN Index;
826 UINT32 Authentication;
827 PEI_CORE_INSTANCE *PrivateData;
828 EFI_GUID *SectionDefinitionGuid;
829 BOOLEAN SectionCached;
830 VOID *TempOutputBuffer;
831 UINT32 TempAuthenticationStatus;
832 UINT16 GuidedSectionAttributes;
833
834 PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
835 *OutputBuffer = NULL;
836 ParsedLength = 0;
837 Index = 0;
838 Status = EFI_NOT_FOUND;
839 PpiOutput = NULL;
840 PpiOutputSize = 0;
841 while (ParsedLength < SectionSize) {
842 if (IS_SECTION2 (Section)) {
843 ASSERT (SECTION2_SIZE (Section) > 0x00FFFFFF);
844 if (!IsFfs3Fv) {
845 DEBUG ((DEBUG_ERROR, "Found a FFS3 formatted section in a non-FFS3 formatted FV.\n"));
846 SectionLength = SECTION2_SIZE (Section);
847 if (SectionLength == 0) {
848 break;
849 }
850
851 //
852 // SectionLength is adjusted it is 4 byte aligned.
853 // Go to the next section
854 //
855 SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);
856 ASSERT (SectionLength != 0);
857 ParsedLength += SectionLength;
858 Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength);
859 continue;
860 }
861 }
862
863 if (Section->Type == SectionType) {
864 //
865 // The type matches, so check the instance count to see if it's the one we want.
866 //
867 (*SectionInstance)--;
868 if (*SectionInstance == 0) {
869 //
870 // Got it!
871 //
872 if (IS_SECTION2 (Section)) {
873 *OutputBuffer = (VOID *)((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER2));
874 } else {
875 *OutputBuffer = (VOID *)((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER));
876 }
877
878 return EFI_SUCCESS;
879 } else {
880 if (IS_SECTION2 (Section)) {
881 SectionLength = SECTION2_SIZE (Section);
882 } else {
883 SectionLength = SECTION_SIZE (Section);
884 }
885
886 if (SectionLength == 0) {
887 break;
888 }
889
890 //
891 // SectionLength is adjusted it is 4 byte aligned.
892 // Go to the next section
893 //
894 SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);
895 ASSERT (SectionLength != 0);
896 ParsedLength += SectionLength;
897 Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength);
898 continue;
899 }
900 } else if ((Section->Type == EFI_SECTION_GUID_DEFINED) || (Section->Type == EFI_SECTION_COMPRESSION)) {
901 //
902 // Check the encapsulated section is extracted into the cache data.
903 //
904 SectionCached = FALSE;
905 for (Index = 0; Index < PrivateData->CacheSection.AllSectionCount; Index++) {
906 if (Section == PrivateData->CacheSection.Section[Index]) {
907 SectionCached = TRUE;
908 PpiOutput = PrivateData->CacheSection.SectionData[Index];
909 PpiOutputSize = PrivateData->CacheSection.SectionSize[Index];
910 Authentication = PrivateData->CacheSection.AuthenticationStatus[Index];
911 //
912 // Search section directly from the cache data.
913 //
914 TempAuthenticationStatus = 0;
915 Status = ProcessSection (
916 PeiServices,
917 SectionType,
918 SectionInstance,
919 PpiOutput,
920 PpiOutputSize,
921 &TempOutputBuffer,
922 &TempAuthenticationStatus,
923 IsFfs3Fv
924 );
925 if (!EFI_ERROR (Status)) {
926 *OutputBuffer = TempOutputBuffer;
927 *AuthenticationStatus = TempAuthenticationStatus | Authentication;
928 return EFI_SUCCESS;
929 }
930 }
931 }
932
933 //
934 // If SectionCached is TRUE, the section data has been cached and scanned.
935 //
936 if (!SectionCached) {
937 Status = EFI_NOT_FOUND;
938 Authentication = 0;
939 if (Section->Type == EFI_SECTION_GUID_DEFINED) {
940 if (IS_SECTION2 (Section)) {
941 SectionDefinitionGuid = &((EFI_GUID_DEFINED_SECTION2 *)Section)->SectionDefinitionGuid;
942 GuidedSectionAttributes = ((EFI_GUID_DEFINED_SECTION2 *)Section)->Attributes;
943 } else {
944 SectionDefinitionGuid = &((EFI_GUID_DEFINED_SECTION *)Section)->SectionDefinitionGuid;
945 GuidedSectionAttributes = ((EFI_GUID_DEFINED_SECTION *)Section)->Attributes;
946 }
947
948 if (VerifyGuidedSectionGuid (SectionDefinitionGuid, &GuidSectionPpi)) {
949 Status = GuidSectionPpi->ExtractSection (
950 GuidSectionPpi,
951 Section,
952 &PpiOutput,
953 &PpiOutputSize,
954 &Authentication
955 );
956 } else if ((GuidedSectionAttributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == 0) {
957 //
958 // Figure out the proper authentication status for GUIDED section without processing required
959 //
960 Status = EFI_SUCCESS;
961 if ((GuidedSectionAttributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) == EFI_GUIDED_SECTION_AUTH_STATUS_VALID) {
962 Authentication |= EFI_AUTH_STATUS_IMAGE_SIGNED | EFI_AUTH_STATUS_NOT_TESTED;
963 }
964
965 if (IS_SECTION2 (Section)) {
966 PpiOutputSize = SECTION2_SIZE (Section) - ((EFI_GUID_DEFINED_SECTION2 *)Section)->DataOffset;
967 PpiOutput = (UINT8 *)Section + ((EFI_GUID_DEFINED_SECTION2 *)Section)->DataOffset;
968 } else {
969 PpiOutputSize = SECTION_SIZE (Section) - ((EFI_GUID_DEFINED_SECTION *)Section)->DataOffset;
970 PpiOutput = (UINT8 *)Section + ((EFI_GUID_DEFINED_SECTION *)Section)->DataOffset;
971 }
972 }
973 } else if (Section->Type == EFI_SECTION_COMPRESSION) {
974 Status = PeiServicesLocatePpi (&gEfiPeiDecompressPpiGuid, 0, NULL, (VOID **)&DecompressPpi);
975 if (!EFI_ERROR (Status)) {
976 Status = DecompressPpi->Decompress (
977 DecompressPpi,
979 &PpiOutput,
980 &PpiOutputSize
981 );
982 }
983 }
984
985 if (!EFI_ERROR (Status)) {
986 if ((Authentication & EFI_AUTH_STATUS_NOT_TESTED) == 0) {
987 //
988 // Update cache section data.
989 //
990 if (PrivateData->CacheSection.AllSectionCount < CACHE_SETION_MAX_NUMBER) {
991 PrivateData->CacheSection.AllSectionCount++;
992 }
993
994 PrivateData->CacheSection.Section[PrivateData->CacheSection.SectionIndex] = Section;
995 PrivateData->CacheSection.SectionData[PrivateData->CacheSection.SectionIndex] = PpiOutput;
996 PrivateData->CacheSection.SectionSize[PrivateData->CacheSection.SectionIndex] = PpiOutputSize;
997 PrivateData->CacheSection.AuthenticationStatus[PrivateData->CacheSection.SectionIndex] = Authentication;
998 PrivateData->CacheSection.SectionIndex = (PrivateData->CacheSection.SectionIndex + 1)%CACHE_SETION_MAX_NUMBER;
999 }
1000
1001 TempAuthenticationStatus = 0;
1002 Status = ProcessSection (
1003 PeiServices,
1004 SectionType,
1005 SectionInstance,
1006 PpiOutput,
1007 PpiOutputSize,
1008 &TempOutputBuffer,
1009 &TempAuthenticationStatus,
1010 IsFfs3Fv
1011 );
1012 if (!EFI_ERROR (Status)) {
1013 *OutputBuffer = TempOutputBuffer;
1014 *AuthenticationStatus = TempAuthenticationStatus | Authentication;
1015 return EFI_SUCCESS;
1016 }
1017 }
1018 }
1019 }
1020
1021 if (IS_SECTION2 (Section)) {
1022 SectionLength = SECTION2_SIZE (Section);
1023 } else {
1024 SectionLength = SECTION_SIZE (Section);
1025 }
1026
1027 if (SectionLength == 0) {
1028 break;
1029 }
1030
1031 //
1032 // SectionLength is adjusted it is 4 byte aligned.
1033 // Go to the next section
1034 //
1035 SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);
1036 ASSERT (SectionLength != 0);
1037 ParsedLength += SectionLength;
1038 Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength);
1039 }
1040
1041 return EFI_NOT_FOUND;
1042}
1043
1058EFIAPI
1060 IN CONST EFI_PEI_SERVICES **PeiServices,
1061 IN EFI_SECTION_TYPE SectionType,
1062 IN EFI_PEI_FILE_HANDLE FileHandle,
1063 OUT VOID **SectionData
1064 )
1065{
1066 PEI_CORE_FV_HANDLE *CoreFvHandle;
1067
1068 CoreFvHandle = FileHandleToVolume (FileHandle);
1069 if ((CoreFvHandle == NULL) || (CoreFvHandle->FvPpi == NULL)) {
1070 return EFI_NOT_FOUND;
1071 }
1072
1073 return CoreFvHandle->FvPpi->FindSectionByType (CoreFvHandle->FvPpi, SectionType, FileHandle, SectionData);
1074}
1075
1091EFIAPI
1093 IN CONST EFI_PEI_SERVICES **PeiServices,
1094 IN EFI_SECTION_TYPE SectionType,
1095 IN UINTN SectionInstance,
1096 IN EFI_PEI_FILE_HANDLE FileHandle,
1097 OUT VOID **SectionData,
1098 OUT UINT32 *AuthenticationStatus
1099 )
1100{
1101 PEI_CORE_FV_HANDLE *CoreFvHandle;
1102
1103 CoreFvHandle = FileHandleToVolume (FileHandle);
1104 if ((CoreFvHandle == NULL) || (CoreFvHandle->FvPpi == NULL)) {
1105 return EFI_NOT_FOUND;
1106 }
1107
1108 if ((CoreFvHandle->FvPpi->Signature == EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE) &&
1109 (CoreFvHandle->FvPpi->Revision == EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION))
1110 {
1111 return CoreFvHandle->FvPpi->FindSectionByType2 (CoreFvHandle->FvPpi, SectionType, SectionInstance, FileHandle, SectionData, AuthenticationStatus);
1112 }
1113
1114 //
1115 // The old FvPpi doesn't support to find section by section instance
1116 // and return authentication status, so return EFI_UNSUPPORTED.
1117 //
1118 return EFI_UNSUPPORTED;
1119}
1120
1138EFIAPI
1140 IN CONST EFI_PEI_SERVICES **PeiServices,
1141 IN UINT8 SearchType,
1142 IN EFI_PEI_FV_HANDLE FvHandle,
1143 IN OUT EFI_PEI_FILE_HANDLE *FileHandle
1144 )
1145{
1146 PEI_CORE_FV_HANDLE *CoreFvHandle;
1147
1148 CoreFvHandle = FvHandleToCoreHandle (FvHandle);
1149
1150 if ((CoreFvHandle == NULL) || (CoreFvHandle->FvPpi == NULL)) {
1151 return EFI_NOT_FOUND;
1152 }
1153
1154 return CoreFvHandle->FvPpi->FindFileByType (CoreFvHandle->FvPpi, SearchType, FvHandle, FileHandle);
1155}
1156
1171EFIAPI
1173 IN CONST EFI_PEI_SERVICES **PeiServices,
1174 IN UINTN Instance,
1175 IN OUT EFI_PEI_FV_HANDLE *VolumeHandle
1176 )
1177{
1178 PEI_CORE_INSTANCE *Private;
1179 PEI_CORE_FV_HANDLE *CoreFvHandle;
1180
1181 if (VolumeHandle == NULL) {
1182 return EFI_INVALID_PARAMETER;
1183 }
1184
1185 Private = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
1186
1187 CoreFvHandle = FindNextCoreFvHandle (Private, Instance);
1188 if (CoreFvHandle == NULL) {
1189 *VolumeHandle = NULL;
1190 return EFI_NOT_FOUND;
1191 }
1192
1193 *VolumeHandle = CoreFvHandle->FvHandle;
1194
1195 return EFI_SUCCESS;
1196}
1197
1212EFIAPI
1214 IN CONST EFI_GUID *FileName,
1215 IN EFI_PEI_FV_HANDLE VolumeHandle,
1216 OUT EFI_PEI_FILE_HANDLE *FileHandle
1217 )
1218{
1219 PEI_CORE_FV_HANDLE *CoreFvHandle;
1220
1221 if ((VolumeHandle == NULL) || (FileName == NULL) || (FileHandle == NULL)) {
1222 return EFI_INVALID_PARAMETER;
1223 }
1224
1225 CoreFvHandle = FvHandleToCoreHandle (VolumeHandle);
1226 if ((CoreFvHandle == NULL) || (CoreFvHandle->FvPpi == NULL)) {
1227 return EFI_NOT_FOUND;
1228 }
1229
1230 return CoreFvHandle->FvPpi->FindFileByName (CoreFvHandle->FvPpi, FileName, &VolumeHandle, FileHandle);
1231}
1232
1245EFIAPI
1247 IN EFI_PEI_FILE_HANDLE FileHandle,
1249 )
1250{
1251 PEI_CORE_FV_HANDLE *CoreFvHandle;
1252
1253 if ((FileHandle == NULL) || (FileInfo == NULL)) {
1254 return EFI_INVALID_PARAMETER;
1255 }
1256
1257 //
1258 // Retrieve the FirmwareVolume which the file resides in.
1259 //
1260 CoreFvHandle = FileHandleToVolume (FileHandle);
1261 if ((CoreFvHandle == NULL) || (CoreFvHandle->FvPpi == NULL)) {
1262 return EFI_INVALID_PARAMETER;
1263 }
1264
1265 return CoreFvHandle->FvPpi->GetFileInfo (CoreFvHandle->FvPpi, FileHandle, FileInfo);
1266}
1267
1280EFIAPI
1282 IN EFI_PEI_FILE_HANDLE FileHandle,
1284 )
1285{
1286 PEI_CORE_FV_HANDLE *CoreFvHandle;
1287
1288 if ((FileHandle == NULL) || (FileInfo == NULL)) {
1289 return EFI_INVALID_PARAMETER;
1290 }
1291
1292 //
1293 // Retrieve the FirmwareVolume which the file resides in.
1294 //
1295 CoreFvHandle = FileHandleToVolume (FileHandle);
1296 if ((CoreFvHandle == NULL) || (CoreFvHandle->FvPpi == NULL)) {
1297 return EFI_INVALID_PARAMETER;
1298 }
1299
1300 if ((CoreFvHandle->FvPpi->Signature == EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE) &&
1301 (CoreFvHandle->FvPpi->Revision == EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION))
1302 {
1303 return CoreFvHandle->FvPpi->GetFileInfo2 (CoreFvHandle->FvPpi, FileHandle, FileInfo);
1304 }
1305
1306 //
1307 // The old FvPpi doesn't support to return file info with authentication status,
1308 // so return EFI_UNSUPPORTED.
1309 //
1310 return EFI_UNSUPPORTED;
1311}
1312
1331EFIAPI
1333 IN EFI_PEI_FV_HANDLE VolumeHandle,
1334 OUT EFI_FV_INFO *VolumeInfo
1335 )
1336{
1337 PEI_CORE_FV_HANDLE *CoreHandle;
1338
1339 if ((VolumeInfo == NULL) || (VolumeHandle == NULL)) {
1340 return EFI_INVALID_PARAMETER;
1341 }
1342
1343 CoreHandle = FvHandleToCoreHandle (VolumeHandle);
1344
1345 if ((CoreHandle == NULL) || (CoreHandle->FvPpi == NULL)) {
1346 return EFI_INVALID_PARAMETER;
1347 }
1348
1349 return CoreHandle->FvPpi->GetVolumeInfo (CoreHandle->FvPpi, VolumeHandle, VolumeInfo);
1350}
1351
1366BOOLEAN
1369 OUT UINT32 *FvUsedSize,
1370 OUT UINT8 *EraseByte
1371 )
1372{
1373 UINT16 ExtHeaderOffset;
1375 EFI_FIRMWARE_VOLUME_EXT_ENTRY *ExtEntryList;
1377
1378 ExtHeaderOffset = ReadUnaligned16 (&FvHeader->ExtHeaderOffset);
1379 if (ExtHeaderOffset != 0) {
1380 ExtHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER *)((UINT8 *)FvHeader + ExtHeaderOffset);
1381 ExtEntryList = (EFI_FIRMWARE_VOLUME_EXT_ENTRY *)(ExtHeader + 1);
1382 while ((UINTN)ExtEntryList < ((UINTN)ExtHeader + ReadUnaligned32 (&ExtHeader->ExtHeaderSize))) {
1383 if (ReadUnaligned16 (&ExtEntryList->ExtEntryType) == EFI_FV_EXT_TYPE_USED_SIZE_TYPE) {
1384 //
1385 // USED_SIZE FV_EXT_TYPE entry is found.
1386 //
1387 ExtEntryUsedSize = (EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE *)ExtEntryList;
1388 *FvUsedSize = ReadUnaligned32 (&ExtEntryUsedSize->UsedSize);
1389 if ((ReadUnaligned32 (&FvHeader->Attributes) & EFI_FVB2_ERASE_POLARITY) != 0) {
1390 *EraseByte = 0xFF;
1391 } else {
1392 *EraseByte = 0;
1393 }
1394
1395 DEBUG ((
1396 DEBUG_INFO,
1397 "FV at 0x%x has 0x%x used size, and erase byte is 0x%02x\n",
1398 FvHeader,
1399 *FvUsedSize,
1400 *EraseByte
1401 ));
1402 return TRUE;
1403 }
1404
1405 ExtEntryList = (EFI_FIRMWARE_VOLUME_EXT_ENTRY *)
1406 ((UINT8 *)ExtEntryList + ReadUnaligned16 (&ExtEntryList->ExtEntrySize));
1407 }
1408 }
1409
1410 //
1411 // No USED_SIZE FV_EXT_TYPE entry found.
1412 //
1413 return FALSE;
1414}
1415
1432 IN PEI_CORE_INSTANCE *PrivateData,
1433 IN PEI_CORE_FV_HANDLE *ParentFvCoreHandle,
1434 IN EFI_PEI_FILE_HANDLE ParentFvFileHandle
1435 )
1436{
1437 EFI_STATUS Status;
1438 EFI_FV_INFO ParentFvImageInfo;
1439 UINT32 FvAlignment;
1440 VOID *NewFvBuffer;
1441 EFI_PEI_HOB_POINTERS HobPtr;
1442 EFI_PEI_FIRMWARE_VOLUME_PPI *ParentFvPpi;
1443 EFI_PEI_FV_HANDLE ParentFvHandle;
1446 UINT64 FvLength;
1447 UINT32 AuthenticationStatus;
1448 UINT32 FvUsedSize;
1449 UINT8 EraseByte;
1450 UINTN Index;
1451
1452 //
1453 // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already
1454 // been extracted.
1455 //
1456 HobPtr.Raw = GetHobList ();
1457 while ((HobPtr.Raw = GetNextHob (EFI_HOB_TYPE_FV2, HobPtr.Raw)) != NULL) {
1458 if (CompareGuid (&(((EFI_FFS_FILE_HEADER *)ParentFvFileHandle)->Name), &HobPtr.FirmwareVolume2->FileName)) {
1459 //
1460 // this FILE has been dispatched, it will not be dispatched again.
1461 //
1462 DEBUG ((DEBUG_INFO, "FV file %p has been dispatched!\r\n", ParentFvFileHandle));
1463 return EFI_SUCCESS;
1464 }
1465
1466 HobPtr.Raw = GET_NEXT_HOB (HobPtr);
1467 }
1468
1469 ParentFvHandle = ParentFvCoreHandle->FvHandle;
1470 ParentFvPpi = ParentFvCoreHandle->FvPpi;
1471
1472 Status = EFI_SUCCESS;
1473
1474 //
1475 // Find FvImage(s) in FvFile
1476 //
1477 Index = 0;
1478 do {
1479 AuthenticationStatus = 0;
1480 if ((ParentFvPpi->Signature == EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE) &&
1481 (ParentFvPpi->Revision == EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION))
1482 {
1483 Status = ParentFvPpi->FindSectionByType2 (
1484 ParentFvPpi,
1485 EFI_SECTION_FIRMWARE_VOLUME_IMAGE,
1486 Index,
1487 ParentFvFileHandle,
1488 (VOID **)&FvHeader,
1489 &AuthenticationStatus
1490 );
1491 } else {
1492 //
1493 // Old FvPpi has no parameter to input SearchInstance,
1494 // only one instance is supported.
1495 //
1496 if (Index > 0) {
1497 break;
1498 }
1499
1500 Status = ParentFvPpi->FindSectionByType (
1501 ParentFvPpi,
1502 EFI_SECTION_FIRMWARE_VOLUME_IMAGE,
1503 ParentFvFileHandle,
1504 (VOID **)&FvHeader
1505 );
1506 }
1507
1508 if (EFI_ERROR (Status)) {
1509 break;
1510 }
1511
1512 Status = VerifyPeim (PrivateData, ParentFvHandle, ParentFvFileHandle, AuthenticationStatus);
1513 if (Status == EFI_SECURITY_VIOLATION) {
1514 break;
1515 }
1516
1517 //
1518 // If EFI_FVB2_WEAK_ALIGNMENT is set in the volume header then the first byte of the volume
1519 // can be aligned on any power-of-two boundary. A weakly aligned volume can not be moved from
1520 // its initial linked location and maintain its alignment.
1521 //
1522 if ((ReadUnaligned32 (&FvHeader->Attributes) & EFI_FVB2_WEAK_ALIGNMENT) != EFI_FVB2_WEAK_ALIGNMENT) {
1523 //
1524 // FvAlignment must be greater than or equal to 8 bytes of the minimum FFS alignment value.
1525 //
1526 FvAlignment = 1 << ((ReadUnaligned32 (&FvHeader->Attributes) & EFI_FVB2_ALIGNMENT) >> 16);
1527 if (FvAlignment < 8) {
1528 FvAlignment = 8;
1529 }
1530
1531 DEBUG ((
1532 DEBUG_INFO,
1533 "%a() FV at 0x%x, FvAlignment required is 0x%x\n",
1534 __func__,
1535 FvHeader,
1536 FvAlignment
1537 ));
1538
1539 //
1540 // Check FvImage alignment.
1541 //
1542 if ((UINTN)FvHeader % FvAlignment != 0) {
1543 FvLength = ReadUnaligned64 (&FvHeader->FvLength);
1544 NewFvBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINT32)FvLength), FvAlignment);
1545 if (NewFvBuffer == NULL) {
1546 Status = EFI_OUT_OF_RESOURCES;
1547 break;
1548 }
1549
1550 if (GetFvUsedSize (FvHeader, &FvUsedSize, &EraseByte)) {
1551 //
1552 // Copy the used bytes and fill the rest with the erase value.
1553 //
1554 CopyMem (NewFvBuffer, FvHeader, (UINTN)FvUsedSize);
1555 SetMem (
1556 (UINT8 *)NewFvBuffer + FvUsedSize,
1557 (UINTN)(FvLength - FvUsedSize),
1558 EraseByte
1559 );
1560 } else {
1561 CopyMem (NewFvBuffer, FvHeader, (UINTN)FvLength);
1562 }
1563
1564 FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)NewFvBuffer;
1565 }
1566 }
1567
1568 Status = ParentFvPpi->GetVolumeInfo (ParentFvPpi, ParentFvHandle, &ParentFvImageInfo);
1569 ASSERT_EFI_ERROR (Status);
1570
1571 Status = ParentFvPpi->GetFileInfo (ParentFvPpi, ParentFvFileHandle, &FileInfo);
1572 ASSERT_EFI_ERROR (Status);
1573
1574 //
1575 // Install FvInfo(2) Ppi
1576 // NOTE: FvInfo2 must be installed before FvInfo so that recursive processing of encapsulated
1577 // FVs inherit the proper AuthenticationStatus.
1578 //
1580 &FvHeader->FileSystemGuid,
1581 (VOID **)FvHeader,
1582 (UINT32)FvHeader->FvLength,
1583 &ParentFvImageInfo.FvName,
1585 AuthenticationStatus
1586 );
1587
1589 &FvHeader->FileSystemGuid,
1590 (VOID **)FvHeader,
1591 (UINT32)FvHeader->FvLength,
1592 &ParentFvImageInfo.FvName,
1594 );
1595
1596 //
1597 // Expose the extracted FvImage to the FV HOB consumer phase, i.e. DXE phase
1598 //
1599 BuildFvHob (
1600 (EFI_PHYSICAL_ADDRESS)(UINTN)FvHeader,
1601 FvHeader->FvLength
1602 );
1603
1604 //
1605 // Makes the encapsulated volume show up in DXE phase to skip processing of
1606 // encapsulated file again.
1607 //
1608 BuildFv2Hob (
1609 (EFI_PHYSICAL_ADDRESS)(UINTN)FvHeader,
1610 FvHeader->FvLength,
1611 &ParentFvImageInfo.FvName,
1613 );
1614
1615 //
1616 // Build FV3 HOB with authentication status to be propagated to DXE.
1617 //
1618 BuildFv3Hob (
1619 (EFI_PHYSICAL_ADDRESS)(UINTN)FvHeader,
1620 FvHeader->FvLength,
1621 AuthenticationStatus,
1622 TRUE,
1623 &ParentFvImageInfo.FvName,
1625 );
1626
1627 Index++;
1628 } while (TRUE);
1629
1630 if (Index > 0) {
1631 //
1632 // At least one FvImage has been processed successfully.
1633 //
1634 return EFI_SUCCESS;
1635 } else {
1636 return Status;
1637 }
1638}
1639
1665EFIAPI
1668 IN VOID *Buffer,
1669 IN UINTN BufferSize,
1670 OUT EFI_PEI_FV_HANDLE *FvHandle
1671 )
1672{
1673 EFI_STATUS Status;
1674
1675 ASSERT (FvHandle != NULL);
1676
1677 if (Buffer == NULL) {
1678 return EFI_VOLUME_CORRUPTED;
1679 }
1680
1681 //
1682 // The build-in EFI_PEI_FIRMWARE_VOLUME_PPI for FFS2/FFS3 support memory-mapped
1683 // FV image and the handle is pointed to FV image's buffer.
1684 //
1685 *FvHandle = (EFI_PEI_FV_HANDLE)Buffer;
1686
1687 //
1688 // Do verify for given FV buffer.
1689 //
1690 Status = VerifyFv ((EFI_FIRMWARE_VOLUME_HEADER *)Buffer);
1691 if (EFI_ERROR (Status)) {
1692 DEBUG ((DEBUG_ERROR, "Fail to verify FV which address is 0x%11p", Buffer));
1693 return EFI_VOLUME_CORRUPTED;
1694 }
1695
1696 return EFI_SUCCESS;
1697}
1698
1722EFIAPI
1725 IN EFI_FV_FILETYPE SearchType,
1726 IN EFI_PEI_FV_HANDLE FvHandle,
1727 IN OUT EFI_PEI_FILE_HANDLE *FileHandle
1728 )
1729{
1730 return FindFileEx (FvHandle, NULL, SearchType, FileHandle, NULL);
1731}
1732
1759EFIAPI
1762 IN CONST EFI_GUID *FileName,
1763 IN EFI_PEI_FV_HANDLE *FvHandle,
1764 OUT EFI_PEI_FILE_HANDLE *FileHandle
1765 )
1766{
1767 EFI_STATUS Status;
1768 PEI_CORE_INSTANCE *PrivateData;
1769 UINTN Index;
1770
1771 if ((FvHandle == NULL) || (FileName == NULL) || (FileHandle == NULL)) {
1772 return EFI_INVALID_PARAMETER;
1773 }
1774
1775 if (*FvHandle != NULL) {
1776 Status = FindFileEx (*FvHandle, FileName, 0, FileHandle, NULL);
1777 if (Status == EFI_NOT_FOUND) {
1778 *FileHandle = NULL;
1779 }
1780 } else {
1781 //
1782 // If *FvHandle = NULL, so search all FV for given filename
1783 //
1784 Status = EFI_NOT_FOUND;
1785
1787 for (Index = 0; Index < PrivateData->FvCount; Index++) {
1788 //
1789 // Only search the FV which is associated with a EFI_PEI_FIRMWARE_VOLUME_PPI instance.
1790 //
1791 if (PrivateData->Fv[Index].FvPpi != NULL) {
1792 Status = FindFileEx (PrivateData->Fv[Index].FvHandle, FileName, 0, FileHandle, NULL);
1793 if (!EFI_ERROR (Status)) {
1794 *FvHandle = PrivateData->Fv[Index].FvHandle;
1795 break;
1796 }
1797 }
1798 }
1799 }
1800
1801 return Status;
1802}
1803
1824EFIAPI
1827 IN EFI_PEI_FILE_HANDLE FileHandle,
1829 )
1830{
1831 UINT8 FileState;
1832 UINT8 ErasePolarity;
1833 EFI_FFS_FILE_HEADER *FileHeader;
1834 PEI_CORE_FV_HANDLE *CoreFvHandle;
1835 PEI_FW_VOL_INSTANCE *FwVolInstance;
1836
1837 if ((FileHandle == NULL) || (FileInfo == NULL)) {
1838 return EFI_INVALID_PARAMETER;
1839 }
1840
1841 //
1842 // Retrieve the FirmwareVolume which the file resides in.
1843 //
1844 CoreFvHandle = FileHandleToVolume (FileHandle);
1845 if (CoreFvHandle == NULL) {
1846 return EFI_INVALID_PARAMETER;
1847 }
1848
1849 FwVolInstance = PEI_FW_VOL_INSTANCE_FROM_FV_THIS (This);
1850
1851 if ((CoreFvHandle->FvHeader->Attributes & EFI_FVB2_ERASE_POLARITY) != 0) {
1852 ErasePolarity = 1;
1853 } else {
1854 ErasePolarity = 0;
1855 }
1856
1857 //
1858 // Get FileState which is the highest bit of the State
1859 //
1860 FileState = GetFileState (ErasePolarity, (EFI_FFS_FILE_HEADER *)FileHandle);
1861
1862 switch (FileState) {
1863 case EFI_FILE_DATA_VALID:
1864 case EFI_FILE_MARKED_FOR_UPDATE:
1865 break;
1866 default:
1867 return EFI_INVALID_PARAMETER;
1868 }
1869
1870 FileHeader = (EFI_FFS_FILE_HEADER *)FileHandle;
1871 if (IS_FFS_FILE2 (FileHeader)) {
1872 ASSERT (FFS_FILE2_SIZE (FileHeader) > 0x00FFFFFF);
1873 if (!FwVolInstance->IsFfs3Fv) {
1874 DEBUG ((DEBUG_ERROR, "It is a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FileHeader->Name));
1875 return EFI_INVALID_PARAMETER;
1876 }
1877
1878 FileInfo->BufferSize = FFS_FILE2_SIZE (FileHeader) - sizeof (EFI_FFS_FILE_HEADER2);
1879 FileInfo->Buffer = (UINT8 *)FileHeader + sizeof (EFI_FFS_FILE_HEADER2);
1880 } else {
1881 FileInfo->BufferSize = FFS_FILE_SIZE (FileHeader) - sizeof (EFI_FFS_FILE_HEADER);
1882 FileInfo->Buffer = (UINT8 *)FileHeader + sizeof (EFI_FFS_FILE_HEADER);
1883 }
1884
1885 CopyMem (&FileInfo->FileName, &FileHeader->Name, sizeof (EFI_GUID));
1886 FileInfo->FileType = FileHeader->Type;
1887 FileInfo->FileAttributes = FfsAttributes2FvFileAttributes (FileHeader->Attributes);
1888 if ((CoreFvHandle->FvHeader->Attributes & EFI_FVB2_MEMORY_MAPPED) == EFI_FVB2_MEMORY_MAPPED) {
1889 FileInfo->FileAttributes |= EFI_FV_FILE_ATTRIB_MEMORY_MAPPED;
1890 }
1891
1892 return EFI_SUCCESS;
1893}
1894
1915EFIAPI
1918 IN EFI_PEI_FILE_HANDLE FileHandle,
1920 )
1921{
1922 EFI_STATUS Status;
1923 PEI_CORE_FV_HANDLE *CoreFvHandle;
1924
1925 if ((FileHandle == NULL) || (FileInfo == NULL)) {
1926 return EFI_INVALID_PARAMETER;
1927 }
1928
1929 //
1930 // Retrieve the FirmwareVolume which the file resides in.
1931 //
1932 CoreFvHandle = FileHandleToVolume (FileHandle);
1933 if (CoreFvHandle == NULL) {
1934 return EFI_INVALID_PARAMETER;
1935 }
1936
1937 Status = PeiFfsFvPpiGetFileInfo (This, FileHandle, (EFI_FV_FILE_INFO *)FileInfo);
1938 if (!EFI_ERROR (Status)) {
1939 FileInfo->AuthenticationStatus = CoreFvHandle->AuthenticationStatus;
1940 }
1941
1942 return Status;
1943}
1944
1960EFIAPI
1963 IN EFI_PEI_FV_HANDLE FvHandle,
1964 OUT EFI_FV_INFO *VolumeInfo
1965 )
1966{
1967 EFI_FIRMWARE_VOLUME_HEADER FwVolHeader;
1968 EFI_FIRMWARE_VOLUME_EXT_HEADER *FwVolExHeaderInfo;
1969
1970 if ((VolumeInfo == NULL) || (FvHandle == NULL)) {
1971 return EFI_INVALID_PARAMETER;
1972 }
1973
1974 //
1975 // VolumeHandle may not align at 8 byte,
1976 // but FvLength is UINT64 type, which requires FvHeader align at least 8 byte.
1977 // So, Copy FvHeader into the local FvHeader structure.
1978 //
1979 CopyMem (&FwVolHeader, FvHandle, sizeof (EFI_FIRMWARE_VOLUME_HEADER));
1980
1981 //
1982 // Check FV Image Signature
1983 //
1984 if (FwVolHeader.Signature != EFI_FVH_SIGNATURE) {
1985 return EFI_INVALID_PARAMETER;
1986 }
1987
1988 ZeroMem (VolumeInfo, sizeof (EFI_FV_INFO));
1989 VolumeInfo->FvAttributes = FwVolHeader.Attributes;
1990 VolumeInfo->FvStart = (VOID *)FvHandle;
1991 VolumeInfo->FvSize = FwVolHeader.FvLength;
1992 CopyMem (&VolumeInfo->FvFormat, &FwVolHeader.FileSystemGuid, sizeof (EFI_GUID));
1993
1994 if (FwVolHeader.ExtHeaderOffset != 0) {
1995 FwVolExHeaderInfo = (EFI_FIRMWARE_VOLUME_EXT_HEADER *)(((UINT8 *)FvHandle) + FwVolHeader.ExtHeaderOffset);
1996 CopyMem (&VolumeInfo->FvName, &FwVolExHeaderInfo->FvName, sizeof (EFI_GUID));
1997 }
1998
1999 return EFI_SUCCESS;
2000}
2001
2022EFIAPI
2025 IN EFI_SECTION_TYPE SearchType,
2026 IN EFI_PEI_FILE_HANDLE FileHandle,
2027 OUT VOID **SectionData
2028 )
2029{
2030 UINT32 AuthenticationStatus;
2031
2032 return PeiFfsFvPpiFindSectionByType2 (This, SearchType, 0, FileHandle, SectionData, &AuthenticationStatus);
2033}
2034
2059EFIAPI
2062 IN EFI_SECTION_TYPE SearchType,
2063 IN UINTN SearchInstance,
2064 IN EFI_PEI_FILE_HANDLE FileHandle,
2065 OUT VOID **SectionData,
2066 OUT UINT32 *AuthenticationStatus
2067 )
2068{
2069 EFI_STATUS Status;
2070 EFI_FFS_FILE_HEADER *FfsFileHeader;
2071 UINT32 FileSize;
2073 PEI_FW_VOL_INSTANCE *FwVolInstance;
2074 PEI_CORE_FV_HANDLE *CoreFvHandle;
2075 UINTN Instance;
2076 UINT32 ExtractedAuthenticationStatus;
2077
2078 if (SectionData == NULL) {
2079 return EFI_NOT_FOUND;
2080 }
2081
2082 FwVolInstance = PEI_FW_VOL_INSTANCE_FROM_FV_THIS (This);
2083
2084 //
2085 // Retrieve the FirmwareVolume which the file resides in.
2086 //
2087 CoreFvHandle = FileHandleToVolume (FileHandle);
2088 if (CoreFvHandle == NULL) {
2089 return EFI_NOT_FOUND;
2090 }
2091
2092 FfsFileHeader = (EFI_FFS_FILE_HEADER *)(FileHandle);
2093
2094 if (IS_FFS_FILE2 (FfsFileHeader)) {
2095 ASSERT (FFS_FILE2_SIZE (FfsFileHeader) > 0x00FFFFFF);
2096 if (!FwVolInstance->IsFfs3Fv) {
2097 DEBUG ((DEBUG_ERROR, "It is a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader->Name));
2098 return EFI_NOT_FOUND;
2099 }
2100
2101 Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER2));
2102 FileSize = FFS_FILE2_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER2);
2103 } else {
2104 Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER));
2105 FileSize = FFS_FILE_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER);
2106 }
2107
2108 Instance = SearchInstance + 1;
2109 ExtractedAuthenticationStatus = 0;
2110 Status = ProcessSection (
2112 SearchType,
2113 &Instance,
2114 Section,
2115 FileSize,
2116 SectionData,
2117 &ExtractedAuthenticationStatus,
2118 FwVolInstance->IsFfs3Fv
2119 );
2120 if (!EFI_ERROR (Status)) {
2121 //
2122 // Inherit the authentication status.
2123 //
2124 *AuthenticationStatus = ExtractedAuthenticationStatus | CoreFvHandle->AuthenticationStatus;
2125 }
2126
2127 return Status;
2128}
2129
2140 IN EFI_PEI_FV_HANDLE FvHandle
2141 )
2142{
2143 UINTN Index;
2144 PEI_CORE_INSTANCE *PrivateData;
2145
2147 for (Index = 0; Index < PrivateData->FvCount; Index++) {
2148 if (FvHandle == PrivateData->Fv[Index].FvHandle) {
2149 return &PrivateData->Fv[Index];
2150 }
2151 }
2152
2153 return NULL;
2154}
2155
2169 IN PEI_CORE_INSTANCE *Private,
2170 IN UINTN Instance
2171 )
2172{
2173 if (Instance >= Private->FvCount) {
2174 return NULL;
2175 }
2176
2177 return &Private->Fv[Instance];
2178}
2179
2188VOID
2190 IN PEI_CORE_INSTANCE *PrivateData
2191 )
2192{
2193 VOID *OldFfsFvPpi;
2194 EFI_PEI_PPI_DESCRIPTOR *OldDescriptor;
2195 UINTN Index;
2196 EFI_STATUS Status;
2197
2198 //
2199 // Locate old build-in Ffs2 EFI_PEI_FIRMWARE_VOLUME_PPI which
2200 // in flash.
2201 //
2202 Status = PeiServicesLocatePpi (
2203 &gEfiFirmwareFileSystem2Guid,
2204 0,
2205 &OldDescriptor,
2206 &OldFfsFvPpi
2207 );
2208 ASSERT_EFI_ERROR (Status);
2209
2210 //
2211 // Re-install the EFI_PEI_FIRMWARE_VOLUME_PPI for build-in Ffs2
2212 // which is shadowed from flash to permanent memory within PeiCore image.
2213 //
2214 Status = PeiServicesReInstallPpi (OldDescriptor, &mPeiFfs2FvPpiList);
2215 ASSERT_EFI_ERROR (Status);
2216
2217 //
2218 // Fixup all FvPpi pointers for the implementation in flash to permanent memory.
2219 //
2220 for (Index = 0; Index < PrivateData->FvCount; Index++) {
2221 if (PrivateData->Fv[Index].FvPpi == OldFfsFvPpi) {
2222 PrivateData->Fv[Index].FvPpi = &mPeiFfs2FwVol.Fv;
2223 }
2224 }
2225
2226 //
2227 // Locate old build-in Ffs3 EFI_PEI_FIRMWARE_VOLUME_PPI which
2228 // in flash.
2229 //
2230 Status = PeiServicesLocatePpi (
2231 &gEfiFirmwareFileSystem3Guid,
2232 0,
2233 &OldDescriptor,
2234 &OldFfsFvPpi
2235 );
2236 ASSERT_EFI_ERROR (Status);
2237
2238 //
2239 // Re-install the EFI_PEI_FIRMWARE_VOLUME_PPI for build-in Ffs3
2240 // which is shadowed from flash to permanent memory within PeiCore image.
2241 //
2242 Status = PeiServicesReInstallPpi (OldDescriptor, &mPeiFfs3FvPpiList);
2243 ASSERT_EFI_ERROR (Status);
2244
2245 //
2246 // Fixup all FvPpi pointers for the implementation in flash to permanent memory.
2247 //
2248 for (Index = 0; Index < PrivateData->FvCount; Index++) {
2249 if (PrivateData->Fv[Index].FvPpi == OldFfsFvPpi) {
2250 PrivateData->Fv[Index].FvPpi = &mPeiFfs3FwVol.Fv;
2251 }
2252 }
2253}
2254
2274 IN PEI_CORE_INSTANCE *PrivateData,
2276 )
2277{
2278 PEI_CORE_UNKNOW_FORMAT_FV_INFO *NewUnknownFv;
2279 VOID *TempPtr;
2280
2281 if (PrivateData->UnknownFvInfoCount >= PrivateData->MaxUnknownFvInfoCount) {
2282 //
2283 // Run out of room, grow the buffer.
2284 //
2285 TempPtr = AllocateZeroPool (
2286 sizeof (PEI_CORE_UNKNOW_FORMAT_FV_INFO) * (PrivateData->MaxUnknownFvInfoCount + FV_GROWTH_STEP)
2287 );
2288 ASSERT (TempPtr != NULL);
2289 CopyMem (
2290 TempPtr,
2291 PrivateData->UnknownFvInfo,
2292 sizeof (PEI_CORE_UNKNOW_FORMAT_FV_INFO) * PrivateData->MaxUnknownFvInfoCount
2293 );
2294 PrivateData->UnknownFvInfo = TempPtr;
2295 PrivateData->MaxUnknownFvInfoCount = PrivateData->MaxUnknownFvInfoCount + FV_GROWTH_STEP;
2296 }
2297
2298 NewUnknownFv = &PrivateData->UnknownFvInfo[PrivateData->UnknownFvInfoCount];
2299 PrivateData->UnknownFvInfoCount++;
2300
2301 CopyGuid (&NewUnknownFv->FvFormat, &FvInfo2Ppi->FvFormat);
2302 NewUnknownFv->FvInfo = FvInfo2Ppi->FvInfo;
2303 NewUnknownFv->FvInfoSize = FvInfo2Ppi->FvInfoSize;
2304 NewUnknownFv->AuthenticationStatus = FvInfo2Ppi->AuthenticationStatus;
2305 NewUnknownFv->NotifyDescriptor.Flags = (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);
2306 NewUnknownFv->NotifyDescriptor.Guid = &NewUnknownFv->FvFormat;
2307 NewUnknownFv->NotifyDescriptor.Notify = ThirdPartyFvPpiNotifyCallback;
2308
2309 PeiServicesNotifyPpi (&NewUnknownFv->NotifyDescriptor);
2310 return EFI_SUCCESS;
2311}
2312
2330 IN PEI_CORE_INSTANCE *PrivateData,
2331 IN EFI_GUID *Format,
2332 OUT VOID **FvInfo,
2333 OUT UINT32 *FvInfoSize,
2334 OUT UINT32 *AuthenticationStatus
2335 )
2336{
2337 UINTN Index;
2338 UINTN Index2;
2339
2340 Index = 0;
2341 for ( ; Index < PrivateData->UnknownFvInfoCount; Index++) {
2342 if (CompareGuid (Format, &PrivateData->UnknownFvInfo[Index].FvFormat)) {
2343 break;
2344 }
2345 }
2346
2347 if (Index == PrivateData->UnknownFvInfoCount) {
2348 return EFI_NOT_FOUND;
2349 }
2350
2351 *FvInfo = PrivateData->UnknownFvInfo[Index].FvInfo;
2352 *FvInfoSize = PrivateData->UnknownFvInfo[Index].FvInfoSize;
2353 *AuthenticationStatus = PrivateData->UnknownFvInfo[Index].AuthenticationStatus;
2354
2355 //
2356 // Remove an entry from UnknownFvInfo array.
2357 //
2358 Index2 = Index + 1;
2359 for ( ; Index2 < PrivateData->UnknownFvInfoCount; Index2++, Index++) {
2360 CopyMem (&PrivateData->UnknownFvInfo[Index], &PrivateData->UnknownFvInfo[Index2], sizeof (PEI_CORE_UNKNOW_FORMAT_FV_INFO));
2361 }
2362
2363 PrivateData->UnknownFvInfoCount--;
2364 return EFI_SUCCESS;
2365}
2366
2380EFIAPI
2382 IN EFI_PEI_SERVICES **PeiServices,
2383 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
2384 IN VOID *Ppi
2385 )
2386{
2387 PEI_CORE_INSTANCE *PrivateData;
2389 VOID *FvInfo;
2390 UINT32 FvInfoSize;
2391 UINT32 AuthenticationStatus;
2392 EFI_STATUS Status;
2393 EFI_PEI_FV_HANDLE FvHandle;
2394 BOOLEAN IsProcessed;
2395 UINTN FvIndex;
2396 EFI_PEI_FILE_HANDLE FileHandle;
2397 VOID *DepexData;
2398 UINTN CurFvCount;
2399 VOID *TempPtr;
2400
2401 PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
2402 FvPpi = (EFI_PEI_FIRMWARE_VOLUME_PPI *)Ppi;
2403
2404 do {
2405 Status = FindUnknownFormatFvInfo (PrivateData, NotifyDescriptor->Guid, &FvInfo, &FvInfoSize, &AuthenticationStatus);
2406 if (EFI_ERROR (Status)) {
2407 return EFI_SUCCESS;
2408 }
2409
2410 //
2411 // Process new found FV and get FV handle.
2412 //
2413 Status = FvPpi->ProcessVolume (FvPpi, FvInfo, FvInfoSize, &FvHandle);
2414 if (EFI_ERROR (Status)) {
2415 DEBUG ((DEBUG_ERROR, "Fail to process the FV 0x%p, FV may be corrupted!\n", FvInfo));
2416 continue;
2417 }
2418
2419 //
2420 // Check whether the FV has already been processed.
2421 //
2422 IsProcessed = FALSE;
2423 for (FvIndex = 0; FvIndex < PrivateData->FvCount; FvIndex++) {
2424 if (PrivateData->Fv[FvIndex].FvHandle == FvHandle) {
2425 DEBUG ((DEBUG_INFO, "The FV %p has already been processed!\n", FvInfo));
2426 IsProcessed = TRUE;
2427 break;
2428 }
2429 }
2430
2431 if (IsProcessed) {
2432 continue;
2433 }
2434
2435 if (PrivateData->FvCount >= PrivateData->MaxFvCount) {
2436 //
2437 // Run out of room, grow the buffer.
2438 //
2439 TempPtr = AllocateZeroPool (
2440 sizeof (PEI_CORE_FV_HANDLE) * (PrivateData->MaxFvCount + FV_GROWTH_STEP)
2441 );
2442 ASSERT (TempPtr != NULL);
2443 CopyMem (
2444 TempPtr,
2445 PrivateData->Fv,
2446 sizeof (PEI_CORE_FV_HANDLE) * PrivateData->MaxFvCount
2447 );
2448 PrivateData->Fv = TempPtr;
2449 PrivateData->MaxFvCount = PrivateData->MaxFvCount + FV_GROWTH_STEP;
2450 }
2451
2452 //
2453 // Update internal PEI_CORE_FV array.
2454 //
2455 PrivateData->Fv[PrivateData->FvCount].FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)FvInfo;
2456 PrivateData->Fv[PrivateData->FvCount].FvPpi = FvPpi;
2457 PrivateData->Fv[PrivateData->FvCount].FvHandle = FvHandle;
2458 PrivateData->Fv[PrivateData->FvCount].AuthenticationStatus = AuthenticationStatus;
2459 CurFvCount = PrivateData->FvCount;
2460 DEBUG ((
2461 DEBUG_INFO,
2462 "The %dth FV[%g] start address is 0x%11p, size is 0x%08x, handle is 0x%p\n",
2463 (UINT32)CurFvCount,
2465 (VOID *)FvInfo,
2466 FvInfoSize,
2467 FvHandle
2468 ));
2469 PrivateData->FvCount++;
2470
2471 //
2472 // Scan and process the new discovered FV for EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
2473 //
2474 FileHandle = NULL;
2475 do {
2476 Status = FvPpi->FindFileByType (
2477 FvPpi,
2478 EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE,
2479 FvHandle,
2480 &FileHandle
2481 );
2482 if (!EFI_ERROR (Status)) {
2483 Status = FvPpi->FindSectionByType (
2484 FvPpi,
2485 EFI_SECTION_PEI_DEPEX,
2486 FileHandle,
2487 (VOID **)&DepexData
2488 );
2489 if (!EFI_ERROR (Status)) {
2490 if (!PeimDispatchReadiness (PeiServices, DepexData)) {
2491 //
2492 // Dependency is not satisfied.
2493 //
2494 continue;
2495 }
2496 }
2497
2498 DEBUG ((DEBUG_INFO, "Found firmware volume Image File[%g] %p in FV[%d] %p\n", FileHandle, FileHandle, CurFvCount, FvHandle));
2499 ProcessFvFile (PrivateData, &PrivateData->Fv[CurFvCount], FileHandle);
2500 }
2501 } while (FileHandle != NULL);
2502 } while (TRUE);
2503}
UINT64 UINTN
CONST EFI_PEI_SERVICES **EFIAPI GetPeiServicesTablePointer(VOID)
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 GetFirstGuidHob(IN CONST EFI_GUID *Guid)
Definition: HobLib.c:215
VOID EFIAPI BuildFvHob(IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length)
Definition: HobLib.c:404
VOID EFIAPI BuildFv3Hob(IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN UINT32 AuthenticationStatus, IN BOOLEAN ExtractedFv, IN CONST EFI_GUID *FvName OPTIONAL, IN CONST EFI_GUID *FileName OPTIONAL)
Definition: HobLib.c:466
VOID *EFIAPI GetNextHob(IN UINT16 Type, IN CONST VOID *HobStart)
Definition: HobLib.c:103
VOID *EFIAPI GetHobList(VOID)
Definition: HobLib.c:76
UINT64 EFIAPI ReadUnaligned64(IN CONST VOID *Buffer)
Definition: Unaligned.c:191
UINT8 EFIAPI CalculateSum8(IN CONST UINT8 *Buffer, IN UINTN Length)
Definition: CheckSum.c:33
UINT8 EFIAPI CalculateCheckSum8(IN CONST UINT8 *Buffer, IN UINTN Length)
Definition: CheckSum.c:71
UINT32 EFIAPI ReadUnaligned32(IN CONST VOID *Buffer)
Definition: Unaligned.c:140
UINT16 EFIAPI ReadUnaligned16(IN CONST VOID *Buffer)
Definition: Unaligned.c:36
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI SetMem(OUT VOID *Buffer, IN UINTN Length, IN UINT8 Value)
Definition: SetMemWrapper.c:38
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
GUID *EFIAPI CopyGuid(OUT GUID *DestinationGuid, IN CONST GUID *SourceGuid)
Definition: MemLibGuid.c:39
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
STATIC BOOLEAN EFIAPI FileHandleToVolume(IN EFI_PEI_FILE_HANDLE FileHandle, OUT EFI_PEI_FV_HANDLE *VolumeHandle)
Definition: FwVol.c:110
STATIC EFI_FFS_FILE_STATE GetFileState(IN UINT8 ErasePolarity, IN EFI_FFS_FILE_HEADER *FfsHeader)
Definition: FwVol.c:31
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
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI PeiServicesInstallFvInfoPpi(IN CONST EFI_GUID *FvFormat OPTIONAL, IN CONST VOID *FvInfo, IN UINT32 FvInfoSize, IN CONST EFI_GUID *ParentFvName OPTIONAL, IN CONST EFI_GUID *ParentFileName OPTIONAL)
EFI_STATUS EFIAPI PeiServicesLocatePpi(IN CONST EFI_GUID *Guid, IN UINTN Instance, IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor, IN OUT VOID **Ppi)
EFI_STATUS EFIAPI PeiServicesNotifyPpi(IN CONST EFI_PEI_NOTIFY_DESCRIPTOR *NotifyList)
EFI_STATUS EFIAPI PeiServicesInstallPpi(IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList)
EFI_STATUS EFIAPI PeiServicesReInstallPpi(IN CONST EFI_PEI_PPI_DESCRIPTOR *OldPpi, IN CONST EFI_PEI_PPI_DESCRIPTOR *NewPpi)
BOOLEAN PeimDispatchReadiness(IN EFI_PEI_SERVICES **PeiServices, IN VOID *DependencyExpression)
Definition: Dependency.c:92
EFI_STATUS EFIAPI PeiFfsGetVolumeInfo(IN EFI_PEI_FV_HANDLE VolumeHandle, OUT EFI_FV_INFO *VolumeInfo)
Definition: FwVol.c:1332
EFI_STATUS EFIAPI PeiFfsFindFileByName(IN CONST EFI_GUID *FileName, IN EFI_PEI_FV_HANDLE VolumeHandle, OUT EFI_PEI_FILE_HANDLE *FileHandle)
Definition: FwVol.c:1213
EFI_STATUS EFIAPI PeiFfsFvPpiGetFileInfo2(IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This, IN EFI_PEI_FILE_HANDLE FileHandle, OUT EFI_FV_FILE_INFO2 *FileInfo)
Definition: FwVol.c:1916
PEI_CORE_FV_HANDLE * FvHandleToCoreHandle(IN EFI_PEI_FV_HANDLE FvHandle)
Definition: FwVol.c:2139
EFI_STATUS EFIAPI PeiFfsFvPpiFindSectionByType2(IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This, IN EFI_SECTION_TYPE SearchType, IN UINTN SearchInstance, IN EFI_PEI_FILE_HANDLE FileHandle, OUT VOID **SectionData, OUT UINT32 *AuthenticationStatus)
Definition: FwVol.c:2060
EFI_STATUS AddUnknownFormatFvInfo(IN PEI_CORE_INSTANCE *PrivateData, IN EFI_PEI_FIRMWARE_VOLUME_INFO2_PPI *FvInfo2Ppi)
Definition: FwVol.c:2273
PEI_CORE_FV_HANDLE * FindNextCoreFvHandle(IN PEI_CORE_INSTANCE *Private, IN UINTN Instance)
Definition: FwVol.c:2168
VOID PeiReinitializeFv(IN PEI_CORE_INSTANCE *PrivateData)
Definition: FwVol.c:2189
EFI_STATUS EFIAPI PeiFfsFindSectionData3(IN CONST EFI_PEI_SERVICES **PeiServices, IN EFI_SECTION_TYPE SectionType, IN UINTN SectionInstance, IN EFI_PEI_FILE_HANDLE FileHandle, OUT VOID **SectionData, OUT UINT32 *AuthenticationStatus)
Definition: FwVol.c:1092
EFI_STATUS EFIAPI PeiFfsFvPpiFindFileByType(IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This, IN EFI_FV_FILETYPE SearchType, IN EFI_PEI_FV_HANDLE FvHandle, IN OUT EFI_PEI_FILE_HANDLE *FileHandle)
Definition: FwVol.c:1723
UINT8 mFvAttributes[]
Definition: FwVol.c:91
EFI_STATUS EFIAPI PeiFfsGetFileInfo(IN EFI_PEI_FILE_HANDLE FileHandle, OUT EFI_FV_FILE_INFO *FileInfo)
Definition: FwVol.c:1246
BOOLEAN GetFvUsedSize(IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader, OUT UINT32 *FvUsedSize, OUT UINT8 *EraseByte)
Definition: FwVol.c:1367
EFI_STATUS EFIAPI PeiFfsGetFileInfo2(IN EFI_PEI_FILE_HANDLE FileHandle, OUT EFI_FV_FILE_INFO2 *FileInfo)
Definition: FwVol.c:1281
EFI_STATUS FindUnknownFormatFvInfo(IN PEI_CORE_INSTANCE *PrivateData, IN EFI_GUID *Format, OUT VOID **FvInfo, OUT UINT32 *FvInfoSize, OUT UINT32 *AuthenticationStatus)
Definition: FwVol.c:2329
EFI_STATUS EFIAPI PeiFfsFvPpiProcessVolume(IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This, IN VOID *Buffer, IN UINTN BufferSize, OUT EFI_PEI_FV_HANDLE *FvHandle)
Definition: FwVol.c:1666
EFI_STATUS EFIAPI FirmwareVolumeInfoPpiNotifyCallback(IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, IN VOID *Ppi)
Definition: FwVol.c:577
VOID PeiInitializeFv(IN PEI_CORE_INSTANCE *PrivateData, IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData)
Definition: FwVol.c:488
EFI_STATUS EFIAPI PeiFfsFvPpiGetFileInfo(IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This, IN EFI_PEI_FILE_HANDLE FileHandle, OUT EFI_FV_FILE_INFO *FileInfo)
Definition: FwVol.c:1825
EFI_STATUS EFIAPI PeiFfsFindNextVolume(IN CONST EFI_PEI_SERVICES **PeiServices, IN UINTN Instance, IN OUT EFI_PEI_FV_HANDLE *VolumeHandle)
Definition: FwVol.c:1172
EFI_STATUS EFIAPI PeiFfsFindSectionData(IN CONST EFI_PEI_SERVICES **PeiServices, IN EFI_SECTION_TYPE SectionType, IN EFI_PEI_FILE_HANDLE FileHandle, OUT VOID **SectionData)
Definition: FwVol.c:1059
EFI_FV_FILE_ATTRIBUTES FfsAttributes2FvFileAttributes(IN EFI_FFS_FILE_ATTRIBUTES FfsAttributes)
Definition: FwVol.c:103
EFI_STATUS EFIAPI PeiFfsFindNextFile(IN CONST EFI_PEI_SERVICES **PeiServices, IN UINT8 SearchType, IN EFI_PEI_FV_HANDLE FvHandle, IN OUT EFI_PEI_FILE_HANDLE *FileHandle)
Definition: FwVol.c:1139
EFI_STATUS EFIAPI PeiFfsFvPpiFindSectionByType(IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This, IN EFI_SECTION_TYPE SearchType, IN EFI_PEI_FILE_HANDLE FileHandle, OUT VOID **SectionData)
Definition: FwVol.c:2023
EFI_STATUS ProcessSection(IN CONST EFI_PEI_SERVICES **PeiServices, IN EFI_SECTION_TYPE SectionType, IN OUT UINTN *SectionInstance, IN EFI_COMMON_SECTION_HEADER *Section, IN UINTN SectionSize, OUT VOID **OutputBuffer, OUT UINT32 *AuthenticationStatus, IN BOOLEAN IsFfs3Fv)
Definition: FwVol.c:807
EFI_STATUS EFIAPI PeiFfsFvPpiGetVolumeInfo(IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This, IN EFI_PEI_FV_HANDLE FvHandle, OUT EFI_FV_INFO *VolumeInfo)
Definition: FwVol.c:1961
EFI_STATUS EFIAPI PeiFfsFvPpiFindFileByName(IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This, IN CONST EFI_GUID *FileName, IN EFI_PEI_FV_HANDLE *FvHandle, OUT EFI_PEI_FILE_HANDLE *FileHandle)
Definition: FwVol.c:1760
EFI_GUID * GetFvName(IN CONST EFI_FIRMWARE_VOLUME_HEADER *FvHeader)
Definition: FwVol.c:467
BOOLEAN VerifyGuidedSectionGuid(IN EFI_GUID *GuidedSectionGuid, OUT EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI **GuidedSectionExtraction)
Definition: FwVol.c:751
EFI_STATUS ProcessFvFile(IN PEI_CORE_INSTANCE *PrivateData, IN PEI_CORE_FV_HANDLE *ParentFvCoreHandle, IN EFI_PEI_FILE_HANDLE ParentFvFileHandle)
Definition: FwVol.c:1431
EFI_STATUS EFIAPI ThirdPartyFvPpiNotifyCallback(IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, IN VOID *Ppi)
Definition: FwVol.c:2381
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define ALIGN_POINTER(Pointer, Alignment)
Definition: Base.h:963
#define VOID
Definition: Base.h:269
#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:463
#define DEBUG(Expression)
Definition: DebugLib.h:435
EFI_STATUS VerifyFv(IN EFI_FIRMWARE_VOLUME_HEADER *CurrentFvAddress)
Definition: Security.c:137
EFI_STATUS VerifyPeim(IN PEI_CORE_INSTANCE *PrivateData, IN EFI_PEI_FV_HANDLE VolumeHandle, IN EFI_PEI_FILE_HANDLE FileHandle, IN UINT32 AuthenticationStatus)
Definition: Security.c:88
#define PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE
Definition: PeiMain.h:59
#define PEI_CORE_INSTANCE_FROM_PS_THIS(a)
Definition: PeiMain.h:343
VOID EFIAPI PeiServicesInstallFvInfo2Ppi(IN CONST EFI_GUID *FvFormat OPTIONAL, IN CONST VOID *FvInfo, IN UINT32 FvInfoSize, IN CONST EFI_GUID *ParentFvName OPTIONAL, IN CONST EFI_GUID *ParentFileName OPTIONAL, IN UINT32 AuthenticationStatus)
#define EFI_FILE_HEADER_CONSTRUCTION
#define EFI_FV_FILETYPE_ALL
#define EFI_GUIDED_SECTION_PROCESSING_REQUIRED
#define EFI_SECTION_COMPRESSION
#define FFS_FIXED_CHECKSUM
#define FFS_FILE_SIZE(FfsFileHeaderPtr)
#define SECTION_SIZE(SectionHeaderPtr)
UINT32 EFI_FV_FILE_ATTRIBUTES
VOID * EFI_PEI_FILE_HANDLE
Definition: PiPeiCis.h:26
VOID * EFI_PEI_FV_HANDLE
Definition: PiPeiCis.h:21
VOID *EFIAPI AllocateAlignedPages(IN UINTN Pages, IN UINTN Alignment)
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
EFI_PEIM_NOTIFY_ENTRY_POINT Notify
Definition: PiPeiCis.h:122
PEI_CORE_FV_HANDLE * Fv
Definition: PeiMain.h:259
EFI_FFS_INTEGRITY_CHECK IntegrityCheck
EFI_FFS_FILE_STATE State
EFI_FFS_INTEGRITY_CHECK IntegrityCheck
EFI_FV_FILETYPE Type
EFI_FFS_FILE_ATTRIBUTES Attributes
CHAR16 FileName[1]
Definition: FileInfo.h:52
EFI_FVB_ATTRIBUTES_2 Attributes
EFI_GUID FvName
Definition: PiPeiCis.h:779
Definition: Base.h:213