diff options
Diffstat (limited to 'Core/CORE_PEI/CORE_PEI_PI/FwVol.c')
-rw-r--r-- | Core/CORE_PEI/CORE_PEI_PI/FwVol.c | 782 |
1 files changed, 782 insertions, 0 deletions
diff --git a/Core/CORE_PEI/CORE_PEI_PI/FwVol.c b/Core/CORE_PEI/CORE_PEI_PI/FwVol.c new file mode 100644 index 0000000..2ecf88e --- /dev/null +++ b/Core/CORE_PEI/CORE_PEI_PI/FwVol.c @@ -0,0 +1,782 @@ +/*++ + +Copyright (c) 2004 - 2009, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + FwVol.c + +Abstract: + + Pei Core Firmware File System service routines. + +--*/ + +#include "Tiano.h" +#include "EfiImageFormat.h" +#include "PeiCore.h" +#include "PeiLib.h" + +#define GET_OCCUPIED_SIZE(ActualSize, Alignment) \ + (ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1)) + + +EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList = { + (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiFirmwareVolumeInfoPpiGuid, + FirmwareVolmeInfoPpiNotifyCallback +}; + + + + +STATIC +EFI_FFS_FILE_STATE +GetFileState( + IN UINT8 ErasePolarity, + IN EFI_FFS_FILE_HEADER *FfsHeader + ) +/*++ + +Routine Description: + + Returns the highest bit set of the State field + +Arguments: + + ErasePolarity - Erase Polarity as defined by EFI_FVB_ERASE_POLARITY + in the Attributes field. + FfsHeader - Pointer to FFS File Header. + +Returns: + Returns the highest bit in the State field + +--*/ +{ + EFI_FFS_FILE_STATE FileState; + EFI_FFS_FILE_STATE HighestBit; + + FileState = FfsHeader->State; + + if (ErasePolarity != 0) { + FileState = (EFI_FFS_FILE_STATE)~FileState; + } + + HighestBit = 0x80; + while (HighestBit != 0 && (HighestBit & FileState) == 0) { + HighestBit >>= 1; + } + + return HighestBit; +} + +STATIC +UINT8 +CalculateHeaderChecksum ( + IN EFI_FFS_FILE_HEADER *FileHeader + ) +/*++ + +Routine Description: + + Calculates the checksum of the header of a file. + +Arguments: + + FileHeader - Pointer to FFS File Header. + +Returns: + Checksum of the header. + + The header is zero byte checksum. + - Zero means the header is good. + - Non-zero means the header is bad. + + +Bugbug: For PEI performance reason, we comments this code at this time. +--*/ +{ + UINT8 *ptr; + UINTN Index; + UINT8 Sum; + + Sum = 0; + ptr = (UINT8 *)FileHeader; + + for (Index = 0; Index < sizeof(EFI_FFS_FILE_HEADER) - 3; Index += 4) { + Sum = (UINT8)(Sum + ptr[Index]); + Sum = (UINT8)(Sum + ptr[Index+1]); + Sum = (UINT8)(Sum + ptr[Index+2]); + Sum = (UINT8)(Sum + ptr[Index+3]); + } + + for (; Index < sizeof(EFI_FFS_FILE_HEADER); Index++) { + Sum = (UINT8)(Sum + ptr[Index]); + } + + // + // State field (since this indicates the different state of file). + // + Sum = (UINT8)(Sum - FileHeader->State); + // + // Checksum field of the file is not part of the header checksum. + // + Sum = (UINT8)(Sum - FileHeader->IntegrityCheck.Checksum.File); + + return Sum; +} + +STATIC +BOOLEAN +EFIAPI +PeiFileHandleToVolume ( + IN EFI_PEI_FILE_HANDLE FileHandle, + OUT EFI_PEI_FV_HANDLE *VolumeHandle + ) +{ + UINTN Index; + PEI_CORE_INSTANCE *PrivateData; + EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; + + PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ()); + for (Index = 0; Index < PrivateData->FvCount; Index++) { + FwVolHeader = PrivateData->Fv[Index].FvHeader; + if (((UINTN)FileHandle > (UINTN)FwVolHeader ) && \ + ((UINTN)FileHandle < ((UINTN)FwVolHeader + (UINTN)FwVolHeader->FvLength))) { + *VolumeHandle = (EFI_PEI_FV_HANDLE)FwVolHeader; + return TRUE; + } + } + return FALSE; +} + + +EFI_STATUS +PeiFindFileEx ( + 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, + IN OUT EFI_PEI_FILE_HANDLE *AprioriFile OPTIONAL + ) +/*++ + +Routine Description: + Given the input file pointer, search for the next matching file in the + FFS volume as defined by SearchType. The search starts from FileHeader inside + the Firmware Volume defined by FwVolHeader. + +Arguments: + PeiServices - Pointer to the PEI Core Services Table. + SearchType - Filter to find only files of this type. + Type EFI_FV_FILETYPE_ALL causes no filtering to be done. + FwVolHeader - Pointer to the FV header of the volume to search. + This parameter must point to a valid FFS volume. + FileHeader - Pointer to the current file from which to begin searching. + This pointer will be updated upon return to reflect the file found. + Flag - Indicator for if this is for PEI Dispath search + +Returns: + EFI_NOT_FOUND - No files matching the search criteria were found + EFI_SUCCESS + +--*/ +{ + EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; + EFI_FFS_FILE_HEADER **FileHeader; + EFI_FFS_FILE_HEADER *FfsFileHeader; + EFI_FIRMWARE_VOLUME_EXT_HEADER *FwVolExHeaderInfo; + UINT32 FileLength; + UINT32 FileOccupiedSize; + UINT32 FileOffset; + UINT64 FvLength; + UINT8 ErasePolarity; + UINT8 FileState; + EFI_PEI_SERVICES **PeiServices; + + PeiServices = GetPeiServicesTablePointer(); + FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)FvHandle; + FileHeader = (EFI_FFS_FILE_HEADER **)FileHandle; + + FvLength = FwVolHeader->FvLength; + if (FwVolHeader->Attributes & EFI_FVB_ERASE_POLARITY) { + ErasePolarity = 1; + } else { + ErasePolarity = 0; + } + + // + // If FileHeader is not specified (NULL) or FileName is not NULL, + // start with the first file in the firmware volume. Otherwise, + // start from the FileHeader. + // + if ((*FileHeader == NULL) || (FileName != NULL)) { + FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FwVolHeader + FwVolHeader->HeaderLength); + if (FwVolHeader->ExtHeaderOffset != 0) { + FwVolExHeaderInfo = (EFI_FIRMWARE_VOLUME_EXT_HEADER *)(((UINT8 *)FwVolHeader) + FwVolHeader->ExtHeaderOffset); + FfsFileHeader = (EFI_FFS_FILE_HEADER *)(((UINT8 *)FwVolExHeaderInfo) + FwVolExHeaderInfo->ExtHeaderSize); + } + } else { + // + // Length is 24 bits wide so mask upper 8 bits + // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned. + // + FileLength = *(UINT32 *)(*FileHeader)->Size & 0x00FFFFFF; + FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8); + FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)*FileHeader + FileOccupiedSize); + } + + FileOffset = (UINT32) ((UINT8 *)FfsFileHeader - (UINT8 *)FwVolHeader); + PEI_ASSERT (PeiServices,(FileOffset <= 0xFFFFFFFF)); + + while (FileOffset < (FvLength - sizeof (EFI_FFS_FILE_HEADER))) { + // + // Get FileState which is the highest bit of the State + // + FileState = GetFileState (ErasePolarity, FfsFileHeader); + switch (FileState) { + + case EFI_FILE_HEADER_INVALID: + FileOffset += sizeof(EFI_FFS_FILE_HEADER); + FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + sizeof(EFI_FFS_FILE_HEADER)); + break; + + case EFI_FILE_DATA_VALID: + case EFI_FILE_MARKED_FOR_UPDATE: + if (CalculateHeaderChecksum (FfsFileHeader) != 0) { +//*** AMI PORTING BEGIN ***// +// Skip the assert to support a more sophisiticated +// FV corruption handling outside of the Core. +// PEI_ASSERT (PeiServices,FALSE); +//*** AMI PORTING END *****// + return EFI_NOT_FOUND; + } + + FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF; + FileOccupiedSize = GET_OCCUPIED_SIZE(FileLength, 8); + + if (FileName != NULL) { + if (CompareGuid (&FfsFileHeader->Name, (EFI_GUID*)FileName)) { + *FileHeader = FfsFileHeader; + return EFI_SUCCESS; + } + } else if (SearchType == PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE) { + if ((FfsFileHeader->Type == EFI_FV_FILETYPE_PEIM) || + (FfsFileHeader->Type == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER)) { + + *FileHeader = FfsFileHeader; + return EFI_SUCCESS; + } else if (AprioriFile != NULL) { + if (FfsFileHeader->Type == EFI_FV_FILETYPE_FREEFORM) { + if (CompareGuid (&FfsFileHeader->Name, &gEfiPeiAprioriGuid)) { + *AprioriFile = FfsFileHeader; + } + } + } + } else if ((SearchType == FfsFileHeader->Type) || (SearchType == EFI_FV_FILETYPE_ALL)) { + *FileHeader = FfsFileHeader; + return EFI_SUCCESS; + } + + FileOffset += FileOccupiedSize; + FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize); + break; + + case EFI_FILE_DELETED: + FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF; + FileOccupiedSize = GET_OCCUPIED_SIZE(FileLength, 8); + FileOffset += FileOccupiedSize; + FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize); + break; + + default: + return EFI_NOT_FOUND; + + } + } + + return EFI_NOT_FOUND; +} + + +VOID +PeiInitializeFv ( + IN PEI_CORE_INSTANCE *PrivateData, + IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData + ) +/*++ + +Routine Description: + + Initialize PeiCore Fv List. + +Arguments: + PrivateData - Pointer to PEI_CORE_INSTANCE. + SecCoreData - Pointer to EFI_SEC_PEI_HAND_OFF. + +Returns: + NONE + +--*/ +{ + EFI_STATUS Status; + // + // The BFV must be the first entry. The Core FV support is stateless + // The AllFV list has a single entry per FV in PEI. + // The Fv list only includes FV that PEIMs will be dispatched from and + // its File System Format is PI 1.0 definition. + // + PrivateData->FvCount = 1; + PrivateData->Fv[0].FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)SecCoreData->BootFirmwareVolumeBase; + + PrivateData->AllFvCount = 1; + PrivateData->AllFv[0] = (EFI_PEI_FV_HANDLE)PrivateData->Fv[0].FvHeader; + + + // + // Post a call-back for the FvInfoPPI services to expose + // additional Fvs to PeiCore. + // + Status = (PrivateData->PS)->NotifyPpi (&PrivateData->PS, &mNotifyList); + ASSERT_PEI_ERROR (&PrivateData->PS, Status); + +} + + + +EFI_STATUS +EFIAPI +FirmwareVolmeInfoPpiNotifyCallback ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ) +/*++ + +Routine Description: + + Process Firmware Volum Information once FvInfoPPI install. + +Arguments: + + PeiServices - General purpose services available to every PEIM. + +Returns: + + Status - EFI_SUCCESS if the interface could be successfully + installed + +--*/ +{ + UINT8 FvCount; + EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *Fv; + PEI_CORE_INSTANCE *PrivateData; + + PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices); + + if (PrivateData->FvCount >= PEI_CORE_MAX_FV_SUPPORTED) { + PEI_ASSERT (GetPeiServicesTablePointer(),FALSE); + } + + Fv = (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *)Ppi; + + if (CompareGuid (&Fv->FvFormat, &gEfiFirmwareFileSystem2Guid)) { + for (FvCount = 0; FvCount < PrivateData->FvCount; FvCount ++) { + if ((UINTN)PrivateData->Fv[FvCount].FvHeader == (UINTN)Fv->FvInfo) { + return EFI_SUCCESS; + } + } + PrivateData->Fv[PrivateData->FvCount++].FvHeader = (EFI_FIRMWARE_VOLUME_HEADER*)Fv->FvInfo; + } + + // + // Allways add to the All list + // + PrivateData->AllFv[PrivateData->AllFvCount++] = (EFI_PEI_FV_HANDLE)Fv->FvInfo; + + return EFI_SUCCESS; +} + + +EFI_STATUS +EFIAPI +PeiFfsFindNextVolume ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN UINTN Instance, + OUT EFI_PEI_FV_HANDLE *VolumeHandle + ) +/*++ + +Routine Description: + + Search the next FV Volume. + +Arguments: + PeiServices - Pointer to the PEI Core Services Table. + Instance - The Fv Volume Instance. + VolumeHandle - Pointer to the current Fv Volume to search. + +Returns: + EFI_INVALID_PARAMETER - VolumeHandle is NULL. + EFI_NOT_FOUND - No FV Volume is found. + EFI_SUCCESS - The next FV Volume is found. + +--*/ + +{ + PEI_CORE_INSTANCE *Private; + + Private = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices); + if (VolumeHandle == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (Instance >= Private->AllFvCount) { + VolumeHandle = NULL; + return EFI_NOT_FOUND; + } + + *VolumeHandle = Private->AllFv[Instance]; + return EFI_SUCCESS; +} + + +EFI_STATUS +EFIAPI +PeiFfsFindNextFile ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_FV_FILETYPE SearchType, + IN CONST EFI_PEI_FV_HANDLE FvHandle, + IN OUT EFI_PEI_FILE_HANDLE *FileHandle + ) +/*++ + +Routine Description: + + Given the input FvHandle, search for the next matching type file in the FV Volume. + +Arguments: + PeiServices - Pointer to the PEI Core Services Table. + SearchType - Filter to find only file of this type. + FvHandle - Pointer to the current FV to search. + FileHandle - Pointer to the file matching SearchType in FwVolHeader. + - NULL if file not found +Returns: + EFI_STATUS + +--*/ +{ + return PeiFindFileEx (FvHandle, NULL, SearchType, FileHandle, NULL); +} + +EFI_STATUS +PeiFfsProcessSection ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_SECTION_TYPE SectionType, + IN EFI_COMMON_SECTION_HEADER *Section, + IN UINTN SectionSize, + OUT VOID **OutputBuffer, + OUT UINTN *OutputSize, + OUT UINT32 *Authentication + ) +/*++ + +Routine Description: + + Go through the file to search SectionType section, + when meeting an encapsuled section, search recursively. + +Arguments: + PeiServices - Pointer to the PEI Core Services Table. + SearchType - Filter to find only section of this type. + Section - From where to search. + SectionSize - The file size to search. + OutputBuffer - Pointer to the section to search. + OutputSize - The size of the section to search. + Authentication - Authenticate the section. + +Returns: + EFI_STATUS + +--*/ +{ + EFI_STATUS Status; + UINT32 SectionLength; + UINT32 ParsedLength; + EFI_GUID_DEFINED_SECTION *GuidSection; + EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *GuidSectionPpi; + EFI_COMPRESSION_SECTION *CompressionSection; + EFI_PEI_DECOMPRESS_PPI *DecompressPpi; + VOID *PpiOutput; + UINTN PpiOutputSize; + + *OutputBuffer = NULL; + ParsedLength = 0; + while (ParsedLength < SectionSize) { + if (Section->Type == SectionType) { + *OutputBuffer = (VOID *)(Section + 1); + return EFI_SUCCESS; + } else if (Section->Type == EFI_SECTION_GUID_DEFINED) { + GuidSection = (EFI_GUID_DEFINED_SECTION *)Section; + GuidSectionPpi = PeiReturnPpi (PeiServices, &GuidSection->SectionDefinitionGuid); + if (GuidSectionPpi != NULL) { + Status = GuidSectionPpi->ExtractSection ( + GuidSectionPpi, + Section, + &PpiOutput, + &PpiOutputSize, + Authentication + ); + if (!EFI_ERROR (Status)) { + return PeiFfsProcessSection ( + PeiServices, + SectionType, + PpiOutput, + PpiOutputSize, + OutputBuffer, + OutputSize, + Authentication + ); + } + } + } else if (Section->Type == EFI_SECTION_COMPRESSION) { + CompressionSection = (EFI_COMPRESSION_SECTION *)Section; + DecompressPpi = PeiReturnPpi (PeiServices, &gEfiPeiDecompressPpiGuid); + if (DecompressPpi != NULL) { + Status = DecompressPpi->Decompress ( + DecompressPpi, + CompressionSection, + &PpiOutput, + &PpiOutputSize + ); + if (!EFI_ERROR (Status)) { + return PeiFfsProcessSection ( + PeiServices, SectionType, PpiOutput, PpiOutputSize, OutputBuffer, OutputSize, Authentication + ); + } + } + } + + // + // Size is 24 bits wide so mask upper 8 bits. + // SectionLength is adjusted it is 4 byte aligned. + // Go to the next section + // + SectionLength = *(UINT32 *)Section->Size & 0x00FFFFFF; + SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4); + PEI_ASSERT (PeiServices, (SectionLength != 0)); + ParsedLength += SectionLength; + Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength); + } + + return EFI_NOT_FOUND; +} + + +EFI_STATUS +EFIAPI +PeiFfsFindSectionData ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_SECTION_TYPE SectionType, + IN EFI_PEI_FILE_HANDLE FileHandle, + OUT VOID **SectionData + ) +/*++ + +Routine Description: + Given the input file pointer, search for the next matching section in the + FFS volume. + +Arguments: + PeiServices - Pointer to the PEI Core Services Table. + SearchType - Filter to find only sections of this type. + FileHandle - Pointer to the current file to search. + SectionData - Pointer to the Section matching SectionType in FfsFileHeader. + - NULL if section not found + +Returns: + EFI_NOT_FOUND - No files matching the search criteria were found + EFI_SUCCESS + +--*/ +{ + EFI_FFS_FILE_HEADER *FfsFileHeader; + UINT32 FileSize; + EFI_COMMON_SECTION_HEADER *Section; + UINTN OutputSize; + UINT32 AuthenticationStatus; + + + FfsFileHeader = (EFI_FFS_FILE_HEADER *)FileHandle; + + // + // Size is 24 bits wide so mask upper 8 bits. + // Does not include FfsFileHeader header size + // FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned. + // + Section = (EFI_COMMON_SECTION_HEADER *)(FfsFileHeader + 1); + FileSize = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF; + FileSize -= sizeof (EFI_FFS_FILE_HEADER); + + return PeiFfsProcessSection ( + PeiServices, + SectionType, + Section, + FileSize, + SectionData, + &OutputSize, + &AuthenticationStatus + ); +} + + +EFI_STATUS +EFIAPI +PeiFfsFindFileByName ( + IN CONST EFI_GUID *FileName, + IN EFI_PEI_FV_HANDLE VolumeHandle, + OUT EFI_PEI_FILE_HANDLE *FileHandle + ) +/*++ + +Routine Description: + + Given the input VolumeHandle, search for the next matching name file. + +Arguments: + + FileName - File name to search. + VolumeHandle - The current FV to search. + FileHandle - Pointer to the file matching name in VolumeHandle. + - NULL if file not found +Returns: + EFI_STATUS + +--*/ +{ + EFI_STATUS Status; + if ((VolumeHandle == NULL) || (FileName == NULL) || (FileHandle == NULL)) { + return EFI_INVALID_PARAMETER; + } + Status = PeiFindFileEx (VolumeHandle, FileName, 0, FileHandle, NULL); + if (Status == EFI_NOT_FOUND) { + *FileHandle = NULL; + } + return Status; +} + + +EFI_STATUS +EFIAPI +PeiFfsGetFileInfo ( + IN EFI_PEI_FILE_HANDLE FileHandle, + OUT EFI_FV_FILE_INFO *FileInfo + ) +/*++ + +Routine Description: + + Collect information of given file. + +Arguments: + FileHandle - The handle to file. + FileInfo - Pointer to the file information. + +Returns: + EFI_STATUS + +--*/ +{ + UINT8 FileState; + UINT8 ErasePolarity; + EFI_FFS_FILE_HEADER *FileHeader; + EFI_PEI_FV_HANDLE VolumeHandle; + + if ((FileHandle == NULL) || (FileInfo == NULL)) { + return EFI_INVALID_PARAMETER; + } + + // + // Retrieve the FirmwareVolume which the file resides in. + // + if (!PeiFileHandleToVolume(FileHandle, &VolumeHandle)) { + return EFI_INVALID_PARAMETER; + } + + if (((EFI_FIRMWARE_VOLUME_HEADER*)VolumeHandle)->Attributes & EFI_FVB_ERASE_POLARITY) { + ErasePolarity = 1; + } else { + ErasePolarity = 0; + } + + // + // Get FileState which is the highest bit of the State + // + FileState = GetFileState (ErasePolarity, (EFI_FFS_FILE_HEADER*)FileHandle); + + switch (FileState) { + case EFI_FILE_DATA_VALID: + case EFI_FILE_MARKED_FOR_UPDATE: + break; + default: + return EFI_INVALID_PARAMETER; + } + + FileHeader = (EFI_FFS_FILE_HEADER *)FileHandle; + CopyMem (&FileInfo->FileName, &FileHeader->Name, sizeof(EFI_GUID)); + FileInfo->FileType = FileHeader->Type; + FileInfo->FileAttributes = FileHeader->Attributes; + FileInfo->BufferSize = ((*(UINT32 *)FileHeader->Size) & 0x00FFFFFF) - sizeof (EFI_FFS_FILE_HEADER); + FileInfo->Buffer = (FileHeader + 1); + return EFI_SUCCESS; +} + + +EFI_STATUS +EFIAPI +PeiFfsGetVolumeInfo ( + IN EFI_PEI_FV_HANDLE VolumeHandle, + OUT EFI_FV_INFO *VolumeInfo + ) +/*++ + +Routine Description: + + Collect information of given Fv Volume. + +Arguments: + VolumeHandle - The handle to Fv Volume. + VolumeInfo - The pointer to volume information. + +Returns: + EFI_STATUS + +--*/ +{ + EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; + EFI_FIRMWARE_VOLUME_EXT_HEADER *FwVolExHeaderInfo; + + if (VolumeInfo == NULL) { + return EFI_INVALID_PARAMETER; + } + + FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)VolumeHandle; + VolumeInfo->FvAttributes = FwVolHeader->Attributes; + VolumeInfo->FvStart = FwVolHeader; + VolumeInfo->FvSize = FwVolHeader->FvLength; + CopyMem (&VolumeInfo->FvFormat, &FwVolHeader->FileSystemGuid,sizeof(EFI_GUID)); + + if (FwVolHeader->ExtHeaderOffset != 0) { + FwVolExHeaderInfo = (EFI_FIRMWARE_VOLUME_EXT_HEADER*)(((UINT8 *)FwVolHeader) + FwVolHeader->ExtHeaderOffset); + CopyMem (&VolumeInfo->FvName, &FwVolExHeaderInfo->FvName, sizeof(EFI_GUID)); + } + return EFI_SUCCESS; +} + |