+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation \r
-All rights reserved. This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-Module Name:\r
-\r
- FwVol.c\r
-\r
-Abstract:\r
-\r
- Pei Core Firmware File System service routines.\r
-\r
---*/\r
-\r
-#include <PeiMain.h>\r
-\r
-#define GETOCCUPIEDSIZE(ActualSize, Alignment) \\r
- (ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1))\r
-\r
-STATIC\r
-EFI_FFS_FILE_STATE\r
-GetFileState(\r
- IN UINT8 ErasePolarity,\r
- IN EFI_FFS_FILE_HEADER *FfsHeader\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Returns the highest bit set of the State field\r
-\r
-Arguments:\r
-\r
- ErasePolarity - Erase Polarity as defined by EFI_FVB_ERASE_POLARITY\r
- in the Attributes field.\r
- FfsHeader - Pointer to FFS File Header.\r
-\r
-Returns:\r
- Returns the highest bit in the State field\r
-\r
---*/\r
-{\r
- EFI_FFS_FILE_STATE FileState;\r
- EFI_FFS_FILE_STATE HighestBit;\r
-\r
- FileState = FfsHeader->State;\r
-\r
- if (ErasePolarity != 0) {\r
- FileState = (EFI_FFS_FILE_STATE)~FileState;\r
- }\r
-\r
- HighestBit = 0x80;\r
- while (HighestBit != 0 && (HighestBit & FileState) == 0) {\r
- HighestBit >>= 1;\r
- }\r
-\r
- return HighestBit;\r
-} \r
-\r
-STATIC\r
-UINT8\r
-CalculateHeaderChecksum (\r
- IN EFI_FFS_FILE_HEADER *FileHeader\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Calculates the checksum of the header of a file.\r
-\r
-Arguments:\r
-\r
- FileHeader - Pointer to FFS File Header.\r
-\r
-Returns:\r
- Checksum of the header.\r
- \r
- The header is zero byte checksum.\r
- - Zero means the header is good.\r
- - Non-zero means the header is bad.\r
- \r
- \r
-Bugbug: For PEI performance reason, we comments this code at this time.\r
---*/\r
-{\r
- UINT8 *ptr;\r
- UINTN Index;\r
- UINT8 Sum;\r
- \r
- Sum = 0;\r
- ptr = (UINT8 *)FileHeader;\r
-\r
- for (Index = 0; Index < sizeof(EFI_FFS_FILE_HEADER) - 3; Index += 4) {\r
- Sum = (UINT8)(Sum + ptr[Index]);\r
- Sum = (UINT8)(Sum + ptr[Index+1]);\r
- Sum = (UINT8)(Sum + ptr[Index+2]);\r
- Sum = (UINT8)(Sum + ptr[Index+3]);\r
- }\r
-\r
- for (; Index < sizeof(EFI_FFS_FILE_HEADER); Index++) {\r
- Sum = (UINT8)(Sum + ptr[Index]);\r
- }\r
- \r
- //\r
- // State field (since this indicates the different state of file). \r
- //\r
- Sum = (UINT8)(Sum - FileHeader->State);\r
- //\r
- // Checksum field of the file is not part of the header checksum.\r
- //\r
- Sum = (UINT8)(Sum - FileHeader->IntegrityCheck.Checksum.File);\r
-\r
- return Sum;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-PeiFfsFindNextFileEx (\r
- IN EFI_FV_FILETYPE SearchType,\r
- IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader,\r
- IN OUT EFI_FFS_FILE_HEADER **FileHeader,\r
- IN BOOLEAN Flag\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Given the input file pointer, search for the next matching file in the\r
- FFS volume as defined by SearchType. The search starts from FileHeader inside\r
- the Firmware Volume defined by FwVolHeader.\r
-\r
-Arguments:\r
- PeiServices - Pointer to the PEI Core Services Table.\r
- SearchType - Filter to find only files of this type.\r
- Type EFI_FV_FILETYPE_ALL causes no filtering to be done.\r
- FwVolHeader - Pointer to the FV header of the volume to search.\r
- This parameter must point to a valid FFS volume.\r
- FileHeader - Pointer to the current file from which to begin searching.\r
- This pointer will be updated upon return to reflect the file found.\r
- Flag - Indicator for if this is for PEI Dispath search \r
-Returns:\r
- EFI_NOT_FOUND - No files matching the search criteria were found\r
- EFI_SUCCESS\r
-\r
---*/\r
-{\r
- EFI_FFS_FILE_HEADER *FfsFileHeader;\r
- UINT32 FileLength;\r
- UINT32 FileOccupiedSize;\r
- UINT32 FileOffset;\r
- UINT64 FvLength;\r
- UINT8 ErasePolarity;\r
- UINT8 FileState;\r
- \r
-\r
- FvLength = FwVolHeader->FvLength;\r
- if (FwVolHeader->Attributes & EFI_FVB_ERASE_POLARITY) {\r
- ErasePolarity = 1;\r
- } else {\r
- ErasePolarity = 0;\r
- }\r
- \r
- //\r
- // If FileHeader is not specified (NULL) start with the first file in the\r
- // firmware volume. Otherwise, start from the FileHeader.\r
- //\r
- if (*FileHeader == NULL) {\r
- FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FwVolHeader + FwVolHeader->HeaderLength);\r
- } else {\r
- //\r
- // Length is 24 bits wide so mask upper 8 bits\r
- // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned.\r
- //\r
- FileLength = *(UINT32 *)(*FileHeader)->Size & 0x00FFFFFF;\r
- FileOccupiedSize = GETOCCUPIEDSIZE(FileLength, 8);\r
- FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)*FileHeader + FileOccupiedSize);\r
- }\r
-\r
- FileOffset = (UINT32) ((UINT8 *)FfsFileHeader - (UINT8 *)FwVolHeader);\r
- ASSERT (FileOffset <= 0xFFFFFFFF);\r
- \r
- while (FileOffset < (FvLength - sizeof(EFI_FFS_FILE_HEADER))) {\r
- //\r
- // Get FileState which is the highest bit of the State \r
- //\r
- FileState = GetFileState (ErasePolarity, FfsFileHeader);\r
-\r
- switch (FileState) {\r
-\r
- case EFI_FILE_HEADER_INVALID:\r
- FileOffset += sizeof(EFI_FFS_FILE_HEADER);\r
- FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + sizeof(EFI_FFS_FILE_HEADER));\r
- break;\r
- \r
- case EFI_FILE_DATA_VALID:\r
- case EFI_FILE_MARKED_FOR_UPDATE:\r
- if (CalculateHeaderChecksum (FfsFileHeader) == 0) {\r
- FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;\r
- FileOccupiedSize = GETOCCUPIEDSIZE(FileLength, 8);\r
- if (Flag) {\r
- if ((FfsFileHeader->Type == EFI_FV_FILETYPE_PEIM) || \r
- (FfsFileHeader->Type == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER)) { \r
- \r
- *FileHeader = FfsFileHeader;\r
- \r
- \r
- return EFI_SUCCESS;\r
- }\r
- } else { \r
- if ((SearchType == FfsFileHeader->Type) || \r
- (SearchType == EFI_FV_FILETYPE_ALL)) { \r
- \r
- *FileHeader = FfsFileHeader;\r
- \r
- \r
- return EFI_SUCCESS;\r
- }\r
- }\r
-\r
- FileOffset += FileOccupiedSize; \r
- FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);\r
- } else {\r
- ASSERT (FALSE);\r
- return EFI_NOT_FOUND;\r
- }\r
- break;\r
- \r
- case EFI_FILE_DELETED:\r
- FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;\r
- FileOccupiedSize = GETOCCUPIEDSIZE(FileLength, 8);\r
- FileOffset += FileOccupiedSize;\r
- FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);\r
- break;\r
-\r
- default:\r
- return EFI_NOT_FOUND;\r
-\r
- } \r
- }\r
-\r
- return EFI_NOT_FOUND; \r
-}\r
-\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PeiFfsFindSectionData (\r
- IN EFI_PEI_SERVICES **PeiServices,\r
- IN EFI_SECTION_TYPE SectionType,\r
- IN EFI_FFS_FILE_HEADER *FfsFileHeader,\r
- IN OUT VOID **SectionData\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Given the input file pointer, search for the next matching section in the\r
- FFS volume.\r
-\r
-Arguments:\r
- PeiServices - Pointer to the PEI Core Services Table.\r
- SearchType - Filter to find only sections of this type.\r
- FfsFileHeader - Pointer to the current file to search.\r
- SectionData - Pointer to the Section matching SectionType in FfsFileHeader.\r
- - NULL if section not found\r
-\r
-Returns:\r
- EFI_NOT_FOUND - No files matching the search criteria were found\r
- EFI_SUCCESS\r
-\r
---*/\r
-{\r
- UINT32 FileSize;\r
- EFI_COMMON_SECTION_HEADER *Section;\r
- UINT32 SectionLength;\r
- UINT32 ParsedLength;\r
- \r
-\r
- //\r
- // Size is 24 bits wide so mask upper 8 bits. \r
- // Does not include FfsFileHeader header size\r
- // FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned.\r
- //\r
- Section = (EFI_COMMON_SECTION_HEADER *)(FfsFileHeader + 1);\r
- FileSize = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;\r
- FileSize -= sizeof(EFI_FFS_FILE_HEADER);\r
- \r
- *SectionData = NULL;\r
- ParsedLength = 0;\r
- while (ParsedLength < FileSize) {\r
- if (Section->Type == SectionType) {\r
- *SectionData = (VOID *)(Section + 1);\r
-\r
-\r
- return EFI_SUCCESS;\r
- }\r
- //\r
- // Size is 24 bits wide so mask upper 8 bits. \r
- // SectionLength is adjusted it is 4 byte aligned.\r
- // Go to the next section\r
- //\r
- SectionLength = *(UINT32 *)Section->Size & 0x00FFFFFF;\r
- SectionLength = GETOCCUPIEDSIZE (SectionLength, 4);\r
- ASSERT (SectionLength != 0);\r
- ParsedLength += SectionLength;\r
- Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength);\r
- }\r
- \r
- return EFI_NOT_FOUND;\r
- \r
-}\r
-\r
-\r
-EFI_STATUS\r
-FindNextPeim (\r
- IN EFI_PEI_SERVICES **PeiServices,\r
- IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader,\r
- IN OUT EFI_FFS_FILE_HEADER **PeimFileHeader\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Given the input file pointer, search for the next matching file in the\r
- FFS volume. The search starts from FileHeader inside\r
- the Firmware Volume defined by FwVolHeader.\r
-\r
-Arguments:\r
- PeiServices - Pointer to the PEI Core Services Table.\r
-\r
- FwVolHeader - Pointer to the FV header of the volume to search.\r
- This parameter must point to a valid FFS volume.\r
- \r
- PeimFileHeader - Pointer to the current file from which to begin searching.\r
- This pointer will be updated upon return to reflect the file found.\r
-\r
-Returns:\r
- EFI_NOT_FOUND - No files matching the search criteria were found\r
- EFI_SUCCESS\r
-\r
---*/\r
-{\r
- return PeiFfsFindNextFileEx ( \r
- 0,\r
- FwVolHeader,\r
- PeimFileHeader,\r
- TRUE\r
- );\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PeiFfsFindNextFile (\r
- IN EFI_PEI_SERVICES **PeiServices,\r
- IN EFI_FV_FILETYPE SearchType,\r
- IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader,\r
- IN OUT EFI_FFS_FILE_HEADER **FileHeader\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Given the input file pointer, search for the next matching file in the\r
- FFS volume as defined by SearchType. The search starts from FileHeader inside\r
- the Firmware Volume defined by FwVolHeader.\r
-\r
-Arguments:\r
- PeiServices - Pointer to the PEI Core Services Table.\r
- \r
- SearchType - Filter to find only files of this type.\r
- Type EFI_FV_FILETYPE_ALL causes no filtering to be done.\r
- \r
- FwVolHeader - Pointer to the FV header of the volume to search.\r
- This parameter must point to a valid FFS volume.\r
- \r
- FileHeader - Pointer to the current file from which to begin searching.\r
- This pointer will be updated upon return to reflect the file found.\r
- \r
-Returns:\r
- EFI_NOT_FOUND - No files matching the search criteria were found\r
- EFI_SUCCESS\r
-\r
---*/\r
-{\r
- return PeiFfsFindNextFileEx ( \r
- SearchType,\r
- FwVolHeader,\r
- FileHeader,\r
- FALSE\r
- );\r
-}\r
-\r
-EFI_STATUS \r
-EFIAPI\r
-PeiFvFindNextVolume (\r
- IN EFI_PEI_SERVICES **PeiServices,\r
- IN UINTN Instance,\r
- IN OUT EFI_FIRMWARE_VOLUME_HEADER **FwVolHeader\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Return the BFV location\r
-\r
- BugBug -- Move this to the location of this code to where the\r
- other FV and FFS support code lives.\r
- Also, update to use FindFV for instances #'s >= 1.\r
-\r
-Arguments:\r
-\r
- PeiServices - The PEI core services table.\r
- Instance - Instance of FV to find\r
- FwVolHeader - Pointer to contain the data to return\r
-\r
-Returns:\r
- Pointer to the Firmware Volume instance requested\r
-\r
- EFI_INVALID_PARAMETER - FwVolHeader is NULL\r
- \r
- EFI_SUCCESS - Firmware volume instance successfully found.\r
-\r
---*/\r
-{\r
- PEI_CORE_INSTANCE *PrivateData;\r
- EFI_STATUS Status;\r
- EFI_PEI_FIND_FV_PPI *FindFvPpi;\r
- UINT8 LocalInstance;\r
-\r
-\r
- LocalInstance = (UINT8) Instance;\r
-\r
- Status = EFI_SUCCESS;\r
- PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);\r
-\r
- if (FwVolHeader == NULL) {\r
-\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (Instance == 0) {\r
- *FwVolHeader = PrivateData->DispatchData.BootFvAddress;\r
-\r
-\r
- return Status;\r
- } else {\r
- //\r
- // Locate all instances of FindFV\r
- // Alternately, could use FV HOBs, but the PPI is cleaner\r
- //\r
- Status = PeiServicesLocatePpi (\r
- &gEfiFindFvPpiGuid,\r
- 0,\r
- NULL,\r
- (VOID **)&FindFvPpi\r
- );\r
-\r
- if (Status != EFI_SUCCESS) {\r
- Status = EFI_NOT_FOUND;\r
- } else {\r
- Status = FindFvPpi->FindFv (\r
- FindFvPpi,\r
- PeiServices,\r
- &LocalInstance,\r
- FwVolHeader\r
- ); \r
-\r
- }\r
- }\r
- return Status;\r
-}\r