4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Pei Core Firmware File System service routines.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncCopyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncThis program and the accompanying materials
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncare licensed and made available under the terms and conditions of the BSD License
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncwhich accompanies this distribution. The full text of the license may be found at
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRequired Alignment Alignment Value in FFS Alignment Value in
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync(bytes) Attributes Field Firmware Volume Interfaces
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncUINT8 mFvAttributes[] = {0, 4, 7, 9, 10, 12, 15, 16};
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Convert the FFS File Attributes to FV File Attributes
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param FfsAttributes The attributes of UINT8 type.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return The attributes of EFI_FV_FILE_ATTRIBUTES
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DataAlignment = (UINT8) ((FfsAttributes & FFS_ATTRIB_DATA_ALIGNMENT) >> 3);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FileAttribute = (EFI_FV_FILE_ATTRIBUTES) mFvAttributes[DataAlignment];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((FfsAttributes & FFS_ATTRIB_FIXED) == FFS_ATTRIB_FIXED) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Returns the file state set by the highest zero bit in the State field
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param ErasePolarity Erase Polarity as defined by EFI_FVB2_ERASE_POLARITY
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync in the Attributes field.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param FfsHeader Pointer to FFS File Header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_FFS_FILE_STATE File state is set by the highest none zero bit
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync in the header State field.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get file state set by its highest none zero bit.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (HighestBit != 0 && (HighestBit & FileState) == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Calculates the checksum of the header of a file.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param FileHeader Pointer to FFS File Header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return Checksum of the header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Zero means the header is good.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Non-zero means the header is bad.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (&TestFileHeader, FileHeader, sizeof (EFI_FFS_FILE_HEADER2));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Ingore State and File field in FFS header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return CalculateSum8 ((CONST UINT8 *) &TestFileHeader, sizeof (EFI_FFS_FILE_HEADER2));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (&TestFileHeader, FileHeader, sizeof (EFI_FFS_FILE_HEADER));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Ingore State and File field in FFS header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return CalculateSum8 ((CONST UINT8 *) &TestFileHeader, sizeof (EFI_FFS_FILE_HEADER));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Find FV handler according to FileHandle in that FV.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param FileHandle Handle of file image
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return Pointer to instance of PEI_CORE_FV_HANDLE.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < PrivateData->FvCount; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (((UINT64) (UINTN) FileHandle > (UINT64) (UINTN) FwVolHeader ) && \
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ((UINT64) (UINTN) FileHandle <= ((UINT64) (UINTN) FwVolHeader + FwVolHeader->FvLength - 1))) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Given the input file pointer, search for the first matching file in the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FFS volume as defined by SearchType. The search starts from FileHeader inside
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the Firmware Volume defined by FwVolHeader.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync If SearchType is EFI_FV_FILETYPE_ALL, the first FFS file will return without check its file type.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync If SearchType is PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the first PEIM, or COMBINED PEIM or FV file type FFS file will return.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param FvHandle Pointer to the FV header of the volume to search
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param FileName File name
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param SearchType Filter to find only files of this type.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param FileHandle This parameter must point to a valid FFS volume.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param AprioriFile Pointer to AprioriFile image in this FV if has
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return EFI_NOT_FOUND No files matching the search criteria were found
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Success to search given file
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Convert the handle of FV to FV header for memory-mapped firmware volume
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) FvHandle;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IsFfs3Fv = CompareGuid (&FwVolHeader->FileSystemGuid, &gEfiFirmwareFileSystem3Guid);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((FwVolHeader->Attributes & EFI_FVB2_ERASE_POLARITY) != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If FileHeader is not specified (NULL) or FileName is not NULL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // start with the first file in the firmware volume. Otherwise,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // start from the FileHeader.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Searching for files starts on an 8 byte aligned boundary after the end of the Extended Header if it exists.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FwVolExtHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER *) ((UINT8 *) FwVolHeader + FwVolHeader->ExtHeaderOffset);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FwVolExtHeader + FwVolExtHeader->ExtHeaderSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FfsFileHeader = (EFI_FFS_FILE_HEADER *) ALIGN_POINTER (FfsFileHeader, 8);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *) FwVolHeader + FwVolHeader->HeaderLength);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, "It is a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &(*FileHeader)->Name));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)*FileHeader + FileOccupiedSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FileOffset = (UINT32) ((UINT8 *)FfsFileHeader - (UINT8 *)FwVolHeader);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (FileOffset < (FvLength - sizeof (EFI_FFS_FILE_HEADER))) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get FileState which is the highest bit of the State
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FileState = GetFileState (ErasePolarity, FfsFileHeader);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader->Name));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER2));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (CalculateHeaderChecksum (FfsFileHeader) != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader->Name));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsFileHeader + FileOccupiedSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((FfsFileHeader->Attributes & FFS_ATTRIB_CHECKSUM) == FFS_ATTRIB_CHECKSUM) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DataCheckSum = CalculateCheckSum8 ((CONST UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER2), FileLength - sizeof(EFI_FFS_FILE_HEADER2));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DataCheckSum = CalculateCheckSum8 ((CONST UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER), FileLength - sizeof(EFI_FFS_FILE_HEADER));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (FfsFileHeader->IntegrityCheck.Checksum.File != DataCheckSum) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (CompareGuid (&FfsFileHeader->Name, (EFI_GUID*)FileName)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (SearchType == PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((FfsFileHeader->Type == EFI_FV_FILETYPE_PEIM) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (FfsFileHeader->Type == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (FfsFileHeader->Type == EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (FfsFileHeader->Type == EFI_FV_FILETYPE_FREEFORM) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (CompareGuid (&FfsFileHeader->Name, &gPeiAprioriFileNameGuid)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (((SearchType == FfsFileHeader->Type) || (SearchType == EFI_FV_FILETYPE_ALL)) &&
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (FfsFileHeader->Type != EFI_FV_FILETYPE_FFS_PAD)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader->Name));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FileOccupiedSize = GET_OCCUPIED_SIZE(FileLength, 8);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Initialize PeiCore Fv List.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param PrivateData - Pointer to PEI_CORE_INSTANCE.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param SecCoreData - Pointer to EFI_SEC_PEI_HAND_OFF.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Install FV_PPI for FFS2 file system.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Install FV_PPI for FFS3 file system.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BfvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)SecCoreData->BootFirmwareVolumeBase;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The FV_PPI in BFV's format should be installed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get handle of BFV
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update internal PEI_CORE_FV array.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PrivateData->Fv[PrivateData->FvCount].FvHeader = BfvHeader;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PrivateData->Fv[PrivateData->FvCount].FvPpi = FvPpi;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PrivateData->Fv[PrivateData->FvCount].FvHandle = FvHandle;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Post a call-back for the FvInfoPPI services to expose
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // additional Fvs to PeiCore.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = PeiServicesNotifyPpi (&mNotifyOnFvInfoList);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Process Firmware Volum Information once FvInfoPPI install.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The FV Info will be registered into PeiCore private data structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync And search the inside FV image, if found, the new FV INFO PPI will be installed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param NotifyDescriptor Address of the notification descriptor data structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Ppi Address of the PPI that was installed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The FV Info is registered into PeiCore private data structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return if not EFI_SUCESS, fail to verify FV.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (PrivateData->FvCount >= FixedPcdGet32 (PcdPeiCoreMaxFvSupported)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, "The number of Fv Images (%d) exceed the max supported FVs (%d) in Pei", PrivateData->FvCount + 1, FixedPcdGet32 (PcdPeiCoreMaxFvSupported)));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, "PcdPeiCoreMaxFvSupported value need be reconfigurated in DSC"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FvInfoPpi = (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *)Ppi;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Locate the corresponding FV_PPI according to founded FV's format guid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Process new found FV and get FV handle.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = FvPpi->ProcessVolume (FvPpi, FvInfoPpi->FvInfo, FvInfoPpi->FvInfoSize, &FvHandle);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, "Fail to process new found FV, FV may be corrupted!\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check whether the FV has already been processed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (FvIndex = 0; FvIndex < PrivateData->FvCount; FvIndex ++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (PrivateData->Fv[FvIndex].FvHandle == FvHandle) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, "The Fv %p has already been processed!\n", FvInfoPpi->FvInfo));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update internal PEI_CORE_FV array.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PrivateData->Fv[PrivateData->FvCount].FvHeader = (EFI_FIRMWARE_VOLUME_HEADER*) FvInfoPpi->FvInfo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PrivateData->Fv[PrivateData->FvCount].FvPpi = FvPpi;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PrivateData->Fv[PrivateData->FvCount].FvHandle = FvHandle;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Scan and process the new discoveried FV for EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!PeimDispatchReadiness (PeiServices, DepexData)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Dependency is not satisfied.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, "Found firmware volume Image File %p in FV[%d] %p\n", FileHandle, PrivateData->FvCount - 1, FvHandle));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ProcessFvFile (&PrivateData->Fv[PrivateData->FvCount - 1], FileHandle);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, "Fail to process FV %p because no corresponding EFI_FIRMWARE_VOLUME_PPI is found!\n", FvInfoPpi->FvInfo));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AddUnknownFormatFvInfo (PrivateData, &FvInfoPpi->FvFormat, FvInfoPpi->FvInfo, FvInfoPpi->FvInfoSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Go through the file to search SectionType section.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Search within encapsulation sections (compression and GUIDed) recursively,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync until the match section is found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param SectionType Filter to find only section of this type.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Section From where to search.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param SectionSize The file size to search.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param OutputBuffer A pointer to the discovered section, if successful.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL if section not found
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param IsFfs3Fv Indicates the FV format.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return EFI_NOT_FOUND The match section is not found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return EFI_SUCCESS The match section is found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *GuidSectionPpi;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, "Found a FFS3 formatted section in a non-FFS3 formatted FV.\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // SectionLength is adjusted it is 4 byte aligned.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Go to the next section
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + SectionLength);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *OutputBuffer = (VOID *)((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER2));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *OutputBuffer = (VOID *)((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if ((Section->Type == EFI_SECTION_GUID_DEFINED) || (Section->Type == EFI_SECTION_COMPRESSION)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check the encapsulated section is extracted into the cache data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < PrivateData->CacheSection.AllSectionCount; Index ++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Section == PrivateData->CacheSection.Section[Index]) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PpiOutput = PrivateData->CacheSection.SectionData[Index];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PpiOutputSize = PrivateData->CacheSection.SectionSize[Index];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Search section directly from the cache data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &((EFI_GUID_DEFINED_SECTION2 *)Section)->SectionDefinitionGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &((EFI_GUID_DEFINED_SECTION *)Section)->SectionDefinitionGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (Section->Type == EFI_SECTION_COMPRESSION) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = PeiServicesLocatePpi (&gEfiPeiDecompressPpiGuid, 0, NULL, (VOID **) &DecompressPpi);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update cache section data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (PrivateData->CacheSection.AllSectionCount < CACHE_SETION_MAX_NUMBER) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PrivateData->CacheSection.Section [PrivateData->CacheSection.SectionIndex] = Section;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PrivateData->CacheSection.SectionData [PrivateData->CacheSection.SectionIndex] = PpiOutput;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PrivateData->CacheSection.SectionSize [PrivateData->CacheSection.SectionIndex] = PpiOutputSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PrivateData->CacheSection.SectionIndex = (PrivateData->CacheSection.SectionIndex + 1)%CACHE_SETION_MAX_NUMBER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // SectionLength is adjusted it is 4 byte aligned.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Go to the next section
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Searches for the next matching section within the specified file.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param SectionType Filter to find only sections of this type.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param FileHandle Pointer to the current file to search.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param SectionData A pointer to the discovered section, if successful.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL if section not found
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND The section was not found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The section was found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((CoreFvHandle == NULL) || (CoreFvHandle->FvPpi == NULL)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return CoreFvHandle->FvPpi->FindSectionByType (CoreFvHandle->FvPpi, SectionType, FileHandle, SectionData);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Searches for the next matching file in the firmware volume.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param SearchType Filter to find only files of this type.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param FvHandle Handle of firmware volume in which to search.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param FileHandle On entry, points to the current handle from which to begin searching or NULL to start
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync at the beginning of the firmware volume. On exit, points the file handle of the next file
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync in the volume or NULL if there are no more files.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND The file was not found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND The header checksum was not zero.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The file was found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // To make backward compatiblity, if can not find corresponding the handle of FV
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // then treat FV as build-in FFS2/FFS3 format and memory mapped FV that FV handle is pointed
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // to the address of first byte of FV.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((CoreFvHandle == NULL) && FeaturePcdGet (PcdFrameworkCompatibilitySupport)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return FindFileEx (FvHandle, NULL, SearchType, FileHandle, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((CoreFvHandle == NULL) || CoreFvHandle->FvPpi == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return CoreFvHandle->FvPpi->FindFileByType (CoreFvHandle->FvPpi, SearchType, FvHandle, FileHandle);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Search the firmware volumes by index
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Instance This instance of the firmware volume to find. The value 0 is the Boot Firmware
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Volume (BFV).
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param VolumeHandle On exit, points to the next volume handle or NULL if it does not exist.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER VolumeHandle is NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND The volume was not found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The volume was found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Private = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CoreFvHandle = FindNextCoreFvHandle (Private, Instance);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Find a file within a volume by its name.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param FileName A pointer to the name of the file to find within the firmware volume.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param VolumeHandle The firmware volume to search
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param FileHandle Upon exit, points to the found file's handle
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync or NULL if it could not be found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS File was found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND File was not found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER VolumeHandle or FileHandle or FileName was NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((VolumeHandle == NULL) || (FileName == NULL) || (FileHandle == NULL)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CoreFvHandle = FvHandleToCoreHandle (VolumeHandle);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((CoreFvHandle == NULL) || (CoreFvHandle->FvPpi == NULL)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return CoreFvHandle->FvPpi->FindFileByName (CoreFvHandle->FvPpi, FileName, &VolumeHandle, FileHandle);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Returns information about a specific file.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param FileHandle Handle of the file.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param FileInfo Upon exit, points to the file's information.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER If FileHandle does not represent a valid file.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS File information returned.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Retrieve the FirmwareVolume which the file resides in.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((CoreFvHandle == NULL) || (CoreFvHandle->FvPpi == NULL)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return CoreFvHandle->FvPpi->GetFileInfo (CoreFvHandle->FvPpi, FileHandle, FileInfo);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Returns information about the specified volume.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function returns information about a specific firmware
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync volume, including its name, type, attributes, starting address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param VolumeHandle Handle of the volume.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param VolumeInfo Upon exit, points to the volume's information.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Volume information returned.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER If VolumeHandle does not represent a valid volume.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER If VolumeHandle is NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Information successfully returned.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER The volume designated by the VolumeHandle is not available.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((VolumeInfo == NULL) || (VolumeHandle == NULL)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((CoreHandle == NULL) || (CoreHandle->FvPpi == NULL)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return CoreHandle->FvPpi->GetVolumeInfo (CoreHandle->FvPpi, VolumeHandle, VolumeInfo);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Get Fv image from the FV type file, then install FV INFO ppi, Build FV hob.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param ParentFvCoreHandle Pointer of EFI_CORE_FV_HANDLE to parent Fv image that contain this Fv image.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param ParentFvFileHandle File handle of a Fv type file that contain this Fv image.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND FV image can't be found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Successfully to process it.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES Can not allocate page when aligning FV image
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Others Can not find EFI_SECTION_FIRMWARE_VOLUME_IMAGE section
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // been extracted.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while ((HobPtr.Raw = GetNextHob (EFI_HOB_TYPE_FV2, HobPtr.Raw)) != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (CompareGuid (&(((EFI_FFS_FILE_HEADER *)ParentFvFileHandle)->Name), &HobPtr.FirmwareVolume2->FileName)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // this FILE has been dispatched, it will not be dispatched again.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, "FV file %p has been dispatched!\r\n", ParentFvFileHandle));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Find FvImage in FvFile
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // FvAlignment must be more than 8 bytes required by FvHeader structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FvAlignment = 1 << ((ReadUnaligned32 (&FvHeader->Attributes) & EFI_FVB2_ALIGNMENT) >> 16);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check FvImage
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewFvBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINT32) FvLength), FvAlignment);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FvHeader = (EFI_FIRMWARE_VOLUME_HEADER*) NewFvBuffer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = ParentFvPpi->GetVolumeInfo (ParentFvPpi, ParentFvHandle, &ParentFvImageInfo);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = ParentFvPpi->GetFileInfo (ParentFvPpi, ParentFvFileHandle, &FileInfo);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Install FvPpi and Build FvHob
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Inform the extracted FvImage to Fv HOB consumer phase, i.e. DXE phase
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Makes the encapsulated volume show up in DXE phase to skip processing of
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // encapsulated file again.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Process a firmware volume and create a volume handle.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Create a volume handle from the information in the buffer. For
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync memory-mapped firmware volumes, Buffer and BufferSize refer to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the start of the firmware volume and the firmware volume size.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync For non memory-mapped firmware volumes, this points to a
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync buffer which contains the necessary information for creating
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the firmware volume handle. Normally, these values are derived
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync from the EFI_FIRMWARE_VOLUME_INFO_PPI.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param This Points to this instance of the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PEI_FIRMWARE_VOLUME_PPI.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Buffer Points to the start of the buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BufferSize Size of the buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param FvHandle Points to the returned firmware volume
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync handle. The firmware volume handle must
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync be unique within the system.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Firmware volume handle created.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_VOLUME_CORRUPTED Volume was corrupt.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The build-in EFI_PEI_FIRMWARE_VOLUME_PPI for FFS2/FFS3 support memory-mapped
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // FV image and the handle is pointed to Fv image's buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Do verify for given FV buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = VerifyFv ((EFI_FIRMWARE_VOLUME_HEADER*) Buffer);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, "Fail to verify FV which address is 0x%11p", Buffer));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Finds the next file of the specified type.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This service enables PEI modules to discover additional firmware files.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The FileHandle must be unique within the system.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param This Points to this instance of the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PEI_FIRMWARE_VOLUME_PPI.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param SearchType A filter to find only files of this type. Type
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_FV_FILETYPE_ALL causes no filtering to be
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param FvHandle Handle of firmware volume in which to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param FileHandle Points to the current handle from which to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync begin searching or NULL to start at the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync beginning of the firmware volume. Updated
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync upon return to reflect the file found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The file was found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND The file was not found. FileHandle contains NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return FindFileEx (FvHandle, NULL, SearchType, FileHandle, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Find a file within a volume by its name.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This service searches for files with a specific name, within
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync either the specified firmware volume or all firmware volumes.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param This Points to this instance of the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PEI_FIRMWARE_VOLUME_PPI.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param FileName A pointer to the name of the file to find
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync within the firmware volume.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param FvHandle Upon entry, the pointer to the firmware
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync volume to search or NULL if all firmware
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync volumes should be searched. Upon exit, the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync actual firmware volume in which the file was
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param FileHandle Upon exit, points to the found file's
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync handle or NULL if it could not be found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS File was found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND File was not found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER FvHandle or FileHandle or
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FileName was NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((FvHandle == NULL) || (FileName == NULL) || (FileHandle == NULL)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = FindFileEx (*FvHandle, FileName, 0, FileHandle, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If *FvHandle = NULL, so search all FV for given filename
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer());
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < PrivateData->FvCount; Index ++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Only search the FV which is associated with a EFI_PEI_FIRMWARE_VOLUME_PPI instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = FindFileEx (PrivateData->Fv[Index].FvHandle, FileName, 0, FileHandle, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Returns information about a specific file.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function returns information about a specific
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync file, including its file name, type, attributes, starting
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync address and size.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param This Points to this instance of the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PEI_FIRMWARE_VOLUME_PPI.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param FileHandle Handle of the file.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param FileInfo Upon exit, points to the file's
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync information.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS File information returned.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER If FileHandle does not
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync represent a valid file.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Retrieve the FirmwareVolume which the file resides in.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FwVolInstance = PEI_FW_VOL_INSTANCE_FROM_FV_THIS (This);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((CoreFvHandle->FvHeader->Attributes & EFI_FVB2_ERASE_POLARITY) != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get FileState which is the highest bit of the State
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FileState = GetFileState (ErasePolarity, (EFI_FFS_FILE_HEADER*)FileHandle);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (&FileInfo->FileName, &FileHeader->Name, sizeof(EFI_GUID));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FileInfo->FileAttributes = FfsAttributes2FvFileAttributes (FileHeader->Attributes);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((CoreFvHandle->FvHeader->Attributes & EFI_FVB2_MEMORY_MAPPED) == EFI_FVB2_MEMORY_MAPPED) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FileInfo->FileAttributes |= EFI_FV_FILE_ATTRIB_MEMORY_MAPPED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, "It is a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FileHeader->Name));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FileInfo->BufferSize = FFS_FILE2_SIZE (FileHeader) - sizeof (EFI_FFS_FILE_HEADER2);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FileInfo->Buffer = (UINT8 *) FileHeader + sizeof (EFI_FFS_FILE_HEADER2);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FileInfo->BufferSize = FFS_FILE_SIZE (FileHeader) - sizeof (EFI_FFS_FILE_HEADER);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FileInfo->Buffer = (UINT8 *) FileHeader + sizeof (EFI_FFS_FILE_HEADER);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function returns information about the firmware volume.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param This Points to this instance of the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PEI_FIRMWARE_VOLUME_PPI.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param FvHandle Handle to the firmware handle.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param VolumeInfo Points to the returned firmware volume
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync information.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Information returned successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER FvHandle does not indicate a valid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync firmware volume or VolumeInfo is NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // VolumeHandle may not align at 8 byte,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // but FvLength is UINT64 type, which requires FvHeader align at least 8 byte.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // So, Copy FvHeader into the local FvHeader structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (&FwVolHeader, FvHandle, sizeof (EFI_FIRMWARE_VOLUME_HEADER));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check Fv Image Signature
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (&VolumeInfo->FvFormat, &FwVolHeader.FileSystemGuid, sizeof(EFI_GUID));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FwVolExHeaderInfo = (EFI_FIRMWARE_VOLUME_EXT_HEADER*)(((UINT8 *)FvHandle) + FwVolHeader.ExtHeaderOffset);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (&VolumeInfo->FvName, &FwVolExHeaderInfo->FvName, sizeof(EFI_GUID));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Find the next matching section in the firmware file.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This service enables PEI modules to discover sections
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync of a given type within a valid file.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param This Points to this instance of the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PEI_FIRMWARE_VOLUME_PPI.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param SearchType A filter to find only sections of this
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param FileHandle Handle of firmware file in which to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param SectionData Updated upon return to point to the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync section found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Section was found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND Section of the specified type was not
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync found. SectionData contains NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FwVolInstance = PEI_FW_VOL_INSTANCE_FROM_FV_THIS (This);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FfsFileHeader = (EFI_FFS_FILE_HEADER *)(FileHandle);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (FFS_FILE2_SIZE (FfsFileHeader) > 0x00FFFFFF);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, "It is a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader->Name));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER2));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FileSize = FFS_FILE2_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER2);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FileSize = FFS_FILE_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Convert the handle of FV to pointer of corresponding PEI_CORE_FV_HANDLE.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param FvHandle The handle of a FV.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval NULL if can not find.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return Pointer of corresponding PEI_CORE_FV_HANDLE.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer());
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < PrivateData->FvCount; Index ++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Get instance of PEI_CORE_FV_HANDLE for next volume according to given index.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This routine also will install FvInfo ppi for FV hob in PI ways.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Private Pointer of PEI_CORE_INSTANCE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Instance The index of FV want to be searched.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return Instance of PEI_CORE_FV_HANDLE.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Handle Framework FvHob and Install FvInfo Ppi for it.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (FeaturePcdGet (PcdFrameworkCompatibilitySupport)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Loop to search the wanted FirmwareVolume which supports FFS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FvHob = (EFI_HOB_FIRMWARE_VOLUME *)GetFirstHob (EFI_HOB_TYPE_FV);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Search whether FvHob has been installed into PeiCore's FV database.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If found, no need install new FvInfoPpi for it.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0, Match = FALSE; Index < Private->FvCount; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((EFI_PEI_FV_HANDLE)(UINTN)FvHob->BaseAddress == Private->Fv[Index].FvHeader) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Search whether FvHob has been cached into PeiCore's Unknown FV database.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If found, no need install new FvInfoPpi for it.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < Private->UnknownFvInfoCount; Index ++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((UINTN)FvHob->BaseAddress == (UINTN)Private->UnknownFvInfo[Index].FvInfo) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If the Fv in FvHob has not been installed into PeiCore's FV database and has
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // not been cached into PeiCore's Unknown FV database, install a new FvInfoPpi
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // for it then PeiCore will dispatch it in callback of FvInfoPpi.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &(((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FvHob->BaseAddress)->FileSystemGuid),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FvHob = (EFI_HOB_FIRMWARE_VOLUME *)GetNextHob (EFI_HOB_TYPE_FV, (VOID *)((UINTN)FvHob + FvHob->Header.HobLength));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (Private->FvCount <= FixedPcdGet32 (PcdPeiCoreMaxFvSupported));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync After PeiCore image is shadowed into permanent memory, all build-in FvPpi should
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync be re-installed with the instance in permanent memory and all cached FvPpi pointers in
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PrivateData->Fv[] array should be fixed up to be pointed to the one in permenant
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param PrivateData Pointer to PEI_CORE_INSTANCE.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Locate old build-in Ffs2 EFI_PEI_FIRMWARE_VOLUME_PPI which
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // in flash.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Re-install the EFI_PEI_FIRMWARE_VOLUME_PPI for build-in Ffs2
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // which is shadowed from flash to permanent memory within PeiCore image.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = PeiServicesReInstallPpi (OldDescriptor, &mPeiFfs2FvPpiList);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Fixup all FvPpi pointers for the implementation in flash to permanent memory.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < FixedPcdGet32 (PcdPeiCoreMaxFvSupported); Index ++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Locate old build-in Ffs3 EFI_PEI_FIRMWARE_VOLUME_PPI which
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // in flash.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Re-install the EFI_PEI_FIRMWARE_VOLUME_PPI for build-in Ffs3
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // which is shadowed from flash to permanent memory within PeiCore image.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = PeiServicesReInstallPpi (OldDescriptor, &mPeiFfs3FvPpiList);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Fixup all FvPpi pointers for the implementation in flash to permanent memory.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < FixedPcdGet32 (PcdPeiCoreMaxFvSupported); Index ++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Report the information for a new discoveried FV in unknown third-party format.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync If the EFI_PEI_FIRMWARE_VOLUME_PPI has not been installed for third-party FV format, but
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the FV in this format has been discoveried, then this FV's information will be cached into
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PEI_CORE_INSTANCE's UnknownFvInfo array.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Also a notification would be installed for unknown third-party FV format guid, if EFI_PEI_FIRMWARE_VOLUME_PPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync is installed later by platform's PEIM, the original unknown third-party FV will be processed by
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync using new installed EFI_PEI_FIRMWARE_VOLUME_PPI.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param PrivateData Point to instance of PEI_CORE_INSTANCE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Format Point to the unknown third-party format guid.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param FvInfo Point to FvInfo buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param FvInfoSize The size of FvInfo buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES The FV info array in PEI_CORE_INSTANCE has no more spaces.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Success to add the information for unknown FV.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (PrivateData->UnknownFvInfoCount + 1 >= FixedPcdGet32 (PcdPeiCoreMaxFvSupported)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewUnknownFv = &PrivateData->UnknownFvInfo[PrivateData->UnknownFvInfoCount];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewUnknownFv->NotifyDescriptor.Flags = (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewUnknownFv->NotifyDescriptor.Guid = &NewUnknownFv->FvFormat;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewUnknownFv->NotifyDescriptor.Notify = ThirdPartyFvPpiNotifyCallback;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PeiServicesNotifyPpi (&NewUnknownFv->NotifyDescriptor);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Find the FV information according to third-party FV format guid.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This routine also will remove the FV information found by given FV format guid from
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PrivateData->UnknownFvInfo[].
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param PrivateData Point to instance of PEI_CORE_INSTANCE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Format Point to given FV format guid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param FvInfo On return, the pointer of FV information buffer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param FvInfoSize On return, the size of FV information buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND The FV is not found for new installed EFI_PEI_FIRMWARE_VOLUME_PPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Success to find a FV which could be processed by new installed EFI_PEI_FIRMWARE_VOLUME_PPI.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (; Index < PrivateData->UnknownFvInfoCount; Index ++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (CompareGuid (Format, &PrivateData->UnknownFvInfo[Index].FvFormat)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *FvInfo = PrivateData->UnknownFvInfo[Index].FvInfo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *FvInfoSize = PrivateData->UnknownFvInfo[Index].FvInfoSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Remove an entry from UnknownFvInfo array.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (;Index2 < PrivateData->UnknownFvInfoCount; Index2 ++, Index ++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (&PrivateData->UnknownFvInfo[Index], &PrivateData->UnknownFvInfo[Index2], sizeof (PEI_CORE_UNKNOW_FORMAT_FV_INFO));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Notification callback function for EFI_PEI_FIRMWARE_VOLUME_PPI.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync When a EFI_PEI_FIRMWARE_VOLUME_PPI is installed to support new FV format, this
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync routine is called to process all discoveried FVs in this format.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param NotifyDescriptor Address of the notification descriptor data structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Ppi Address of the PPI that was installed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The notification callback is processed correctly.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = FindUnknownFormatFvInfo (PrivateData, NotifyDescriptor->Guid, &FvInfo, &FvInfoSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Process new found FV and get FV handle.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = FvPpi->ProcessVolume (FvPpi, FvInfo, FvInfoSize, &FvHandle);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, "Fail to process the FV 0x%p, FV may be corrupted!\n", FvInfo));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check whether the FV has already been processed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (FvIndex = 0; FvIndex < PrivateData->FvCount; FvIndex ++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (PrivateData->Fv[FvIndex].FvHandle == FvHandle) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, "The Fv %p has already been processed!\n", FvInfo));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (PrivateData->FvCount >= FixedPcdGet32 (PcdPeiCoreMaxFvSupported)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, "The number of Fv Images (%d) exceed the max supported FVs (%d) in Pei", PrivateData->FvCount + 1, FixedPcdGet32 (PcdPeiCoreMaxFvSupported)));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, "PcdPeiCoreMaxFvSupported value need be reconfigurated in DSC"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update internal PEI_CORE_FV array.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PrivateData->Fv[PrivateData->FvCount].FvHeader = (EFI_FIRMWARE_VOLUME_HEADER*) FvInfo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PrivateData->Fv[PrivateData->FvCount].FvPpi = FvPpi;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PrivateData->Fv[PrivateData->FvCount].FvHandle = FvHandle;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Scan and process the new discoveried FV for EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!PeimDispatchReadiness (PeiServices, DepexData)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Dependency is not satisfied.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, "Found firmware volume Image File %p in FV[%d] %p\n", FileHandle, PrivateData->FvCount - 1, FvHandle));