diff --git a/IntelFrameworkModulePkg/Universal/FirmwareVolume/FwVolDxe/Ffs.c b/IntelFrameworkModulePkg/Universal/FirmwareVolume/FwVolDxe/Ffs.c index 1e3c839e27..12508b4335 100644 --- a/IntelFrameworkModulePkg/Universal/FirmwareVolume/FwVolDxe/Ffs.c +++ b/IntelFrameworkModulePkg/Universal/FirmwareVolume/FwVolDxe/Ffs.c @@ -239,7 +239,11 @@ VerifyHeaderChecksum ( { UINT8 HeaderChecksum; - HeaderChecksum = CalculateSum8 ((UINT8 *) FfsHeader, sizeof (EFI_FFS_FILE_HEADER)); + if (IS_FFS_FILE2 (FfsHeader)) { + HeaderChecksum = CalculateSum8 ((UINT8 *) FfsHeader, sizeof (EFI_FFS_FILE_HEADER2)); + } else { + HeaderChecksum = CalculateSum8 ((UINT8 *) FfsHeader, sizeof (EFI_FFS_FILE_HEADER)); + } HeaderChecksum = (UINT8) (HeaderChecksum - FfsHeader->State - FfsHeader->IntegrityCheck.Checksum.File); if (HeaderChecksum == 0) { @@ -265,18 +269,19 @@ VerifyFileChecksum ( { UINT8 FileChecksum; EFI_FV_FILE_ATTRIBUTES Attributes; - UINT32 FileSize; Attributes = FfsHeader->Attributes; if ((Attributes & FFS_ATTRIB_CHECKSUM) != 0) { - FileSize = *(UINT32 *) FfsHeader->Size & 0x00FFFFFF; - // // Check checksum of FFS data // - FileChecksum = CalculateSum8 ((UINT8 *) FfsHeader + sizeof (EFI_FFS_FILE_HEADER), FileSize - sizeof (EFI_FFS_FILE_HEADER)); + if (IS_FFS_FILE2 (FfsHeader)) { + FileChecksum = CalculateSum8 ((UINT8 *) FfsHeader + sizeof (EFI_FFS_FILE_HEADER2), FFS_FILE2_SIZE (FfsHeader) - sizeof (EFI_FFS_FILE_HEADER2)); + } else { + FileChecksum = CalculateSum8 ((UINT8 *) FfsHeader + sizeof (EFI_FFS_FILE_HEADER), FFS_FILE_SIZE (FfsHeader) - sizeof (EFI_FFS_FILE_HEADER)); + } FileChecksum = (UINT8) (FileChecksum + FfsHeader->IntegrityCheck.Checksum.File); if (FileChecksum == 0) { @@ -388,10 +393,18 @@ GetNextPossibleFileHeader ( // // Skip this header // - return (EFI_PHYSICAL_ADDRESS) (UINTN) FfsHeader + sizeof (EFI_FFS_FILE_HEADER); + if (IS_FFS_FILE2 (FfsHeader)) { + return (EFI_PHYSICAL_ADDRESS) (UINTN) FfsHeader + sizeof (EFI_FFS_FILE_HEADER2); + } else { + return (EFI_PHYSICAL_ADDRESS) (UINTN) FfsHeader + sizeof (EFI_FFS_FILE_HEADER); + } } - FileLength = *(UINT32 *) FfsHeader->Size & 0x00FFFFFF; + if (IS_FFS_FILE2 (FfsHeader)) { + FileLength = FFS_FILE2_SIZE (FfsHeader); + } else { + FileLength = FFS_FILE_SIZE (FfsHeader); + } // // Since FileLength is not multiple of 8, we need skip some bytes @@ -593,33 +606,3 @@ IsValidFFSFile ( return TRUE; } -/** - Locate the first file in FV. - - @param FvDevice Cached FV image. - @param FirstFile Points to the got first FFS file header. - - @retval EFI_NOT_FOUND No FFS file is found in FV. - @retval EFI_SUCCESS The first FFS file is got. - -**/ -EFI_STATUS -FvLocateFirstFile ( - IN FV_DEVICE *FvDevice, - OUT EFI_FFS_FILE_HEADER **FirstFile - ) -{ - FFS_FILE_LIST_ENTRY *TmpFileList; - LIST_ENTRY *Link; - - Link = FvDevice->FfsFileListHeader.ForwardLink; - - if (Link == &FvDevice->FfsFileListHeader) { - return EFI_NOT_FOUND; - } - - TmpFileList = (FFS_FILE_LIST_ENTRY *) Link; - *FirstFile = (EFI_FFS_FILE_HEADER *) TmpFileList->FfsHeader; - - return EFI_SUCCESS; -} diff --git a/IntelFrameworkModulePkg/Universal/FirmwareVolume/FwVolDxe/FwPadFile.c b/IntelFrameworkModulePkg/Universal/FirmwareVolume/FwVolDxe/FwPadFile.c index 14b8563143..8d53d879bd 100644 --- a/IntelFrameworkModulePkg/Universal/FirmwareVolume/FwVolDxe/FwPadFile.c +++ b/IntelFrameworkModulePkg/Universal/FirmwareVolume/FwVolDxe/FwPadFile.c @@ -27,17 +27,22 @@ SetPadFileChecksum ( IN EFI_FFS_FILE_HEADER *PadFileHeader ) { - UINT32 PadFileLength; - if ((PadFileHeader->Attributes & FFS_ATTRIB_CHECKSUM) != 0) { - PadFileLength = *(UINT32 *) PadFileHeader->Size & 0x00FFFFFF; + if (IS_FFS_FILE2 (PadFileHeader)) { + // + // Calculate checksum of Pad File Data + // + PadFileHeader->IntegrityCheck.Checksum.File = + CalculateCheckSum8 ((UINT8 *) PadFileHeader + sizeof (EFI_FFS_FILE_HEADER2), FFS_FILE2_SIZE (PadFileHeader) - sizeof (EFI_FFS_FILE_HEADER2)); - // - // Calculate checksum of Pad File Data - // - PadFileHeader->IntegrityCheck.Checksum.File = - CalculateCheckSum8 ((UINT8 *) PadFileHeader + sizeof (EFI_FFS_FILE_HEADER), PadFileLength - sizeof (EFI_FFS_FILE_HEADER)); + } else { + // + // Calculate checksum of Pad File Data + // + PadFileHeader->IntegrityCheck.Checksum.File = + CalculateCheckSum8 ((UINT8 *) PadFileHeader + sizeof (EFI_FFS_FILE_HEADER), FFS_FILE_SIZE (PadFileHeader) - sizeof (EFI_FFS_FILE_HEADER)); + } } else { @@ -76,8 +81,17 @@ FvCreatePadFileInFreeSpace ( UINTN StateOffset; UINT8 *StartPos; FFS_FILE_LIST_ENTRY *FfsFileEntry; + UINTN HeaderSize; + UINTN FileSize; - if (FreeSpaceEntry->Length < Size + sizeof (EFI_FFS_FILE_HEADER)) { + HeaderSize = sizeof (EFI_FFS_FILE_HEADER); + FileSize = Size + HeaderSize; + if (FileSize > 0x00FFFFFF) { + HeaderSize = sizeof (EFI_FFS_FILE_HEADER2); + FileSize = Size + HeaderSize; + } + + if (FreeSpaceEntry->Length < FileSize) { return EFI_OUT_OF_RESOURCES; } @@ -93,7 +107,7 @@ FvCreatePadFileInFreeSpace ( if (!IsBufferErased ( FvDevice->ErasePolarity, StartPos, - Size + sizeof (EFI_FFS_FILE_HEADER) + FileSize )) { return EFI_DEVICE_ERROR; } @@ -122,8 +136,8 @@ FvCreatePadFileInFreeSpace ( // // Update Free Space Entry, since header is allocated // - FreeSpaceEntry->Length -= sizeof (EFI_FFS_FILE_HEADER); - FreeSpaceEntry->StartingAddress += sizeof (EFI_FFS_FILE_HEADER); + FreeSpaceEntry->Length -= HeaderSize; + FreeSpaceEntry->StartingAddress += HeaderSize; // // Fill File Name Guid, here we assign a NULL-GUID to Pad files @@ -135,15 +149,21 @@ FvCreatePadFileInFreeSpace ( // PadFileHeader->Type = EFI_FV_FILETYPE_FFS_PAD; PadFileHeader->Attributes = 0; - *(UINT32 *) PadFileHeader->Size &= 0xFF000000; - *(UINT32 *) PadFileHeader->Size |= (Size + sizeof (EFI_FFS_FILE_HEADER)); + if ((FileSize) > 0x00FFFFFF) { + ((EFI_FFS_FILE_HEADER2 *) PadFileHeader)->ExtendedSize = (UINT32) FileSize; + *(UINT32 *) PadFileHeader->Size &= 0xFF000000; + PadFileHeader->Attributes |= FFS_ATTRIB_LARGE_FILE; + } else { + *(UINT32 *) PadFileHeader->Size &= 0xFF000000; + *(UINT32 *) PadFileHeader->Size |= FileSize; + } SetHeaderChecksum (PadFileHeader); SetPadFileChecksum (PadFileHeader); Offset = (UINTN) (StartPos - FvDevice->CachedFv); - NumBytesWritten = sizeof (EFI_FFS_FILE_HEADER); + NumBytesWritten = HeaderSize; Status = FvcWrite ( FvDevice, Offset, @@ -220,8 +240,14 @@ FvFillPadFile ( // PadFileHeader->Type = EFI_FV_FILETYPE_FFS_PAD; PadFileHeader->Attributes = 0; - *(UINT32 *) PadFileHeader->Size &= 0xFF000000; - *(UINT32 *) PadFileHeader->Size |= PadFileLength; + if (PadFileLength > 0x00FFFFFF) { + ((EFI_FFS_FILE_HEADER2 *) PadFileHeader)->ExtendedSize = (UINT32) PadFileLength; + *(UINT32 *) PadFileHeader->Size &= 0xFF000000; + PadFileHeader->Attributes |= FFS_ATTRIB_LARGE_FILE; + } else { + *(UINT32 *) PadFileHeader->Size &= 0xFF000000; + *(UINT32 *) PadFileHeader->Size |= PadFileLength; + } SetHeaderChecksum (PadFileHeader); SetPadFileChecksum (PadFileHeader); @@ -286,8 +312,14 @@ FvFillFfsFile ( TmpFileHeader->Attributes = TmpFileAttribute; - *(UINT32 *) TmpFileHeader->Size &= 0xFF000000; - *(UINT32 *) TmpFileHeader->Size |= ActualFileSize; + if (ActualFileSize > 0x00FFFFFF) { + ((EFI_FFS_FILE_HEADER2 *) FileHeader)->ExtendedSize = (UINT32) ActualFileSize; + *(UINT32 *) FileHeader->Size &= 0xFF000000; + FileHeader->Attributes |= FFS_ATTRIB_LARGE_FILE; + } else { + *(UINT32 *) FileHeader->Size &= 0xFF000000; + *(UINT32 *) FileHeader->Size |= ActualFileSize; + } SetHeaderChecksum (TmpFileHeader); SetFileChecksum (TmpFileHeader, ActualFileSize); @@ -319,12 +351,14 @@ FvAdjustFfsFile ( IN UINTN ExtraLength ) { - UINTN FileLength; UINT8 *Ptr; UINT8 PadingByte; - FileLength = *(UINT32 *) FileHeader->Size & 0x00FFFFFF; - Ptr = (UINT8 *) FileHeader + FileLength; + if (IS_FFS_FILE2 (FileHeader)) { + Ptr = (UINT8 *) FileHeader + FFS_FILE2_SIZE (FileHeader); + } else { + Ptr = (UINT8 *) FileHeader + FFS_FILE_SIZE (FileHeader); + } if (ErasePolarity == 0) { PadingByte = 0; @@ -461,11 +495,15 @@ FvCreateNewFileInsidePadFile ( // InitializeListHead (&NewFileList); - PadAreaLength = (*(UINT32 *) OldPadFileHeader->Size & 0x00FFFFFF) - sizeof (EFI_FFS_FILE_HEADER); + if (IS_FFS_FILE2 (OldPadFileHeader)) { + PadAreaLength = FFS_FILE2_SIZE (OldPadFileHeader) - sizeof (EFI_FFS_FILE_HEADER); + PadFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) OldPadFileHeader + sizeof (EFI_FFS_FILE_HEADER2)); + } else { + PadAreaLength = FFS_FILE_SIZE (OldPadFileHeader) - sizeof (EFI_FFS_FILE_HEADER); + PadFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) OldPadFileHeader + sizeof (EFI_FFS_FILE_HEADER)); + } - PadFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) OldPadFileHeader + sizeof (EFI_FFS_FILE_HEADER)); - - if (RequiredAlignment != 8) { + if (PadSize != 0) { // // Insert a PAD file before to achieve required alignment // @@ -488,6 +526,7 @@ FvCreateNewFileInsidePadFile ( FileAttributes ); if (EFI_ERROR (Status)) { + FreeFileList (&NewFileList); return Status; } @@ -527,7 +566,11 @@ FvCreateNewFileInsidePadFile ( // // Start writing to FV // - StartPos = (UINT8 *) OldPadFileHeader + sizeof (EFI_FFS_FILE_HEADER); + if (IS_FFS_FILE2 (OldPadFileHeader)) { + StartPos = (UINT8 *) OldPadFileHeader + sizeof (EFI_FFS_FILE_HEADER2); + } else { + StartPos = (UINT8 *) OldPadFileHeader + sizeof (EFI_FFS_FILE_HEADER); + } Offset = (UINTN) (StartPos - FvDevice->CachedFv); @@ -540,6 +583,7 @@ FvCreateNewFileInsidePadFile ( ); if (EFI_ERROR (Status)) { FreeFileList (&NewFileList); + FvDevice->CurrentFfsFile = NULL; return Status; } @@ -562,6 +606,8 @@ FvCreateNewFileInsidePadFile ( ); if (EFI_ERROR (Status)) { SetFileState (EFI_FILE_HEADER_INVALID, OldPadFileHeader); + FreeFileList (&NewFileList); + FvDevice->CurrentFfsFile = NULL; return Status; } @@ -657,7 +703,11 @@ FvCreateMultipleFilesInsidePadFile ( NewFileListEntry = NULL; OldPadFileHeader = (EFI_FFS_FILE_HEADER *) PadFileEntry->FfsHeader; - PadAreaLength = (*(UINT32 *) OldPadFileHeader->Size & 0x00FFFFFF) - sizeof (EFI_FFS_FILE_HEADER); + if (IS_FFS_FILE2 (OldPadFileHeader)) { + PadAreaLength = FFS_FILE2_SIZE (OldPadFileHeader) - sizeof (EFI_FFS_FILE_HEADER2); + } else { + PadAreaLength = FFS_FILE_SIZE (OldPadFileHeader) - sizeof (EFI_FFS_FILE_HEADER); + } Status = UpdateHeaderBit ( FvDevice, @@ -671,7 +721,11 @@ FvCreateMultipleFilesInsidePadFile ( // Update PAD area // TotalSize = 0; - PadFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) OldPadFileHeader + sizeof (EFI_FFS_FILE_HEADER)); + if (IS_FFS_FILE2 (OldPadFileHeader)) { + PadFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) OldPadFileHeader + sizeof (EFI_FFS_FILE_HEADER2)); + } else { + PadFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) OldPadFileHeader + sizeof (EFI_FFS_FILE_HEADER)); + } FileHeader = PadFileHeader; for (Index = 0; Index < NumOfFiles; Index++) { @@ -679,6 +733,7 @@ FvCreateMultipleFilesInsidePadFile ( FvFillPadFile (PadFileHeader, PadSize[Index]); NewFileListEntry = AllocatePool (sizeof (FFS_FILE_LIST_ENTRY)); if (NewFileListEntry == NULL) { + FreeFileList (&NewFileList); return EFI_OUT_OF_RESOURCES; } @@ -697,6 +752,7 @@ FvCreateMultipleFilesInsidePadFile ( FileData[Index].FileAttributes ); if (EFI_ERROR (Status)) { + FreeFileList (&NewFileList); return Status; } @@ -729,6 +785,7 @@ FvCreateMultipleFilesInsidePadFile ( NewFileListEntry = AllocatePool (sizeof (FFS_FILE_LIST_ENTRY)); if (NewFileListEntry == NULL) { FreeFileList (&NewFileList); + FvDevice->CurrentFfsFile = NULL; return EFI_OUT_OF_RESOURCES; } @@ -749,7 +806,11 @@ FvCreateMultipleFilesInsidePadFile ( // // Start writing to FV // - StartPos = (UINT8 *) OldPadFileHeader + sizeof (EFI_FFS_FILE_HEADER); + if (IS_FFS_FILE2 (OldPadFileHeader)) { + StartPos = (UINT8 *) OldPadFileHeader + sizeof (EFI_FFS_FILE_HEADER2); + } else { + StartPos = (UINT8 *) OldPadFileHeader + sizeof (EFI_FFS_FILE_HEADER); + } Offset = (UINTN) (StartPos - FvDevice->CachedFv); @@ -762,6 +823,7 @@ FvCreateMultipleFilesInsidePadFile ( ); if (EFI_ERROR (Status)) { FreeFileList (&NewFileList); + FvDevice->CurrentFfsFile = NULL; return Status; } @@ -772,6 +834,7 @@ FvCreateMultipleFilesInsidePadFile ( ); if (EFI_ERROR (Status)) { FreeFileList (&NewFileList); + FvDevice->CurrentFfsFile = NULL; return Status; } @@ -795,6 +858,136 @@ FvCreateMultipleFilesInsidePadFile ( return EFI_SUCCESS; } +/** + Create multiple files within the Free Space. + + @param FvDevice Firmware Volume Device. + @param FreeSpaceEntry Indicating in which Free Space(Cache) the multiple files will be inserted. + @param NumOfFiles Total File number to be written. + @param BufferSize The array of buffer size of each FfsBuffer. + @param ActualFileSize The array of actual file size. + @param PadSize The array of leading pad file size for each FFS File + @param FfsBuffer The array of Ffs Buffer pointer. + @param FileData The array of EFI_FV_WRITE_FILE_DATA structure, + used to get name, attributes, type, etc. + + @retval EFI_SUCCESS Add the input multiple files into PAD file area. + @retval EFI_OUT_OF_RESOURCES No enough memory is allocated. + @retval other error Files can't be added into PAD file area. + +**/ +EFI_STATUS +FvCreateMultipleFilesInsideFreeSpace ( + IN FV_DEVICE *FvDevice, + IN FREE_SPACE_ENTRY *FreeSpaceEntry, + IN UINTN NumOfFiles, + IN UINTN *BufferSize, + IN UINTN *ActualFileSize, + IN UINTN *PadSize, + IN UINT8 **FfsBuffer, + IN EFI_FV_WRITE_FILE_DATA *FileData + ) +{ + EFI_STATUS Status; + UINTN Index; + EFI_FFS_FILE_HEADER *PadFileHeader; + EFI_FFS_FILE_HEADER *FileHeader; + UINTN TotalSize; + LIST_ENTRY NewFileList; + FFS_FILE_LIST_ENTRY *NewFileListEntry; + UINTN Offset; + UINTN NumBytesWritten; + UINT8 *StartPos; + + InitializeListHead (&NewFileList); + + NewFileListEntry = NULL; + + TotalSize = 0; + StartPos = FreeSpaceEntry->StartingAddress; + PadFileHeader = (EFI_FFS_FILE_HEADER *) StartPos; + FileHeader = PadFileHeader; + + for (Index = 0; Index < NumOfFiles; Index++) { + if (PadSize[Index] != 0) { + FvFillPadFile (PadFileHeader, PadSize[Index]); + NewFileListEntry = AllocatePool (sizeof (FFS_FILE_LIST_ENTRY)); + if (NewFileListEntry == NULL) { + FreeFileList (&NewFileList); + return EFI_OUT_OF_RESOURCES; + } + + NewFileListEntry->FfsHeader = (UINT8 *) PadFileHeader; + InsertTailList (&NewFileList, &NewFileListEntry->Link); + } + + FileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) PadFileHeader + PadSize[Index]); + Status = FvFillFfsFile ( + FileHeader, + FfsBuffer[Index], + BufferSize[Index], + ActualFileSize[Index], + FileData[Index].NameGuid, + FileData[Index].Type, + FileData[Index].FileAttributes + ); + if (EFI_ERROR (Status)) { + FreeFileList (&NewFileList); + return Status; + } + + NewFileListEntry = AllocatePool (sizeof (FFS_FILE_LIST_ENTRY)); + if (NewFileListEntry == NULL) { + FreeFileList (&NewFileList); + return EFI_OUT_OF_RESOURCES; + } + + NewFileListEntry->FfsHeader = (UINT8 *) FileHeader; + InsertTailList (&NewFileList, &NewFileListEntry->Link); + + PadFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FileHeader + BufferSize[Index]); + TotalSize += PadSize[Index]; + TotalSize += BufferSize[Index]; + } + + if (FreeSpaceEntry->Length < TotalSize) { + FreeFileList (&NewFileList); + return EFI_OUT_OF_RESOURCES; + } + + FvDevice->CurrentFfsFile = NewFileListEntry; + + // + // Start writing to FV + // + Offset = (UINTN) (StartPos - FvDevice->CachedFv); + + NumBytesWritten = TotalSize; + Status = FvcWrite ( + FvDevice, + Offset, + &NumBytesWritten, + StartPos + ); + if (EFI_ERROR (Status)) { + FreeFileList (&NewFileList); + FvDevice->CurrentFfsFile = NULL; + return Status; + } + + FreeSpaceEntry->Length -= TotalSize; + FreeSpaceEntry->StartingAddress += TotalSize; + + NewFileListEntry = (FFS_FILE_LIST_ENTRY *) (NewFileList.ForwardLink); + + while (NewFileListEntry != (FFS_FILE_LIST_ENTRY *) &NewFileList) { + InsertTailList (&FvDevice->FfsFileListHeader, &NewFileListEntry->Link); + NewFileListEntry = (FFS_FILE_LIST_ENTRY *) (NewFileListEntry->Link.ForwardLink); + } + + return EFI_SUCCESS; +} + /** Write multiple files into FV in reliable method. @@ -838,6 +1031,7 @@ FvCreateMultipleFiles ( FFS_FILE_LIST_ENTRY *OldFfsFileEntry[MAX_FILES]; EFI_FFS_FILE_HEADER *OldFileHeader[MAX_FILES]; BOOLEAN IsCreateFile; + UINTN HeaderSize; // // To use this function, we must ensure that the NumOfFiles is great @@ -863,10 +1057,15 @@ FvCreateMultipleFiles ( // Adjust file size // for (Index1 = 0; Index1 < NumOfFiles; Index1++) { - ActualFileSize[Index1] = FileData[Index1].BufferSize + sizeof (EFI_FFS_FILE_HEADER); + HeaderSize = sizeof (EFI_FFS_FILE_HEADER); + ActualFileSize[Index1] = FileData[Index1].BufferSize + HeaderSize; + if (ActualFileSize[Index1] > 0x00FFFFFF) { + HeaderSize = sizeof (EFI_FFS_FILE_HEADER2); + ActualFileSize[Index1] = FileData[Index1].BufferSize + HeaderSize; + } BufferSize[Index1] = ActualFileSize[Index1]; - if (BufferSize[Index1] == sizeof (EFI_FFS_FILE_HEADER)) { + if (BufferSize[Index1] == HeaderSize) { // // clear file attributes, zero-length file does not have any attributes // @@ -883,18 +1082,18 @@ FvCreateMultipleFiles ( // Copy File Data into FileBuffer // CopyMem ( - FfsBuffer[Index1] + sizeof (EFI_FFS_FILE_HEADER), + FfsBuffer[Index1] + HeaderSize, FileData[Index1].Buffer, FileData[Index1].BufferSize ); if (FvDevice->ErasePolarity == 1) { - for (Index2 = 0; Index2 < sizeof (EFI_FFS_FILE_HEADER); Index2++) { + for (Index2 = 0; Index2 < HeaderSize; Index2++) { FfsBuffer[Index1][Index2] = (UINT8)~FfsBuffer[Index1][Index2]; } } - if ((FileData[Index1].FileAttributes & FFS_ATTRIB_DATA_ALIGNMENT) != 0) { + if ((FileData[Index1].FileAttributes & EFI_FV_FILE_ATTRIB_ALIGNMENT) != 0) { RequiredAlignment[Index1] = GetRequiredAlignment (FileData[Index1].FileAttributes); } // @@ -954,7 +1153,6 @@ FvCreateMultipleFiles ( if (Status == EFI_NOT_FOUND) { // // Try to find a free space that can hold these files - // and create a suitable PAD file in this free space // Status = FvSearchSuitableFreeSpace ( FvDevice, @@ -969,35 +1167,33 @@ FvCreateMultipleFiles ( FreeFfsBuffer (NumOfFiles, FfsBuffer); return EFI_OUT_OF_RESOURCES; } - // - // Create a PAD file in that space - // - Status = FvCreatePadFileInFreeSpace ( + Status = FvCreateMultipleFilesInsideFreeSpace ( FvDevice, FreeSpaceEntry, - TotalSizeNeeded, - &PadFileEntry + NumOfFiles, + BufferSize, + ActualFileSize, + PadSize, + FfsBuffer, + FileData ); - if (EFI_ERROR (Status)) { - FreeFfsBuffer (NumOfFiles, FfsBuffer); - return Status; - } + } else { + // + // Create multiple files inside such a pad file + // to achieve lock-step update + // + Status = FvCreateMultipleFilesInsidePadFile ( + FvDevice, + PadFileEntry, + NumOfFiles, + BufferSize, + ActualFileSize, + PadSize, + FfsBuffer, + FileData + ); } - // - // Create multiple files inside such a pad file - // to achieve lock-step update - // - Status = FvCreateMultipleFilesInsidePadFile ( - FvDevice, - PadFileEntry, - NumOfFiles, - BufferSize, - ActualFileSize, - PadSize, - FfsBuffer, - FileData - ); FreeFfsBuffer (NumOfFiles, FfsBuffer); diff --git a/IntelFrameworkModulePkg/Universal/FirmwareVolume/FwVolDxe/FwVol.c b/IntelFrameworkModulePkg/Universal/FirmwareVolume/FwVolDxe/FwVol.c index f453d5ec0a..a3e507afd0 100644 --- a/IntelFrameworkModulePkg/Universal/FirmwareVolume/FwVolDxe/FwVol.c +++ b/IntelFrameworkModulePkg/Universal/FirmwareVolume/FwVolDxe/FwVol.c @@ -4,7 +4,7 @@ Layers on top of Firmware Block protocol to produce a file abstraction of FV based files. - Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions @@ -206,7 +206,6 @@ FvCheck ( UINT8 *FreeStart; UINTN FreeSize; UINT8 ErasePolarity; - UINTN FileLength; EFI_FFS_FILE_STATE FileState; UINT8 *TopFvAddress; UINTN TestLength; @@ -230,6 +229,8 @@ FvCheck ( } ASSERT (FwVolHeader != NULL); + FvDevice->IsFfs3Fv = CompareGuid (&FwVolHeader->FileSystemGuid, &gEfiFirmwareFileSystem3Guid); + // // Double Check firmware volume header here // @@ -412,7 +413,14 @@ FvCheck ( (EFI_FFS_FILE_HEADER *) Ptr ); if ((FileState == EFI_FILE_HEADER_INVALID) || (FileState == EFI_FILE_HEADER_CONSTRUCTION)) { - Ptr += sizeof (EFI_FFS_FILE_HEADER); + if (IS_FFS_FILE2 (Ptr)) { + if (!FvDevice->IsFfs3Fv) { + DEBUG ((EFI_D_ERROR, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &((EFI_FFS_FILE_HEADER *) Ptr)->Name)); + } + Ptr = Ptr + sizeof (EFI_FFS_FILE_HEADER2); + } else { + Ptr = Ptr + sizeof (EFI_FFS_FILE_HEADER); + } continue; @@ -425,8 +433,22 @@ FvCheck ( } } + if (IS_FFS_FILE2 (Ptr)) { + ASSERT (FFS_FILE2_SIZE (Ptr) > 0x00FFFFFF); + if (!FvDevice->IsFfs3Fv) { + DEBUG ((EFI_D_ERROR, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &((EFI_FFS_FILE_HEADER *) Ptr)->Name)); + Ptr = Ptr + FFS_FILE2_SIZE (Ptr); + // + // Adjust Ptr to the next 8-byte aligned boundry. + // + while (((UINTN) Ptr & 0x07) != 0) { + Ptr++; + } + continue; + } + } + if (IsValidFFSFile (FvDevice, (EFI_FFS_FILE_HEADER *) Ptr)) { - FileLength = *(UINT32 *) ((EFI_FFS_FILE_HEADER *) Ptr)->Size & 0x00FFFFFF; FileState = GetFileState ( FvDevice->ErasePolarity, (EFI_FFS_FILE_HEADER *) Ptr @@ -449,7 +471,11 @@ FvCheck ( InsertTailList (&FvDevice->FfsFileListHeader, &FfsFileEntry->Link); } - Ptr += FileLength; + if (IS_FFS_FILE2 (Ptr)) { + Ptr = Ptr + FFS_FILE2_SIZE (Ptr); + } else { + Ptr = Ptr + FFS_FILE_SIZE (Ptr); + } // // Adjust Ptr to the next 8-byte aligned boundry. @@ -513,9 +539,7 @@ FwVolDriverInit ( if (EFI_ERROR (Status)) { return EFI_NOT_FOUND; } - // - // Get FV with gEfiFirmwareFileSystemGuid - // + for (Index = 0; Index < HandleCount; Index += 1) { Status = gBS->HandleProtocol ( HandleBuffer[Index], @@ -536,10 +560,8 @@ FwVolDriverInit ( // Check to see that the file system is indeed formatted in a way we can // understand it... // - if (!CompareGuid ( - &FwVolHeader->FileSystemGuid, - &gEfiFirmwareFileSystem2Guid - )) { + if ((!CompareGuid (&FwVolHeader->FileSystemGuid, &gEfiFirmwareFileSystem2Guid)) && + (!CompareGuid (&FwVolHeader->FileSystemGuid, &gEfiFirmwareFileSystem3Guid))) { FreePool (FwVolHeader); continue; } diff --git a/IntelFrameworkModulePkg/Universal/FirmwareVolume/FwVolDxe/FwVolDriver.h b/IntelFrameworkModulePkg/Universal/FirmwareVolume/FwVolDxe/FwVolDriver.h index 9c2788da32..2de65f511d 100644 --- a/IntelFrameworkModulePkg/Universal/FirmwareVolume/FwVolDxe/FwVolDriver.h +++ b/IntelFrameworkModulePkg/Universal/FirmwareVolume/FwVolDxe/FwVolDriver.h @@ -1,7 +1,7 @@ /** @file Common defines and definitions for a FwVolDxe driver. - Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -92,7 +93,7 @@ typedef struct { LIST_ENTRY FfsFileListHeader; FFS_FILE_LIST_ENTRY *CurrentFfsFile; - + BOOLEAN IsFfs3Fv; } FV_DEVICE; #define FV_DEVICE_FROM_THIS(a) CR (a, FV_DEVICE, Fv, FV_DEVICE_SIGNATURE) @@ -489,22 +490,6 @@ GetFwVolHeader ( OUT EFI_FIRMWARE_VOLUME_HEADER **FwVolHeader ); -/** - Locate the first file in FV. - - @param FvDevice Cached FV image. - @param FirstFile Points to the got first FFS file header. - - @retval EFI_NOT_FOUND No FFS file is found in FV. - @retval EFI_SUCCESS The first FFS file is got. - -**/ -EFI_STATUS -FvLocateFirstFile ( - IN FV_DEVICE *FvDevice, - OUT EFI_FFS_FILE_HEADER **FirstFile - ); - /** Convert the Buffer Address to LBA Entry Address. diff --git a/IntelFrameworkModulePkg/Universal/FirmwareVolume/FwVolDxe/FwVolDxe.inf b/IntelFrameworkModulePkg/Universal/FirmwareVolume/FwVolDxe/FwVolDxe.inf index fb1355b5a8..2199026898 100644 --- a/IntelFrameworkModulePkg/Universal/FirmwareVolume/FwVolDxe/FwVolDxe.inf +++ b/IntelFrameworkModulePkg/Universal/FirmwareVolume/FwVolDxe/FwVolDxe.inf @@ -57,6 +57,7 @@ [Guids] gEfiFirmwareVolumeTopFileGuid ## CONSUMES gEfiFirmwareFileSystem2Guid ## CONSUMES + gEfiFirmwareFileSystem3Guid ## CONSUMES [Protocols] gEfiSectionExtractionProtocolGuid ## CONSUMES diff --git a/IntelFrameworkModulePkg/Universal/FirmwareVolume/FwVolDxe/FwVolRead.c b/IntelFrameworkModulePkg/Universal/FirmwareVolume/FwVolDxe/FwVolRead.c index b1b4a73a3c..5a26e11e2e 100644 --- a/IntelFrameworkModulePkg/Universal/FirmwareVolume/FwVolDxe/FwVolRead.c +++ b/IntelFrameworkModulePkg/Universal/FirmwareVolume/FwVolDxe/FwVolRead.c @@ -1,7 +1,7 @@ /** @file Implements functions to read firmware file. - Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions @@ -100,7 +100,6 @@ FvGetNextFile ( UINTN *KeyValue; LIST_ENTRY *Link; FFS_FILE_LIST_ENTRY *FfsFileEntry; - UINTN FileLength; FvDevice = FV_DEVICE_FROM_THIS (This); @@ -202,12 +201,14 @@ FvGetNextFile ( CopyGuid (NameGuid, &FfsFileHeader->Name); *Attributes = FfsAttributes2FvFileAttributes (FfsFileHeader->Attributes); - FileLength = *(UINT32 *) FfsFileHeader->Size & 0x00FFFFFF; - // // we need to substract the header size // - *Size = FileLength - sizeof (EFI_FFS_FILE_HEADER); + if (IS_FFS_FILE2 (FfsFileHeader)) { + *Size = FFS_FILE2_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER2); + } else { + *Size = FFS_FILE_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER); + } if (CompareGuid (&gEfiFirmwareVolumeTopFileGuid, NameGuid)) { // @@ -216,8 +217,11 @@ FvGetNextFile ( UINT8 *SrcPtr; UINT32 Tmp; - SrcPtr = (UINT8 *) FfsFileHeader; - SrcPtr += sizeof (EFI_FFS_FILE_HEADER); + if (IS_FFS_FILE2 (FfsFileHeader)) { + SrcPtr = ((UINT8 *) FfsFileHeader) + sizeof (EFI_FFS_FILE_HEADER2); + } else { + SrcPtr = ((UINT8 *) FfsFileHeader) + sizeof (EFI_FFS_FILE_HEADER); + } while (*Size >= 4) { Tmp = *(UINT32 *) SrcPtr; @@ -362,8 +366,11 @@ FvReadFile ( // // Get File Size of the cached file // - FileSize = *(UINT32 *) FfsHeader->Size & 0x00FFFFFF; - FileSize -= sizeof (EFI_FFS_FILE_HEADER); + if (IS_FFS_FILE2 (FfsHeader)) { + FileSize = FFS_FILE2_SIZE (FfsHeader) - sizeof (EFI_FFS_FILE_HEADER2); + } else { + FileSize = FFS_FILE_SIZE (FfsHeader) - sizeof (EFI_FFS_FILE_HEADER); + } } // // Get file info @@ -380,8 +387,11 @@ FvReadFile ( return EFI_SUCCESS; } - SrcPtr = (UINT8 *) FfsHeader; - SrcPtr += sizeof (EFI_FFS_FILE_HEADER); + if (IS_FFS_FILE2 (FfsHeader)) { + SrcPtr = ((UINT8 *) FfsHeader) + sizeof (EFI_FFS_FILE_HEADER2); + } else { + SrcPtr = ((UINT8 *) FfsHeader) + sizeof (EFI_FFS_FILE_HEADER); + } if (CompareGuid (&gEfiFirmwareVolumeTopFileGuid, NameGuid)) { // diff --git a/IntelFrameworkModulePkg/Universal/FirmwareVolume/FwVolDxe/FwVolWrite.c b/IntelFrameworkModulePkg/Universal/FirmwareVolume/FwVolDxe/FwVolWrite.c index 5c7e8abf75..7ca8f44b15 100644 --- a/IntelFrameworkModulePkg/Universal/FirmwareVolume/FwVolDxe/FwVolWrite.c +++ b/IntelFrameworkModulePkg/Universal/FirmwareVolume/FwVolDxe/FwVolWrite.c @@ -28,7 +28,6 @@ SetHeaderChecksum ( ) { EFI_FFS_FILE_STATE State; - UINT8 HeaderChecksum; UINT8 FileChecksum; // @@ -42,12 +41,17 @@ SetHeaderChecksum ( FfsHeader->IntegrityCheck.Checksum.Header = 0; - HeaderChecksum = CalculateSum8 ( - (UINT8 *)FfsHeader, - sizeof (EFI_FFS_FILE_HEADER) - ); - - FfsHeader->IntegrityCheck.Checksum.Header = (UINT8) (~HeaderChecksum + 1); + if (IS_FFS_FILE2 (FfsHeader)) { + FfsHeader->IntegrityCheck.Checksum.Header = CalculateCheckSum8 ( + (UINT8 *) FfsHeader, + sizeof (EFI_FFS_FILE_HEADER2) + ); + } else { + FfsHeader->IntegrityCheck.Checksum.Header = CalculateCheckSum8 ( + (UINT8 *) FfsHeader, + sizeof (EFI_FFS_FILE_HEADER) + ); + } FfsHeader->State = State; FfsHeader->IntegrityCheck.Checksum.File = FileChecksum; @@ -68,29 +72,21 @@ SetFileChecksum ( IN UINTN ActualFileSize ) { - EFI_FFS_FILE_STATE State; - UINT8 FileChecksum; - if ((FfsHeader->Attributes & FFS_ATTRIB_CHECKSUM) != 0) { - // - // The file state is not included - // - State = FfsHeader->State; - FfsHeader->State = 0; FfsHeader->IntegrityCheck.Checksum.File = 0; - // - // File checksum - // - FileChecksum = CalculateSum8 ( - (UINT8 *)(FfsHeader + 1), - ActualFileSize - sizeof (EFI_FFS_FILE_HEADER) - ); - - FfsHeader->IntegrityCheck.Checksum.File = (UINT8) (~FileChecksum + 1); - - FfsHeader->State = State; + if (IS_FFS_FILE2 (FfsHeader)) { + FfsHeader->IntegrityCheck.Checksum.File = CalculateCheckSum8 ( + (UINT8 *) FfsHeader + sizeof (EFI_FFS_FILE_HEADER2), + ActualFileSize - sizeof (EFI_FFS_FILE_HEADER2) + ); + } else { + FfsHeader->IntegrityCheck.Checksum.File = CalculateCheckSum8 ( + (UINT8 *) FfsHeader + sizeof (EFI_FFS_FILE_HEADER), + ActualFileSize - sizeof (EFI_FFS_FILE_HEADER) + ); + } } else { @@ -138,6 +134,7 @@ GetRequiredAlignment ( @param FvDevice Cached Firmware Volume. @param StartAddress The starting address to write the FFS File. + @param BufferSize The FFS File Buffer Size. @param RequiredAlignment FFS File Data alignment requirement. @return The required Pad File Size. @@ -147,6 +144,7 @@ UINTN CaculatePadFileSize ( IN FV_DEVICE *FvDevice, IN EFI_PHYSICAL_ADDRESS StartAddress, + IN UINTN BufferSize, IN UINTN RequiredAlignment ) { @@ -154,7 +152,11 @@ CaculatePadFileSize ( UINTN RelativePos; UINTN PadSize; - DataStartPos = (UINTN) StartAddress + sizeof (EFI_FFS_FILE_HEADER); + if (BufferSize > 0x00FFFFFF) { + DataStartPos = (UINTN) StartAddress + sizeof (EFI_FFS_FILE_HEADER2); + } else { + DataStartPos = (UINTN) StartAddress + sizeof (EFI_FFS_FILE_HEADER); + } RelativePos = DataStartPos - (UINTN) FvDevice->CachedFv; PadSize = 0; @@ -331,6 +333,7 @@ FvLocateFreeSpaceEntry ( PadFileSize = CaculatePadFileSize ( FvDevice, (EFI_PHYSICAL_ADDRESS) (UINTN) FreeSpaceListEntry->StartingAddress, + Size, RequiredAlignment ); if (FreeSpaceListEntry->Length >= Size + PadFileSize) { @@ -346,54 +349,6 @@ FvLocateFreeSpaceEntry ( } -/** - Locate a free space that can hold this file. - - @param FvDevice Cached Firmware Volume. - @param Size On input, it is the required size. - On output, it is the actual size of free space. - @param RequiredAlignment FFS File Data alignment requirement. - @param PadSize Pointer to the size of leading Pad File. - @param StartingAddress The starting address of the Free Space Entry - that meets the requirement. - - @retval EFI_SUCCESS The free space is found. - @retval EFI_NOT_FOUND The free space can't be found. - -**/ -EFI_STATUS -FvLocateFreeSpace ( - IN FV_DEVICE *FvDevice, - IN OUT UINTN *Size, - IN UINTN RequiredAlignment, - OUT UINTN *PadSize, - OUT EFI_PHYSICAL_ADDRESS *StartingAddress - ) -{ - EFI_STATUS Status; - FREE_SPACE_ENTRY *FreeSpaceEntry; - - // - // First find the free space entry - // - Status = FvLocateFreeSpaceEntry ( - FvDevice, - *Size, - RequiredAlignment, - PadSize, - &FreeSpaceEntry - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - *Size = FreeSpaceEntry->Length; - *StartingAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) FreeSpaceEntry->StartingAddress; - - return EFI_SUCCESS; -} - /** Locate Pad File for writing, this is got from FV Cache. @@ -419,9 +374,9 @@ FvLocatePadFile ( FFS_FILE_LIST_ENTRY *FileEntry; EFI_FFS_FILE_STATE FileState; EFI_FFS_FILE_HEADER *FileHeader; - UINTN FileLength; UINTN PadAreaLength; UINTN PadFileSize; + UINTN HeaderSize; FileEntry = (FFS_FILE_LIST_ENTRY *) FvDevice->FfsFileListHeader.ForwardLink; @@ -437,12 +392,18 @@ FvLocatePadFile ( // // we find one valid pad file, check its free area length // - FileLength = *(UINT32 *) FileHeader->Size & 0x00FFFFFF; - PadAreaLength = FileLength - sizeof (EFI_FFS_FILE_HEADER); + if (IS_FFS_FILE2 (FileHeader)) { + HeaderSize = sizeof (EFI_FFS_FILE_HEADER2); + PadAreaLength = FFS_FILE2_SIZE (FileHeader) - HeaderSize; + } else { + HeaderSize = sizeof (EFI_FFS_FILE_HEADER); + PadAreaLength = FFS_FILE_SIZE (FileHeader) - HeaderSize; + } PadFileSize = CaculatePadFileSize ( FvDevice, - (EFI_PHYSICAL_ADDRESS) (UINTN) FileHeader + sizeof (EFI_FFS_FILE_HEADER), + (EFI_PHYSICAL_ADDRESS) (UINTN) FileHeader + HeaderSize, + Size, RequiredAlignment ); if (PadAreaLength >= (Size + PadFileSize)) { @@ -487,10 +448,10 @@ FvSearchSuitablePadFile ( FFS_FILE_LIST_ENTRY *FileEntry; EFI_FFS_FILE_STATE FileState; EFI_FFS_FILE_HEADER *FileHeader; - UINTN FileLength; UINTN PadAreaLength; UINTN TotalSize; UINTN Index; + UINTN HeaderSize; FileEntry = (FFS_FILE_LIST_ENTRY *) FvDevice->FfsFileListHeader.ForwardLink; @@ -506,14 +467,20 @@ FvSearchSuitablePadFile ( // // we find one valid pad file, check its length // - FileLength = *(UINT32 *) FileHeader->Size & 0x00FFFFFF; - PadAreaLength = FileLength - sizeof (EFI_FFS_FILE_HEADER); + if (IS_FFS_FILE2 (FileHeader)) { + HeaderSize = sizeof (EFI_FFS_FILE_HEADER2); + PadAreaLength = FFS_FILE2_SIZE (FileHeader) - HeaderSize; + } else { + HeaderSize = sizeof (EFI_FFS_FILE_HEADER); + PadAreaLength = FFS_FILE_SIZE (FileHeader) - HeaderSize; + } TotalSize = 0; for (Index = 0; Index < NumOfFiles; Index++) { PadSize[Index] = CaculatePadFileSize ( FvDevice, - (EFI_PHYSICAL_ADDRESS) (UINTN) FileHeader + sizeof (EFI_FFS_FILE_HEADER) + TotalSize, + (EFI_PHYSICAL_ADDRESS) (UINTN) FileHeader + HeaderSize + TotalSize, + BufferSize[Index], RequiredAlignment[Index] ); TotalSize += PadSize[Index]; @@ -589,6 +556,7 @@ FvSearchSuitableFreeSpace ( PadSize[Index] = CaculatePadFileSize ( FvDevice, (EFI_PHYSICAL_ADDRESS) (UINTN) StartAddr + TotalSize, + BufferSize[Index], RequiredAlignment[Index] ); @@ -803,6 +771,7 @@ FvCreateNewFile ( FFS_FILE_LIST_ENTRY *PadFileEntry; EFI_FFS_FILE_ATTRIBUTES TmpFileAttribute; FFS_FILE_LIST_ENTRY *FfsFileEntry; + UINTN HeaderSize; // // File Type: 0x0E~0xE0 are reserved @@ -869,6 +838,11 @@ FvCreateNewFile ( // Write Name, IntegrityCheck.Header, Type, Attributes, and Size // FileHeader = (EFI_FFS_FILE_HEADER *) FfsFileBuffer; + if (ActualFileSize > 0x00FFFFFF) { + HeaderSize = sizeof (EFI_FFS_FILE_HEADER2); + } else { + HeaderSize = sizeof (EFI_FFS_FILE_HEADER); + } SetFileState (EFI_FILE_HEADER_CONSTRUCTION, FileHeader); Offset = (UINTN) (BufferPtr - FvDevice->CachedFv); @@ -890,14 +864,14 @@ FvCreateNewFile ( CopyMem ( (UINT8 *) (UINTN) BufferPtr, FileHeader, - sizeof (EFI_FFS_FILE_HEADER) + HeaderSize ); // - // update Free Space Entry, now need to substract the EFI_FFS_FILE_HEADER + // update Free Space Entry, now need to substract the file header length // - FreeSpaceEntry->StartingAddress += sizeof (EFI_FFS_FILE_HEADER); - FreeSpaceEntry->Length -= sizeof (EFI_FFS_FILE_HEADER); + FreeSpaceEntry->StartingAddress += HeaderSize; + FreeSpaceEntry->Length -= HeaderSize; CopyGuid (&FileHeader->Name, FileName); FileHeader->Type = FileType; @@ -912,14 +886,20 @@ FvCreateNewFile ( // // File size is including the FFS File Header. // - *(UINT32 *) FileHeader->Size &= 0xFF000000; - *(UINT32 *) FileHeader->Size |= ActualFileSize; + if (ActualFileSize > 0x00FFFFFF) { + ((EFI_FFS_FILE_HEADER2 *) FileHeader)->ExtendedSize = (UINT32) ActualFileSize; + *(UINT32 *) FileHeader->Size &= 0xFF000000; + FileHeader->Attributes |= FFS_ATTRIB_LARGE_FILE; + } else { + *(UINT32 *) FileHeader->Size &= 0xFF000000; + *(UINT32 *) FileHeader->Size |= ActualFileSize; + } SetHeaderChecksum (FileHeader); Offset = (UINTN) (BufferPtr - FvDevice->CachedFv); - NumBytesWritten = sizeof (EFI_FFS_FILE_HEADER); + NumBytesWritten = HeaderSize; Status = FvcWrite ( FvDevice, Offset, @@ -935,7 +915,7 @@ FvCreateNewFile ( CopyMem ( (UINT8 *) (UINTN) BufferPtr, FileHeader, - sizeof (EFI_FFS_FILE_HEADER) + HeaderSize ); // @@ -966,14 +946,14 @@ FvCreateNewFile ( CopyMem ( (UINT8 *) (UINTN) BufferPtr, FileHeader, - sizeof (EFI_FFS_FILE_HEADER) + HeaderSize ); // // update Free Space Entry, now need to substract the file data length // - FreeSpaceEntry->StartingAddress += (BufferSize - sizeof (EFI_FFS_FILE_HEADER)); - FreeSpaceEntry->Length -= (BufferSize - sizeof (EFI_FFS_FILE_HEADER)); + FreeSpaceEntry->StartingAddress += (BufferSize - HeaderSize); + FreeSpaceEntry->Length -= (BufferSize - HeaderSize); // // Caculate File Checksum @@ -1025,7 +1005,7 @@ FvCreateNewFile ( CopyMem ( (UINT8 *) (UINTN) BufferPtr, FileHeader, - sizeof (EFI_FFS_FILE_HEADER) + HeaderSize ); // @@ -1381,6 +1361,7 @@ FvWriteFile ( UINTN NumDelete; EFI_FV_ATTRIBUTES FvAttributes; UINT32 AuthenticationStatus; + UINTN HeaderSize; if (NumberOfFiles > MAX_FILES) { return EFI_UNSUPPORTED; @@ -1416,6 +1397,15 @@ FvWriteFile ( // NumDelete = 0; for (Index1 = 0; Index1 < NumberOfFiles; Index1++) { + + if ((FileData[Index1].BufferSize + sizeof (EFI_FFS_FILE_HEADER) > 0x00FFFFFF) && !FvDevice->IsFfs3Fv) { + // + // Found a file needs a FFS3 formatted file to store it, but it is in a non-FFS3 formatted FV. + // + DEBUG ((EFI_D_ERROR, "FFS3 formatted file can't be written in a non-FFS3 formatted FV.\n")); + return EFI_INVALID_PARAMETER; + } + if (FileData[Index1].BufferSize == 0) { // // Here we will delete this file @@ -1525,7 +1515,12 @@ FvWriteFile ( // // Making Buffersize QWORD boundry, and add file tail. // - ActualSize = FileData[Index1].BufferSize + sizeof (EFI_FFS_FILE_HEADER); + HeaderSize = sizeof (EFI_FFS_FILE_HEADER); + ActualSize = FileData[Index1].BufferSize + HeaderSize; + if (ActualSize > 0x00FFFFFF) { + HeaderSize = sizeof (EFI_FFS_FILE_HEADER2); + ActualSize = FileData[Index1].BufferSize + HeaderSize; + } BufferSize = ActualSize; while ((BufferSize & 0x07) != 0) { @@ -1540,7 +1535,7 @@ FvWriteFile ( // Copy File Data into FileBuffer // CopyMem ( - FileBuffer + sizeof (EFI_FFS_FILE_HEADER), + FileBuffer + HeaderSize, FileData[Index1].Buffer, FileData[Index1].BufferSize ); @@ -1549,7 +1544,7 @@ FvWriteFile ( // // Fill the file header and padding byte with Erase Byte // - for (Index2 = 0; Index2 < sizeof (EFI_FFS_FILE_HEADER); Index2++) { + for (Index2 = 0; Index2 < HeaderSize; Index2++) { FileBuffer[Index2] = (UINT8)~FileBuffer[Index2]; } diff --git a/IntelFrameworkModulePkg/Universal/SectionExtractionDxe/SectionExtraction.c b/IntelFrameworkModulePkg/Universal/SectionExtractionDxe/SectionExtraction.c index 5756fb2d7b..d586de2556 100644 --- a/IntelFrameworkModulePkg/Universal/SectionExtractionDxe/SectionExtraction.c +++ b/IntelFrameworkModulePkg/Universal/SectionExtractionDxe/SectionExtraction.c @@ -27,7 +27,7 @@ 3) A support protocol is not found, and the data is not available to be read without it. This results in EFI_PROTOCOL_ERROR. -Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2011, 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 @@ -278,7 +278,11 @@ IsValidSectionStream ( SectionHeader = (EFI_COMMON_SECTION_HEADER *)SectionStream; while (TotalLength < SectionStreamLength) { - SectionLength = SECTION_SIZE (SectionHeader); + if (IS_SECTION2 (SectionHeader)) { + SectionLength = SECTION2_SIZE (SectionHeader); + } else { + SectionLength = SECTION_SIZE (SectionHeader); + } TotalLength += SectionLength; if (TotalLength == SectionStreamLength) { @@ -462,7 +466,11 @@ ChildIsType ( return TRUE; } GuidedSection = (EFI_GUID_DEFINED_SECTION * )(Stream->StreamBuffer + Child->OffsetInStream); - return CompareGuid (&GuidedSection->SectionDefinitionGuid, SectionDefinitionGuid); + if (IS_SECTION2 (GuidedSection)) { + return CompareGuid (&(((EFI_GUID_DEFINED_SECTION2 *) GuidedSection)->SectionDefinitionGuid), SectionDefinitionGuid); + } else { + return CompareGuid (&GuidedSection->SectionDefinitionGuid, SectionDefinitionGuid); + } } /** @@ -580,7 +588,7 @@ NotifyGuidedExtraction ( ); ASSERT_EFI_ERROR (Status); // - // OR in the parent stream's aggregagate status. + // OR in the parent stream's aggregate status. // AuthenticationStatus |= Context->ParentStream->AuthenticationStatus & EFI_AGGREGATE_AUTH_STATUS_ALL; Status = OpenSectionStreamEx ( @@ -674,7 +682,11 @@ CreateChildNode ( UINT32 ScratchSize; UINTN NewStreamBufferSize; UINT32 AuthenticationStatus; - UINT32 SectionLength; + VOID *CompressionSource; + UINT32 CompressionSourceSize; + UINT32 UncompressedLength; + UINT8 CompressionType; + UINT16 GuidedSectionAttributes; FRAMEWORK_SECTION_CHILD_NODE *Node; @@ -694,7 +706,11 @@ CreateChildNode ( // Node->Signature = FRAMEWORK_SECTION_CHILD_SIGNATURE; Node->Type = SectionHeader->Type; - Node->Size = SECTION_SIZE (SectionHeader); + if (IS_SECTION2 (SectionHeader)) { + Node->Size = SECTION2_SIZE (SectionHeader); + } else { + Node->Size = SECTION_SIZE (SectionHeader); + } Node->OffsetInStream = ChildOffset; Node->EncapsulatedStreamHandle = NULL_STREAM_HANDLE; Node->EncapsulationGuid = NULL; @@ -710,24 +726,36 @@ CreateChildNode ( ASSERT (Node->Size >= sizeof (EFI_COMPRESSION_SECTION)); CompressionHeader = (EFI_COMPRESSION_SECTION *) SectionHeader; - + + if (IS_SECTION2 (CompressionHeader)) { + CompressionSource = (VOID *) ((UINT8 *) CompressionHeader + sizeof (EFI_COMPRESSION_SECTION2)); + CompressionSourceSize = (UINT32) (SECTION2_SIZE (CompressionHeader) - sizeof (EFI_COMPRESSION_SECTION2)); + UncompressedLength = ((EFI_COMPRESSION_SECTION2 *) CompressionHeader)->UncompressedLength; + CompressionType = ((EFI_COMPRESSION_SECTION2 *) CompressionHeader)->CompressionType; + } else { + CompressionSource = (VOID *) ((UINT8 *) CompressionHeader + sizeof (EFI_COMPRESSION_SECTION)); + CompressionSourceSize = (UINT32) (SECTION_SIZE (CompressionHeader) - sizeof (EFI_COMPRESSION_SECTION)); + UncompressedLength = CompressionHeader->UncompressedLength; + CompressionType = CompressionHeader->CompressionType; + } + // // Allocate space for the new stream // - if (CompressionHeader->UncompressedLength > 0) { - NewStreamBufferSize = CompressionHeader->UncompressedLength; + if (UncompressedLength > 0) { + NewStreamBufferSize = UncompressedLength; NewStreamBuffer = AllocatePool (NewStreamBufferSize); if (NewStreamBuffer == NULL) { FreePool (Node); return EFI_OUT_OF_RESOURCES; } - if (CompressionHeader->CompressionType == EFI_NOT_COMPRESSED) { + if (CompressionType == EFI_NOT_COMPRESSED) { // // stream is not actually compressed, just encapsulated. So just copy it. // - CopyMem (NewStreamBuffer, CompressionHeader + 1, NewStreamBufferSize); - } else if (CompressionHeader->CompressionType == EFI_STANDARD_COMPRESSION) { + CopyMem (NewStreamBuffer, CompressionSource, NewStreamBufferSize); + } else if (CompressionType == EFI_STANDARD_COMPRESSION) { // // Only support the EFI_SATNDARD_COMPRESSION algorithm. // @@ -741,13 +769,13 @@ CreateChildNode ( Status = Decompress->GetInfo ( Decompress, - CompressionHeader + 1, - Node->Size - sizeof (EFI_COMPRESSION_SECTION), + CompressionSource, + CompressionSourceSize, (UINT32 *)&NewStreamBufferSize, &ScratchSize ); ASSERT_EFI_ERROR (Status); - ASSERT (NewStreamBufferSize == CompressionHeader->UncompressedLength); + ASSERT (NewStreamBufferSize == UncompressedLength); ScratchBuffer = AllocatePool (ScratchSize); if (ScratchBuffer == NULL) { @@ -758,8 +786,8 @@ CreateChildNode ( Status = Decompress->Decompress ( Decompress, - CompressionHeader + 1, - Node->Size - sizeof (EFI_COMPRESSION_SECTION), + CompressionSource, + CompressionSourceSize, NewStreamBuffer, (UINT32)NewStreamBufferSize, ScratchBuffer, @@ -789,7 +817,13 @@ CreateChildNode ( case EFI_SECTION_GUID_DEFINED: GuidedHeader = (EFI_GUID_DEFINED_SECTION *) SectionHeader; - Node->EncapsulationGuid = &GuidedHeader->SectionDefinitionGuid; + if (IS_SECTION2 (GuidedHeader)) { + Node->EncapsulationGuid = &(((EFI_GUID_DEFINED_SECTION2 *) GuidedHeader)->SectionDefinitionGuid); + GuidedSectionAttributes = ((EFI_GUID_DEFINED_SECTION2 *) GuidedHeader)->Attributes; + } else { + Node->EncapsulationGuid = &GuidedHeader->SectionDefinitionGuid; + GuidedSectionAttributes = GuidedHeader->Attributes; + } Status = gBS->LocateProtocol (Node->EncapsulationGuid, NULL, (VOID **)&GuidedExtraction); if (!EFI_ERROR (Status)) { // @@ -812,7 +846,7 @@ CreateChildNode ( // Make sure we initialize the new stream with the correct // authentication status for both aggregate and local status fields. // - if ((GuidedHeader->Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) == EFI_GUIDED_SECTION_AUTH_STATUS_VALID) { + if ((GuidedSectionAttributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) == EFI_GUIDED_SECTION_AUTH_STATUS_VALID) { // // OR in the parent stream's aggregate status. // @@ -841,7 +875,7 @@ CreateChildNode ( // // There's no GUIDed section extraction protocol available. // - if ((GuidedHeader->Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == EFI_GUIDED_SECTION_PROCESSING_REQUIRED) { + if ((GuidedSectionAttributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == EFI_GUIDED_SECTION_PROCESSING_REQUIRED) { // // If the section REQUIRES an extraction protocol, register for RPN // when the required GUIDed extraction protocol becomes available. @@ -853,7 +887,7 @@ CreateChildNode ( // Figure out the proper authentication status // AuthenticationStatus = Stream->AuthenticationStatus; - if ((GuidedHeader->Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) == EFI_GUIDED_SECTION_AUTH_STATUS_VALID) { + if ((GuidedSectionAttributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) == EFI_GUIDED_SECTION_AUTH_STATUS_VALID) { // // The local status of the new stream is contained in // AuthenticaionStatus. This value needs to be ORed into the @@ -871,14 +905,23 @@ CreateChildNode ( AuthenticationStatus |= AuthenticationStatus >> 16; } - SectionLength = SECTION_SIZE (GuidedHeader); - Status = OpenSectionStreamEx ( - SectionLength - GuidedHeader->DataOffset, - (UINT8 *) GuidedHeader + GuidedHeader->DataOffset, - TRUE, - AuthenticationStatus, - &Node->EncapsulatedStreamHandle - ); + if (IS_SECTION2 (GuidedHeader)) { + Status = OpenSectionStreamEx ( + SECTION2_SIZE (GuidedHeader) - ((EFI_GUID_DEFINED_SECTION2 *) GuidedHeader)->DataOffset, + (UINT8 *) GuidedHeader + ((EFI_GUID_DEFINED_SECTION2 *) GuidedHeader)->DataOffset, + TRUE, + AuthenticationStatus, + &Node->EncapsulatedStreamHandle + ); + } else { + Status = OpenSectionStreamEx ( + SECTION_SIZE (GuidedHeader) - ((EFI_GUID_DEFINED_SECTION *) GuidedHeader)->DataOffset, + (UINT8 *) GuidedHeader + ((EFI_GUID_DEFINED_SECTION *) GuidedHeader)->DataOffset, + TRUE, + AuthenticationStatus, + &Node->EncapsulatedStreamHandle + ); + } if (EFI_ERROR (Status)) { FreePool (Node); return Status; @@ -1177,6 +1220,7 @@ GetSection ( UINTN Instance; UINT8 *CopyBuffer; UINTN SectionSize; + EFI_COMMON_SECTION_HEADER *Section; OldTpl = gBS->RaiseTPL (TPL_NOTIFY); @@ -1219,8 +1263,15 @@ GetSection ( } ASSERT (ChildNode != NULL); ASSERT (ChildStreamNode != NULL); - CopySize = ChildNode->Size - sizeof (EFI_COMMON_SECTION_HEADER); - CopyBuffer = ChildStreamNode->StreamBuffer + ChildNode->OffsetInStream + sizeof (EFI_COMMON_SECTION_HEADER); + Section = (EFI_COMMON_SECTION_HEADER *) (ChildStreamNode->StreamBuffer + ChildNode->OffsetInStream); + + if (IS_SECTION2 (Section)) { + CopySize = SECTION2_SIZE (Section) - sizeof (EFI_COMMON_SECTION_HEADER2); + CopyBuffer = (UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER2); + } else { + CopySize = SECTION_SIZE (Section) - sizeof (EFI_COMMON_SECTION_HEADER); + CopyBuffer = (UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER); + } *AuthenticationStatus = ExtractedAuthenticationStatus; }