+++ /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
- FwVol.c\r
-\r
-Abstract:\r
- A simple FV stack so the SEC can extract the SEC Core from an\r
- FV.\r
-\r
---*/\r
-\r
-#include "SecMain.h"\r
-\r
-#define GET_OCCUPIED_SIZE(ActualSize, Alignment) \\r
- (ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1))\r
-\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
- Returns the highest bit set of the State field\r
-\r
-Arguments:\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
-UINT8\r
-CalculateHeaderChecksum (\r
- IN EFI_FFS_FILE_HEADER *FileHeader\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Calculates the checksum of the header of a file.\r
-\r
-Arguments:\r
- FileHeader - Pointer to FFS File Header.\r
-\r
-Returns:\r
- Checksum of the header.\r
- \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
- // 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
-EFI_STATUS\r
-SecFfsFindNextFile (\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
- 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\r
- found.\r
-\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
- FvLength = FwVolHeader->FvLength;\r
- if (FwVolHeader->Attributes & EFI_FVB_ERASE_POLARITY) {\r
- ErasePolarity = 1;\r
- } else {\r
- ErasePolarity = 0;\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 = GET_OCCUPIED_SIZE (FileLength, 8);\r
- FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) *FileHeader + FileOccupiedSize);\r
- }\r
-\r
- FileOffset = (UINT32) ((UINT8 *) FfsFileHeader - (UINT8 *) FwVolHeader);\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 = GET_OCCUPIED_SIZE (FileLength, 8);\r
-\r
- if ((SearchType == FfsFileHeader->Type) || (SearchType == EFI_FV_FILETYPE_ALL)) {\r
-\r
- *FileHeader = FfsFileHeader;\r
-\r
- return EFI_SUCCESS;\r
- }\r
-\r
- FileOffset += FileOccupiedSize;\r
- FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsFileHeader + FileOccupiedSize);\r
- } else {\r
- return EFI_NOT_FOUND;\r
- }\r
- break;\r
-\r
- case EFI_FILE_DELETED:\r
- FileLength = *(UINT32 *) (FfsFileHeader->Size) & 0x00FFFFFF;\r
- FileOccupiedSize = GET_OCCUPIED_SIZE (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
-EFI_STATUS\r
-SecFfsFindSectionData (\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
- 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
- // 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
- 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 = GET_OCCUPIED_SIZE (SectionLength, 4);\r
-\r
- ParsedLength += SectionLength;\r
- Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + SectionLength);\r
- }\r
-\r
- return EFI_NOT_FOUND;\r
-}\r
-\r
-EFI_STATUS\r
-SecFfsFindPeiCore (\r
- IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader,\r
- OUT VOID **Pe32Data\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Given the pointer to the Firmware Volume Header find the SEC\r
- core and return it's PE32 image.\r
-\r
-Arguments:\r
- FwVolHeader - Pointer to memory mapped FV\r
- Pe32Data - Pointer to SEC PE32 iamge.\r
- \r
-Returns: \r
- EFI_SUCCESS - Pe32Data is valid\r
- other - Failure\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_FFS_FILE_HEADER *FileHeader;\r
- EFI_FV_FILETYPE SearchType;\r
-\r
- SearchType = EFI_FV_FILETYPE_PEI_CORE;\r
- FileHeader = NULL;\r
- do {\r
- Status = SecFfsFindNextFile (SearchType, FwVolHeader, &FileHeader);\r
- if (!EFI_ERROR (Status)) {\r
- Status = SecFfsFindSectionData (EFI_SECTION_PE32, FileHeader, Pe32Data);\r
- return Status;\r
- }\r
- } while (!EFI_ERROR (Status));\r
-\r
- return Status;\r
-}\r