2 This file contains functions required to generate a boot strap file (BSF) also
3 known as the Volume Top File (VTF)
5 Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials are licensed and made available
7 under the terms and conditions of the BSD License which accompanies this
8 distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
20 #include <Common/UefiBaseTypes.h>
22 #include <Guid/PiFirmwareFileSystem.h>
23 #include "CommonLib.h"
24 #include "EfiUtilityMsgs.h"
29 UINTN SectionOptionFlag
= 0;
30 UINTN SectionCompFlag
= 0;
35 BOOLEAN QuietMode
= FALSE
;
37 BOOLEAN VTF_OUTPUT
= FALSE
;
45 PARSED_VTF_INFO
*FileListPtr
;
46 PARSED_VTF_INFO
*FileListHeadPtr
;
53 UINTN ValidLineNum
= 0;
54 UINTN ValidFFDFileListNum
= 0;
57 // Section Description and their number of occurences in *.INF file
60 UINTN SectionOptionNum
= 0;
63 // Global flag which will check for VTF Present, if yes then will be used
64 // to decide about adding FFS header to pad data
66 BOOLEAN VTFPresent
= FALSE
;
67 BOOLEAN SecondVTF
= FALSE
;
70 // Address related information
72 UINT64 Fv1BaseAddress
= 0;
73 UINT64 Fv2BaseAddress
= 0;
74 UINT64 Fv1EndAddress
= 0;
75 UINT64 Fv2EndAddress
= 0;
76 UINT32 Vtf1TotalSize
= SIZE_TO_OFFSET_PAL_A_END
;
77 UINT64 Vtf1LastStartAddress
= 0;
78 UINT32 Vtf2TotalSize
= 0;
79 UINT64 Vtf2LastStartAddress
= 0;
81 UINT32 BufferToTop
= 0;
84 // IA32 Reset Vector Bin name
86 CHAR8 IA32BinFile
[FILE_NAME_SIZE
];
89 // Function Implementations
94 IN OUT UINT8
*MajorVer
,
95 IN OUT UINT8
*MinorVer
100 This function split version to major version and minor version
104 Str - String representing in form XX.XX
105 MajorVer - The major version
106 MinorVer - The minor version
110 EFI_SUCCESS - The function completed successfully.
114 CHAR8 TemStr
[5] = "0000";
122 if (strstr (Str
, ".") != NULL
) {
130 Length
= strlen(Str
);
132 strncpy (TemStr
+ 4 - Length
, Str
, Length
);
134 strncpy (TemStr
, Str
+ Length
- 4, 4);
145 *MajorVer
= (UINT8
) Major
;
146 *MinorVer
= (UINT8
) Minor
;
157 This function cleans up the line by removing all whitespace and
162 Line - The pointer of the string
170 CHAR8 TmpLine
[FILE_NAME_SIZE
];
177 // Change '#' to '//' for Comment style
179 if (((Ptr0
= strchr (Line
, '#')) != NULL
) || ((Ptr0
= strstr (Line
, "//")) != NULL
)) {
180 Line
[Ptr0
- Line
] = 0;
184 // Initialize counters
189 while ((Char
= Line
[Index
]) != 0) {
190 if ((Char
!= ' ') && (Char
!= '\t') && (Char
!= '\n') && (Char
!= '\r')) {
191 TmpLine
[Index2
++] = Char
;
197 strcpy (Line
, TmpLine
);
208 This function calculated number of valid lines in a input file.
212 Fp - Pointer to a file handle which has been opened.
220 CHAR8 Buff
[FILE_NAME_SIZE
];
221 while (fgets(Buff
, sizeof (Buff
), Fp
)) {
238 This function parses the input file and tokenize the string
242 Fp - Pointer to a file handle which has been opened.
251 CHAR8 Buff
[FILE_NAME_SIZE
+ 1];
252 CHAR8 Delimit
[] = "=";
254 Buff
[FILE_NAME_SIZE
] = '\0';
257 while (fgets (Buff
, FILE_NAME_SIZE
, Fp
) != NULL
) {
262 Token
= strtok (Buff
, Delimit
);
263 while (Token
!= NULL
) {
264 strcpy (*TokenStr
, Token
);
266 Token
= strtok (NULL
, Delimit
);
280 This function initializes the relevant global variable which is being
281 used to store the information retrieved from INF file. This also initializes
290 EFI_SUCCESS - The function completed successfully
291 EFI_OUT_OF_RESOURCES - Malloc failed.
296 FileListPtr
= malloc (sizeof (PARSED_VTF_INFO
));
298 if (FileListPtr
== NULL
) {
299 return EFI_OUT_OF_RESOURCES
;
302 FileListHeadPtr
= FileListPtr
;
303 memset (FileListPtr
, 0, sizeof (PARSED_VTF_INFO
));
304 FileListPtr
->NextVtfInfo
= NULL
;
306 remove (SymFileName
);
311 ParseAndUpdateComponents (
312 IN PARSED_VTF_INFO
*VtfInfo
318 This function initializes the relevant global variable which is being
319 used to store the information retrieved from INF file.
323 VtfInfo - A pointer to the VTF Info Structure
334 while (*TokenStr
!= NULL
&& (strnicmp (*TokenStr
, "COMP_NAME", 9) != 0)) {
336 if (strnicmp (*TokenStr
, "COMP_LOC", 8) == 0) {
338 if (strnicmp (*TokenStr
, "F", 1) == 0) {
339 VtfInfo
->LocationType
= FIRST_VTF
;
340 } else if (strnicmp (*TokenStr
, "S", 1) == 0) {
341 VtfInfo
->LocationType
= SECOND_VTF
;
343 VtfInfo
->LocationType
= NONE
;
345 } else if (strnicmp (*TokenStr
, "COMP_TYPE", 9) == 0) {
347 if (AsciiStringToUint64 (*TokenStr
, FALSE
, &StringValue
) != EFI_SUCCESS
) {
348 Error (NULL
, 0, 5001, "Cannot get: \"0x%s\".", *TokenStr
);
352 VtfInfo
->CompType
= (UINT8
) StringValue
;
353 } else if (strnicmp (*TokenStr
, "COMP_VER", 8) == 0) {
355 if (strnicmp (*TokenStr
, "-", 1) == 0) {
356 VtfInfo
->VersionPresent
= FALSE
;
357 VtfInfo
->MajorVer
= 0;
358 VtfInfo
->MinorVer
= 0;
360 VtfInfo
->VersionPresent
= TRUE
;
361 ConvertVersionInfo (*TokenStr
, &VtfInfo
->MajorVer
, &VtfInfo
->MinorVer
);
363 } else if (strnicmp (*TokenStr
, "COMP_BIN", 8) == 0) {
365 strcpy (VtfInfo
->CompBinName
, *TokenStr
);
366 } else if (strnicmp (*TokenStr
, "COMP_SYM", 8) == 0) {
368 strcpy (VtfInfo
->CompSymName
, *TokenStr
);
369 } else if (strnicmp (*TokenStr
, "COMP_SIZE", 9) == 0) {
371 if (strnicmp (*TokenStr
, "-", 1) == 0) {
372 VtfInfo
->PreferredSize
= FALSE
;
373 VtfInfo
->CompSize
= 0;
375 VtfInfo
->PreferredSize
= TRUE
;
376 if (AsciiStringToUint64 (*TokenStr
, FALSE
, &StringValue
) != EFI_SUCCESS
) {
377 Error (NULL
, 0, 5001, "Parse error", "Cannot get: %s.", TokenStr
);
381 VtfInfo
->CompSize
= (UINTN
) StringValue
;
384 } else if (strnicmp (*TokenStr
, "COMP_CS", 7) == 0) {
386 if (strnicmp (*TokenStr
, "1", 1) == 0) {
387 VtfInfo
->CheckSumRequired
= 1;
388 } else if (strnicmp (*TokenStr
, "0", 1) == 0) {
389 VtfInfo
->CheckSumRequired
= 0;
391 Error (NULL
, 0, 3000, "Invaild", "Bad value in INF file required field: Checksum, the value must be '0' or '1'.");
396 if (*TokenStr
== NULL
) {
403 InitializeInFileInfo (
410 This function intializes the relevant global variable which is being
411 used to store the information retrieved from INF file.
424 SectionOptionFlag
= 0;
426 TokenStr
= OrgStrTokPtr
;
428 while (*TokenStr
!= NULL
) {
429 if (strnicmp (*TokenStr
, "[OPTIONS]", 9) == 0) {
430 SectionOptionFlag
= 1;
434 if (strnicmp (*TokenStr
, "[COMPONENTS]", 12) == 0) {
435 if (FileListPtr
== NULL
) {
436 FileListPtr
= FileListHeadPtr
;
440 SectionOptionFlag
= 0;
444 if (SectionOptionFlag
) {
445 if (stricmp (*TokenStr
, "IA32_RST_BIN") == 0) {
447 strcpy (IA32BinFile
, *TokenStr
);
451 if (SectionCompFlag
) {
452 if (stricmp (*TokenStr
, "COMP_NAME") == 0) {
454 strcpy (FileListPtr
->CompName
, *TokenStr
);
456 ParseAndUpdateComponents (FileListPtr
);
459 if (*TokenStr
!= NULL
) {
460 FileListPtr
->NextVtfInfo
= malloc (sizeof (PARSED_VTF_INFO
));
461 if (FileListPtr
->NextVtfInfo
== NULL
) {
462 Error (NULL
, 0, 4003, "Resource", "Out of memory resources.", NULL
);
465 FileListPtr
= FileListPtr
->NextVtfInfo
;
466 memset (FileListPtr
, 0, sizeof (PARSED_VTF_INFO
));
467 FileListPtr
->NextVtfInfo
= NULL
;
479 GetVtfRelatedInfoFromInfFile (
486 This function reads the input file, parse it and create a list of tokens
487 which is parsed and used, to intialize the data related to VTF
491 FileName - FileName which needed to be read to parse data
495 EFI_ABORTED - Error in opening file
496 EFI_INVALID_PARAMETER - File doesn't contain any valid information
497 EFI_OUT_OF_RESOURCES - Malloc Failed
498 EFI_SUCCESS - The function completed successfully
507 Status
= EFI_SUCCESS
;
510 Error (NULL
, 0, 2000, "Invalid parameter", "BSF INF file is invalid!");
516 if (ValidLineNum
== 0) {
517 Error (NULL
, 0, 2000, "Invalid parameter", "File does not contain any valid information!");
518 return EFI_INVALID_PARAMETER
;
521 TokenStr
= (CHAR8
**) malloc (sizeof (UINTN
) * (2 * ValidLineNum
+ 1));
523 if (TokenStr
== NULL
) {
524 return EFI_OUT_OF_RESOURCES
;
527 memset (TokenStr
, 0, (sizeof (UINTN
) * (2 * ValidLineNum
+ 1)));
528 OrgStrTokPtr
= TokenStr
;
530 for (Index
= 0; Index
< (2 * ValidLineNum
); Index
++) {
531 *TokenStr
= (CHAR8
*)malloc (sizeof (CHAR8
) * FILE_NAME_SIZE
);
533 if (*TokenStr
== NULL
) {
534 Status
= EFI_OUT_OF_RESOURCES
;
538 memset (*TokenStr
, 0, FILE_NAME_SIZE
);
542 TokenStr
= OrgStrTokPtr
;
543 fseek (Fp
, 0L, SEEK_SET
);
545 Status
= InitializeComps ();
547 if (Status
!= EFI_SUCCESS
) {
551 Status
= ParseInputFile (Fp
);
552 if (Status
!= EFI_SUCCESS
) {
556 InitializeInFileInfo ();
560 for (Index1
= 0; Index1
< Index
; Index1
++) {
561 free (OrgStrTokPtr
[Index1
]);
570 GetRelativeAddressInVtfBuffer (
572 IN OUT UINTN
*RelativeAddress
,
579 This function checks for the address alignmnet for specified data boundary. In
580 case the address is not aligned, it returns FALSE and the amount of data in
581 terms of byte needed to adjust to get the boundary alignmnet. If data is
582 aligned, TRUE will be returned.
586 Address - The address of the flash map space
587 RelativeAddress - The relative address of the Buffer
588 LocType - The type of the VTF
599 if (LocType
== FIRST_VTF
) {
600 LocalBuff
= (UINT8
*) Vtf1EndBuffer
;
601 TempAddress
= Fv1EndAddress
- Address
;
602 *RelativeAddress
= (UINTN
) LocalBuff
- (UINTN
) TempAddress
;
604 LocalBuff
= (UINT8
*) Vtf2EndBuffer
;
605 TempAddress
= Fv2EndAddress
- Address
;
606 *RelativeAddress
= (UINTN
) LocalBuff
- (UINTN
) TempAddress
;
611 GetComponentVersionInfo (
612 IN OUT PARSED_VTF_INFO
*VtfInfo
,
618 This function will extract the version information from File
622 VtfInfo - A Pointer to the VTF Info Structure
623 Buffer - A Pointer to type UINT8
627 EFI_SUCCESS - The function completed successfully
628 EFI_INVALID_PARAMETER - The parameter is invalid
635 switch (VtfInfo
->CompType
) {
637 case COMP_TYPE_FIT_PAL_A
:
638 case COMP_TYPE_FIT_PAL_B
:
639 memcpy (&VersionInfo
, (Buffer
+ 8), sizeof (UINT16
));
640 VtfInfo
->MajorVer
= (UINT8
) ((VersionInfo
& 0xFF00) >> 8);
641 VtfInfo
->MinorVer
= (UINT8
) (VersionInfo
& 0x00FF);
642 Status
= EFI_SUCCESS
;
646 Status
= EFI_INVALID_PARAMETER
;
654 CheckAddressAlignment (
656 IN UINT64 AlignmentData
,
657 IN OUT UINT64
*AlignAdjustByte
663 This function checks for the address alignmnet for specified data boundary. In
664 case the address is not aligned, it returns FALSE and the amount of data in
665 terms of byte needed to adjust to get the boundary alignmnet. If data is
666 aligned, TRUE will be returned.
670 Address - Pointer to buffer containing byte data of component.
671 AlignmentData - DataSize for which address needed to be aligned
672 AlignAdjustByte - Number of bytes needed to adjust alignment.
676 TRUE - Address is aligned to specific data size boundary
677 FALSE - Address in not aligned to specified data size boundary
678 - Add/Subtract AlignAdjustByte to aling the address.
683 // Check if the assigned address is on address boundary. If not, it will
684 // return the remaining byte required to adjust the address for specified
687 *AlignAdjustByte
= (Address
% AlignmentData
);
689 if (*AlignAdjustByte
== 0) {
697 GetFitTableStartAddress (
698 IN OUT FIT_TABLE
**FitTable
704 Get the FIT table start address in VTF Buffer
708 FitTable - Pointer to available fit table where new component can be added
712 EFI_SUCCESS - The function completed successfully
717 UINT64 FitTableAddOffset
;
718 UINTN RelativeAddress
;
721 // Read the Fit Table address from Itanium-based address map.
723 FitTableAddOffset
= Fv1EndAddress
- (SIZE_IA32_RESET_VECT
+ SIZE_SALE_ENTRY_POINT
+ SIZE_FIT_TABLE_ADD
);
726 // Translate this Itanium-based address in terms of local buffer address which
727 // contains the image for Boot Strapped File. The relative address will be
728 // the address of fit table VTF buffer.
730 GetRelativeAddressInVtfBuffer (FitTableAddOffset
, &RelativeAddress
, FIRST_VTF
);
731 FitTableAdd
= *(UINTN
*) RelativeAddress
;
734 // The FitTableAdd is the extracted Itanium based address pointing to FIT
735 // table. The relative address will return its actual location in VTF
738 GetRelativeAddressInVtfBuffer (FitTableAdd
, &RelativeAddress
, FIRST_VTF
);
740 *FitTable
= (FIT_TABLE
*) RelativeAddress
;
746 GetNextAvailableFitPtr (
747 IN FIT_TABLE
**FitPtr
753 Get the FIT table address and locate the free space in fit where we can add
754 new component. In this process, this function locates the fit table using
755 Fit pointer in Itanium-based address map (as per Intel?Itanium(TM) SAL spec)
756 and locate the available location in FIT table to be used by new components.
757 If there are any Fit table which areg not being used contains ComponentType
758 field as 0x7F. If needed we can change this and spec this out.
762 FitPtr - Pointer to available fit table where new component can be added
766 EFI_SUCCESS - The function completed successfully
770 FIT_TABLE
*TmpFitPtr
;
772 UINT64 FitTableAddOffset
;
774 UINTN NumFitComponents
;
775 UINTN RelativeAddress
;
778 // Read the Fit Table address from Itanium-based address map.
780 FitTableAddOffset
= Fv1EndAddress
- (SIZE_IA32_RESET_VECT
+ SIZE_SALE_ENTRY_POINT
+ SIZE_FIT_TABLE_ADD
);
783 // Translate this Itanium-based address in terms of local buffer address which
784 // contains the image for Boot Strapped File. The relative address will be
785 // the address of fit table VTF buffer.
787 GetRelativeAddressInVtfBuffer (FitTableAddOffset
, &RelativeAddress
, FIRST_VTF
);
788 FitTableAdd
= *(UINTN
*) RelativeAddress
;
791 // The FitTableAdd is the extracted Itanium based address pointing to FIT
792 // table. The relative address will return its actual location in VTF
795 GetRelativeAddressInVtfBuffer (FitTableAdd
, &RelativeAddress
, FIRST_VTF
);
797 TmpFitPtr
= (FIT_TABLE
*) RelativeAddress
;
798 NumFitComponents
= TmpFitPtr
->CompSize
;
801 for (Index
= 0; Index
< NumFitComponents
; Index
++) {
802 if ((TmpFitPtr
->CvAndType
& FIT_TYPE_MASK
) == COMP_TYPE_FIT_UNUSED
) {
822 This function is used by qsort to sort the FIT table based upon Component
823 Type in their incresing order.
827 Arg1 - Pointer to Arg1
828 Arg2 - Pointer to Arg2
836 if ((((FIT_TABLE
*) Arg1
)->CvAndType
& FIT_TYPE_MASK
) > (((FIT_TABLE
*) Arg2
)->CvAndType
& FIT_TYPE_MASK
)) {
838 } else if ((((FIT_TABLE
*) Arg1
)->CvAndType
& FIT_TYPE_MASK
) < (((FIT_TABLE
*) Arg2
)->CvAndType
& FIT_TYPE_MASK
)) {
853 This function is used by qsort to sort the FIT table based upon Component
854 Type in their incresing order.
867 FIT_TABLE
*TmpFitPtr
;
868 UINTN NumFitComponents
;
871 GetFitTableStartAddress (&FitTable
);
872 TmpFitPtr
= FitTable
;
873 NumFitComponents
= 0;
874 for (Index
= 0; Index
< FitTable
->CompSize
; Index
++) {
875 if ((TmpFitPtr
->CvAndType
& FIT_TYPE_MASK
) != COMP_TYPE_FIT_UNUSED
) {
876 NumFitComponents
+= 1;
880 qsort ((VOID
*) FitTable
, NumFitComponents
, sizeof (FIT_TABLE
), CompareItems
);
884 UpdateFitEntryForFwVolume (
891 This function updates the information about Firmware Volume in FIT TABLE.
892 This FIT table has to be immediately below the PAL_A Start and it contains
893 component type and address information. Other information can't be
894 created this time so we would need to fix it up..
899 Size - Firmware Volume Size
907 FIT_TABLE
*CompFitPtr
;
908 UINTN RelativeAddress
;
911 // FV Fit table will be located at PAL_A Startaddress - 16 byte location
913 Vtf1LastStartAddress
-= 0x10;
914 Vtf1TotalSize
+= 0x10;
916 GetRelativeAddressInVtfBuffer (Vtf1LastStartAddress
, &RelativeAddress
, FIRST_VTF
);
918 CompFitPtr
= (FIT_TABLE
*) RelativeAddress
;
919 CompFitPtr
->CompAddress
= Fv1BaseAddress
;
922 // Since we don't have any information about its location in Firmware Volume,
923 // initialize address to 0. This will be updated once Firmware Volume is
924 // being build and its current address will be fixed in FIT table. Currently
925 // we haven't implemented it so far and working on architectural clarafication
928 // Firmware Volume Size in 16 byte block
930 CompFitPtr
->CompSize
= ((UINT32
) Size
) / 16;
933 // Since Firmware Volume does not exist by the time we create this FIT info
934 // this should be fixedup from Firmware Volume creation tool. We haven't
935 // worked out a method so far.
937 CompFitPtr
->CompVersion
= MAKE_VERSION (0, 0);
940 // Since we don't have any info about this file, we are making sure that
941 // checksum is not needed.
943 CompFitPtr
->CvAndType
= CV_N_TYPE (0, COMP_TYPE_FIT_FV_BOOT
);
946 // Since non VTF component will reside outside the VTF, we will not have its
947 // binary image while creating VTF, hence we will not perform checksum at
948 // this time. Once Firmware Volume is being created which will contain this
949 // VTF, it will fix the FIT table for all the non VTF component and hence
952 CompFitPtr
->CheckSum
= 0;
956 UpdateFitEntryForNonVTFComp (
957 IN PARSED_VTF_INFO
*VtfInfo
963 This function updates the information about non VTF component in FIT TABLE.
964 Since non VTF componets binaries are not part of VTF binary, we would still
965 be required to update its location information in Firmware Volume, inside
970 VtfInfo - Pointer to VTF Info Structure
974 EFI_ABORTED - The function fails to update the component in FIT
975 EFI_SUCCESS - The function completed successfully
979 FIT_TABLE
*CompFitPtr
;
982 // Scan the FIT table for available space
984 GetNextAvailableFitPtr (&CompFitPtr
);
985 if (CompFitPtr
== NULL
) {
986 Error (NULL
, 0, 5003, "Invalid", "Can't update this component in FIT");
991 // Since we don't have any information about its location in Firmware Volume,
992 // initialize address to 0. This will be updated once Firmware Volume is
993 // being build and its current address will be fixed in FIT table
995 CompFitPtr
->CompAddress
= 0;
996 CompFitPtr
->CompSize
= VtfInfo
->CompSize
;
997 CompFitPtr
->CompVersion
= MAKE_VERSION (VtfInfo
->MajorVer
, VtfInfo
->MinorVer
);
998 CompFitPtr
->CvAndType
= CV_N_TYPE (VtfInfo
->CheckSumRequired
, VtfInfo
->CompType
);
1001 // Since non VTF component will reside outside the VTF, we will not have its
1002 // binary image while creating VTF, hence we will not perform checksum at
1003 // this time. Once Firmware Volume is being created which will contain this
1004 // VTF, it will fix the FIT table for all the non VTF component and hence
1007 CompFitPtr
->CheckSum
= 0;
1010 // Fit Type is FV_BOOT which means Firmware Volume, we initialize this to base
1011 // address of Firmware Volume in which this VTF will be attached.
1013 if ((CompFitPtr
->CvAndType
& 0x7F) == COMP_TYPE_FIT_FV_BOOT
) {
1014 CompFitPtr
->CompAddress
= Fv1BaseAddress
;
1022 // This function is updating the SALE_ENTRY in Itanium address space as per SAL
1023 // spec. SALE_ENTRY is being read from SYM file of PEICORE. Once the PEI
1024 // CORE moves in Firmware Volume, we would need to modify this function to be
1025 // used with a API which will detect PEICORE component while building Firmware
1026 // Volume and update its entry in FIT table as well as in Itanium address space
1027 // as per Intel?Itanium(TM) SAL address space
1031 IN PARSED_VTF_INFO
*VtfInfo
,
1032 IN UINT64
*CompStartAddress
1036 Routine Description:
1038 This function updated the architectural entry point in IPF, SALE_ENTRY.
1042 VtfInfo - Pointer to VTF Info Structure
1043 CompStartAddress - Pointer to Component Start Address
1047 EFI_INVALID_PARAMETER - The parameter is invalid
1048 EFI_OUT_OF_RESOURCES - Resource can not be allocated
1049 EFI_SUCCESS - The function completed successfully
1053 UINTN RelativeAddress
;
1058 CHAR8 Buff
[FILE_NAME_SIZE
];
1061 CHAR8 OffsetStr
[30];
1066 CHAR8
*FormatString
;
1069 Fp
= fopen (LongFilePath (VtfInfo
->CompSymName
), "rb");
1072 Error (NULL
, 0, 0001, "Error opening file", VtfInfo
->CompSymName
);
1073 return EFI_INVALID_PARAMETER
;
1077 // Generate the format string for fscanf
1079 FormatLength
= snprintf (
1082 "%%%us %%%us %%%us %%%us %%%us %%%us %%%us",
1083 (unsigned) sizeof (Buff1
) - 1,
1084 (unsigned) sizeof (Buff2
) - 1,
1085 (unsigned) sizeof (OffsetStr
) - 1,
1086 (unsigned) sizeof (Buff3
) - 1,
1087 (unsigned) sizeof (Buff4
) - 1,
1088 (unsigned) sizeof (Buff5
) - 1,
1089 (unsigned) sizeof (Token
) - 1
1092 FormatString
= (CHAR8
*) malloc (FormatLength
);
1093 if (FormatString
== NULL
) {
1096 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
1097 return EFI_OUT_OF_RESOURCES
;
1103 "%%%us %%%us %%%us %%%us %%%us %%%us %%%us",
1104 (unsigned) sizeof (Buff1
) - 1,
1105 (unsigned) sizeof (Buff2
) - 1,
1106 (unsigned) sizeof (OffsetStr
) - 1,
1107 (unsigned) sizeof (Buff3
) - 1,
1108 (unsigned) sizeof (Buff4
) - 1,
1109 (unsigned) sizeof (Buff5
) - 1,
1110 (unsigned) sizeof (Token
) - 1
1113 while (fgets (Buff
, sizeof (Buff
), Fp
) != NULL
) {
1125 if (strnicmp (Token
, "SALE_ENTRY", 10) == 0) {
1130 Offset
= strtoul (OffsetStr
, NULL
, 16);
1132 *CompStartAddress
+= Offset
;
1133 SalEntryAdd
= Fv1EndAddress
- (SIZE_IA32_RESET_VECT
+ SIZE_SALE_ENTRY_POINT
);
1135 GetRelativeAddressInVtfBuffer (SalEntryAdd
, &RelativeAddress
, FIRST_VTF
);
1137 memcpy ((VOID
*) RelativeAddress
, (VOID
*) CompStartAddress
, sizeof (UINT64
));
1139 if (FormatString
!= NULL
) {
1140 free (FormatString
);
1151 CreateAndUpdateComponent (
1152 IN PARSED_VTF_INFO
*VtfInfo
1156 Routine Description:
1158 This function reads the binary file for each components and update them
1159 in VTF Buffer as well as in FIT table. If the component is located in non
1160 VTF area, only the FIT table address will be updated
1164 VtfInfo - Pointer to Parsed Info
1168 EFI_SUCCESS - The function completed successful
1169 EFI_ABORTED - Aborted due to one of the many reasons like:
1170 (a) Component Size greater than the specified size.
1171 (b) Error opening files.
1172 (c) Fail to get the FIT table address.
1174 EFI_INVALID_PARAMETER Value returned from call to UpdateEntryPoint()
1175 EFI_OUT_OF_RESOURCES Memory allocation failure.
1180 UINT64 CompStartAddress
;
1182 UINT64 NumAdjustByte
;
1185 FIT_TABLE
*CompFitPtr
;
1188 if (VtfInfo
->LocationType
== NONE
) {
1189 UpdateFitEntryForNonVTFComp (VtfInfo
);
1193 Fp
= fopen (LongFilePath (VtfInfo
->CompBinName
), "rb");
1196 Error (NULL
, 0, 0001, "Error opening file", VtfInfo
->CompBinName
);
1200 FileSize
= _filelength (fileno (Fp
));
1201 if ((VtfInfo
->CompType
== COMP_TYPE_FIT_PAL_B
) || (VtfInfo
->CompType
== COMP_TYPE_FIT_PAL_A_SPECIFIC
)) {
1204 // BUGBUG: Satish to correct
1206 FileSize
-= SIZE_OF_PAL_HEADER
;
1209 if (VtfInfo
->PreferredSize
) {
1210 if (FileSize
> VtfInfo
->CompSize
) {
1212 Error (NULL
, 0, 2000, "Invalid parameter", "The component size is more than specified size.");
1216 FileSize
= VtfInfo
->CompSize
;
1219 Buffer
= malloc ((UINTN
) FileSize
);
1220 if (Buffer
== NULL
) {
1222 return EFI_OUT_OF_RESOURCES
;
1224 memset (Buffer
, 0, (UINTN
) FileSize
);
1226 if ((VtfInfo
->CompType
== COMP_TYPE_FIT_PAL_B
) || (VtfInfo
->CompType
== COMP_TYPE_FIT_PAL_A_SPECIFIC
)) {
1229 // Read first 64 bytes of PAL header and use it to find version info
1231 fread (Buffer
, sizeof (UINT8
), SIZE_OF_PAL_HEADER
, Fp
);
1234 // PAL header contains the version info. Currently, we will use the header
1235 // to read version info and then discard.
1237 if (!VtfInfo
->VersionPresent
) {
1238 GetComponentVersionInfo (VtfInfo
, Buffer
);
1242 fread (Buffer
, sizeof (UINT8
), (UINTN
) FileSize
, Fp
);
1246 // If it is non PAL_B component, pass the entire buffer to get the version
1247 // info and implement any specific case inside GetComponentVersionInfo.
1249 if (VtfInfo
->CompType
!= COMP_TYPE_FIT_PAL_B
) {
1250 if (!VtfInfo
->VersionPresent
) {
1251 GetComponentVersionInfo (VtfInfo
, Buffer
);
1255 if (VtfInfo
->LocationType
== SECOND_VTF
) {
1257 CompStartAddress
= (Vtf2LastStartAddress
- FileSize
);
1259 CompStartAddress
= (Vtf1LastStartAddress
- FileSize
);
1262 if (VtfInfo
->CompType
== COMP_TYPE_FIT_PAL_B
) {
1263 Aligncheck
= CheckAddressAlignment (CompStartAddress
, 32 * 1024, &NumAdjustByte
);
1265 Aligncheck
= CheckAddressAlignment (CompStartAddress
, 8, &NumAdjustByte
);
1269 CompStartAddress
-= NumAdjustByte
;
1272 if (VtfInfo
->LocationType
== SECOND_VTF
&& SecondVTF
== TRUE
) {
1273 Vtf2LastStartAddress
= CompStartAddress
;
1274 Vtf2TotalSize
+= (UINT32
) (FileSize
+ NumAdjustByte
);
1275 Status
= UpdateVtfBuffer (CompStartAddress
, Buffer
, FileSize
, SECOND_VTF
);
1276 } else if (VtfInfo
->LocationType
== FIRST_VTF
) {
1277 Vtf1LastStartAddress
= CompStartAddress
;
1278 Vtf1TotalSize
+= (UINT32
) (FileSize
+ NumAdjustByte
);
1279 Status
= UpdateVtfBuffer (CompStartAddress
, Buffer
, FileSize
, FIRST_VTF
);
1282 Error (NULL
, 0, 2000,"Invalid Parameter", "There's component in second VTF so second BaseAddress and Size must be specified!");
1283 return EFI_INVALID_PARAMETER
;
1286 if (EFI_ERROR (Status
)) {
1291 GetNextAvailableFitPtr (&CompFitPtr
);
1292 if (CompFitPtr
== NULL
) {
1297 CompFitPtr
->CompAddress
= CompStartAddress
| IPF_CACHE_BIT
;
1298 if ((FileSize
% 16) != 0) {
1300 Error (NULL
, 0, 2000, "Invalid parameter", "Binary FileSize must be a multiple of 16.");
1301 return EFI_INVALID_PARAMETER
;
1303 //assert ((FileSize % 16) == 0);
1304 CompFitPtr
->CompSize
= (UINT32
) (FileSize
/ 16);
1305 CompFitPtr
->CompVersion
= MAKE_VERSION (VtfInfo
->MajorVer
, VtfInfo
->MinorVer
);
1306 CompFitPtr
->CvAndType
= CV_N_TYPE (VtfInfo
->CheckSumRequired
, VtfInfo
->CompType
);
1307 if (VtfInfo
->CheckSumRequired
) {
1308 CompFitPtr
->CheckSum
= 0;
1309 CompFitPtr
->CheckSum
= CalculateChecksum8 (Buffer
, (UINTN
) FileSize
);
1320 // Update the SYM file for this component based on it's start address.
1322 Status
= UpdateSymFile (CompStartAddress
, SymFileName
, VtfInfo
->CompSymName
, FileSize
);
1323 if (EFI_ERROR (Status
)) {
1326 // At this time, SYM files are not required, so continue on error.
1330 // !!!!!!!!!!!!!!!!!!!!!
1332 // This part of the code is a temporary line since PEICORE is going to be inside
1333 // VTF till we work out how to determine the SALE_ENTRY through it. We will need
1334 // to clarify so many related questions
1335 // !!!!!!!!!!!!!!!!!!!!!!!
1337 if (VtfInfo
->CompType
== COMP_TYPE_FIT_PEICORE
) {
1338 Status
= UpdateEntryPoint (VtfInfo
, &CompStartAddress
);
1345 CreateAndUpdatePAL_A (
1346 IN PARSED_VTF_INFO
*VtfInfo
1350 Routine Description:
1352 This function reads the binary file for each components and update them
1353 in VTF Buffer as well as FIT table
1357 VtfInfo - Pointer to Parsed Info
1361 EFI_ABORTED - Due to one of the following reasons:
1362 (a)Error Opening File
1363 (b)The PAL_A Size is more than specified size status
1364 One of the values mentioned below returned from
1365 call to UpdateSymFile
1366 EFI_SUCCESS - The function completed successfully.
1367 EFI_INVALID_PARAMETER - One of the input parameters was invalid.
1368 EFI_ABORTED - An error occurred.UpdateSymFile
1369 EFI_OUT_OF_RESOURCES - Memory allocation failed.
1374 UINT64 PalStartAddress
;
1376 UINTN RelativeAddress
;
1380 FIT_TABLE
*PalFitPtr
;
1382 Fp
= fopen (LongFilePath (VtfInfo
->CompBinName
), "rb");
1385 Error (NULL
, 0, 0001, "Error opening file", VtfInfo
->CompBinName
);
1389 FileSize
= _filelength (fileno (Fp
));
1390 if (FileSize
< 64) {
1392 Error (NULL
, 0, 2000, "Invalid parameter", "PAL_A bin header is 64 bytes, so the Bin size must be larger than 64 bytes!");
1393 return EFI_INVALID_PARAMETER
;
1395 FileSize
-= SIZE_OF_PAL_HEADER
;
1398 if (VtfInfo
->PreferredSize
) {
1399 if (FileSize
> VtfInfo
->CompSize
) {
1401 Error (NULL
, 0, 2000, "Invalid parameter", "The PAL_A Size is more than the specified size.");
1405 FileSize
= VtfInfo
->CompSize
;
1408 Buffer
= malloc ((UINTN
) FileSize
);
1409 if (Buffer
== NULL
) {
1411 return EFI_OUT_OF_RESOURCES
;
1413 memset (Buffer
, 0, (UINTN
) FileSize
);
1416 // Read, Get version Info and discard the PAL header.
1418 fread (Buffer
, sizeof (UINT8
), SIZE_OF_PAL_HEADER
, Fp
);
1421 // Extract the version info from header of PAL_A. Once done, discrad this buffer
1423 if (!VtfInfo
->VersionPresent
) {
1424 GetComponentVersionInfo (VtfInfo
, Buffer
);
1428 // Read PAL_A file in a buffer
1430 fread (Buffer
, sizeof (UINT8
), (UINTN
) FileSize
, Fp
);
1433 PalStartAddress
= Fv1EndAddress
- (SIZE_TO_OFFSET_PAL_A_END
+ FileSize
);
1434 Vtf1LastStartAddress
= PalStartAddress
;
1435 Vtf1TotalSize
+= (UINT32
) FileSize
;
1436 Status
= UpdateVtfBuffer (PalStartAddress
, Buffer
, FileSize
, FIRST_VTF
);
1438 AbsAddress
= Fv1EndAddress
- SIZE_TO_PAL_A_FIT
;
1439 GetRelativeAddressInVtfBuffer (AbsAddress
, &RelativeAddress
, FIRST_VTF
);
1440 PalFitPtr
= (FIT_TABLE
*) RelativeAddress
;
1441 PalFitPtr
->CompAddress
= PalStartAddress
| IPF_CACHE_BIT
;
1442 //assert ((FileSize % 16) == 0);
1443 if ((FileSize
% 16) != 0) {
1445 Error (NULL
, 0, 2000, "Invalid parameter", "Binary FileSize must be a multiple of 16.");
1446 return EFI_INVALID_PARAMETER
;
1449 PalFitPtr
->CompSize
= (UINT32
) (FileSize
/ 16);
1450 PalFitPtr
->CompVersion
= MAKE_VERSION (VtfInfo
->MajorVer
, VtfInfo
->MinorVer
);
1451 PalFitPtr
->CvAndType
= CV_N_TYPE (VtfInfo
->CheckSumRequired
, VtfInfo
->CompType
);
1452 if (VtfInfo
->CheckSumRequired
) {
1453 PalFitPtr
->CheckSum
= 0;
1454 PalFitPtr
->CheckSum
= CalculateChecksum8 (Buffer
, (UINTN
) FileSize
);
1462 // Update the SYM file for this component based on it's start address.
1464 Status
= UpdateSymFile (PalStartAddress
, SymFileName
, VtfInfo
->CompSymName
, FileSize
);
1465 if (EFI_ERROR (Status
)) {
1468 // At this time, SYM files are not required, so continue on error.
1476 CreateFitTableAndInitialize (
1477 IN PARSED_VTF_INFO
*VtfInfo
1481 Routine Description:
1483 This function creates and intializes FIT table which would be used to
1484 add component info inside this
1488 VtfInfo - Pointer to Parsed Info
1492 EFI_ABORTED - Aborted due to no size information
1493 EFI_SUCCESS - The function completed successfully
1497 UINT64 PalFitTableAdd
;
1499 UINT64 FitTableAddressOffset
;
1500 FIT_TABLE
*PalFitPtr
;
1501 FIT_TABLE
*FitStartPtr
;
1503 UINTN RelativeAddress
;
1506 if (!VtfInfo
->PreferredSize
) {
1507 Error (NULL
, 0, 2000, "Invalid parameter", "FIT could not be allocated because there is no size information.");
1511 if ((VtfInfo
->CompSize
% 16) != 0) {
1512 Error (NULL
, 0, 2000, "Invalid parameter", "Invalid FIT Table Size, it is not a multiple of 16 bytes. Please correct the size.");
1515 PalFitTableAdd
= Fv1EndAddress
- SIZE_TO_PAL_A_FIT
;
1516 GetRelativeAddressInVtfBuffer (PalFitTableAdd
, &RelativeAddress
, FIRST_VTF
);
1517 PalFitPtr
= (FIT_TABLE
*) RelativeAddress
;
1518 PalFitTableAdd
= (PalFitPtr
->CompAddress
- VtfInfo
->CompSize
);
1520 FitTableAdd
= (PalFitPtr
->CompAddress
- 0x10) - VtfInfo
->CompSize
;
1521 FitTableAddressOffset
= Fv1EndAddress
- (SIZE_IA32_RESET_VECT
+ SIZE_SALE_ENTRY_POINT
+ SIZE_FIT_TABLE_ADD
);
1522 GetRelativeAddressInVtfBuffer (FitTableAddressOffset
, &RelativeAddress
, FIRST_VTF
);
1523 *(UINT64
*) RelativeAddress
= FitTableAdd
;
1525 GetRelativeAddressInVtfBuffer (FitTableAdd
, &RelativeAddress
, FIRST_VTF
);
1528 // Update Fit Table with FIT Signature and FIT info in first 16 bytes.
1530 FitStartPtr
= (FIT_TABLE
*) RelativeAddress
;
1532 strncpy ((CHAR8
*) &FitStartPtr
->CompAddress
, FIT_SIGNATURE
, 8); // "_FIT_ "
1533 assert (((VtfInfo
->CompSize
& 0x00FFFFFF) % 16) == 0);
1534 FitStartPtr
->CompSize
= (VtfInfo
->CompSize
& 0x00FFFFFF) / 16;
1535 FitStartPtr
->CompVersion
= MAKE_VERSION (VtfInfo
->MajorVer
, VtfInfo
->MinorVer
);
1538 // BUGBUG: If a checksum is required, add code to checksum the FIT table. Also
1539 // determine what to do for things like the FV component that aren't easily checksummed.
1540 // The checksum will be done once we are done with all the componet update in the FIT
1543 FitStartPtr
->CvAndType
= CV_N_TYPE (VtfInfo
->CheckSumRequired
, VtfInfo
->CompType
);
1545 NumFitComp
= FitStartPtr
->CompSize
;
1550 // Intialize remaining FIT table space to UNUSED fit component type
1551 // so that when we need to create a FIT entry for a component, we can
1552 // locate a free one and use it.
1554 for (Index
= 0; Index
< (NumFitComp
- 1); Index
++) {
1555 FitStartPtr
->CvAndType
= 0x7F; // Initialize all with UNUSED
1559 Vtf1TotalSize
+= VtfInfo
->CompSize
;
1560 Vtf1LastStartAddress
-= VtfInfo
->CompSize
;
1573 Routine Description:
1575 Write Firmware Volume from memory to a file.
1579 FileName - Output File Name which needed to be created/
1581 LocType - The type of the VTF
1585 EFI_ABORTED - Returned due to one of the following resons:
1586 (a) Error Opening File
1587 (b) Failing to copy buffers
1588 EFI_SUCCESS - The fuction completes successfully
1595 UINTN RelativeAddress
;
1597 if (LocType
== FIRST_VTF
) {
1598 GetRelativeAddressInVtfBuffer (Vtf1LastStartAddress
, &RelativeAddress
, FIRST_VTF
);
1599 VtfBuffer
= (VOID
*) RelativeAddress
;
1601 GetRelativeAddressInVtfBuffer (Vtf2LastStartAddress
, &RelativeAddress
, SECOND_VTF
);
1602 VtfBuffer
= (VOID
*) RelativeAddress
;
1605 Fp
= fopen (LongFilePath (FileName
), "wb");
1607 Error (NULL
, 0, 0001, "Error opening file", FileName
);
1611 NumByte
= fwrite (VtfBuffer
, sizeof (UINT8
), (UINTN
) VtfSize
, Fp
);
1617 if (NumByte
!= (sizeof (UINT8
) * VtfSize
)) {
1618 Error (NULL
, 0, 0002, "Error writing file", FileName
);
1627 IN UINT64 StartAddress
,
1634 Routine Description:
1636 Update the Firmware Volume Buffer with requested buffer data
1640 StartAddress - StartAddress in buffer. This number will automatically
1641 point to right address in buffer where data needed
1643 Buffer - Buffer pointer from data will be copied to memory mapped buffer.
1644 DataSize - Size of the data needed to be copied.
1645 LocType - The type of the VTF: First or Second
1649 EFI_ABORTED - The input parameter is error
1650 EFI_SUCCESS - The function completed successfully
1654 UINT8
*LocalBufferPtrToWrite
;
1656 if (LocType
== FIRST_VTF
) {
1657 if ((StartAddress
| IPF_CACHE_BIT
) < (Vtf1LastStartAddress
| IPF_CACHE_BIT
)) {
1658 Error (NULL
, 0, 2000, "Invalid parameter", "Start Address is less than the VTF start address.");
1662 LocalBufferPtrToWrite
= (UINT8
*) Vtf1EndBuffer
;
1664 LocalBufferPtrToWrite
-= (Fv1EndAddress
- StartAddress
);
1668 if ((StartAddress
| IPF_CACHE_BIT
) < (Vtf2LastStartAddress
| IPF_CACHE_BIT
)) {
1669 Error (NULL
, 0, 2000, "Invalid parameter", "Error StartAddress");
1672 LocalBufferPtrToWrite
= (UINT8
*) Vtf2EndBuffer
;
1673 LocalBufferPtrToWrite
-= (Fv2EndAddress
- StartAddress
);
1676 memcpy (LocalBufferPtrToWrite
, Buffer
, (UINTN
) DataSize
);
1683 IN UINT32 TotalVtfSize
,
1688 Routine Description:
1690 Update the Firmware Volume Buffer with requested buffer data
1694 TotalVtfSize - Size of the VTF
1695 Fileoffset - The start of the file relative to the start of the FV.
1696 LocType - The type of the VTF
1700 EFI_SUCCESS - The function completed successfully
1701 EFI_INVALID_PARAMETER - The Ffs File Header Pointer is NULL
1705 EFI_FFS_FILE_HEADER
*FileHeader
;
1706 UINTN RelativeAddress
;
1707 EFI_GUID EfiFirmwareVolumeTopFileGuid
= EFI_FFS_VOLUME_TOP_FILE_GUID
;
1710 // Find the VTF file header location
1712 if (LocType
== FIRST_VTF
) {
1713 GetRelativeAddressInVtfBuffer (Vtf1LastStartAddress
, &RelativeAddress
, FIRST_VTF
);
1714 FileHeader
= (EFI_FFS_FILE_HEADER
*) RelativeAddress
;
1716 GetRelativeAddressInVtfBuffer (Vtf2LastStartAddress
, &RelativeAddress
, SECOND_VTF
);
1717 FileHeader
= (EFI_FFS_FILE_HEADER
*) RelativeAddress
;
1720 if (FileHeader
== NULL
) {
1721 return EFI_INVALID_PARAMETER
;
1727 memset (FileHeader
, 0, sizeof (EFI_FFS_FILE_HEADER
));
1728 memcpy (&FileHeader
->Name
, &EfiFirmwareVolumeTopFileGuid
, sizeof (EFI_GUID
));
1729 FileHeader
->Type
= EFI_FV_FILETYPE_RAW
;
1730 FileHeader
->Attributes
= FFS_ATTRIB_CHECKSUM
;
1733 // Now FileSize includes the EFI_FFS_FILE_HEADER
1735 FileHeader
->Size
[0] = (UINT8
) (TotalVtfSize
& 0x000000FF);
1736 FileHeader
->Size
[1] = (UINT8
) ((TotalVtfSize
& 0x0000FF00) >> 8);
1737 FileHeader
->Size
[2] = (UINT8
) ((TotalVtfSize
& 0x00FF0000) >> 16);
1740 // Fill in checksums and state, all three must be zero for the checksums.
1742 FileHeader
->IntegrityCheck
.Checksum
.Header
= 0;
1743 FileHeader
->IntegrityCheck
.Checksum
.File
= 0;
1744 FileHeader
->State
= 0;
1745 FileHeader
->IntegrityCheck
.Checksum
.Header
= CalculateChecksum8 ((UINT8
*) FileHeader
, sizeof (EFI_FFS_FILE_HEADER
));
1746 FileHeader
->IntegrityCheck
.Checksum
.File
= CalculateChecksum8 ((UINT8
*) (FileHeader
+ 1), TotalVtfSize
- sizeof (EFI_FFS_FILE_HEADER
));
1747 FileHeader
->State
= EFI_FILE_HEADER_CONSTRUCTION
| EFI_FILE_HEADER_VALID
| EFI_FILE_DATA_VALID
;
1753 ValidateAddressAndSize (
1754 IN UINT64 BaseAddress
,
1759 Routine Description:
1761 Update the Firmware Volume Buffer with requested buffer data
1765 BaseAddress - Base address for the Fw Volume.
1767 FwVolSize - Total Size of the FwVolume to which VTF will be attached..
1771 EFI_SUCCESS - The function completed successfully
1772 EFI_UNSUPPORTED - The input parameter is error
1776 if ((FwVolSize
> 0x40) && ((BaseAddress
+ FwVolSize
) % 8 == 0)) {
1780 return EFI_UNSUPPORTED
;
1784 UpdateIA32ResetVector (
1786 IN UINT64 FirstFwVSize
1790 Routine Description:
1792 Update the 16 byte IA32 Reset vector to maintain the compatibility
1796 FileName - Binary file name which contains the IA32 Reset vector info..
1797 FirstFwVSize - Total Size of the FwVolume to which VTF will be attached..
1801 EFI_SUCCESS - The function completed successfully
1802 EFI_ABORTED - Invalid File Size
1803 EFI_INVALID_PARAMETER - Bad File Name
1804 EFI_OUT_OF_RESOURCES - Memory allocation failed.
1809 UINT8
*LocalVtfBuffer
;
1813 if (!strcmp (FileName
, "")) {
1814 return EFI_INVALID_PARAMETER
;
1817 Fp
= fopen (LongFilePath (FileName
), "rb");
1820 Error (NULL
, 0, 0001, "Error opening file", FileName
);
1824 FileSize
= _filelength (fileno (Fp
));
1826 if (FileSize
> 16) {
1831 Buffer
= malloc (FileSize
);
1832 if (Buffer
== NULL
) {
1834 return EFI_OUT_OF_RESOURCES
;
1837 fread (Buffer
, sizeof (UINT8
), FileSize
, Fp
);
1839 LocalVtfBuffer
= (UINT8
*) Vtf1EndBuffer
- SIZE_IA32_RESET_VECT
;
1840 memcpy (LocalVtfBuffer
, Buffer
, FileSize
);
1858 Routine Description:
1860 This function cleans up any allocated buffer
1872 PARSED_VTF_INFO
*TempFileListPtr
;
1883 // Cleanup the buffer which was allocated to read the file names from FV.INF
1885 FileListPtr
= FileListHeadPtr
;
1886 while (FileListPtr
!= NULL
) {
1887 TempFileListPtr
= FileListPtr
->NextVtfInfo
;
1889 FileListPtr
= TempFileListPtr
;
1894 ProcessAndCreateVtf (
1899 Routine Description:
1901 This function process the link list created during INF file parsing
1902 and create component in VTF and updates its info in FIT table
1906 Size - Size of the Firmware Volume of which, this VTF belongs to.
1910 EFI_UNSUPPORTED - Unknown FIT type
1911 EFI_SUCCESS - The function completed successfully
1916 PARSED_VTF_INFO
*ParsedInfoPtr
;
1918 Status
= EFI_SUCCESS
;
1920 ParsedInfoPtr
= FileListHeadPtr
;
1922 while (ParsedInfoPtr
!= NULL
) {
1924 switch (ParsedInfoPtr
->CompType
) {
1926 // COMP_TYPE_FIT_HEADER is a special case, hence handle it here
1928 case COMP_TYPE_FIT_HEADER
:
1929 //COMP_TYPE_FIT_HEADER 0x00
1930 Status
= CreateFitTableAndInitialize (ParsedInfoPtr
);
1934 // COMP_TYPE_FIT_PAL_A is a special case, hence handle it here
1936 case COMP_TYPE_FIT_PAL_A
:
1937 //COMP_TYPE_FIT_PAL_A 0x0F
1938 Status
= CreateAndUpdatePAL_A (ParsedInfoPtr
);
1941 // Based on VTF specification, once the PAL_A component has been written,
1942 // update the Firmware Volume info as FIT table. This will be utilized
1943 // to extract the Firmware Volume Start address where this VTF will be
1946 if (Status
== EFI_SUCCESS
) {
1947 UpdateFitEntryForFwVolume (Size
);
1951 case COMP_TYPE_FIT_FV_BOOT
:
1952 //COMP_TYPE_FIT_FV_BOOT 0x7E
1954 // Since FIT entry for Firmware Volume has been created and it is
1955 // located at (PAL_A start - 16 byte). So we will not process any
1956 // Firmware Volume related entry from INF file
1958 Status
= EFI_SUCCESS
;
1963 // Any other component type should be handled here. This will create the
1964 // image in specified VTF and create appropriate entry about this
1965 // component in FIT Entry.
1967 Status
= CreateAndUpdateComponent (ParsedInfoPtr
);
1968 if (EFI_ERROR (Status
)) {
1969 Error (NULL
, 0, 0002, "Error updating component", ParsedInfoPtr
->CompName
);
1975 ParsedInfoPtr
= ParsedInfoPtr
->NextVtfInfo
;
1982 IN UINT64 StartAddress1
,
1984 IN UINT64 StartAddress2
,
1990 Routine Description:
1992 This is the main function which will be called from application.
1996 StartAddress1 - The start address of the first VTF
1997 Size1 - The size of the first VTF
1998 StartAddress2 - The start address of the second VTF
1999 Size2 - The size of the second VTF
2000 fp - The pointer to BSF inf file
2004 EFI_OUT_OF_RESOURCES - Can not allocate memory
2005 The return value can be any of the values
2006 returned by the calls to following functions:
2007 GetVtfRelatedInfoFromInfFile
2009 UpdateIA32ResetVector
2018 Status
= EFI_UNSUPPORTED
;
2021 if (StartAddress2
== 0) {
2027 Fv1BaseAddress
= StartAddress1
;
2028 Fv1EndAddress
= Fv1BaseAddress
+ Size1
;
2029 if (Fv1EndAddress
!= 0x100000000ULL
|| Size1
< 0x100000) {
2030 Error (NULL
, 0, 2000, "Invalid parameter", "Error BaseAddress and Size parameters!");
2031 if (Size1
< 0x100000) {
2032 Error (NULL
, 0, 2000, "Invalid parameter", "The FwVolumeSize must be larger than 1M!");
2033 } else if (SecondVTF
!= TRUE
) {
2034 Error (NULL
, 0, 2000, "Invalid parameter", "BaseAddress + FwVolumeSize must equal 0x100000000!");
2037 return EFI_INVALID_PARAMETER
;
2041 // The image buffer for the First VTF
2043 Vtf1Buffer
= malloc ((UINTN
) Size1
);
2044 if (Vtf1Buffer
== NULL
) {
2045 Error (NULL
, 0, 4001, "Resource", "Not enough resources available to create memory mapped file for the Boot Strap File!");
2046 return EFI_OUT_OF_RESOURCES
;
2048 memset (Vtf1Buffer
, 0x00, (UINTN
) Size1
);
2049 Vtf1EndBuffer
= (UINT8
*) Vtf1Buffer
+ Size1
;
2050 Vtf1LastStartAddress
= Fv1EndAddress
| IPF_CACHE_BIT
;
2053 Fv2BaseAddress
= StartAddress2
;
2054 Fv2EndAddress
= Fv2BaseAddress
+ Size2
;
2055 if (Fv2EndAddress
!= StartAddress1
) {
2056 Error (NULL
, 0, 2000, "Invalid parameter", "Error BaseAddress and Size parameters!");
2057 if (SecondVTF
== TRUE
) {
2058 Error (NULL
, 0, 2000, "Invalid parameter", "FirstBaseAddress + FirstFwVolumeSize must equal 0x100000000!");
2059 Error (NULL
, 0, 2000, "Invalid parameter", "SecondBaseAddress + SecondFwVolumeSize must equal FirstBaseAddress!");
2062 return EFI_INVALID_PARAMETER
;
2066 // The image buffer for the second VTF
2068 Vtf2Buffer
= malloc ((UINTN
) Size2
);
2069 if (Vtf2Buffer
== NULL
) {
2070 Error (NULL
, 0, 4001, "Resource", "Not enough resources available to create memory mapped file for the Boot Strap File!");
2071 return EFI_OUT_OF_RESOURCES
;
2073 memset (Vtf2Buffer
, 0x00, (UINTN
) Size2
);
2074 Vtf2EndBuffer
= (UINT8
*) Vtf2Buffer
+ Size2
;
2075 Vtf2LastStartAddress
= Fv2EndAddress
| IPF_CACHE_BIT
;
2078 Status
= GetVtfRelatedInfoFromInfFile (VtfFP
);
2080 if (Status
!= EFI_SUCCESS
) {
2081 Error (NULL
, 0, 0003, "Error parsing file", "the input file.");
2086 Status
= ProcessAndCreateVtf (Size1
);
2087 if (Status
!= EFI_SUCCESS
) {
2092 if (SectionOptionFlag
) {
2093 Status
= UpdateIA32ResetVector (IA32BinFile
, Vtf1TotalSize
);
2094 if (Status
!= EFI_SUCCESS
) {
2101 // Re arrange the FIT Table for Ascending order of their FIT Type..
2106 // All components have been updated in FIT table. Now perform the FIT table
2107 // checksum. The following function will check if Checksum is required,
2108 // if yes, then it will perform the checksum otherwise not.
2110 CalculateFitTableChecksum ();
2113 // Write the FFS header
2115 Vtf1TotalSize
+= sizeof (EFI_FFS_FILE_HEADER
);
2116 Vtf1LastStartAddress
-= sizeof (EFI_FFS_FILE_HEADER
);
2118 Status
= UpdateFfsHeader (Vtf1TotalSize
, FIRST_VTF
);
2119 if (Status
!= EFI_SUCCESS
) {
2124 // Update the VTF buffer into specified VTF binary file
2126 Status
= WriteVtfBinary (OutFileName1
, Vtf1TotalSize
, FIRST_VTF
);
2129 Vtf2TotalSize
+= sizeof (EFI_FFS_FILE_HEADER
);
2130 Vtf2LastStartAddress
-= sizeof (EFI_FFS_FILE_HEADER
);
2131 Status
= UpdateFfsHeader (Vtf2TotalSize
, SECOND_VTF
);
2132 if (Status
!= EFI_SUCCESS
) {
2138 // Update the VTF buffer into specified VTF binary file
2140 Status
= WriteVtfBinary (OutFileName2
, Vtf2TotalSize
, SECOND_VTF
);
2149 PeimFixupInFitTable (
2150 IN UINT64 StartAddress
2154 Routine Description:
2156 This function is an entry point to fixup SAL-E entry point.
2160 StartAddress - StartAddress for PEIM.....
2164 EFI_SUCCESS - The function completed successfully
2165 EFI_ABORTED - Error Opening File
2166 EFI_OUT_OF_RESOURCES - System out of resources for memory allocation.
2172 UINT64
*StartAddressPtr
;
2175 StartAddressPtr
= malloc (sizeof (UINT64
));
2176 if (StartAddressPtr
== NULL
) {
2177 return EFI_OUT_OF_RESOURCES
;
2179 *StartAddressPtr
= StartAddress
;
2181 Fp
= fopen (LongFilePath (OutFileName1
), "rb");
2184 Error (NULL
, 0, 0001, "Error opening file", OutFileName1
);
2185 if (StartAddressPtr
) {
2186 free (StartAddressPtr
);
2191 FirstFwVSize
= _filelength (fileno (Fp
));
2192 fseek (Fp
, (long) (FirstFwVSize
- (UINTN
) (SIZE_IA32_RESET_VECT
+ SIZE_SALE_ENTRY_POINT
)), SEEK_SET
);
2193 fwrite ((VOID
*) StartAddressPtr
, sizeof (UINT64
), 1, Fp
);
2199 if (StartAddressPtr
) {
2200 free (StartAddressPtr
);
2203 Status
= EFI_SUCCESS
;
2209 IN UINT64 BaseAddress
,
2210 IN CHAR8
*DestFileName
,
2211 IN CHAR8
*SourceFileName
,
2217 Routine Description:
2219 This function adds the SYM tokens in the source file to the destination file.
2220 The SYM tokens are updated to reflect the base address.
2224 BaseAddress - The base address for the new SYM tokens.
2225 DestFileName - The destination file.
2226 SourceFileName - The source file.
2227 FileSize - Size of bin file.
2231 EFI_SUCCESS - The function completed successfully.
2232 EFI_INVALID_PARAMETER - One of the input parameters was invalid.
2233 EFI_ABORTED - An error occurred.
2239 CHAR8 Buffer
[MAX_LONG_FILE_PATH
];
2240 CHAR8 Type
[MAX_LONG_FILE_PATH
];
2241 CHAR8 Address
[MAX_LONG_FILE_PATH
];
2242 CHAR8 Section
[MAX_LONG_FILE_PATH
];
2243 CHAR8 Token
[MAX_LONG_FILE_PATH
];
2244 CHAR8 BaseToken
[MAX_LONG_FILE_PATH
];
2245 CHAR8
*FormatString
;
2247 UINT64 TokenAddress
;
2251 // Verify input parameters.
2253 if (BaseAddress
== 0 || DestFileName
== NULL
|| SourceFileName
== NULL
) {
2254 return EFI_INVALID_PARAMETER
;
2258 // Open the source file
2260 SourceFile
= fopen (LongFilePath (SourceFileName
), "r");
2261 if (SourceFile
== NULL
) {
2264 // SYM files are not required.
2270 // Use the file name minus extension as the base for tokens
2272 strcpy (BaseToken
, SourceFileName
);
2273 strtok (BaseToken
, ". \t\n");
2274 strcat (BaseToken
, "__");
2277 // Open the destination file
2279 DestFile
= fopen (LongFilePath (DestFileName
), "a+");
2280 if (DestFile
== NULL
) {
2281 fclose (SourceFile
);
2282 Error (NULL
, 0, 0001, "Error opening file", DestFileName
);
2287 // If this is the beginning of the output file, write the symbol format info.
2289 if (fseek (DestFile
, 0, SEEK_END
) != 0) {
2290 fclose (SourceFile
);
2292 Error (NULL
, 0, 2000, "Invalid parameter", "not at the beginning of the output file.");
2296 StartLocation
= ftell (DestFile
);
2298 if (StartLocation
== 0) {
2299 fprintf (DestFile
, "TEXTSYM format | V1.0\n");
2300 } else if (StartLocation
== -1) {
2301 fclose (SourceFile
);
2303 Error (NULL
, 0, 2000, "Invalid parameter", "StartLocation error");
2308 // Read the first line
2310 if (fgets (Buffer
, MAX_LONG_FILE_PATH
, SourceFile
) == NULL
) {
2315 // Make sure it matches the expected sym format
2317 if (strcmp (Buffer
, "TEXTSYM format | V1.0\n")) {
2318 fclose (SourceFile
);
2320 Error (NULL
, 0, 2000, "Invalid parameter", "The symbol file does not match the expected TEXTSYM format (V1.0.)");
2325 // Generate the format string for fscanf
2327 FormatLength
= snprintf (
2330 "%%%us | %%%us | %%%us | %%%us\n",
2331 (unsigned) sizeof (Type
) - 1,
2332 (unsigned) sizeof (Address
) - 1,
2333 (unsigned) sizeof (Section
) - 1,
2334 (unsigned) sizeof (Token
) - 1
2337 FormatString
= (CHAR8
*) malloc (FormatLength
);
2338 if (FormatString
== NULL
) {
2339 fclose (SourceFile
);
2341 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
2348 "%%%us | %%%us | %%%us | %%%us\n",
2349 (unsigned) sizeof (Type
) - 1,
2350 (unsigned) sizeof (Address
) - 1,
2351 (unsigned) sizeof (Section
) - 1,
2352 (unsigned) sizeof (Token
) - 1
2358 while (feof (SourceFile
) == 0) {
2363 if (fscanf (SourceFile
, FormatString
, Type
, Address
, Section
, Token
) == 4) {
2366 // Get the token address
2368 AsciiStringToUint64 (Address
, TRUE
, &TokenAddress
);
2369 if (TokenAddress
> FileSize
) {
2371 // Symbol offset larger than FileSize. This Symbol can't be in Bin file. Don't print them.
2377 // Add the base address, the size of the FFS file header and the size of the peim header.
2379 TokenAddress
+= BaseAddress
&~IPF_CACHE_BIT
;
2381 fprintf (DestFile
, "%s | %016llX | ", Type
, (unsigned long long) TokenAddress
);
2382 fprintf (DestFile
, "%s | %s\n %s\n", Section
, Token
, BaseToken
);
2386 free (FormatString
);
2387 fclose (SourceFile
);
2393 CalculateFitTableChecksum (
2398 Routine Description:
2400 This function will perform byte checksum on the FIT table, if the the checksum required
2401 field is set to CheckSum required. If the checksum is not required then checksum byte
2402 will have value as 0;.
2410 Status - Value returned by call to CalculateChecksum8 ()
2411 EFI_SUCCESS - The function completed successfully
2415 FIT_TABLE
*TmpFitPtr
;
2417 UINT64 FitTableAddOffset
;
2418 UINTN RelativeAddress
;
2422 // Read the Fit Table address from Itanium-based address map.
2424 FitTableAddOffset
= Fv1EndAddress
- (SIZE_IA32_RESET_VECT
+ SIZE_SALE_ENTRY_POINT
+ SIZE_FIT_TABLE_ADD
);
2427 // Translate this Itanium-based address in terms of local buffer address which
2428 // contains the image for Boot Strapped File
2430 GetRelativeAddressInVtfBuffer (FitTableAddOffset
, &RelativeAddress
, FIRST_VTF
);
2431 FitTableAdd
= *(UINTN
*) RelativeAddress
;
2433 GetRelativeAddressInVtfBuffer (FitTableAdd
, &RelativeAddress
, FIRST_VTF
);
2435 TmpFitPtr
= (FIT_TABLE
*) RelativeAddress
;
2437 Size
= TmpFitPtr
->CompSize
* 16;
2439 if ((TmpFitPtr
->CvAndType
& CHECKSUM_BIT_MASK
) >> 7) {
2440 TmpFitPtr
->CheckSum
= 0;
2441 TmpFitPtr
->CheckSum
= CalculateChecksum8 ((UINT8
*) TmpFitPtr
, Size
);
2443 TmpFitPtr
->CheckSum
= 0;
2455 Routine Description:
2457 Displays the standard utility information to SDTOUT
2469 fprintf (stdout
, "%s Version %d.%d %s \n", UTILITY_NAME
, UTILITY_MAJOR_VERSION
, UTILITY_MINOR_VERSION
, __BUILD_VERSION
);
2478 Routine Description:
2480 Displays the utility usage syntax to STDOUT
2495 fprintf (stdout
, "Usage: %s [options] <-f input_file> <-r BaseAddress> <-s FwVolumeSize>\n\n", UTILITY_NAME
);
2498 // Copyright declaration
2500 fprintf (stdout
, "Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.\n\n");
2504 fprintf (stdout
, "Options:\n");
2505 fprintf (stdout
, " -f Input_file, --filename Input_file\n\
2506 Input_file is name of the BS Image INF file\n");
2507 fprintf (stdout
, " -r BaseAddress, --baseaddr BaseAddress\n\
2508 BaseAddress is the starting address of Firmware Volume\n\
2509 where Boot Strapped Image will reside.\n");
2510 fprintf (stdout
, " -s FwVolumeSize, --size FwVolumeSize\n\
2511 FwVolumeSize is the size of Firmware Volume.\n");
2512 fprintf (stdout
, " -o FileName, --output FileName\n\
2513 File will be created to store the ouput content.\n");
2514 fprintf (stdout
, " -v, --verbose Turn on verbose output with informational messages.\n");
2515 fprintf (stdout
, " --version Show program's version number and exit.\n");
2516 fprintf (stdout
, " -h, --help Show this help message and exit.\n");
2517 fprintf (stdout
, " -q, --quiet Disable all messages except FATAL ERRORS.\n");
2518 fprintf (stdout
, " -d, --debug [#, 0-9] Enable debug messages at level #.\n");
2528 Routine Description:
2530 This utility uses GenVtf.dll to build a Boot Strap File Image which will be
2531 part of firmware volume image.
2535 argc - The count of the parameters
2536 argv - The parameters
2541 0 - No error conditions detected.
2542 1 - One or more of the input parameters is invalid.
2543 2 - A resource required by the utility was unavailable.
2544 - Most commonly this will be memory allocation or file creation.
2545 3 - GenFvImage.dll could not be loaded.
2546 4 - Error executing the GenFvImage dll.
2547 5 - Now this tool does not support the IA32 platform
2552 UINT64 StartAddress1
;
2553 UINT64 StartAddress2
;
2556 BOOLEAN FirstRoundO
;
2557 BOOLEAN FirstRoundB
;
2558 BOOLEAN FirstRoundS
;
2563 SetUtilityName (UTILITY_NAME
);
2566 // Initialize variables
2576 OutFileName1
= NULL
;
2577 OutFileName2
= NULL
;
2582 // Verify the correct number of arguments
2589 if ((strcmp(argv
[1], "-h") == 0) || (strcmp(argv
[1], "--help") == 0)) {
2594 if ((strcmp(argv
[1], "--version") == 0)) {
2600 // Parse the command line arguments
2602 for (Index
= 1; Index
< argc
; Index
+= 2) {
2603 if ((stricmp (argv
[Index
], "-o") == 0) || (stricmp (argv
[Index
], "--output") == 0)) {
2604 if (argv
[Index
+ 1] == NULL
|| argv
[Index
+ 1][0] == '-') {
2605 Error (NULL
, 0, 1003, "Invalid option value", "Output file is missing for -o option");
2609 // Get the output file name
2614 // It's the first output file name
2616 OutFileName1
= (CHAR8
*)argv
[Index
+1];
2617 FirstRoundO
= FALSE
;
2620 //It's the second output file name
2622 OutFileName2
= (CHAR8
*)argv
[Index
+1];
2627 if ((stricmp (argv
[Index
], "-f") == 0) || (stricmp (argv
[Index
], "--filename") == 0)) {
2628 if (argv
[Index
+ 1] == NULL
|| argv
[Index
+ 1][0] == '-') {
2629 Error (NULL
, 0, 1003, "Invalid option value", "BS Image INF file is missing for -f option");
2633 // Get the input VTF file name
2635 VtfFileName
= argv
[Index
+1];
2636 if (VtfFP
!= NULL
) {
2638 // VTF file name has been given previously, override with the new value
2642 VtfFP
= fopen (LongFilePath (VtfFileName
), "rb");
2643 if (VtfFP
== NULL
) {
2644 Error (NULL
, 0, 0001, "Error opening file", VtfFileName
);
2650 if ((stricmp (argv
[Index
], "-r") == 0) || (stricmp (argv
[Index
], "--baseaddr") == 0)) {
2652 Status
= AsciiStringToUint64 (argv
[Index
+ 1], FALSE
, &StartAddress1
);
2653 FirstRoundB
= FALSE
;
2655 Status
= AsciiStringToUint64 (argv
[Index
+ 1], FALSE
, &StartAddress2
);
2657 if (Status
!= EFI_SUCCESS
) {
2658 Error (NULL
, 0, 2000, "Invalid option value", "%s is Bad FV start address.", argv
[Index
+ 1]);
2664 if ((stricmp (argv
[Index
], "-s") == 0) || (stricmp (argv
[Index
], "--size") == 0)) {
2666 Status
= AsciiStringToUint64 (argv
[Index
+ 1], FALSE
, &FwVolSize1
);
2667 FirstRoundS
= FALSE
;
2669 Status
= AsciiStringToUint64 (argv
[Index
+ 1], FALSE
, &FwVolSize2
);
2673 if (Status
!= EFI_SUCCESS
) {
2674 Error (NULL
, 0, 2000, "Invalid option value", "%s is Bad FV size.", argv
[Index
+ 1]);
2680 if ((stricmp (argv
[Index
], "-v") == 0) || (stricmp (argv
[Index
], "--verbose") == 0)) {
2686 if ((stricmp (argv
[Index
], "-q") == 0) || (stricmp (argv
[Index
], "--quiet") == 0)) {
2692 if ((stricmp (argv
[Index
], "-d") == 0) || (stricmp (argv
[Index
], "--debug") == 0)) {
2694 // debug level specified
2696 Status
= AsciiStringToUint64(argv
[Index
+ 1], FALSE
, &DebugLevel
);
2697 if (EFI_ERROR (Status
)) {
2698 Error (NULL
, 0, 1003, "Invalid option value", "%s = %s", argv
[Index
], argv
[Index
+ 1]);
2701 if (DebugLevel
> 9) {
2702 Error (NULL
, 0, 2000, "Invalid option value", "Unrecognized argument %s.", argv
[Index
+ 1]);
2705 if((DebugLevel
<= 9) &&(DebugLevel
>= 5)) {
2713 Error (NULL
, 0, 2000, "Invalid parameter", "Unrecognized argument %s.", argv
[Index
]);
2717 if (VtfFP
== NULL
) {
2718 Error (NULL
, 0, 2000, "Invalid parameter", "No BS Image INF file is specified");
2723 Error (NULL
, 0, 2000, "Invalid parameter", "No FV base address is specified");
2728 Error (NULL
, 0, 2000, "Invalid parameter", "No FV Size is specified");
2732 // All Parameters has been parsed, now set the message print level
2736 } else if (VerboseMode
) {
2738 } else if (DebugMode
) {
2739 SetPrintLevel(DebugLevel
);
2743 VerboseMsg("%s tool start.\n", UTILITY_NAME
);
2746 if (VTF_OUTPUT
== FALSE
) {
2747 if (SecondVTF
== TRUE
) {
2748 OutFileName1
= VTF_OUTPUT_FILE1
;
2749 OutFileName2
= VTF_OUTPUT_FILE2
;
2751 OutFileName1
= VTF_OUTPUT_FILE1
;
2753 SymFileName
= VTF_SYM_FILE
;
2755 assert (OutFileName1
);
2756 INTN OutFileNameLen
= strlen(OutFileName1
);
2759 for (NewIndex
= OutFileNameLen
; NewIndex
> 0; --NewIndex
) {
2760 if (OutFileName1
[NewIndex
] == '/' || OutFileName1
[NewIndex
] == '\\') {
2764 if (NewIndex
== 0) {
2765 SymFileName
= VTF_SYM_FILE
;
2767 INTN SymFileNameLen
= NewIndex
+ 1 + strlen(VTF_SYM_FILE
);
2768 SymFileName
= malloc(SymFileNameLen
+ 1);
2769 if (SymFileName
== NULL
) {
2770 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
2773 memcpy(SymFileName
, OutFileName1
, NewIndex
+ 1);
2774 memcpy(SymFileName
+ NewIndex
+ 1, VTF_SYM_FILE
, strlen(VTF_SYM_FILE
));
2775 SymFileName
[SymFileNameLen
] = '\0';
2778 DebugMsg(UTILITY_NAME
, 0, DebugLevel
, SymFileName
, NULL
);
2783 // Call the GenVtfImage
2786 DebugMsg(UTILITY_NAME
, 0, DebugLevel
, "Start to generate the VTF image\n", NULL
);
2788 Status
= GenerateVtfImage (StartAddress1
, FwVolSize1
, StartAddress2
, FwVolSize2
, VtfFP
);
2790 if (EFI_ERROR (Status
)) {
2793 case EFI_INVALID_PARAMETER
:
2794 Error (NULL
, 0, 2000, "Invalid parameter", "Invalid parameter passed to GenVtf function.");
2798 Error (NULL
, 0, 3000, "Invalid", "Error detected while creating the file image.");
2801 case EFI_OUT_OF_RESOURCES
:
2802 Error (NULL
, 0, 4002, "Resource", "GenVtfImage function could not allocate required resources.");
2805 case EFI_VOLUME_CORRUPTED
:
2806 Error (NULL
, 0, 3000, "Invalid", "No base address was specified.");
2810 Error (NULL
, 0, 3000, "Invalid", "GenVtfImage function returned unknown status %x.", (int) Status
);
2815 if (VtfFP
!= NULL
) {
2820 DebugMsg(UTILITY_NAME
, 0, DebugLevel
, "VTF image generated successful\n", NULL
);
2824 VerboseMsg("%s tool done with return code is 0x%x.\n", UTILITY_NAME
, GetUtilityStatus ());
2826 return GetUtilityStatus();