3 Copyright (c) 1999 - 2008, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14 FirmwareVolumeBuffer.c
18 EFI Firmware Volume routines which work on a Fv image in buffers.
22 #include "FirmwareVolumeBufferLib.h"
23 #include "BinderFuncs.h"
28 #define EFI_TEST_FFS_ATTRIBUTES_BIT(FvbAttributes, TestAttributes, Bit) \
31 (FvbAttributes & EFI_FVB2_ERASE_POLARITY) ? (((~TestAttributes) & Bit) == Bit) : ((TestAttributes & Bit) == Bit) \
42 FvBufCalculateChecksum16 (
49 FvBufCalculateChecksum8 (
67 Clears out all files from the Fv buffer in memory
71 SourceFv - Address of the Fv in memory, this firmware volume volume will
72 be modified, if SourceFfsFile exists
73 SourceFfsFile - Input FFS file to replace
83 EFI_FFS_FILE_HEADER
* FileToRm
;
86 Status
= FvBufFindFileByName(
91 if (EFI_ERROR (Status
)) {
95 FileToRmLength
= FvBufExpand3ByteSize (FileToRm
->Size
);
97 CommonLibBinderSetMem (
100 (((EFI_FIRMWARE_VOLUME_HEADER
*)Fv
)->Attributes
& EFI_FVB2_ERASE_POLARITY
)
117 Clears out all files from the Fv buffer in memory
121 SourceFv - Address of the Fv in memory, this firmware volume volume will
122 be modified, if SourceFfsFile exists
123 SourceFfsFile - Input FFS file to replace
133 EFI_FFS_FILE_HEADER
*NextFile
;
134 EFI_FIRMWARE_VOLUME_HEADER
*TempFv
;
138 Status
= FvBufFindFileByName(
143 if (EFI_ERROR (Status
)) {
147 Status
= FvBufGetSize (Fv
, &FvLength
);
148 if (EFI_ERROR (Status
)) {
153 Status
= FvBufDuplicate (Fv
, (VOID
**)&TempFv
);
154 if (EFI_ERROR (Status
)) {
158 Status
= FvBufClearAllFiles (TempFv
);
159 if (EFI_ERROR (Status
)) {
163 // TempFv has been allocated. It must now be freed
169 Status
= FvBufFindNextFile (Fv
, &FileKey
, (VOID
**)&NextFile
);
170 if (Status
== EFI_NOT_FOUND
) {
172 } else if (EFI_ERROR (Status
)) {
173 CommonLibBinderFree (TempFv
);
177 if (CommonLibBinderCompareGuid (Name
, &NextFile
->Name
)) {
181 Status
= FvBufAddFile (TempFv
, NextFile
);
182 if (EFI_ERROR (Status
)) {
183 CommonLibBinderFree (TempFv
);
189 CommonLibBinderCopyMem (Fv
, TempFv
, FvLength
);
190 CommonLibBinderFree (TempFv
);
204 Clears out all files from the Fv buffer in memory
208 SourceFfsFile - Input FFS file to update the checksum for
217 EFI_FFS_FILE_HEADER
* File
= (EFI_FFS_FILE_HEADER
*)FfsFile
;
218 EFI_FFS_FILE_STATE StateBackup
;
221 FileSize
= FvBufExpand3ByteSize (File
->Size
);
224 // Fill in checksums and state, they must be 0 for checksumming.
226 File
->IntegrityCheck
.Checksum
.Header
= 0;
227 File
->IntegrityCheck
.Checksum
.File
= 0;
228 StateBackup
= File
->State
;
231 File
->IntegrityCheck
.Checksum
.Header
=
232 FvBufCalculateChecksum8 (
234 sizeof (EFI_FFS_FILE_HEADER
)
237 if (File
->Attributes
& FFS_ATTRIB_CHECKSUM
) {
238 File
->IntegrityCheck
.Checksum
.File
= FvBufCalculateChecksum8 (
240 FileSize
- sizeof (EFI_FFS_FILE_HEADER
)
243 File
->IntegrityCheck
.Checksum
.File
= FFS_FIXED_CHECKSUM
;
246 File
->State
= StateBackup
;
253 FvBufChecksumHeader (
260 Clears out all files from the Fv buffer in memory
264 SourceFv - Address of the Fv in memory, this firmware volume volume will
265 be modified, if SourceFfsFile exists
266 SourceFfsFile - Input FFS file to replace
275 EFI_FIRMWARE_VOLUME_HEADER
* FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*)Fv
;
277 FvHeader
->Checksum
= 0;
279 FvBufCalculateChecksum16 (
281 FvHeader
->HeaderLength
/ sizeof (UINT16
)
291 IN OUT VOID
**DestinationFv
297 Clears out all files from the Fv buffer in memory
301 SourceFv - Address of the Fv in memory
302 DestinationFv - Output for destination Fv
303 DestinationFv == NULL - invalid parameter
304 *DestinationFv == NULL - memory will be allocated
305 *DestinationFv != NULL - this address will be the destination
316 if (DestinationFv
== NULL
) {
317 return EFI_INVALID_PARAMETER
;
320 Status
= FvBufGetSize (SourceFv
, &size
);
321 if (EFI_ERROR (Status
)) {
325 if (*DestinationFv
== NULL
) {
326 *DestinationFv
= CommonLibBinderAllocate (size
);
329 CommonLibBinderCopyMem (*DestinationFv
, SourceFv
, size
);
344 Extends a firmware volume by the given number of bytes.
346 BUGBUG: Does not handle the case where the firmware volume has a
347 VTF (Volume Top File). The VTF will not be moved to the
348 end of the extended FV.
352 Fv - Source and destination firmware volume.
353 Note: The original firmware volume buffer is freed!
355 Size - The minimum size that the firmware volume is to be extended by.
356 The FV may be extended more than this size.
370 EFI_FIRMWARE_VOLUME_HEADER
* hdr
;
371 EFI_FV_BLOCK_MAP_ENTRY
* blk
;
373 Status
= FvBufGetSize (*Fv
, &OldSize
);
374 if (EFI_ERROR (Status
)) {
379 // Locate the block map in the fv header
381 hdr
= (EFI_FIRMWARE_VOLUME_HEADER
*)*Fv
;
385 // Calculate the number of blocks needed to achieve the requested
388 BlockCount
= ((Size
+ (blk
->Length
- 1)) / blk
->Length
);
391 // Calculate the new size from the number of blocks that will be added
393 NewSize
= OldSize
+ (BlockCount
* blk
->Length
);
395 NewFv
= CommonLibBinderAllocate (NewSize
);
397 return EFI_OUT_OF_RESOURCES
;
403 CommonLibBinderCopyMem (NewFv
, *Fv
, OldSize
);
406 // Free the old fv buffer
408 CommonLibBinderFree (*Fv
);
411 // Locate the block map in the new fv header
413 hdr
= (EFI_FIRMWARE_VOLUME_HEADER
*)NewFv
;
414 hdr
->FvLength
= NewSize
;
418 // Update the block map for the new fv
420 blk
->NumBlocks
+= (UINT32
)BlockCount
;
423 // Update the FV header checksum
425 FvBufChecksumHeader (NewFv
);
428 // Clear out the new area of the FV
430 CommonLibBinderSetMem (
431 (UINT8
*)NewFv
+ OldSize
,
433 (hdr
->Attributes
& EFI_FVB2_ERASE_POLARITY
) ? 0xFF : 0
437 // Set output with new fv that was created
454 Clears out all files from the Fv buffer in memory
458 Fv - Address of the Fv in memory
467 EFI_FIRMWARE_VOLUME_HEADER
*hdr
= (EFI_FIRMWARE_VOLUME_HEADER
*)Fv
;
471 Status
= FvBufGetSize (Fv
, &size
);
472 if (EFI_ERROR (Status
)) {
476 CommonLibBinderSetMem(
477 (UINT8
*)hdr
+ hdr
->HeaderLength
,
478 size
- hdr
->HeaderLength
,
479 (hdr
->Attributes
& EFI_FVB2_ERASE_POLARITY
) ? 0xFF : 0
495 Clears out all files from the Fv buffer in memory
499 Fv - Address of the Fv in memory
508 EFI_FIRMWARE_VOLUME_HEADER
*hdr
= (EFI_FIRMWARE_VOLUME_HEADER
*)Fv
;
509 EFI_FV_BLOCK_MAP_ENTRY
*blk
= hdr
->BlockMap
;
513 while (blk
->Length
!= 0 || blk
->NumBlocks
!= 0) {
514 *Size
= *Size
+ (blk
->Length
* blk
->NumBlocks
);
515 if (*Size
>= 0x40000000) {
516 // If size is greater than 1GB, then assume it is corrupted
517 return EFI_VOLUME_CORRUPTED
;
523 // If size is 0, then assume the volume is corrupted
524 return EFI_VOLUME_CORRUPTED
;
544 Fv - Address of the Fv in memory
545 File - FFS file to add to Fv
553 EFI_FIRMWARE_VOLUME_HEADER
*hdr
= (EFI_FIRMWARE_VOLUME_HEADER
*)Fv
;
555 EFI_FFS_FILE_HEADER
*fhdr
= NULL
;
556 EFI_FVB_ATTRIBUTES FvbAttributes
;
565 Status
= FvBufGetSize (Fv
, &fvSize
);
566 if (EFI_ERROR (Status
)) {
570 FvbAttributes
= hdr
->Attributes
;
571 newSize
= FvBufExpand3ByteSize (((EFI_FFS_FILE_HEADER
*)File
)->Size
);
574 offset
= (UINTN
)ALIGN_POINTER (hdr
->HeaderLength
, 8);
575 offset
+ newSize
<= fvSize
;
576 offset
= (UINTN
)ALIGN_POINTER (offset
, 8)
579 fhdr
= (EFI_FFS_FILE_HEADER
*) ((UINT8
*)hdr
+ offset
);
581 if (EFI_TEST_FFS_ATTRIBUTES_BIT(
584 EFI_FILE_HEADER_VALID
587 // BUGBUG: Need to make sure that the new file does not already
590 fsize
= FvBufExpand3ByteSize (fhdr
->Size
);
591 if (fsize
== 0 || (offset
+ fsize
> fvSize
)) {
592 return EFI_VOLUME_CORRUPTED
;
595 offset
= offset
+ fsize
;
600 while ((clearLoop
< newSize
) &&
601 (((UINT8
*)fhdr
)[clearLoop
] ==
602 (UINT8
)((hdr
->Attributes
& EFI_FVB2_ERASE_POLARITY
) ? 0xFF : 0)
609 // We found a place in the FV which is empty and big enough for
612 if (clearLoop
>= newSize
) {
616 offset
= offset
+ 1; // Make some forward progress
619 if (offset
+ newSize
> fvSize
) {
620 return EFI_OUT_OF_RESOURCES
;
623 CommonLibBinderCopyMem (fhdr
, File
, newSize
);
630 FvBufAddFileWithExtend (
638 Adds a new FFS file. Extends the firmware volume if needed.
642 Fv - Source and destination firmware volume.
643 Note: If the FV is extended, then the original firmware volume
646 Size - The minimum size that the firmware volume is to be extended by.
647 The FV may be extended more than this size.
656 EFI_FFS_FILE_HEADER
* NewFile
;
658 NewFile
= (EFI_FFS_FILE_HEADER
*)File
;
661 // Try to add to the capsule volume
663 Status
= FvBufAddFile (*Fv
, NewFile
);
664 if (Status
== EFI_OUT_OF_RESOURCES
) {
666 // Try to extend the capsule volume by the size of the file
668 Status
= FvBufExtend (Fv
, FvBufExpand3ByteSize (NewFile
->Size
));
669 if (EFI_ERROR (Status
)) {
674 // Now, try to add the file again
676 Status
= FvBufAddFile (*Fv
, NewFile
);
692 Adds a new FFS VFT (Volume Top File) file. In other words, adds the
693 file to the end of the firmware volume.
697 Fv - Address of the Fv in memory
698 File - FFS file to add to Fv
708 EFI_FIRMWARE_VOLUME_HEADER
*hdr
= (EFI_FIRMWARE_VOLUME_HEADER
*)Fv
;
710 EFI_FFS_FILE_HEADER
* NewFile
;
716 EFI_FFS_FILE_HEADER
*LastFile
;
722 Status
= FvBufGetSize (Fv
, &fvSize
);
723 if (EFI_ERROR (Status
)) {
727 erasedUint8
= (UINT8
)((hdr
->Attributes
& EFI_FVB2_ERASE_POLARITY
) ? 0xFF : 0);
728 NewFileSize
= FvBufExpand3ByteSize (((EFI_FFS_FILE_HEADER
*)File
)->Size
);
730 if (NewFileSize
!= (UINTN
)ALIGN_POINTER (NewFileSize
, 8)) {
731 return EFI_INVALID_PARAMETER
;
735 // Find the last file in the FV
741 Status
= FvBufFindNextFile (Fv
, &Key
, (VOID
**)&LastFile
);
742 LastFileSize
= FvBufExpand3ByteSize (((EFI_FFS_FILE_HEADER
*)File
)->Size
);
743 } while (!EFI_ERROR (Status
));
746 // If no files were found, then we start at the beginning of the FV
748 if (LastFile
== NULL
) {
749 LastFile
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)hdr
+ hdr
->HeaderLength
);
753 // We want to put the new file (VTF) at the end of the FV
755 NewFile
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)hdr
+ (fvSize
- NewFileSize
));
758 // Check to see if there is enough room for the VTF after the last file
761 if ((UINT8
*)NewFile
< ((UINT8
*)LastFile
+ LastFileSize
)) {
762 return EFI_OUT_OF_RESOURCES
;
766 // Loop to determine if the end of the FV is empty
769 while ((clearLoop
< NewFileSize
) &&
770 (((UINT8
*)NewFile
)[clearLoop
] == erasedUint8
)
776 // Check to see if there was not enough room for the file
778 if (clearLoop
< NewFileSize
) {
779 return EFI_OUT_OF_RESOURCES
;
782 CommonLibBinderCopyMem (NewFile
, File
, NewFileSize
);
789 FvBufCompact3ByteSize (
797 Expands the 3 byte size commonly used in Firmware Volume data structures
801 Size - Address of the 3 byte array representing the size
809 ((UINT8
*)SizeDest
)[0] = (UINT8
)Size
;
810 ((UINT8
*)SizeDest
)[1] = (UINT8
)(Size
>> 8);
811 ((UINT8
*)SizeDest
)[2] = (UINT8
)(Size
>> 16);
815 FvBufExpand3ByteSize (
822 Expands the 3 byte size commonly used in Firmware Volume data structures
826 Size - Address of the 3 byte array representing the size
834 return (((UINT8
*)Size
)[2] << 16) +
835 (((UINT8
*)Size
)[1] << 8) +
849 Iterates through the files contained within the firmware volume
853 Fv - Address of the Fv in memory
854 Key - Should be 0 to get the first file. After that, it should be
855 passed back in without modifying it's contents to retrieve
857 File - Output file pointer
858 File == NULL - invalid parameter
859 otherwise - *File will be update to the location of the file
869 EFI_FIRMWARE_VOLUME_HEADER
*hdr
= (EFI_FIRMWARE_VOLUME_HEADER
*)Fv
;
871 EFI_FFS_FILE_HEADER
*fhdr
= NULL
;
872 EFI_FVB_ATTRIBUTES FvbAttributes
;
879 return EFI_INVALID_PARAMETER
;
882 Status
= FvBufGetSize (Fv
, &fvSize
);
883 if (EFI_ERROR (Status
)) {
888 *Key
= hdr
->HeaderLength
;
891 FvbAttributes
= hdr
->Attributes
;
894 *Key
= (UINTN
)ALIGN_POINTER (*Key
, 8);
895 (*Key
+ sizeof (*fhdr
)) < fvSize
;
896 *Key
= (UINTN
)ALIGN_POINTER (*Key
, 8)
899 fhdr
= (EFI_FFS_FILE_HEADER
*) ((UINT8
*)hdr
+ *Key
);
900 fsize
= FvBufExpand3ByteSize (fhdr
->Size
);
902 if (!EFI_TEST_FFS_ATTRIBUTES_BIT(
905 EFI_FILE_HEADER_VALID
907 EFI_TEST_FFS_ATTRIBUTES_BIT(
910 EFI_FILE_HEADER_INVALID
913 *Key
= *Key
+ 1; // Make some forward progress
916 EFI_TEST_FFS_ATTRIBUTES_BIT(
919 EFI_FILE_MARKED_FOR_UPDATE
921 EFI_TEST_FFS_ATTRIBUTES_BIT(
929 } else if (EFI_TEST_FFS_ATTRIBUTES_BIT(
935 *File
= (UINT8
*)hdr
+ *Key
;
940 *Key
= *Key
+ 1; // Make some forward progress
943 return EFI_NOT_FOUND
;
948 FvBufFindFileByName (
957 Searches the Fv for a file by its name
961 Fv - Address of the Fv in memory
962 Name - Guid filename to search for in the firmware volume
963 File - Output file pointer
964 File == NULL - Only determine if the file exists, based on return
965 value from the function call.
966 otherwise - *File will be update to the location of the file
978 EFI_FFS_FILE_HEADER
*NextFile
;
982 Status
= FvBufFindNextFile (Fv
, &Key
, (VOID
**)&NextFile
);
983 if (EFI_ERROR (Status
)) {
987 if (CommonLibBinderCompareGuid (Name
, &NextFile
->Name
)) {
995 return EFI_NOT_FOUND
;
1000 FvBufFindFileByType (
1002 IN EFI_FV_FILETYPE Type
,
1007 Routine Description:
1009 Searches the Fv for a file by its type
1013 Fv - Address of the Fv in memory
1014 Type - FFS FILE type to search for
1015 File - Output file pointer
1016 (File == NULL) -> Only determine if the file exists, based on return
1017 value from the function call.
1018 otherwise -> *File will be update to the location of the file
1024 EFI_VOLUME_CORRUPTED
1030 EFI_FFS_FILE_HEADER
*NextFile
;
1034 Status
= FvBufFindNextFile (Fv
, &Key
, (VOID
**)&NextFile
);
1035 if (EFI_ERROR (Status
)) {
1039 if (Type
== NextFile
->Type
) {
1047 return EFI_NOT_FOUND
;
1052 FvBufGetFileRawData (
1055 OUT UINTN
* RawDataSize
1059 Routine Description:
1061 Searches the requested file for raw data.
1063 This routine either returns all the payload of a EFI_FV_FILETYPE_RAW file,
1064 or finds the EFI_SECTION_RAW section within the file and returns its data.
1068 FfsFile - Address of the FFS file in memory
1069 RawData - Pointer to the raw data within the file
1070 (This is NOT allocated. It is within the file.)
1071 RawDataSize - Size of the raw data within the file
1080 EFI_FFS_FILE_HEADER
* File
;
1081 EFI_RAW_SECTION
* Section
;
1083 File
= (EFI_FFS_FILE_HEADER
*)FfsFile
;
1086 // Is the file type == EFI_FV_FILETYPE_RAW?
1088 if (File
->Type
== EFI_FV_FILETYPE_RAW
) {
1090 // Raw filetypes don't have sections, so we just return the raw data
1092 *RawData
= (VOID
*)(File
+ 1);
1093 *RawDataSize
= FvBufExpand3ByteSize (File
->Size
) - sizeof (*File
);
1098 // Within the file, we now need to find the EFI_SECTION_RAW section.
1100 Status
= FvBufFindSectionByType (File
, EFI_SECTION_RAW
, (VOID
**)&Section
);
1101 if (EFI_ERROR (Status
)) {
1105 *RawData
= (VOID
*)(Section
+ 1);
1107 FvBufExpand3ByteSize (Section
->Size
) - sizeof (*Section
);
1115 FvBufPackageFreeformRawFile (
1116 IN EFI_GUID
* Filename
,
1118 IN UINTN RawDataSize
,
1123 Routine Description:
1125 Packages up a FFS file containing the input raw data.
1127 The file created will have a type of EFI_FV_FILETYPE_FREEFORM, and will
1128 contain one EFI_FV_FILETYPE_RAW section.
1132 RawData - Pointer to the raw data to be packed
1133 RawDataSize - Size of the raw data to be packed
1134 FfsFile - Address of the packaged FFS file.
1135 Note: The called must deallocate this memory!
1143 EFI_FFS_FILE_HEADER
* NewFile
;
1145 EFI_RAW_SECTION
* NewSection
;
1146 UINT32 NewSectionSize
;
1149 // The section size is the DataSize + the size of the section header
1151 NewSectionSize
= (UINT32
)sizeof (EFI_RAW_SECTION
) + (UINT32
)RawDataSize
;
1154 // The file size is the size of the file header + the section size
1156 NewFileSize
= sizeof (EFI_FFS_FILE_HEADER
) + NewSectionSize
;
1159 // Try to allocate a buffer to build the new FFS file in
1161 NewFile
= CommonLibBinderAllocate (NewFileSize
);
1162 if (NewFile
== NULL
) {
1163 return EFI_OUT_OF_RESOURCES
;
1165 CommonLibBinderSetMem (NewFile
, NewFileSize
, 0);
1168 // The NewSection follow right after the FFS file header
1170 NewSection
= (EFI_RAW_SECTION
*)(NewFile
+ 1);
1171 FvBufCompact3ByteSize (NewSection
->Size
, NewSectionSize
);
1172 NewSection
->Type
= EFI_SECTION_RAW
;
1175 // Copy the actual file data into the buffer
1177 CommonLibBinderCopyMem (NewSection
+ 1, RawData
, RawDataSize
);
1180 // Initialize the FFS file header
1182 CommonLibBinderCopyMem (&NewFile
->Name
, Filename
, sizeof (EFI_GUID
));
1183 FvBufCompact3ByteSize (NewFile
->Size
, NewFileSize
);
1184 NewFile
->Type
= EFI_FV_FILETYPE_FREEFORM
;
1185 NewFile
->Attributes
= 0;
1186 NewFile
->IntegrityCheck
.Checksum
.Header
=
1187 FvBufCalculateChecksum8 ((UINT8
*)NewFile
, sizeof (*NewFile
));
1188 NewFile
->IntegrityCheck
.Checksum
.File
= FFS_FIXED_CHECKSUM
;
1189 NewFile
->State
= (UINT8
)~( EFI_FILE_HEADER_CONSTRUCTION
|
1190 EFI_FILE_HEADER_VALID
|
1201 FvBufFindNextSection (
1202 IN VOID
*SectionsStart
,
1203 IN UINTN TotalSectionsSize
,
1209 Routine Description:
1211 Iterates through the sections contained within a given array of sections
1215 SectionsStart - Address of the start of the FFS sections array
1216 TotalSectionsSize - Total size of all the sections
1217 Key - Should be 0 to get the first section. After that, it should be
1218 passed back in without modifying it's contents to retrieve
1220 Section - Output section pointer
1221 (Section == NULL) -> invalid parameter
1222 otherwise -> *Section will be update to the location of the file
1228 EFI_VOLUME_CORRUPTED
1232 EFI_COMMON_SECTION_HEADER
*sectionHdr
;
1235 *Key
= (UINTN
)ALIGN_POINTER (*Key
, 4); // Sections are DWORD aligned
1237 if ((*Key
+ sizeof (*sectionHdr
)) > TotalSectionsSize
) {
1238 return EFI_NOT_FOUND
;
1241 sectionHdr
= (EFI_COMMON_SECTION_HEADER
*)((UINT8
*)SectionsStart
+ *Key
);
1242 sectionSize
= FvBufExpand3ByteSize (sectionHdr
->Size
);
1244 if (sectionSize
< sizeof (EFI_COMMON_SECTION_HEADER
)) {
1245 return EFI_NOT_FOUND
;
1248 if ((*Key
+ sectionSize
) > TotalSectionsSize
) {
1249 return EFI_NOT_FOUND
;
1252 *Section
= (UINT8
*)sectionHdr
;
1253 *Key
= *Key
+ sectionSize
;
1260 FvBufCountSections (
1266 Routine Description:
1268 Searches the FFS file and counts the number of sections found.
1269 The sections are NOT recursed.
1273 FfsFile - Address of the FFS file in memory
1274 Count - The location to store the section count in
1280 EFI_VOLUME_CORRUPTED
1287 UINTN TotalSectionsSize
;
1288 EFI_COMMON_SECTION_HEADER
* NextSection
;
1290 SectionStart
= (VOID
*)((UINTN
)FfsFile
+ sizeof (EFI_FFS_FILE_HEADER
));
1292 FvBufExpand3ByteSize (((EFI_FFS_FILE_HEADER
*)FfsFile
)->Size
) -
1293 sizeof (EFI_FFS_FILE_HEADER
);
1297 Status
= FvBufFindNextSection (
1301 (VOID
**)&NextSection
1303 if (Status
== EFI_NOT_FOUND
) {
1305 } else if (EFI_ERROR (Status
)) {
1310 // Increment the section counter
1316 return EFI_NOT_FOUND
;
1321 FvBufFindSectionByType (
1328 Routine Description:
1330 Searches the FFS file for a section by its type
1334 FfsFile - Address of the FFS file in memory
1335 Type - FFS FILE section type to search for
1336 Section - Output section pointer
1337 (Section == NULL) -> Only determine if the section exists, based on return
1338 value from the function call.
1339 otherwise -> *Section will be update to the location of the file
1345 EFI_VOLUME_CORRUPTED
1352 UINTN TotalSectionsSize
;
1353 EFI_COMMON_SECTION_HEADER
* NextSection
;
1355 SectionStart
= (VOID
*)((UINTN
)FfsFile
+ sizeof (EFI_FFS_FILE_HEADER
));
1357 FvBufExpand3ByteSize (((EFI_FFS_FILE_HEADER
*)FfsFile
)->Size
) -
1358 sizeof (EFI_FFS_FILE_HEADER
);
1361 Status
= FvBufFindNextSection (
1365 (VOID
**)&NextSection
1367 if (EFI_ERROR (Status
)) {
1371 if (Type
== NextSection
->Type
) {
1372 if (Section
!= NULL
) {
1373 *Section
= NextSection
;
1379 return EFI_NOT_FOUND
;
1389 Routine Description:
1391 Shrinks a firmware volume (in place) to provide a minimal FV.
1393 BUGBUG: Does not handle the case where the firmware volume has a
1394 VTF (Volume Top File). The VTF will not be moved to the
1395 end of the extended FV.
1399 Fv - Firmware volume.
1410 UINT32 NewBlockSize
= 128;
1412 EFI_FFS_FILE_HEADER
* FileIt
;
1413 VOID
* EndOfLastFile
;
1415 EFI_FIRMWARE_VOLUME_HEADER
* FvHdr
;
1417 Status
= FvBufGetSize (Fv
, &OldSize
);
1418 if (EFI_ERROR (Status
)) {
1422 Status
= FvBufUnifyBlockSizes (Fv
, NewBlockSize
);
1423 if (EFI_ERROR (Status
)) {
1428 // Locate the block map in the fv header
1430 FvHdr
= (EFI_FIRMWARE_VOLUME_HEADER
*)Fv
;
1433 // Find the end of the last file
1436 EndOfLastFile
= (UINT8
*)FvHdr
+ FvHdr
->FvLength
;
1437 while (!EFI_ERROR (FvBufFindNextFile (Fv
, &Key
, (VOID
**)&FileIt
))) {
1439 (VOID
*)((UINT8
*)FileIt
+ FvBufExpand3ByteSize (FileIt
->Size
));
1443 // Set the BlockCount to have the minimal number of blocks for the Fv.
1445 BlockCount
= (UINT32
)((UINTN
)EndOfLastFile
- (UINTN
)Fv
);
1446 BlockCount
= BlockCount
+ NewBlockSize
- 1;
1447 BlockCount
= BlockCount
/ NewBlockSize
;
1450 // Adjust the block count to shrink the Fv in place.
1452 FvHdr
->BlockMap
[0].NumBlocks
= BlockCount
;
1453 FvHdr
->FvLength
= BlockCount
* NewBlockSize
;
1456 // Update the FV header checksum
1458 FvBufChecksumHeader (Fv
);
1466 FvBufUnifyBlockSizes (
1472 Routine Description:
1474 Searches the FFS file for a section by its type
1478 Fv - Address of the Fv in memory
1479 BlockSize - The size of the blocks to convert the Fv to. If the total size
1480 of the Fv is not evenly divisible by this size, then
1481 EFI_INVALID_PARAMETER will be returned.
1487 EFI_VOLUME_CORRUPTED
1491 EFI_FIRMWARE_VOLUME_HEADER
*hdr
= (EFI_FIRMWARE_VOLUME_HEADER
*)Fv
;
1492 EFI_FV_BLOCK_MAP_ENTRY
*blk
= hdr
->BlockMap
;
1498 // Scan through the block map list, performing error checking, and adding
1499 // up the total Fv size.
1501 while( blk
->Length
!= 0 ||
1504 Size
= Size
+ (blk
->Length
* blk
->NumBlocks
);
1506 if ((UINT8
*)blk
> ((UINT8
*)hdr
+ hdr
->HeaderLength
)) {
1507 return EFI_VOLUME_CORRUPTED
;
1512 // Make sure that the Fv size is a multiple of the new block size.
1514 if ((Size
% BlockSize
) != 0) {
1515 return EFI_INVALID_PARAMETER
;
1519 // Zero out the entire block map.
1521 CommonLibBinderSetMem (
1523 (UINTN
)blk
- (UINTN
)&hdr
->BlockMap
,
1528 // Write out the single block map entry.
1530 hdr
->BlockMap
[0].Length
= (UINT32
)BlockSize
;
1531 hdr
->BlockMap
[0].NumBlocks
= Size
/ (UINT32
)BlockSize
;
1538 FvBufCalculateSum16 (
1544 Routine Description:
1546 This function calculates the UINT16 sum for the requested region.
1550 Buffer Pointer to buffer containing byte data of component.
1551 Size Size of the buffer
1565 // Perform the word sum for buffer
1567 for (Index
= 0; Index
< Size
; Index
++) {
1568 Sum
= (UINT16
) (Sum
+ Buffer
[Index
]);
1571 return (UINT16
) Sum
;
1577 FvBufCalculateChecksum16 (
1583 Routine Description::
1585 This function calculates the value needed for a valid UINT16 checksum
1589 Buffer Pointer to buffer containing byte data of component.
1590 Size Size of the buffer
1594 The 16 bit checksum value needed.
1598 return (UINT16
)(0x10000 - FvBufCalculateSum16 (Buffer
, Size
));
1604 FvBufCalculateSum8 (
1612 This function calculates the UINT8 sum for the requested region.
1616 Buffer Pointer to buffer containing byte data of component.
1617 Size Size of the buffer
1621 The 8 bit checksum value needed.
1631 // Perform the byte sum for buffer
1633 for (Index
= 0; Index
< Size
; Index
++) {
1634 Sum
= (UINT8
) (Sum
+ Buffer
[Index
]);
1643 FvBufCalculateChecksum8 (
1651 This function calculates the value needed for a valid UINT8 checksum
1655 Buffer Pointer to buffer containing byte data of component.
1656 Size Size of the buffer
1660 The 8 bit checksum value needed.
1664 return (UINT8
)(0x100 - FvBufCalculateSum8 (Buffer
, Size
));