EDK2 doxygen online documents - Firmware Encoding Index 1
EDK2 doxygen online documents - Firmware Encoding Index

EmulatorPkg/Library/SecPeiServicesLib/FwVol.c

Go to the documentation of this file.
00001 /*++ @file
00002   A simple FV stack so the SEC can extract the SEC Core from an
00003   FV.
00004 
00005 Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
00006 This program and the accompanying materials
00007 are licensed and made available under the terms and conditions of the BSD License
00008 which accompanies this distribution.  The full text of the license may be found at
00009 http://opensource.org/licenses/bsd-license.php
00010 
00011 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
00012 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
00013 
00014 **/
00015 
00016 #include <PiPei.h>
00017 
00018 
00019 #define GET_OCCUPIED_SIZE(ActualSize, Alignment) \
00020   (ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1))
00021 
00022 EFI_FFS_FILE_STATE
00023 GetFileState (
00024   IN UINT8                ErasePolarity,
00025   IN EFI_FFS_FILE_HEADER  *FfsHeader
00026   )
00027 /*++
00028 
00029 Routine Description:
00030   Returns the highest bit set of the State field
00031 
00032 Arguments:
00033   ErasePolarity   - Erase Polarity  as defined by EFI_FVB2_ERASE_POLARITY
00034                     in the Attributes field.
00035   FfsHeader       - Pointer to FFS File Header.
00036 
00037 Returns:
00038   Returns the highest bit in the State field
00039 
00040 **/
00041 {
00042   EFI_FFS_FILE_STATE  FileState;
00043   EFI_FFS_FILE_STATE  HighestBit;
00044 
00045   FileState = FfsHeader->State;
00046 
00047   if (ErasePolarity != 0) {
00048     FileState = (EFI_FFS_FILE_STATE)~FileState;
00049   }
00050 
00051   HighestBit = 0x80;
00052   while (HighestBit != 0 && (HighestBit & FileState) == 0) {
00053     HighestBit >>= 1;
00054   }
00055 
00056   return HighestBit;
00057 }
00058 
00059 UINT8
00060 CalculateHeaderChecksum (
00061   IN EFI_FFS_FILE_HEADER  *FileHeader
00062   )
00063 /*++
00064 
00065 Routine Description:
00066   Calculates the checksum of the header of a file.
00067 
00068 Arguments:
00069   FileHeader       - Pointer to FFS File Header.
00070 
00071 Returns:
00072   Checksum of the header.
00073 
00074 **/
00075 {
00076   UINT8 *ptr;
00077   UINTN Index;
00078   UINT8 Sum;
00079 
00080   Sum = 0;
00081   ptr = (UINT8 *) FileHeader;
00082 
00083   for (Index = 0; Index < sizeof (EFI_FFS_FILE_HEADER) - 3; Index += 4) {
00084     Sum = (UINT8) (Sum + ptr[Index]);
00085     Sum = (UINT8) (Sum + ptr[Index + 1]);
00086     Sum = (UINT8) (Sum + ptr[Index + 2]);
00087     Sum = (UINT8) (Sum + ptr[Index + 3]);
00088   }
00089 
00090   for (; Index < sizeof (EFI_FFS_FILE_HEADER); Index++) {
00091     Sum = (UINT8) (Sum + ptr[Index]);
00092   }
00093   //
00094   // State field (since this indicates the different state of file).
00095   //
00096   Sum = (UINT8) (Sum - FileHeader->State);
00097   //
00098   // Checksum field of the file is not part of the header checksum.
00099   //
00100   Sum = (UINT8) (Sum - FileHeader->IntegrityCheck.Checksum.File);
00101 
00102   return Sum;
00103 }
00104 
00105 EFI_STATUS
00106 SecFfsFindNextFile (
00107   IN EFI_FV_FILETYPE             SearchType,
00108   IN EFI_PEI_FV_HANDLE           FvHandle,
00109   IN OUT EFI_PEI_FILE_HANDLE     *FileHandle
00110   )
00111 /*++
00112 
00113 Routine Description:
00114     Given the input file pointer, search for the next matching file in the
00115     FFS volume as defined by SearchType. The search starts from FileHeader inside
00116     the Firmware Volume defined by FwVolHeader.
00117 
00118 Arguments:
00119     SearchType - Filter to find only files of this type.
00120                  Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
00121     FwVolHeader - Pointer to the FV header of the volume to search.
00122                   This parameter must point to a valid FFS volume.
00123     FileHeader  - Pointer to the current file from which to begin searching.
00124                   This pointer will be updated upon return to reflect the file
00125                   found.
00126 
00127 Returns:
00128     EFI_NOT_FOUND - No files matching the search criteria were found
00129     EFI_SUCCESS
00130 
00131 **/
00132 {
00133   EFI_FFS_FILE_HEADER *FfsFileHeader;
00134   UINT32              FileLength;
00135   UINT32              FileOccupiedSize;
00136   UINT32              FileOffset;
00137   UINT64              FvLength;
00138   UINT8               ErasePolarity;
00139   UINT8               FileState;
00140   EFI_FIRMWARE_VOLUME_HEADER  *FwVolHeader;
00141   EFI_FFS_FILE_HEADER         **FileHeader;
00142 
00143   //
00144   // Convert the handle of FV to FV header for memory-mapped firmware volume
00145   //
00146   FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) FvHandle;
00147   FileHeader  = (EFI_FFS_FILE_HEADER **)FileHandle;
00148 
00149   FvLength = FwVolHeader->FvLength;
00150   if (FwVolHeader->Attributes & EFI_FVB2_ERASE_POLARITY) {
00151     ErasePolarity = 1;
00152   } else {
00153     ErasePolarity = 0;
00154   }
00155   //
00156   // If FileHeader is not specified (NULL) start with the first file in the
00157   // firmware volume.  Otherwise, start from the FileHeader.
00158   //
00159   if (*FileHeader == NULL) {
00160     FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FwVolHeader + FwVolHeader->HeaderLength);
00161   } else {
00162     //
00163     // Length is 24 bits wide so mask upper 8 bits
00164     // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned.
00165     //
00166     FileLength        = *(UINT32 *) (*FileHeader)->Size & 0x00FFFFFF;
00167     FileOccupiedSize  = GET_OCCUPIED_SIZE (FileLength, 8);
00168     FfsFileHeader     = (EFI_FFS_FILE_HEADER *) ((UINT8 *) *FileHeader + FileOccupiedSize);
00169   }
00170 
00171   FileOffset = (UINT32) ((UINT8 *) FfsFileHeader - (UINT8 *) FwVolHeader);
00172 
00173   while (FileOffset < (FvLength - sizeof (EFI_FFS_FILE_HEADER))) {
00174     //
00175     // Get FileState which is the highest bit of the State
00176     //
00177     FileState = GetFileState (ErasePolarity, FfsFileHeader);
00178 
00179     switch (FileState) {
00180 
00181     case EFI_FILE_HEADER_INVALID:
00182       FileOffset += sizeof (EFI_FFS_FILE_HEADER);
00183       FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER));
00184       break;
00185 
00186     case EFI_FILE_DATA_VALID:
00187     case EFI_FILE_MARKED_FOR_UPDATE:
00188       if (CalculateHeaderChecksum (FfsFileHeader) == 0) {
00189         FileLength        = *(UINT32 *) (FfsFileHeader->Size) & 0x00FFFFFF;
00190         FileOccupiedSize  = GET_OCCUPIED_SIZE (FileLength, 8);
00191 
00192         if ((SearchType == FfsFileHeader->Type) || (SearchType == EFI_FV_FILETYPE_ALL)) {
00193 
00194           *FileHeader = FfsFileHeader;
00195 
00196           return EFI_SUCCESS;
00197         }
00198 
00199         FileOffset += FileOccupiedSize;
00200         FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsFileHeader + FileOccupiedSize);
00201       } else {
00202         return EFI_NOT_FOUND;
00203       }
00204       break;
00205 
00206     case EFI_FILE_DELETED:
00207       FileLength        = *(UINT32 *) (FfsFileHeader->Size) & 0x00FFFFFF;
00208       FileOccupiedSize  = GET_OCCUPIED_SIZE (FileLength, 8);
00209       FileOffset += FileOccupiedSize;
00210       FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsFileHeader + FileOccupiedSize);
00211       break;
00212 
00213     default:
00214       return EFI_NOT_FOUND;
00215 
00216     }
00217   }
00218 
00219   return EFI_NOT_FOUND;
00220 }
00221 
00222 EFI_STATUS
00223 SecFfsFindSectionData (
00224   IN EFI_SECTION_TYPE      SectionType,
00225   IN EFI_FFS_FILE_HEADER   *FfsFileHeader,
00226   IN OUT VOID              **SectionData
00227   )
00228 /*++
00229 
00230 Routine Description:
00231     Given the input file pointer, search for the next matching section in the
00232     FFS volume.
00233 
00234 Arguments:
00235     SearchType    - Filter to find only sections of this type.
00236     FfsFileHeader - Pointer to the current file to search.
00237     SectionData   - Pointer to the Section matching SectionType in FfsFileHeader.
00238                      NULL if section not found
00239 
00240 Returns:
00241     EFI_NOT_FOUND - No files matching the search criteria were found
00242     EFI_SUCCESS
00243 
00244 **/
00245 {
00246   UINT32                    FileSize;
00247   EFI_COMMON_SECTION_HEADER *Section;
00248   UINT32                    SectionLength;
00249   UINT32                    ParsedLength;
00250 
00251   //
00252   // Size is 24 bits wide so mask upper 8 bits.
00253   //    Does not include FfsFileHeader header size
00254   // FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned.
00255   //
00256   Section   = (EFI_COMMON_SECTION_HEADER *) (FfsFileHeader + 1);
00257   FileSize  = *(UINT32 *) (FfsFileHeader->Size) & 0x00FFFFFF;
00258   FileSize -= sizeof (EFI_FFS_FILE_HEADER);
00259 
00260   *SectionData  = NULL;
00261   ParsedLength  = 0;
00262   while (ParsedLength < FileSize) {
00263     if (Section->Type == SectionType) {
00264       *SectionData = (VOID *) (Section + 1);
00265       return EFI_SUCCESS;
00266     }
00267     //
00268     // Size is 24 bits wide so mask upper 8 bits.
00269     // SectionLength is adjusted it is 4 byte aligned.
00270     // Go to the next section
00271     //
00272     SectionLength = *(UINT32 *) Section->Size & 0x00FFFFFF;
00273     SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);
00274 
00275     ParsedLength += SectionLength;
00276     Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + SectionLength);
00277   }
00278 
00279   return EFI_NOT_FOUND;
00280 }
00281 
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Defines