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 - 2017, 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 memcpy (TemStr
+ 4 - Length
, Str
, Length
);
134 memcpy (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 if (strlen (*TokenStr
) >= FILE_NAME_SIZE
) {
366 Error (NULL
, 0, 3000, "Invalid", "The 'COMP_BIN' name is too long.");
369 strncpy (VtfInfo
->CompBinName
, *TokenStr
, FILE_NAME_SIZE
- 1);
370 VtfInfo
->CompBinName
[FILE_NAME_SIZE
- 1] = 0;
371 } else if (strnicmp (*TokenStr
, "COMP_SYM", 8) == 0) {
373 if (strlen (*TokenStr
) >= FILE_NAME_SIZE
) {
374 Error (NULL
, 0, 3000, "Invalid", "The 'COMP_SYM' name is too long.");
377 strncpy (VtfInfo
->CompSymName
, *TokenStr
, FILE_NAME_SIZE
- 1);
378 VtfInfo
->CompSymName
[FILE_NAME_SIZE
- 1] = 0;
379 } else if (strnicmp (*TokenStr
, "COMP_SIZE", 9) == 0) {
381 if (strnicmp (*TokenStr
, "-", 1) == 0) {
382 VtfInfo
->PreferredSize
= FALSE
;
383 VtfInfo
->CompSize
= 0;
385 VtfInfo
->PreferredSize
= TRUE
;
386 if (AsciiStringToUint64 (*TokenStr
, FALSE
, &StringValue
) != EFI_SUCCESS
) {
387 Error (NULL
, 0, 5001, "Parse error", "Cannot get: %s.", TokenStr
);
391 VtfInfo
->CompSize
= (UINTN
) StringValue
;
394 } else if (strnicmp (*TokenStr
, "COMP_CS", 7) == 0) {
396 if (strnicmp (*TokenStr
, "1", 1) == 0) {
397 VtfInfo
->CheckSumRequired
= 1;
398 } else if (strnicmp (*TokenStr
, "0", 1) == 0) {
399 VtfInfo
->CheckSumRequired
= 0;
401 Error (NULL
, 0, 3000, "Invaild", "Bad value in INF file required field: Checksum, the value must be '0' or '1'.");
406 if (*TokenStr
== NULL
) {
413 InitializeInFileInfo (
420 This function intializes the relevant global variable which is being
421 used to store the information retrieved from INF file.
434 SectionOptionFlag
= 0;
436 TokenStr
= OrgStrTokPtr
;
438 while (*TokenStr
!= NULL
) {
439 if (strnicmp (*TokenStr
, "[OPTIONS]", 9) == 0) {
440 SectionOptionFlag
= 1;
444 if (strnicmp (*TokenStr
, "[COMPONENTS]", 12) == 0) {
445 if (FileListPtr
== NULL
) {
446 FileListPtr
= FileListHeadPtr
;
450 SectionOptionFlag
= 0;
454 if (SectionOptionFlag
) {
455 if (stricmp (*TokenStr
, "IA32_RST_BIN") == 0) {
457 if (strlen (*TokenStr
) >= FILE_NAME_SIZE
) {
458 Error (NULL
, 0, 3000, "Invalid", "The 'IA32_RST_BIN' name is too long.");
461 strncpy (IA32BinFile
, *TokenStr
, FILE_NAME_SIZE
- 1);
462 IA32BinFile
[FILE_NAME_SIZE
- 1] = 0;
466 if (SectionCompFlag
) {
467 if (stricmp (*TokenStr
, "COMP_NAME") == 0) {
469 if (strlen (*TokenStr
) >= COMPONENT_NAME_SIZE
) {
470 Error (NULL
, 0, 3000, "Invalid", "The 'COMP_NAME' name is too long.");
473 strncpy (FileListPtr
->CompName
, *TokenStr
, COMPONENT_NAME_SIZE
- 1);
474 FileListPtr
->CompName
[COMPONENT_NAME_SIZE
- 1] = 0;
476 ParseAndUpdateComponents (FileListPtr
);
479 if (*TokenStr
!= NULL
) {
480 FileListPtr
->NextVtfInfo
= malloc (sizeof (PARSED_VTF_INFO
));
481 if (FileListPtr
->NextVtfInfo
== NULL
) {
482 Error (NULL
, 0, 4003, "Resource", "Out of memory resources.", NULL
);
485 FileListPtr
= FileListPtr
->NextVtfInfo
;
486 memset (FileListPtr
, 0, sizeof (PARSED_VTF_INFO
));
487 FileListPtr
->NextVtfInfo
= NULL
;
499 GetVtfRelatedInfoFromInfFile (
506 This function reads the input file, parse it and create a list of tokens
507 which is parsed and used, to intialize the data related to VTF
511 FileName - FileName which needed to be read to parse data
515 EFI_ABORTED - Error in opening file
516 EFI_INVALID_PARAMETER - File doesn't contain any valid information
517 EFI_OUT_OF_RESOURCES - Malloc Failed
518 EFI_SUCCESS - The function completed successfully
527 Status
= EFI_SUCCESS
;
530 Error (NULL
, 0, 2000, "Invalid parameter", "BSF INF file is invalid!");
536 if (ValidLineNum
== 0) {
537 Error (NULL
, 0, 2000, "Invalid parameter", "File does not contain any valid information!");
538 return EFI_INVALID_PARAMETER
;
541 TokenStr
= (CHAR8
**) malloc (sizeof (UINTN
) * (2 * ValidLineNum
+ 1));
543 if (TokenStr
== NULL
) {
544 return EFI_OUT_OF_RESOURCES
;
547 memset (TokenStr
, 0, (sizeof (UINTN
) * (2 * ValidLineNum
+ 1)));
548 OrgStrTokPtr
= TokenStr
;
550 for (Index
= 0; Index
< (2 * ValidLineNum
); Index
++) {
551 *TokenStr
= (CHAR8
*)malloc (sizeof (CHAR8
) * FILE_NAME_SIZE
);
553 if (*TokenStr
== NULL
) {
554 Status
= EFI_OUT_OF_RESOURCES
;
558 memset (*TokenStr
, 0, FILE_NAME_SIZE
);
562 TokenStr
= OrgStrTokPtr
;
563 fseek (Fp
, 0L, SEEK_SET
);
565 Status
= InitializeComps ();
567 if (Status
!= EFI_SUCCESS
) {
571 Status
= ParseInputFile (Fp
);
572 if (Status
!= EFI_SUCCESS
) {
576 InitializeInFileInfo ();
580 for (Index1
= 0; Index1
< Index
; Index1
++) {
581 free (OrgStrTokPtr
[Index1
]);
590 GetRelativeAddressInVtfBuffer (
592 IN OUT UINTN
*RelativeAddress
,
599 This function checks for the address alignmnet for specified data boundary. In
600 case the address is not aligned, it returns FALSE and the amount of data in
601 terms of byte needed to adjust to get the boundary alignmnet. If data is
602 aligned, TRUE will be returned.
606 Address - The address of the flash map space
607 RelativeAddress - The relative address of the Buffer
608 LocType - The type of the VTF
619 if (LocType
== FIRST_VTF
) {
620 LocalBuff
= (UINT8
*) Vtf1EndBuffer
;
621 TempAddress
= Fv1EndAddress
- Address
;
622 *RelativeAddress
= (UINTN
) LocalBuff
- (UINTN
) TempAddress
;
624 LocalBuff
= (UINT8
*) Vtf2EndBuffer
;
625 TempAddress
= Fv2EndAddress
- Address
;
626 *RelativeAddress
= (UINTN
) LocalBuff
- (UINTN
) TempAddress
;
631 GetComponentVersionInfo (
632 IN OUT PARSED_VTF_INFO
*VtfInfo
,
638 This function will extract the version information from File
642 VtfInfo - A Pointer to the VTF Info Structure
643 Buffer - A Pointer to type UINT8
647 EFI_SUCCESS - The function completed successfully
648 EFI_INVALID_PARAMETER - The parameter is invalid
655 switch (VtfInfo
->CompType
) {
657 case COMP_TYPE_FIT_PAL_A
:
658 case COMP_TYPE_FIT_PAL_B
:
659 memcpy (&VersionInfo
, (Buffer
+ 8), sizeof (UINT16
));
660 VtfInfo
->MajorVer
= (UINT8
) ((VersionInfo
& 0xFF00) >> 8);
661 VtfInfo
->MinorVer
= (UINT8
) (VersionInfo
& 0x00FF);
662 Status
= EFI_SUCCESS
;
666 Status
= EFI_INVALID_PARAMETER
;
674 CheckAddressAlignment (
676 IN UINT64 AlignmentData
,
677 IN OUT UINT64
*AlignAdjustByte
683 This function checks for the address alignmnet for specified data boundary. In
684 case the address is not aligned, it returns FALSE and the amount of data in
685 terms of byte needed to adjust to get the boundary alignmnet. If data is
686 aligned, TRUE will be returned.
690 Address - Pointer to buffer containing byte data of component.
691 AlignmentData - DataSize for which address needed to be aligned
692 AlignAdjustByte - Number of bytes needed to adjust alignment.
696 TRUE - Address is aligned to specific data size boundary
697 FALSE - Address in not aligned to specified data size boundary
698 - Add/Subtract AlignAdjustByte to aling the address.
703 // Check if the assigned address is on address boundary. If not, it will
704 // return the remaining byte required to adjust the address for specified
707 *AlignAdjustByte
= (Address
% AlignmentData
);
709 if (*AlignAdjustByte
== 0) {
717 GetFitTableStartAddress (
718 IN OUT FIT_TABLE
**FitTable
724 Get the FIT table start address in VTF Buffer
728 FitTable - Pointer to available fit table where new component can be added
732 EFI_SUCCESS - The function completed successfully
737 UINT64 FitTableAddOffset
;
738 UINTN RelativeAddress
;
741 // Read the Fit Table address from Itanium-based address map.
743 FitTableAddOffset
= Fv1EndAddress
- (SIZE_IA32_RESET_VECT
+ SIZE_SALE_ENTRY_POINT
+ SIZE_FIT_TABLE_ADD
);
746 // Translate this Itanium-based address in terms of local buffer address which
747 // contains the image for Boot Strapped File. The relative address will be
748 // the address of fit table VTF buffer.
750 GetRelativeAddressInVtfBuffer (FitTableAddOffset
, &RelativeAddress
, FIRST_VTF
);
751 FitTableAdd
= *(UINTN
*) RelativeAddress
;
754 // The FitTableAdd is the extracted Itanium based address pointing to FIT
755 // table. The relative address will return its actual location in VTF
758 GetRelativeAddressInVtfBuffer (FitTableAdd
, &RelativeAddress
, FIRST_VTF
);
760 *FitTable
= (FIT_TABLE
*) RelativeAddress
;
766 GetNextAvailableFitPtr (
767 IN FIT_TABLE
**FitPtr
773 Get the FIT table address and locate the free space in fit where we can add
774 new component. In this process, this function locates the fit table using
775 Fit pointer in Itanium-based address map (as per Intel?Itanium(TM) SAL spec)
776 and locate the available location in FIT table to be used by new components.
777 If there are any Fit table which areg not being used contains ComponentType
778 field as 0x7F. If needed we can change this and spec this out.
782 FitPtr - Pointer to available fit table where new component can be added
786 EFI_SUCCESS - The function completed successfully
790 FIT_TABLE
*TmpFitPtr
;
792 UINT64 FitTableAddOffset
;
794 UINTN NumFitComponents
;
795 UINTN RelativeAddress
;
798 // Read the Fit Table address from Itanium-based address map.
800 FitTableAddOffset
= Fv1EndAddress
- (SIZE_IA32_RESET_VECT
+ SIZE_SALE_ENTRY_POINT
+ SIZE_FIT_TABLE_ADD
);
803 // Translate this Itanium-based address in terms of local buffer address which
804 // contains the image for Boot Strapped File. The relative address will be
805 // the address of fit table VTF buffer.
807 GetRelativeAddressInVtfBuffer (FitTableAddOffset
, &RelativeAddress
, FIRST_VTF
);
808 FitTableAdd
= *(UINTN
*) RelativeAddress
;
811 // The FitTableAdd is the extracted Itanium based address pointing to FIT
812 // table. The relative address will return its actual location in VTF
815 GetRelativeAddressInVtfBuffer (FitTableAdd
, &RelativeAddress
, FIRST_VTF
);
817 TmpFitPtr
= (FIT_TABLE
*) RelativeAddress
;
818 NumFitComponents
= TmpFitPtr
->CompSize
;
821 for (Index
= 0; Index
< NumFitComponents
; Index
++) {
822 if ((TmpFitPtr
->CvAndType
& FIT_TYPE_MASK
) == COMP_TYPE_FIT_UNUSED
) {
842 This function is used by qsort to sort the FIT table based upon Component
843 Type in their incresing order.
847 Arg1 - Pointer to Arg1
848 Arg2 - Pointer to Arg2
856 if ((((FIT_TABLE
*) Arg1
)->CvAndType
& FIT_TYPE_MASK
) > (((FIT_TABLE
*) Arg2
)->CvAndType
& FIT_TYPE_MASK
)) {
858 } else if ((((FIT_TABLE
*) Arg1
)->CvAndType
& FIT_TYPE_MASK
) < (((FIT_TABLE
*) Arg2
)->CvAndType
& FIT_TYPE_MASK
)) {
873 This function is used by qsort to sort the FIT table based upon Component
874 Type in their incresing order.
887 FIT_TABLE
*TmpFitPtr
;
888 UINTN NumFitComponents
;
891 GetFitTableStartAddress (&FitTable
);
892 TmpFitPtr
= FitTable
;
893 NumFitComponents
= 0;
894 for (Index
= 0; Index
< FitTable
->CompSize
; Index
++) {
895 if ((TmpFitPtr
->CvAndType
& FIT_TYPE_MASK
) != COMP_TYPE_FIT_UNUSED
) {
896 NumFitComponents
+= 1;
900 qsort ((VOID
*) FitTable
, NumFitComponents
, sizeof (FIT_TABLE
), CompareItems
);
904 UpdateFitEntryForFwVolume (
911 This function updates the information about Firmware Volume in FIT TABLE.
912 This FIT table has to be immediately below the PAL_A Start and it contains
913 component type and address information. Other information can't be
914 created this time so we would need to fix it up..
919 Size - Firmware Volume Size
927 FIT_TABLE
*CompFitPtr
;
928 UINTN RelativeAddress
;
931 // FV Fit table will be located at PAL_A Startaddress - 16 byte location
933 Vtf1LastStartAddress
-= 0x10;
934 Vtf1TotalSize
+= 0x10;
936 GetRelativeAddressInVtfBuffer (Vtf1LastStartAddress
, &RelativeAddress
, FIRST_VTF
);
938 CompFitPtr
= (FIT_TABLE
*) RelativeAddress
;
939 CompFitPtr
->CompAddress
= Fv1BaseAddress
;
942 // Since we don't have any information about its location in Firmware Volume,
943 // initialize address to 0. This will be updated once Firmware Volume is
944 // being build and its current address will be fixed in FIT table. Currently
945 // we haven't implemented it so far and working on architectural clarafication
948 // Firmware Volume Size in 16 byte block
950 CompFitPtr
->CompSize
= ((UINT32
) Size
) / 16;
953 // Since Firmware Volume does not exist by the time we create this FIT info
954 // this should be fixedup from Firmware Volume creation tool. We haven't
955 // worked out a method so far.
957 CompFitPtr
->CompVersion
= MAKE_VERSION (0, 0);
960 // Since we don't have any info about this file, we are making sure that
961 // checksum is not needed.
963 CompFitPtr
->CvAndType
= CV_N_TYPE (0, COMP_TYPE_FIT_FV_BOOT
);
966 // Since non VTF component will reside outside the VTF, we will not have its
967 // binary image while creating VTF, hence we will not perform checksum at
968 // this time. Once Firmware Volume is being created which will contain this
969 // VTF, it will fix the FIT table for all the non VTF component and hence
972 CompFitPtr
->CheckSum
= 0;
976 UpdateFitEntryForNonVTFComp (
977 IN PARSED_VTF_INFO
*VtfInfo
983 This function updates the information about non VTF component in FIT TABLE.
984 Since non VTF componets binaries are not part of VTF binary, we would still
985 be required to update its location information in Firmware Volume, inside
990 VtfInfo - Pointer to VTF Info Structure
994 EFI_ABORTED - The function fails to update the component in FIT
995 EFI_SUCCESS - The function completed successfully
999 FIT_TABLE
*CompFitPtr
;
1002 // Scan the FIT table for available space
1004 GetNextAvailableFitPtr (&CompFitPtr
);
1005 if (CompFitPtr
== NULL
) {
1006 Error (NULL
, 0, 5003, "Invalid", "Can't update this component in FIT");
1011 // Since we don't have any information about its location in Firmware Volume,
1012 // initialize address to 0. This will be updated once Firmware Volume is
1013 // being build and its current address will be fixed in FIT table
1015 CompFitPtr
->CompAddress
= 0;
1016 CompFitPtr
->CompSize
= VtfInfo
->CompSize
;
1017 CompFitPtr
->CompVersion
= MAKE_VERSION (VtfInfo
->MajorVer
, VtfInfo
->MinorVer
);
1018 CompFitPtr
->CvAndType
= CV_N_TYPE (VtfInfo
->CheckSumRequired
, VtfInfo
->CompType
);
1021 // Since non VTF component will reside outside the VTF, we will not have its
1022 // binary image while creating VTF, hence we will not perform checksum at
1023 // this time. Once Firmware Volume is being created which will contain this
1024 // VTF, it will fix the FIT table for all the non VTF component and hence
1027 CompFitPtr
->CheckSum
= 0;
1030 // Fit Type is FV_BOOT which means Firmware Volume, we initialize this to base
1031 // address of Firmware Volume in which this VTF will be attached.
1033 if ((CompFitPtr
->CvAndType
& 0x7F) == COMP_TYPE_FIT_FV_BOOT
) {
1034 CompFitPtr
->CompAddress
= Fv1BaseAddress
;
1042 // This function is updating the SALE_ENTRY in Itanium address space as per SAL
1043 // spec. SALE_ENTRY is being read from SYM file of PEICORE. Once the PEI
1044 // CORE moves in Firmware Volume, we would need to modify this function to be
1045 // used with a API which will detect PEICORE component while building Firmware
1046 // Volume and update its entry in FIT table as well as in Itanium address space
1047 // as per Intel?Itanium(TM) SAL address space
1051 IN PARSED_VTF_INFO
*VtfInfo
,
1052 IN UINT64
*CompStartAddress
1056 Routine Description:
1058 This function updated the architectural entry point in IPF, SALE_ENTRY.
1062 VtfInfo - Pointer to VTF Info Structure
1063 CompStartAddress - Pointer to Component Start Address
1067 EFI_INVALID_PARAMETER - The parameter is invalid
1068 EFI_SUCCESS - The function completed successfully
1072 UINTN RelativeAddress
;
1077 CHAR8 Buff
[FILE_NAME_SIZE
];
1080 CHAR8 OffsetStr
[30];
1085 CHAR8 FormatString
[MAX_LINE_LEN
];
1087 Fp
= fopen (LongFilePath (VtfInfo
->CompSymName
), "rb");
1090 Error (NULL
, 0, 0001, "Error opening file", VtfInfo
->CompSymName
);
1091 return EFI_INVALID_PARAMETER
;
1095 // Generate the format string for fscanf
1099 "%%%us %%%us %%%us %%%us %%%us %%%us %%%us",
1100 (unsigned) sizeof (Buff1
) - 1,
1101 (unsigned) sizeof (Buff2
) - 1,
1102 (unsigned) sizeof (OffsetStr
) - 1,
1103 (unsigned) sizeof (Buff3
) - 1,
1104 (unsigned) sizeof (Buff4
) - 1,
1105 (unsigned) sizeof (Buff5
) - 1,
1106 (unsigned) sizeof (Token
) - 1
1109 while (fgets (Buff
, sizeof (Buff
), Fp
) != NULL
) {
1121 if (strnicmp (Token
, "SALE_ENTRY", 10) == 0) {
1126 Offset
= strtoul (OffsetStr
, NULL
, 16);
1128 *CompStartAddress
+= Offset
;
1129 SalEntryAdd
= Fv1EndAddress
- (SIZE_IA32_RESET_VECT
+ SIZE_SALE_ENTRY_POINT
);
1131 GetRelativeAddressInVtfBuffer (SalEntryAdd
, &RelativeAddress
, FIRST_VTF
);
1133 memcpy ((VOID
*) RelativeAddress
, (VOID
*) CompStartAddress
, sizeof (UINT64
));
1143 CreateAndUpdateComponent (
1144 IN PARSED_VTF_INFO
*VtfInfo
1148 Routine Description:
1150 This function reads the binary file for each components and update them
1151 in VTF Buffer as well as in FIT table. If the component is located in non
1152 VTF area, only the FIT table address will be updated
1156 VtfInfo - Pointer to Parsed Info
1160 EFI_SUCCESS - The function completed successful
1161 EFI_ABORTED - Aborted due to one of the many reasons like:
1162 (a) Component Size greater than the specified size.
1163 (b) Error opening files.
1164 (c) Fail to get the FIT table address.
1166 EFI_INVALID_PARAMETER Value returned from call to UpdateEntryPoint()
1167 EFI_OUT_OF_RESOURCES Memory allocation failure.
1172 UINT64 CompStartAddress
;
1174 UINT64 NumAdjustByte
;
1177 FIT_TABLE
*CompFitPtr
;
1180 if (VtfInfo
->LocationType
== NONE
) {
1181 UpdateFitEntryForNonVTFComp (VtfInfo
);
1185 Fp
= fopen (LongFilePath (VtfInfo
->CompBinName
), "rb");
1188 Error (NULL
, 0, 0001, "Error opening file", VtfInfo
->CompBinName
);
1192 FileSize
= _filelength (fileno (Fp
));
1193 if ((VtfInfo
->CompType
== COMP_TYPE_FIT_PAL_B
) || (VtfInfo
->CompType
== COMP_TYPE_FIT_PAL_A_SPECIFIC
)) {
1196 // BUGBUG: Satish to correct
1198 FileSize
-= SIZE_OF_PAL_HEADER
;
1201 if (VtfInfo
->PreferredSize
) {
1202 if (FileSize
> VtfInfo
->CompSize
) {
1204 Error (NULL
, 0, 2000, "Invalid parameter", "The component size is more than specified size.");
1208 FileSize
= VtfInfo
->CompSize
;
1211 Buffer
= malloc ((UINTN
) FileSize
);
1212 if (Buffer
== NULL
) {
1214 return EFI_OUT_OF_RESOURCES
;
1216 memset (Buffer
, 0, (UINTN
) FileSize
);
1218 if ((VtfInfo
->CompType
== COMP_TYPE_FIT_PAL_B
) || (VtfInfo
->CompType
== COMP_TYPE_FIT_PAL_A_SPECIFIC
)) {
1221 // Read first 64 bytes of PAL header and use it to find version info
1223 fread (Buffer
, sizeof (UINT8
), SIZE_OF_PAL_HEADER
, Fp
);
1226 // PAL header contains the version info. Currently, we will use the header
1227 // to read version info and then discard.
1229 if (!VtfInfo
->VersionPresent
) {
1230 GetComponentVersionInfo (VtfInfo
, Buffer
);
1234 fread (Buffer
, sizeof (UINT8
), (UINTN
) FileSize
, Fp
);
1238 // If it is non PAL_B component, pass the entire buffer to get the version
1239 // info and implement any specific case inside GetComponentVersionInfo.
1241 if (VtfInfo
->CompType
!= COMP_TYPE_FIT_PAL_B
) {
1242 if (!VtfInfo
->VersionPresent
) {
1243 GetComponentVersionInfo (VtfInfo
, Buffer
);
1247 if (VtfInfo
->LocationType
== SECOND_VTF
) {
1249 CompStartAddress
= (Vtf2LastStartAddress
- FileSize
);
1251 CompStartAddress
= (Vtf1LastStartAddress
- FileSize
);
1254 if (VtfInfo
->CompType
== COMP_TYPE_FIT_PAL_B
) {
1255 Aligncheck
= CheckAddressAlignment (CompStartAddress
, 32 * 1024, &NumAdjustByte
);
1257 Aligncheck
= CheckAddressAlignment (CompStartAddress
, 8, &NumAdjustByte
);
1261 CompStartAddress
-= NumAdjustByte
;
1264 if (VtfInfo
->LocationType
== SECOND_VTF
&& SecondVTF
== TRUE
) {
1265 Vtf2LastStartAddress
= CompStartAddress
;
1266 Vtf2TotalSize
+= (UINT32
) (FileSize
+ NumAdjustByte
);
1267 Status
= UpdateVtfBuffer (CompStartAddress
, Buffer
, FileSize
, SECOND_VTF
);
1268 } else if (VtfInfo
->LocationType
== FIRST_VTF
) {
1269 Vtf1LastStartAddress
= CompStartAddress
;
1270 Vtf1TotalSize
+= (UINT32
) (FileSize
+ NumAdjustByte
);
1271 Status
= UpdateVtfBuffer (CompStartAddress
, Buffer
, FileSize
, FIRST_VTF
);
1274 Error (NULL
, 0, 2000,"Invalid Parameter", "There's component in second VTF so second BaseAddress and Size must be specified!");
1275 return EFI_INVALID_PARAMETER
;
1278 if (EFI_ERROR (Status
)) {
1283 GetNextAvailableFitPtr (&CompFitPtr
);
1284 if (CompFitPtr
== NULL
) {
1289 CompFitPtr
->CompAddress
= CompStartAddress
| IPF_CACHE_BIT
;
1290 if ((FileSize
% 16) != 0) {
1292 Error (NULL
, 0, 2000, "Invalid parameter", "Binary FileSize must be a multiple of 16.");
1293 return EFI_INVALID_PARAMETER
;
1295 //assert ((FileSize % 16) == 0);
1296 CompFitPtr
->CompSize
= (UINT32
) (FileSize
/ 16);
1297 CompFitPtr
->CompVersion
= MAKE_VERSION (VtfInfo
->MajorVer
, VtfInfo
->MinorVer
);
1298 CompFitPtr
->CvAndType
= CV_N_TYPE (VtfInfo
->CheckSumRequired
, VtfInfo
->CompType
);
1299 if (VtfInfo
->CheckSumRequired
) {
1300 CompFitPtr
->CheckSum
= 0;
1301 CompFitPtr
->CheckSum
= CalculateChecksum8 (Buffer
, (UINTN
) FileSize
);
1312 // Update the SYM file for this component based on it's start address.
1314 Status
= UpdateSymFile (CompStartAddress
, SymFileName
, VtfInfo
->CompSymName
, FileSize
);
1315 if (EFI_ERROR (Status
)) {
1318 // At this time, SYM files are not required, so continue on error.
1322 // !!!!!!!!!!!!!!!!!!!!!
1324 // This part of the code is a temporary line since PEICORE is going to be inside
1325 // VTF till we work out how to determine the SALE_ENTRY through it. We will need
1326 // to clarify so many related questions
1327 // !!!!!!!!!!!!!!!!!!!!!!!
1329 if (VtfInfo
->CompType
== COMP_TYPE_FIT_PEICORE
) {
1330 Status
= UpdateEntryPoint (VtfInfo
, &CompStartAddress
);
1337 CreateAndUpdatePAL_A (
1338 IN PARSED_VTF_INFO
*VtfInfo
1342 Routine Description:
1344 This function reads the binary file for each components and update them
1345 in VTF Buffer as well as FIT table
1349 VtfInfo - Pointer to Parsed Info
1353 EFI_ABORTED - Due to one of the following reasons:
1354 (a)Error Opening File
1355 (b)The PAL_A Size is more than specified size status
1356 One of the values mentioned below returned from
1357 call to UpdateSymFile
1358 EFI_SUCCESS - The function completed successfully.
1359 EFI_INVALID_PARAMETER - One of the input parameters was invalid.
1360 EFI_ABORTED - An error occurred.UpdateSymFile
1361 EFI_OUT_OF_RESOURCES - Memory allocation failed.
1366 UINT64 PalStartAddress
;
1368 UINTN RelativeAddress
;
1372 FIT_TABLE
*PalFitPtr
;
1374 Fp
= fopen (LongFilePath (VtfInfo
->CompBinName
), "rb");
1377 Error (NULL
, 0, 0001, "Error opening file", VtfInfo
->CompBinName
);
1381 FileSize
= _filelength (fileno (Fp
));
1382 if (FileSize
< 64) {
1384 Error (NULL
, 0, 2000, "Invalid parameter", "PAL_A bin header is 64 bytes, so the Bin size must be larger than 64 bytes!");
1385 return EFI_INVALID_PARAMETER
;
1387 FileSize
-= SIZE_OF_PAL_HEADER
;
1390 if (VtfInfo
->PreferredSize
) {
1391 if (FileSize
> VtfInfo
->CompSize
) {
1393 Error (NULL
, 0, 2000, "Invalid parameter", "The PAL_A Size is more than the specified size.");
1397 FileSize
= VtfInfo
->CompSize
;
1400 Buffer
= malloc ((UINTN
) FileSize
);
1401 if (Buffer
== NULL
) {
1403 return EFI_OUT_OF_RESOURCES
;
1405 memset (Buffer
, 0, (UINTN
) FileSize
);
1408 // Read, Get version Info and discard the PAL header.
1410 fread (Buffer
, sizeof (UINT8
), SIZE_OF_PAL_HEADER
, Fp
);
1413 // Extract the version info from header of PAL_A. Once done, discrad this buffer
1415 if (!VtfInfo
->VersionPresent
) {
1416 GetComponentVersionInfo (VtfInfo
, Buffer
);
1420 // Read PAL_A file in a buffer
1422 fread (Buffer
, sizeof (UINT8
), (UINTN
) FileSize
, Fp
);
1425 PalStartAddress
= Fv1EndAddress
- (SIZE_TO_OFFSET_PAL_A_END
+ FileSize
);
1426 Vtf1LastStartAddress
= PalStartAddress
;
1427 Vtf1TotalSize
+= (UINT32
) FileSize
;
1428 Status
= UpdateVtfBuffer (PalStartAddress
, Buffer
, FileSize
, FIRST_VTF
);
1430 AbsAddress
= Fv1EndAddress
- SIZE_TO_PAL_A_FIT
;
1431 GetRelativeAddressInVtfBuffer (AbsAddress
, &RelativeAddress
, FIRST_VTF
);
1432 PalFitPtr
= (FIT_TABLE
*) RelativeAddress
;
1433 PalFitPtr
->CompAddress
= PalStartAddress
| IPF_CACHE_BIT
;
1434 //assert ((FileSize % 16) == 0);
1435 if ((FileSize
% 16) != 0) {
1437 Error (NULL
, 0, 2000, "Invalid parameter", "Binary FileSize must be a multiple of 16.");
1438 return EFI_INVALID_PARAMETER
;
1441 PalFitPtr
->CompSize
= (UINT32
) (FileSize
/ 16);
1442 PalFitPtr
->CompVersion
= MAKE_VERSION (VtfInfo
->MajorVer
, VtfInfo
->MinorVer
);
1443 PalFitPtr
->CvAndType
= CV_N_TYPE (VtfInfo
->CheckSumRequired
, VtfInfo
->CompType
);
1444 if (VtfInfo
->CheckSumRequired
) {
1445 PalFitPtr
->CheckSum
= 0;
1446 PalFitPtr
->CheckSum
= CalculateChecksum8 (Buffer
, (UINTN
) FileSize
);
1454 // Update the SYM file for this component based on it's start address.
1456 Status
= UpdateSymFile (PalStartAddress
, SymFileName
, VtfInfo
->CompSymName
, FileSize
);
1457 if (EFI_ERROR (Status
)) {
1460 // At this time, SYM files are not required, so continue on error.
1468 CreateFitTableAndInitialize (
1469 IN PARSED_VTF_INFO
*VtfInfo
1473 Routine Description:
1475 This function creates and intializes FIT table which would be used to
1476 add component info inside this
1480 VtfInfo - Pointer to Parsed Info
1484 EFI_ABORTED - Aborted due to no size information
1485 EFI_SUCCESS - The function completed successfully
1489 UINT64 PalFitTableAdd
;
1491 UINT64 FitTableAddressOffset
;
1492 FIT_TABLE
*PalFitPtr
;
1493 FIT_TABLE
*FitStartPtr
;
1495 UINTN RelativeAddress
;
1498 if (!VtfInfo
->PreferredSize
) {
1499 Error (NULL
, 0, 2000, "Invalid parameter", "FIT could not be allocated because there is no size information.");
1503 if ((VtfInfo
->CompSize
% 16) != 0) {
1504 Error (NULL
, 0, 2000, "Invalid parameter", "Invalid FIT Table Size, it is not a multiple of 16 bytes. Please correct the size.");
1507 PalFitTableAdd
= Fv1EndAddress
- SIZE_TO_PAL_A_FIT
;
1508 GetRelativeAddressInVtfBuffer (PalFitTableAdd
, &RelativeAddress
, FIRST_VTF
);
1509 PalFitPtr
= (FIT_TABLE
*) RelativeAddress
;
1510 PalFitTableAdd
= (PalFitPtr
->CompAddress
- VtfInfo
->CompSize
);
1512 FitTableAdd
= (PalFitPtr
->CompAddress
- 0x10) - VtfInfo
->CompSize
;
1513 FitTableAddressOffset
= Fv1EndAddress
- (SIZE_IA32_RESET_VECT
+ SIZE_SALE_ENTRY_POINT
+ SIZE_FIT_TABLE_ADD
);
1514 GetRelativeAddressInVtfBuffer (FitTableAddressOffset
, &RelativeAddress
, FIRST_VTF
);
1515 *(UINT64
*) RelativeAddress
= FitTableAdd
;
1517 GetRelativeAddressInVtfBuffer (FitTableAdd
, &RelativeAddress
, FIRST_VTF
);
1520 // Update Fit Table with FIT Signature and FIT info in first 16 bytes.
1522 FitStartPtr
= (FIT_TABLE
*) RelativeAddress
;
1524 strncpy ((CHAR8
*) &FitStartPtr
->CompAddress
, FIT_SIGNATURE
, 8); // "_FIT_ "
1525 assert (((VtfInfo
->CompSize
& 0x00FFFFFF) % 16) == 0);
1526 FitStartPtr
->CompSize
= (VtfInfo
->CompSize
& 0x00FFFFFF) / 16;
1527 FitStartPtr
->CompVersion
= MAKE_VERSION (VtfInfo
->MajorVer
, VtfInfo
->MinorVer
);
1530 // BUGBUG: If a checksum is required, add code to checksum the FIT table. Also
1531 // determine what to do for things like the FV component that aren't easily checksummed.
1532 // The checksum will be done once we are done with all the componet update in the FIT
1535 FitStartPtr
->CvAndType
= CV_N_TYPE (VtfInfo
->CheckSumRequired
, VtfInfo
->CompType
);
1537 NumFitComp
= FitStartPtr
->CompSize
;
1542 // Intialize remaining FIT table space to UNUSED fit component type
1543 // so that when we need to create a FIT entry for a component, we can
1544 // locate a free one and use it.
1546 for (Index
= 0; Index
< (NumFitComp
- 1); Index
++) {
1547 FitStartPtr
->CvAndType
= 0x7F; // Initialize all with UNUSED
1551 Vtf1TotalSize
+= VtfInfo
->CompSize
;
1552 Vtf1LastStartAddress
-= VtfInfo
->CompSize
;
1565 Routine Description:
1567 Write Firmware Volume from memory to a file.
1571 FileName - Output File Name which needed to be created/
1573 LocType - The type of the VTF
1577 EFI_ABORTED - Returned due to one of the following resons:
1578 (a) Error Opening File
1579 (b) Failing to copy buffers
1580 EFI_SUCCESS - The fuction completes successfully
1587 UINTN RelativeAddress
;
1589 if (LocType
== FIRST_VTF
) {
1590 GetRelativeAddressInVtfBuffer (Vtf1LastStartAddress
, &RelativeAddress
, FIRST_VTF
);
1591 VtfBuffer
= (VOID
*) RelativeAddress
;
1593 GetRelativeAddressInVtfBuffer (Vtf2LastStartAddress
, &RelativeAddress
, SECOND_VTF
);
1594 VtfBuffer
= (VOID
*) RelativeAddress
;
1597 Fp
= fopen (LongFilePath (FileName
), "wb");
1599 Error (NULL
, 0, 0001, "Error opening file", FileName
);
1603 NumByte
= fwrite (VtfBuffer
, sizeof (UINT8
), (UINTN
) VtfSize
, Fp
);
1609 if (NumByte
!= (sizeof (UINT8
) * VtfSize
)) {
1610 Error (NULL
, 0, 0002, "Error writing file", FileName
);
1619 IN UINT64 StartAddress
,
1626 Routine Description:
1628 Update the Firmware Volume Buffer with requested buffer data
1632 StartAddress - StartAddress in buffer. This number will automatically
1633 point to right address in buffer where data needed
1635 Buffer - Buffer pointer from data will be copied to memory mapped buffer.
1636 DataSize - Size of the data needed to be copied.
1637 LocType - The type of the VTF: First or Second
1641 EFI_ABORTED - The input parameter is error
1642 EFI_SUCCESS - The function completed successfully
1646 UINT8
*LocalBufferPtrToWrite
;
1648 if (LocType
== FIRST_VTF
) {
1649 if ((StartAddress
| IPF_CACHE_BIT
) < (Vtf1LastStartAddress
| IPF_CACHE_BIT
)) {
1650 Error (NULL
, 0, 2000, "Invalid parameter", "Start Address is less than the VTF start address.");
1654 LocalBufferPtrToWrite
= (UINT8
*) Vtf1EndBuffer
;
1656 LocalBufferPtrToWrite
-= (Fv1EndAddress
- StartAddress
);
1660 if ((StartAddress
| IPF_CACHE_BIT
) < (Vtf2LastStartAddress
| IPF_CACHE_BIT
)) {
1661 Error (NULL
, 0, 2000, "Invalid parameter", "Error StartAddress");
1664 LocalBufferPtrToWrite
= (UINT8
*) Vtf2EndBuffer
;
1665 LocalBufferPtrToWrite
-= (Fv2EndAddress
- StartAddress
);
1668 memcpy (LocalBufferPtrToWrite
, Buffer
, (UINTN
) DataSize
);
1675 IN UINT32 TotalVtfSize
,
1680 Routine Description:
1682 Update the Firmware Volume Buffer with requested buffer data
1686 TotalVtfSize - Size of the VTF
1687 Fileoffset - The start of the file relative to the start of the FV.
1688 LocType - The type of the VTF
1692 EFI_SUCCESS - The function completed successfully
1693 EFI_INVALID_PARAMETER - The Ffs File Header Pointer is NULL
1697 EFI_FFS_FILE_HEADER
*FileHeader
;
1698 UINTN RelativeAddress
;
1699 EFI_GUID EfiFirmwareVolumeTopFileGuid
= EFI_FFS_VOLUME_TOP_FILE_GUID
;
1702 // Find the VTF file header location
1704 if (LocType
== FIRST_VTF
) {
1705 GetRelativeAddressInVtfBuffer (Vtf1LastStartAddress
, &RelativeAddress
, FIRST_VTF
);
1706 FileHeader
= (EFI_FFS_FILE_HEADER
*) RelativeAddress
;
1708 GetRelativeAddressInVtfBuffer (Vtf2LastStartAddress
, &RelativeAddress
, SECOND_VTF
);
1709 FileHeader
= (EFI_FFS_FILE_HEADER
*) RelativeAddress
;
1712 if (FileHeader
== NULL
) {
1713 return EFI_INVALID_PARAMETER
;
1719 memset (FileHeader
, 0, sizeof (EFI_FFS_FILE_HEADER
));
1720 memcpy (&FileHeader
->Name
, &EfiFirmwareVolumeTopFileGuid
, sizeof (EFI_GUID
));
1721 FileHeader
->Type
= EFI_FV_FILETYPE_RAW
;
1722 FileHeader
->Attributes
= FFS_ATTRIB_CHECKSUM
;
1725 // Now FileSize includes the EFI_FFS_FILE_HEADER
1727 FileHeader
->Size
[0] = (UINT8
) (TotalVtfSize
& 0x000000FF);
1728 FileHeader
->Size
[1] = (UINT8
) ((TotalVtfSize
& 0x0000FF00) >> 8);
1729 FileHeader
->Size
[2] = (UINT8
) ((TotalVtfSize
& 0x00FF0000) >> 16);
1732 // Fill in checksums and state, all three must be zero for the checksums.
1734 FileHeader
->IntegrityCheck
.Checksum
.Header
= 0;
1735 FileHeader
->IntegrityCheck
.Checksum
.File
= 0;
1736 FileHeader
->State
= 0;
1737 FileHeader
->IntegrityCheck
.Checksum
.Header
= CalculateChecksum8 ((UINT8
*) FileHeader
, sizeof (EFI_FFS_FILE_HEADER
));
1738 FileHeader
->IntegrityCheck
.Checksum
.File
= CalculateChecksum8 ((UINT8
*) (FileHeader
+ 1), TotalVtfSize
- sizeof (EFI_FFS_FILE_HEADER
));
1739 FileHeader
->State
= EFI_FILE_HEADER_CONSTRUCTION
| EFI_FILE_HEADER_VALID
| EFI_FILE_DATA_VALID
;
1745 ValidateAddressAndSize (
1746 IN UINT64 BaseAddress
,
1751 Routine Description:
1753 Update the Firmware Volume Buffer with requested buffer data
1757 BaseAddress - Base address for the Fw Volume.
1759 FwVolSize - Total Size of the FwVolume to which VTF will be attached..
1763 EFI_SUCCESS - The function completed successfully
1764 EFI_UNSUPPORTED - The input parameter is error
1768 if ((FwVolSize
> 0x40) && ((BaseAddress
+ FwVolSize
) % 8 == 0)) {
1772 return EFI_UNSUPPORTED
;
1776 UpdateIA32ResetVector (
1778 IN UINT64 FirstFwVSize
1782 Routine Description:
1784 Update the 16 byte IA32 Reset vector to maintain the compatibility
1788 FileName - Binary file name which contains the IA32 Reset vector info..
1789 FirstFwVSize - Total Size of the FwVolume to which VTF will be attached..
1793 EFI_SUCCESS - The function completed successfully
1794 EFI_ABORTED - Invalid File Size
1795 EFI_INVALID_PARAMETER - Bad File Name
1796 EFI_OUT_OF_RESOURCES - Memory allocation failed.
1801 UINT8
*LocalVtfBuffer
;
1805 if (!strcmp (FileName
, "")) {
1806 return EFI_INVALID_PARAMETER
;
1809 Fp
= fopen (LongFilePath (FileName
), "rb");
1812 Error (NULL
, 0, 0001, "Error opening file", FileName
);
1816 FileSize
= _filelength (fileno (Fp
));
1818 if (FileSize
> 16) {
1823 Buffer
= malloc (FileSize
);
1824 if (Buffer
== NULL
) {
1826 return EFI_OUT_OF_RESOURCES
;
1829 fread (Buffer
, sizeof (UINT8
), FileSize
, Fp
);
1831 LocalVtfBuffer
= (UINT8
*) Vtf1EndBuffer
- SIZE_IA32_RESET_VECT
;
1832 memcpy (LocalVtfBuffer
, Buffer
, FileSize
);
1850 Routine Description:
1852 This function cleans up any allocated buffer
1864 PARSED_VTF_INFO
*TempFileListPtr
;
1875 // Cleanup the buffer which was allocated to read the file names from FV.INF
1877 FileListPtr
= FileListHeadPtr
;
1878 while (FileListPtr
!= NULL
) {
1879 TempFileListPtr
= FileListPtr
->NextVtfInfo
;
1881 FileListPtr
= TempFileListPtr
;
1886 ProcessAndCreateVtf (
1891 Routine Description:
1893 This function process the link list created during INF file parsing
1894 and create component in VTF and updates its info in FIT table
1898 Size - Size of the Firmware Volume of which, this VTF belongs to.
1902 EFI_UNSUPPORTED - Unknown FIT type
1903 EFI_SUCCESS - The function completed successfully
1908 PARSED_VTF_INFO
*ParsedInfoPtr
;
1910 Status
= EFI_SUCCESS
;
1912 ParsedInfoPtr
= FileListHeadPtr
;
1914 while (ParsedInfoPtr
!= NULL
) {
1916 switch (ParsedInfoPtr
->CompType
) {
1918 // COMP_TYPE_FIT_HEADER is a special case, hence handle it here
1920 case COMP_TYPE_FIT_HEADER
:
1921 //COMP_TYPE_FIT_HEADER 0x00
1922 Status
= CreateFitTableAndInitialize (ParsedInfoPtr
);
1926 // COMP_TYPE_FIT_PAL_A is a special case, hence handle it here
1928 case COMP_TYPE_FIT_PAL_A
:
1929 //COMP_TYPE_FIT_PAL_A 0x0F
1930 Status
= CreateAndUpdatePAL_A (ParsedInfoPtr
);
1933 // Based on VTF specification, once the PAL_A component has been written,
1934 // update the Firmware Volume info as FIT table. This will be utilized
1935 // to extract the Firmware Volume Start address where this VTF will be
1938 if (Status
== EFI_SUCCESS
) {
1939 UpdateFitEntryForFwVolume (Size
);
1943 case COMP_TYPE_FIT_FV_BOOT
:
1944 //COMP_TYPE_FIT_FV_BOOT 0x7E
1946 // Since FIT entry for Firmware Volume has been created and it is
1947 // located at (PAL_A start - 16 byte). So we will not process any
1948 // Firmware Volume related entry from INF file
1950 Status
= EFI_SUCCESS
;
1955 // Any other component type should be handled here. This will create the
1956 // image in specified VTF and create appropriate entry about this
1957 // component in FIT Entry.
1959 Status
= CreateAndUpdateComponent (ParsedInfoPtr
);
1960 if (EFI_ERROR (Status
)) {
1961 Error (NULL
, 0, 0002, "Error updating component", ParsedInfoPtr
->CompName
);
1967 ParsedInfoPtr
= ParsedInfoPtr
->NextVtfInfo
;
1974 IN UINT64 StartAddress1
,
1976 IN UINT64 StartAddress2
,
1982 Routine Description:
1984 This is the main function which will be called from application.
1988 StartAddress1 - The start address of the first VTF
1989 Size1 - The size of the first VTF
1990 StartAddress2 - The start address of the second VTF
1991 Size2 - The size of the second VTF
1992 fp - The pointer to BSF inf file
1996 EFI_OUT_OF_RESOURCES - Can not allocate memory
1997 The return value can be any of the values
1998 returned by the calls to following functions:
1999 GetVtfRelatedInfoFromInfFile
2001 UpdateIA32ResetVector
2010 Status
= EFI_UNSUPPORTED
;
2013 if (StartAddress2
== 0) {
2019 Fv1BaseAddress
= StartAddress1
;
2020 Fv1EndAddress
= Fv1BaseAddress
+ Size1
;
2021 if (Fv1EndAddress
!= 0x100000000ULL
|| Size1
< 0x100000) {
2022 Error (NULL
, 0, 2000, "Invalid parameter", "Error BaseAddress and Size parameters!");
2023 if (Size1
< 0x100000) {
2024 Error (NULL
, 0, 2000, "Invalid parameter", "The FwVolumeSize must be larger than 1M!");
2025 } else if (SecondVTF
!= TRUE
) {
2026 Error (NULL
, 0, 2000, "Invalid parameter", "BaseAddress + FwVolumeSize must equal 0x100000000!");
2029 return EFI_INVALID_PARAMETER
;
2033 // The image buffer for the First VTF
2035 Vtf1Buffer
= malloc ((UINTN
) Size1
);
2036 if (Vtf1Buffer
== NULL
) {
2037 Error (NULL
, 0, 4001, "Resource", "Not enough resources available to create memory mapped file for the Boot Strap File!");
2038 return EFI_OUT_OF_RESOURCES
;
2040 memset (Vtf1Buffer
, 0x00, (UINTN
) Size1
);
2041 Vtf1EndBuffer
= (UINT8
*) Vtf1Buffer
+ Size1
;
2042 Vtf1LastStartAddress
= Fv1EndAddress
| IPF_CACHE_BIT
;
2045 Fv2BaseAddress
= StartAddress2
;
2046 Fv2EndAddress
= Fv2BaseAddress
+ Size2
;
2047 if (Fv2EndAddress
!= StartAddress1
) {
2048 Error (NULL
, 0, 2000, "Invalid parameter", "Error BaseAddress and Size parameters!");
2049 if (SecondVTF
== TRUE
) {
2050 Error (NULL
, 0, 2000, "Invalid parameter", "FirstBaseAddress + FirstFwVolumeSize must equal 0x100000000!");
2051 Error (NULL
, 0, 2000, "Invalid parameter", "SecondBaseAddress + SecondFwVolumeSize must equal FirstBaseAddress!");
2054 return EFI_INVALID_PARAMETER
;
2058 // The image buffer for the second VTF
2060 Vtf2Buffer
= malloc ((UINTN
) Size2
);
2061 if (Vtf2Buffer
== NULL
) {
2062 Error (NULL
, 0, 4001, "Resource", "Not enough resources available to create memory mapped file for the Boot Strap File!");
2063 return EFI_OUT_OF_RESOURCES
;
2065 memset (Vtf2Buffer
, 0x00, (UINTN
) Size2
);
2066 Vtf2EndBuffer
= (UINT8
*) Vtf2Buffer
+ Size2
;
2067 Vtf2LastStartAddress
= Fv2EndAddress
| IPF_CACHE_BIT
;
2070 Status
= GetVtfRelatedInfoFromInfFile (VtfFP
);
2072 if (Status
!= EFI_SUCCESS
) {
2073 Error (NULL
, 0, 0003, "Error parsing file", "the input file.");
2078 Status
= ProcessAndCreateVtf (Size1
);
2079 if (Status
!= EFI_SUCCESS
) {
2084 if (SectionOptionFlag
) {
2085 Status
= UpdateIA32ResetVector (IA32BinFile
, Vtf1TotalSize
);
2086 if (Status
!= EFI_SUCCESS
) {
2093 // Re arrange the FIT Table for Ascending order of their FIT Type..
2098 // All components have been updated in FIT table. Now perform the FIT table
2099 // checksum. The following function will check if Checksum is required,
2100 // if yes, then it will perform the checksum otherwise not.
2102 CalculateFitTableChecksum ();
2105 // Write the FFS header
2107 Vtf1TotalSize
+= sizeof (EFI_FFS_FILE_HEADER
);
2108 Vtf1LastStartAddress
-= sizeof (EFI_FFS_FILE_HEADER
);
2110 Status
= UpdateFfsHeader (Vtf1TotalSize
, FIRST_VTF
);
2111 if (Status
!= EFI_SUCCESS
) {
2116 // Update the VTF buffer into specified VTF binary file
2118 Status
= WriteVtfBinary (OutFileName1
, Vtf1TotalSize
, FIRST_VTF
);
2121 Vtf2TotalSize
+= sizeof (EFI_FFS_FILE_HEADER
);
2122 Vtf2LastStartAddress
-= sizeof (EFI_FFS_FILE_HEADER
);
2123 Status
= UpdateFfsHeader (Vtf2TotalSize
, SECOND_VTF
);
2124 if (Status
!= EFI_SUCCESS
) {
2130 // Update the VTF buffer into specified VTF binary file
2132 Status
= WriteVtfBinary (OutFileName2
, Vtf2TotalSize
, SECOND_VTF
);
2141 PeimFixupInFitTable (
2142 IN UINT64 StartAddress
2146 Routine Description:
2148 This function is an entry point to fixup SAL-E entry point.
2152 StartAddress - StartAddress for PEIM.....
2156 EFI_SUCCESS - The function completed successfully
2157 EFI_ABORTED - Error Opening File
2158 EFI_OUT_OF_RESOURCES - System out of resources for memory allocation.
2164 UINT64
*StartAddressPtr
;
2167 StartAddressPtr
= malloc (sizeof (UINT64
));
2168 if (StartAddressPtr
== NULL
) {
2169 return EFI_OUT_OF_RESOURCES
;
2171 *StartAddressPtr
= StartAddress
;
2173 Fp
= fopen (LongFilePath (OutFileName1
), "rb");
2176 Error (NULL
, 0, 0001, "Error opening file", OutFileName1
);
2177 if (StartAddressPtr
) {
2178 free (StartAddressPtr
);
2183 FirstFwVSize
= _filelength (fileno (Fp
));
2184 fseek (Fp
, (long) (FirstFwVSize
- (UINTN
) (SIZE_IA32_RESET_VECT
+ SIZE_SALE_ENTRY_POINT
)), SEEK_SET
);
2185 fwrite ((VOID
*) StartAddressPtr
, sizeof (UINT64
), 1, Fp
);
2191 if (StartAddressPtr
) {
2192 free (StartAddressPtr
);
2195 Status
= EFI_SUCCESS
;
2201 IN UINT64 BaseAddress
,
2202 IN CHAR8
*DestFileName
,
2203 IN CHAR8
*SourceFileName
,
2209 Routine Description:
2211 This function adds the SYM tokens in the source file to the destination file.
2212 The SYM tokens are updated to reflect the base address.
2216 BaseAddress - The base address for the new SYM tokens.
2217 DestFileName - The destination file.
2218 SourceFileName - The source file.
2219 FileSize - Size of bin file.
2223 EFI_SUCCESS - The function completed successfully.
2224 EFI_INVALID_PARAMETER - One of the input parameters was invalid.
2225 EFI_ABORTED - An error occurred.
2231 CHAR8 Buffer
[MAX_LONG_FILE_PATH
];
2232 CHAR8 Type
[MAX_LONG_FILE_PATH
];
2233 CHAR8 Address
[MAX_LONG_FILE_PATH
];
2234 CHAR8 Section
[MAX_LONG_FILE_PATH
];
2235 CHAR8 Token
[MAX_LONG_FILE_PATH
];
2236 CHAR8 BaseToken
[MAX_LONG_FILE_PATH
];
2237 CHAR8 FormatString
[MAX_LINE_LEN
];
2238 UINT64 TokenAddress
;
2242 // Verify input parameters.
2244 if (BaseAddress
== 0 || DestFileName
== NULL
|| SourceFileName
== NULL
) {
2245 return EFI_INVALID_PARAMETER
;
2249 // Open the source file
2251 SourceFile
= fopen (LongFilePath (SourceFileName
), "r");
2252 if (SourceFile
== NULL
) {
2255 // SYM files are not required.
2261 // Use the file name minus extension as the base for tokens
2263 if (strlen (SourceFileName
) >= MAX_LONG_FILE_PATH
) {
2264 fclose (SourceFile
);
2265 Error (NULL
, 0, 2000, "Invalid parameter", "The source file name is too long.");
2268 strncpy (BaseToken
, SourceFileName
, MAX_LONG_FILE_PATH
- 1);
2269 BaseToken
[MAX_LONG_FILE_PATH
- 1] = 0;
2270 strtok (BaseToken
, ". \t\n");
2271 if (strlen (BaseToken
) + strlen ("__") >= MAX_LONG_FILE_PATH
) {
2272 fclose (SourceFile
);
2273 Error (NULL
, 0, 2000, "Invalid parameter", "The source file name is too long.");
2276 strncat (BaseToken
, "__", MAX_LONG_FILE_PATH
- strlen (BaseToken
) - 1);
2279 // Open the destination file
2281 DestFile
= fopen (LongFilePath (DestFileName
), "a+");
2282 if (DestFile
== NULL
) {
2283 fclose (SourceFile
);
2284 Error (NULL
, 0, 0001, "Error opening file", DestFileName
);
2289 // If this is the beginning of the output file, write the symbol format info.
2291 if (fseek (DestFile
, 0, SEEK_END
) != 0) {
2292 fclose (SourceFile
);
2294 Error (NULL
, 0, 2000, "Invalid parameter", "not at the beginning of the output file.");
2298 StartLocation
= ftell (DestFile
);
2300 if (StartLocation
== 0) {
2301 fprintf (DestFile
, "TEXTSYM format | V1.0\n");
2302 } else if (StartLocation
== -1) {
2303 fclose (SourceFile
);
2305 Error (NULL
, 0, 2000, "Invalid parameter", "StartLocation error");
2310 // Read the first line
2312 if (fgets (Buffer
, MAX_LONG_FILE_PATH
, SourceFile
) == NULL
) {
2317 // Make sure it matches the expected sym format
2319 if (strcmp (Buffer
, "TEXTSYM format | V1.0\n")) {
2320 fclose (SourceFile
);
2322 Error (NULL
, 0, 2000, "Invalid parameter", "The symbol file does not match the expected TEXTSYM format (V1.0.)");
2327 // Generate the format string for fscanf
2331 "%%%us | %%%us | %%%us | %%%us\n",
2332 (unsigned) sizeof (Type
) - 1,
2333 (unsigned) sizeof (Address
) - 1,
2334 (unsigned) sizeof (Section
) - 1,
2335 (unsigned) sizeof (Token
) - 1
2341 while (feof (SourceFile
) == 0) {
2346 if (fscanf (SourceFile
, FormatString
, Type
, Address
, Section
, Token
) == 4) {
2349 // Get the token address
2351 AsciiStringToUint64 (Address
, TRUE
, &TokenAddress
);
2352 if (TokenAddress
> FileSize
) {
2354 // Symbol offset larger than FileSize. This Symbol can't be in Bin file. Don't print them.
2360 // Add the base address, the size of the FFS file header and the size of the peim header.
2362 TokenAddress
+= BaseAddress
&~IPF_CACHE_BIT
;
2364 fprintf (DestFile
, "%s | %016llX | ", Type
, (unsigned long long) TokenAddress
);
2365 fprintf (DestFile
, "%s | %s\n %s\n", Section
, Token
, BaseToken
);
2369 fclose (SourceFile
);
2375 CalculateFitTableChecksum (
2380 Routine Description:
2382 This function will perform byte checksum on the FIT table, if the the checksum required
2383 field is set to CheckSum required. If the checksum is not required then checksum byte
2384 will have value as 0;.
2392 Status - Value returned by call to CalculateChecksum8 ()
2393 EFI_SUCCESS - The function completed successfully
2397 FIT_TABLE
*TmpFitPtr
;
2399 UINT64 FitTableAddOffset
;
2400 UINTN RelativeAddress
;
2404 // Read the Fit Table address from Itanium-based address map.
2406 FitTableAddOffset
= Fv1EndAddress
- (SIZE_IA32_RESET_VECT
+ SIZE_SALE_ENTRY_POINT
+ SIZE_FIT_TABLE_ADD
);
2409 // Translate this Itanium-based address in terms of local buffer address which
2410 // contains the image for Boot Strapped File
2412 GetRelativeAddressInVtfBuffer (FitTableAddOffset
, &RelativeAddress
, FIRST_VTF
);
2413 FitTableAdd
= *(UINTN
*) RelativeAddress
;
2415 GetRelativeAddressInVtfBuffer (FitTableAdd
, &RelativeAddress
, FIRST_VTF
);
2417 TmpFitPtr
= (FIT_TABLE
*) RelativeAddress
;
2419 Size
= TmpFitPtr
->CompSize
* 16;
2421 if ((TmpFitPtr
->CvAndType
& CHECKSUM_BIT_MASK
) >> 7) {
2422 TmpFitPtr
->CheckSum
= 0;
2423 TmpFitPtr
->CheckSum
= CalculateChecksum8 ((UINT8
*) TmpFitPtr
, Size
);
2425 TmpFitPtr
->CheckSum
= 0;
2437 Routine Description:
2439 Displays the standard utility information to SDTOUT
2451 fprintf (stdout
, "%s Version %d.%d %s \n", UTILITY_NAME
, UTILITY_MAJOR_VERSION
, UTILITY_MINOR_VERSION
, __BUILD_VERSION
);
2460 Routine Description:
2462 Displays the utility usage syntax to STDOUT
2477 fprintf (stdout
, "Usage: %s [options] <-f input_file> <-r BaseAddress> <-s FwVolumeSize>\n\n", UTILITY_NAME
);
2480 // Copyright declaration
2482 fprintf (stdout
, "Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.\n\n");
2486 fprintf (stdout
, "Options:\n");
2487 fprintf (stdout
, " -f Input_file, --filename Input_file\n\
2488 Input_file is name of the BS Image INF file\n");
2489 fprintf (stdout
, " -r BaseAddress, --baseaddr BaseAddress\n\
2490 BaseAddress is the starting address of Firmware Volume\n\
2491 where Boot Strapped Image will reside.\n");
2492 fprintf (stdout
, " -s FwVolumeSize, --size FwVolumeSize\n\
2493 FwVolumeSize is the size of Firmware Volume.\n");
2494 fprintf (stdout
, " -o FileName, --output FileName\n\
2495 File will be created to store the ouput content.\n");
2496 fprintf (stdout
, " -v, --verbose Turn on verbose output with informational messages.\n");
2497 fprintf (stdout
, " --version Show program's version number and exit.\n");
2498 fprintf (stdout
, " -h, --help Show this help message and exit.\n");
2499 fprintf (stdout
, " -q, --quiet Disable all messages except FATAL ERRORS.\n");
2500 fprintf (stdout
, " -d, --debug [#, 0-9] Enable debug messages at level #.\n");
2510 Routine Description:
2512 This utility uses GenVtf.dll to build a Boot Strap File Image which will be
2513 part of firmware volume image.
2517 argc - The count of the parameters
2518 argv - The parameters
2523 0 - No error conditions detected.
2524 1 - One or more of the input parameters is invalid.
2525 2 - A resource required by the utility was unavailable.
2526 - Most commonly this will be memory allocation or file creation.
2527 3 - GenFvImage.dll could not be loaded.
2528 4 - Error executing the GenFvImage dll.
2529 5 - Now this tool does not support the IA32 platform
2534 UINT64 StartAddress1
;
2535 UINT64 StartAddress2
;
2538 BOOLEAN FirstRoundO
;
2539 BOOLEAN FirstRoundB
;
2540 BOOLEAN FirstRoundS
;
2545 SetUtilityName (UTILITY_NAME
);
2548 // Initialize variables
2558 OutFileName1
= NULL
;
2559 OutFileName2
= NULL
;
2564 // Verify the correct number of arguments
2571 if ((strcmp(argv
[1], "-h") == 0) || (strcmp(argv
[1], "--help") == 0)) {
2576 if ((strcmp(argv
[1], "--version") == 0)) {
2582 // Parse the command line arguments
2584 for (Index
= 1; Index
< argc
; Index
+= 2) {
2585 if ((stricmp (argv
[Index
], "-o") == 0) || (stricmp (argv
[Index
], "--output") == 0)) {
2586 if (argv
[Index
+ 1] == NULL
|| argv
[Index
+ 1][0] == '-') {
2587 Error (NULL
, 0, 1003, "Invalid option value", "Output file is missing for -o option");
2591 // Get the output file name
2596 // It's the first output file name
2598 OutFileName1
= (CHAR8
*)argv
[Index
+1];
2599 FirstRoundO
= FALSE
;
2602 //It's the second output file name
2604 OutFileName2
= (CHAR8
*)argv
[Index
+1];
2609 if ((stricmp (argv
[Index
], "-f") == 0) || (stricmp (argv
[Index
], "--filename") == 0)) {
2610 if (argv
[Index
+ 1] == NULL
|| argv
[Index
+ 1][0] == '-') {
2611 Error (NULL
, 0, 1003, "Invalid option value", "BS Image INF file is missing for -f option");
2615 // Get the input VTF file name
2617 VtfFileName
= argv
[Index
+1];
2618 if (VtfFP
!= NULL
) {
2620 // VTF file name has been given previously, override with the new value
2624 VtfFP
= fopen (LongFilePath (VtfFileName
), "rb");
2625 if (VtfFP
== NULL
) {
2626 Error (NULL
, 0, 0001, "Error opening file", VtfFileName
);
2632 if ((stricmp (argv
[Index
], "-r") == 0) || (stricmp (argv
[Index
], "--baseaddr") == 0)) {
2634 Status
= AsciiStringToUint64 (argv
[Index
+ 1], FALSE
, &StartAddress1
);
2635 FirstRoundB
= FALSE
;
2637 Status
= AsciiStringToUint64 (argv
[Index
+ 1], FALSE
, &StartAddress2
);
2639 if (Status
!= EFI_SUCCESS
) {
2640 Error (NULL
, 0, 2000, "Invalid option value", "%s is Bad FV start address.", argv
[Index
+ 1]);
2646 if ((stricmp (argv
[Index
], "-s") == 0) || (stricmp (argv
[Index
], "--size") == 0)) {
2648 Status
= AsciiStringToUint64 (argv
[Index
+ 1], FALSE
, &FwVolSize1
);
2649 FirstRoundS
= FALSE
;
2651 Status
= AsciiStringToUint64 (argv
[Index
+ 1], FALSE
, &FwVolSize2
);
2655 if (Status
!= EFI_SUCCESS
) {
2656 Error (NULL
, 0, 2000, "Invalid option value", "%s is Bad FV size.", argv
[Index
+ 1]);
2662 if ((stricmp (argv
[Index
], "-v") == 0) || (stricmp (argv
[Index
], "--verbose") == 0)) {
2668 if ((stricmp (argv
[Index
], "-q") == 0) || (stricmp (argv
[Index
], "--quiet") == 0)) {
2674 if ((stricmp (argv
[Index
], "-d") == 0) || (stricmp (argv
[Index
], "--debug") == 0)) {
2676 // debug level specified
2678 Status
= AsciiStringToUint64(argv
[Index
+ 1], FALSE
, &DebugLevel
);
2679 if (EFI_ERROR (Status
)) {
2680 Error (NULL
, 0, 1003, "Invalid option value", "%s = %s", argv
[Index
], argv
[Index
+ 1]);
2683 if (DebugLevel
> 9) {
2684 Error (NULL
, 0, 2000, "Invalid option value", "Unrecognized argument %s.", argv
[Index
+ 1]);
2687 if((DebugLevel
<= 9) &&(DebugLevel
>= 5)) {
2695 Error (NULL
, 0, 2000, "Invalid parameter", "Unrecognized argument %s.", argv
[Index
]);
2699 if (VtfFP
== NULL
) {
2700 Error (NULL
, 0, 2000, "Invalid parameter", "No BS Image INF file is specified");
2705 Error (NULL
, 0, 2000, "Invalid parameter", "No FV base address is specified");
2710 Error (NULL
, 0, 2000, "Invalid parameter", "No FV Size is specified");
2714 // All Parameters has been parsed, now set the message print level
2718 } else if (VerboseMode
) {
2720 } else if (DebugMode
) {
2721 SetPrintLevel(DebugLevel
);
2725 VerboseMsg("%s tool start.\n", UTILITY_NAME
);
2728 if (VTF_OUTPUT
== FALSE
) {
2729 if (SecondVTF
== TRUE
) {
2730 OutFileName1
= VTF_OUTPUT_FILE1
;
2731 OutFileName2
= VTF_OUTPUT_FILE2
;
2733 OutFileName1
= VTF_OUTPUT_FILE1
;
2735 SymFileName
= VTF_SYM_FILE
;
2737 INTN OutFileNameLen
;
2740 assert (OutFileName1
);
2741 OutFileNameLen
= strlen(OutFileName1
);
2743 for (NewIndex
= OutFileNameLen
; NewIndex
> 0; --NewIndex
) {
2744 if (OutFileName1
[NewIndex
] == '/' || OutFileName1
[NewIndex
] == '\\') {
2748 if (NewIndex
== 0) {
2749 SymFileName
= VTF_SYM_FILE
;
2751 INTN SymFileNameLen
= NewIndex
+ 1 + strlen(VTF_SYM_FILE
);
2752 SymFileName
= malloc(SymFileNameLen
+ 1);
2753 if (SymFileName
== NULL
) {
2754 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
2757 memcpy(SymFileName
, OutFileName1
, NewIndex
+ 1);
2758 memcpy(SymFileName
+ NewIndex
+ 1, VTF_SYM_FILE
, strlen(VTF_SYM_FILE
));
2759 SymFileName
[SymFileNameLen
] = '\0';
2762 DebugMsg(UTILITY_NAME
, 0, DebugLevel
, SymFileName
, NULL
);
2767 // Call the GenVtfImage
2770 DebugMsg(UTILITY_NAME
, 0, DebugLevel
, "Start to generate the VTF image\n", NULL
);
2772 Status
= GenerateVtfImage (StartAddress1
, FwVolSize1
, StartAddress2
, FwVolSize2
, VtfFP
);
2774 if (EFI_ERROR (Status
)) {
2777 case EFI_INVALID_PARAMETER
:
2778 Error (NULL
, 0, 2000, "Invalid parameter", "Invalid parameter passed to GenVtf function.");
2782 Error (NULL
, 0, 3000, "Invalid", "Error detected while creating the file image.");
2785 case EFI_OUT_OF_RESOURCES
:
2786 Error (NULL
, 0, 4002, "Resource", "GenVtfImage function could not allocate required resources.");
2789 case EFI_VOLUME_CORRUPTED
:
2790 Error (NULL
, 0, 3000, "Invalid", "No base address was specified.");
2794 Error (NULL
, 0, 3000, "Invalid", "GenVtfImage function returned unknown status %x.", (int) Status
);
2799 if (VtfFP
!= NULL
) {
2804 DebugMsg(UTILITY_NAME
, 0, DebugLevel
, "VTF image generated successful\n", NULL
);
2808 VerboseMsg("%s tool done with return code is 0x%x.\n", UTILITY_NAME
, GetUtilityStatus ());
2810 return GetUtilityStatus();