3 Copyright (c) 1999 - 2007, Intel Corporation. All rights reserved
\r
4 This software and associated documentation (if any) is furnished
\r
5 under a license and may only be used or copied in accordance
\r
6 with the terms of the license. Except as permitted by such
\r
7 license, no part of this software or documentation may be
\r
8 reproduced, stored in a retrieval system, or transmitted in any
\r
9 form or by any means without the express written consent of
\r
19 This file contains functions required to generate a boot strap file (BSF)
\r
20 also known as the Volume Top File (VTF)
\r
28 #include <Common/UefiBaseTypes.h>
\r
30 #include <Guid/PiFirmwareFileSystem.h>
\r
31 #include "CommonLib.h"
\r
36 UINTN SectionOptionFlag = 0;
\r
37 UINTN SectionCompFlag = 0;
\r
42 BOOLEAN QuietMode = FALSE;
\r
44 BOOLEAN VTF_OUTPUT = FALSE;
\r
45 CHAR8 *OutFileName1;
\r
46 CHAR8 *OutFileName2;
\r
49 CHAR8 **OrgStrTokPtr;
\r
51 PARSED_VTF_INFO *FileListPtr;
\r
52 PARSED_VTF_INFO *FileListHeadPtr;
\r
55 VOID *Vtf1EndBuffer;
\r
57 VOID *Vtf2EndBuffer;
\r
59 UINTN ValidLineNum = 0;
\r
60 UINTN ValidFFDFileListNum = 0;
\r
63 // Section Description and their number of occurences in *.INF file
\r
65 UINTN NumFvFiles = 0;
\r
66 UINTN SectionOptionNum = 0;
\r
69 // Global flag which will check for VTF Present, if yes then will be used
\r
70 // to decide about adding FFS header to pad data
\r
72 BOOLEAN VTFPresent = FALSE;
\r
73 BOOLEAN SecondVTF = FALSE;
\r
76 // Address related information
\r
78 UINT64 Fv1BaseAddress = 0;
\r
79 UINT64 Fv2BaseAddress = 0;
\r
80 UINT64 Fv1EndAddress = 0;
\r
81 UINT64 Fv2EndAddress = 0;
\r
82 UINT32 Vtf1TotalSize = SIZE_TO_OFFSET_PAL_A_END;
\r
83 UINT64 Vtf1LastStartAddress = 0;
\r
84 UINT32 Vtf2TotalSize = 0;
\r
85 UINT64 Vtf2LastStartAddress = 0;
\r
87 UINT32 BufferToTop = 0;
\r
90 // IA32 Reset Vector Bin name
\r
92 CHAR8 IA32BinFile[FILE_NAME_SIZE];
\r
95 // Function Implementations
\r
102 Routine Description:
\r
104 This function builds the token list in an array which will be parsed later
\r
108 Token - The pointer of string
\r
116 strcpy (*TokenStr, Token);
\r
121 ConvertVersionInfo (
\r
123 IN OUT UINT8 *MajorVer,
\r
124 IN OUT UINT8 *MinorVer
\r
127 Routine Description:
\r
129 This function converts GUID string to GUID
\r
133 Str - String representing in form XX.XX
\r
134 MajorVer - The major vertion
\r
135 MinorVer - The minor vertion
\r
139 EFI_SUCCESS - The fuction completed successfully.
\r
151 memset (StrPtr, 0, 40);
\r
152 Token = strtok (Str, ".");
\r
154 while (Token != NULL) {
\r
155 strcat (StrPtr, Token);
\r
156 Token = strtok (NULL, ".");
\r
159 Length = strlen (StrPtr);
\r
167 *MajorVer = (UINT8) Major;
\r
168 *MinorVer = (UINT8) Minor;
\r
169 return EFI_SUCCESS;
\r
177 Routine Description:
\r
179 This function cleans up the line by removing all whitespace and
\r
184 Line - The pointer of the string
\r
192 CHAR8 TmpLine[FILE_NAME_SIZE];
\r
199 // Change '#' to '//' for Comment style
\r
201 if (((Ptr0 = strchr (Line, '#')) != NULL) || ((Ptr0 = strstr (Line, "//")) != NULL)) {
\r
202 Line[Ptr0 - Line] = 0;
\r
206 // Initialize counters
\r
211 while ((Char = Line[Index]) != 0) {
\r
212 if ((Char != ' ') && (Char != '\t') && (Char != '\n') && (Char != '\r')) {
\r
213 TmpLine[Index2++] = Char;
\r
218 TmpLine[Index2] = 0;
\r
219 strcpy (Line, TmpLine);
\r
228 Routine Description:
\r
230 This function calculated number of valid lines in a input file.
\r
234 Fp - Pointer to a file handle which has been opened.
\r
242 CHAR8 Buff[FILE_NAME_SIZE];
\r
243 while (fgets(Buff, sizeof (Buff), Fp)) {
\r
245 if (Buff[0] == 0) {
\r
258 Routine Description:
\r
260 This function parses the input file and tokenize the string
\r
264 Fp - Pointer to a file handle which has been opened.
\r
273 CHAR8 Buff[FILE_NAME_SIZE];
\r
274 CHAR8 OrgLine[FILE_NAME_SIZE];
\r
275 CHAR8 Str[FILE_NAME_SIZE];
\r
276 CHAR8 Delimit[] = "=";
\r
278 while (fgets (Buff, sizeof (Buff), Fp) != NULL) {
\r
279 strcpy (OrgLine, Buff);
\r
281 if (Buff[0] == 0) {
\r
284 Token = strtok (Buff, Delimit);
\r
286 while (Token != NULL) {
\r
287 strcpy (Str, Token);
\r
288 BuildTokenList (Str);
\r
289 Token = strtok (NULL, Delimit);
\r
300 Routine Description:
\r
302 This function intializes the relevant global variable which is being
\r
303 used to store the information retrieved from INF file. This also initializes
\r
304 the VTF symbol file.
\r
312 EFI_SUCCESS - The function completed successfully
\r
313 EFI_OUT_OF_RESOURCES - Malloc failed.
\r
318 FileListPtr = malloc (sizeof (PARSED_VTF_INFO));
\r
320 if (FileListPtr == NULL) {
\r
321 return EFI_OUT_OF_RESOURCES;
\r
324 FileListHeadPtr = FileListPtr;
\r
325 memset (FileListPtr, 0, sizeof (PARSED_VTF_INFO));
\r
326 FileListPtr->NextVtfInfo = NULL;
\r
328 remove (VTF_SYM_FILE);
\r
329 return EFI_SUCCESS;
\r
333 ParseAndUpdateComponents (
\r
334 IN PARSED_VTF_INFO *VtfInfo
\r
338 Routine Description:
\r
340 This function intializes the relevant global variable which is being
\r
341 used to store the information retrieved from INF file.
\r
345 VtfInfo - A pointer to the VTF Info Structure
\r
354 UINT64 StringValue;
\r
356 while (*TokenStr != NULL && (strnicmp (*TokenStr, "COMP_NAME", 9) != 0)) {
\r
358 if (strnicmp (*TokenStr, "COMP_LOC", 8) == 0) {
\r
360 if (strnicmp (*TokenStr, "F", 1) == 0) {
\r
361 VtfInfo->LocationType = FIRST_VTF;
\r
362 } else if (strnicmp (*TokenStr, "S", 1) == 0) {
\r
363 VtfInfo->LocationType = SECOND_VTF;
\r
365 VtfInfo->LocationType = NONE;
\r
366 printf ("\nWARN: Unknown location for component %s\n", VtfInfo->CompName);
\r
368 } else if (strnicmp (*TokenStr, "COMP_TYPE", 9) == 0) {
\r
370 if (AsciiStringToUint64 (*TokenStr, FALSE, &StringValue) != EFI_SUCCESS) {
\r
371 Error (NULL, 0, 5001, "Cannot get: \"0x%x\".", *TokenStr);
\r
375 VtfInfo->CompType = (UINT8) StringValue;
\r
376 } else if (strnicmp (*TokenStr, "COMP_VER", 8) == 0) {
\r
378 if (strnicmp (*TokenStr, "-", 1) == 0) {
\r
379 VtfInfo->VersionPresent = FALSE;
\r
380 VtfInfo->MajorVer = 0;
\r
381 VtfInfo->MinorVer = 0;
\r
383 VtfInfo->VersionPresent = TRUE;
\r
384 ConvertVersionInfo (*TokenStr, &VtfInfo->MajorVer, &VtfInfo->MinorVer);
\r
386 } else if (strnicmp (*TokenStr, "COMP_BIN", 8) == 0) {
\r
388 strcpy (VtfInfo->CompBinName, *TokenStr);
\r
389 } else if (strnicmp (*TokenStr, "COMP_SYM", 8) == 0) {
\r
391 strcpy (VtfInfo->CompSymName, *TokenStr);
\r
392 } else if (strnicmp (*TokenStr, "COMP_SIZE", 9) == 0) {
\r
394 if (strnicmp (*TokenStr, "-", 1) == 0) {
\r
395 VtfInfo->PreferredSize = FALSE;
\r
396 VtfInfo->CompSize = 0;
\r
398 VtfInfo->PreferredSize = TRUE;
\r
399 if (AsciiStringToUint64 (*TokenStr, FALSE, &StringValue) != EFI_SUCCESS) {
\r
400 Error (NULL, 0, 5001, "Cannot get: %s", TokenStr);
\r
404 VtfInfo->CompSize = (UINTN) StringValue;
\r
407 } else if (strnicmp (*TokenStr, "COMP_CS", 7) == 0) {
\r
409 if (strnicmp (*TokenStr, "1", 1) == 0) {
\r
410 VtfInfo->CheckSumRequired = 1;
\r
411 } else if (strnicmp (*TokenStr, "0", 1) == 0) {
\r
412 VtfInfo->CheckSumRequired = 0;
\r
414 Error (NULL, 0, 3000, "Invaild", "Bad information in INF file about Checksum required field");
\r
419 if (*TokenStr == NULL) {
\r
426 InitializeInFileInfo (
\r
431 Routine Description:
\r
433 This function intializes the relevant global variable which is being
\r
434 used to store the information retrieved from INF file.
\r
447 SectionOptionFlag = 0;
\r
448 SectionCompFlag = 0;
\r
449 TokenStr = OrgStrTokPtr;
\r
451 while (*TokenStr != NULL) {
\r
452 if (strnicmp (*TokenStr, "[OPTIONS]", 9) == 0) {
\r
453 SectionOptionFlag = 1;
\r
454 SectionCompFlag = 0;
\r
457 if (strnicmp (*TokenStr, "[COMPONENTS]", 12) == 0) {
\r
458 if (FileListPtr == NULL) {
\r
459 FileListPtr = FileListHeadPtr;
\r
462 SectionCompFlag = 1;
\r
463 SectionOptionFlag = 0;
\r
467 if (SectionOptionFlag) {
\r
468 if (stricmp (*TokenStr, "IA32_RST_BIN") == 0) {
\r
470 strcpy (IA32BinFile, *TokenStr);
\r
474 if (SectionCompFlag) {
\r
475 if (stricmp (*TokenStr, "COMP_NAME") == 0) {
\r
477 strcpy (FileListPtr->CompName, *TokenStr);
\r
479 ParseAndUpdateComponents (FileListPtr);
\r
482 if (*TokenStr != NULL) {
\r
483 FileListPtr->NextVtfInfo = malloc (sizeof (PARSED_VTF_INFO));
\r
484 if (FileListPtr->NextVtfInfo == NULL) {
\r
485 Error (NULL, 0, 4003, "Resource", "Out of memory resources.", NULL);
\r
488 FileListPtr = FileListPtr->NextVtfInfo;
\r
489 memset (FileListPtr, 0, sizeof (PARSED_VTF_INFO));
\r
490 FileListPtr->NextVtfInfo = NULL;
\r
502 GetVtfRelatedInfoFromInfFile (
\r
503 IN FILE *FilePointer
\r
507 Routine Description:
\r
509 This function reads the input file, parse it and create a list of tokens
\r
510 which is parsed and used, to intialize the data related to VTF
\r
514 FileName - FileName which needed to be read to parse data
\r
518 EFI_ABORTED - Error in opening file
\r
519 EFI_INVALID_PARAMETER - File doesn't contain any valid informations
\r
520 EFI_OUT_OF_RESOURCES - Malloc Failed
\r
521 EFI_SUCCESS - The function completed successfully
\r
531 Error (NULL, 0, 2000, "Invalid paramter", "BSF INF file is invalid!");
\r
532 return EFI_ABORTED;
\r
535 ValidLineCount (Fp);
\r
537 if (ValidLineNum == 0) {
\r
538 Error (NULL, 0, 2000, "Invalid paramter", "File doesn't contain any valid informations!");
\r
539 return EFI_INVALID_PARAMETER;
\r
542 TokenStr = (CHAR8 **) malloc (sizeof (UINTN) * (2 * ValidLineNum + 1));
\r
544 if (TokenStr == NULL) {
\r
545 return EFI_OUT_OF_RESOURCES;
\r
548 memset (TokenStr, 0, (sizeof (UINTN) * (2 * ValidLineNum + 1)));
\r
549 OrgStrTokPtr = TokenStr;
\r
551 for (Index = 0; Index < (2 * ValidLineNum); Index++) {
\r
552 *TokenStr = (CHAR8*)malloc (sizeof (CHAR8) * FILE_NAME_SIZE);
\r
554 if (*TokenStr == NULL) {
\r
555 free (OrgStrTokPtr);
\r
556 return EFI_OUT_OF_RESOURCES;
\r
559 memset (*TokenStr, 0, FILE_NAME_SIZE);
\r
564 TokenStr = OrgStrTokPtr;
\r
565 fseek (Fp, 0L, SEEK_SET);
\r
567 Status = InitializeComps ();
\r
569 if (Status != EFI_SUCCESS) {
\r
570 free (OrgStrTokPtr);
\r
574 ParseInputFile (Fp);
\r
576 InitializeInFileInfo ();
\r
581 free (OrgStrTokPtr);
\r
583 return EFI_SUCCESS;
\r
587 GetRelativeAddressInVtfBuffer (
\r
589 IN OUT UINTN *RelativeAddress,
\r
590 IN LOC_TYPE LocType
\r
594 Routine Description:
\r
596 This function checks for the address alignmnet for specified data boundary. In
\r
597 case the address is not aligned, it returns FALSE and the amount of data in
\r
598 terms of byte needed to adjust to get the boundary alignmnet. If data is
\r
599 aligned, TRUE will be returned.
\r
603 Address - The address of the flash map space
\r
604 RelativeAddress - The relative address of the Buffer
\r
605 LocType - The type of the VTF
\r
613 UINT64 TempAddress;
\r
616 if (LocType == FIRST_VTF) {
\r
617 LocalBuff = (UINT8 *) Vtf1EndBuffer;
\r
618 TempAddress = Fv1EndAddress - Address;
\r
619 *RelativeAddress = (UINTN) LocalBuff - (UINTN) TempAddress;
\r
621 LocalBuff = (UINT8 *) Vtf2EndBuffer;
\r
622 TempAddress = Fv2EndAddress - Address;
\r
623 *RelativeAddress = (UINTN) LocalBuff - (UINTN) TempAddress;
\r
628 GetComponentVersionInfo (
\r
629 IN OUT PARSED_VTF_INFO *VtfInfo,
\r
633 Routine Description:
\r
635 This function will extract the version information from File
\r
639 VtfInfo - A Pointer to the VTF Info Structure
\r
640 Buffer - A Pointer to type UINT8
\r
644 EFI_SUCCESS - The function completed successfully
\r
645 EFI_INVALID_PARAMETER - The parameter is invalid
\r
649 UINT16 VersionInfo;
\r
652 switch (VtfInfo->CompType) {
\r
654 case COMP_TYPE_FIT_PAL_A:
\r
655 case COMP_TYPE_FIT_PAL_B:
\r
656 memcpy (&VersionInfo, (Buffer + 8), sizeof (UINT16));
\r
657 VtfInfo->MajorVer = (UINT8) ((VersionInfo & 0xFF00) >> 8);
\r
658 VtfInfo->MinorVer = (UINT8) (VersionInfo & 0x00FF);
\r
659 Status = EFI_SUCCESS;
\r
663 Status = EFI_INVALID_PARAMETER;
\r
671 CheckAddressAlignment (
\r
673 IN UINT64 AlignmentData,
\r
674 IN OUT UINT64 *AlignAdjustByte
\r
678 Routine Description:
\r
680 This function checks for the address alignmnet for specified data boundary. In
\r
681 case the address is not aligned, it returns FALSE and the amount of data in
\r
682 terms of byte needed to adjust to get the boundary alignmnet. If data is
\r
683 aligned, TRUE will be returned.
\r
687 Address - Pointer to buffer containing byte data of component.
\r
688 AlignmentData - DataSize for which address needed to be aligned
\r
689 AlignAdjustByte - Number of bytes needed to adjust alignment.
\r
693 TRUE - Address is aligned to specific data size boundary
\r
694 FALSE - Address in not aligned to specified data size boundary
\r
695 - Add/Subtract AlignAdjustByte to aling the address.
\r
700 // Check if the assigned address is on address boundary. If not, it will
\r
701 // return the remaining byte required to adjust the address for specified
\r
702 // address boundary
\r
704 *AlignAdjustByte = (Address % AlignmentData);
\r
706 if (*AlignAdjustByte == 0) {
\r
714 GetFitTableStartAddress (
\r
715 IN OUT FIT_TABLE **FitTable
\r
719 Routine Description:
\r
721 Get the FIT table start address in VTF Buffer
\r
725 FitTable - Pointer to available fit table where new component can be added
\r
729 EFI_SUCCESS - The function completed successfully
\r
733 UINT64 FitTableAdd;
\r
734 UINT64 FitTableAddOffset;
\r
735 UINTN RelativeAddress;
\r
738 // Read the Fit Table address from Itanium-based address map.
\r
740 FitTableAddOffset = Fv1EndAddress - (SIZE_IA32_RESET_VECT + SIZE_SALE_ENTRY_POINT + SIZE_FIT_TABLE_ADD);
\r
743 // Translate this Itanium-based address in terms of local buffer address which
\r
744 // contains the image for Boot Strapped File. The relative address will be
\r
745 // the address of fit table VTF buffer.
\r
747 GetRelativeAddressInVtfBuffer (FitTableAddOffset, &RelativeAddress, FIRST_VTF);
\r
748 FitTableAdd = *(UINTN *) RelativeAddress;
\r
751 // The FitTableAdd is the extracted Itanium based address pointing to FIT
\r
752 // table. The relative address will return its actual location in VTF
\r
755 GetRelativeAddressInVtfBuffer (FitTableAdd, &RelativeAddress, FIRST_VTF);
\r
757 *FitTable = (FIT_TABLE *) RelativeAddress;
\r
759 return EFI_SUCCESS;
\r
763 GetNextAvailableFitPtr (
\r
764 IN FIT_TABLE **FitPtr
\r
768 Routine Description:
\r
770 Get the FIT table address and locate the free space in fit where we can add
\r
771 new component. In this process, this function locates the fit table using
\r
772 Fit pointer in Itanium-based address map (as per Intel?Itanium(TM) SAL spec)
\r
773 and locate the available location in FIT table to be used by new components.
\r
774 If there are any Fit table which areg not being used contains ComponentType
\r
775 field as 0x7F. If needed we can change this and spec this out.
\r
779 FitPtr - Pointer to available fit table where new component can be added
\r
783 EFI_SUCCESS - The function completed successfully
\r
787 FIT_TABLE *TmpFitPtr;
\r
788 UINT64 FitTableAdd;
\r
789 UINT64 FitTableAddOffset;
\r
791 UINTN NumFitComponents;
\r
792 UINTN RelativeAddress;
\r
795 // Read the Fit Table address from Itanium-based address map.
\r
797 FitTableAddOffset = Fv1EndAddress - (SIZE_IA32_RESET_VECT + SIZE_SALE_ENTRY_POINT + SIZE_FIT_TABLE_ADD);
\r
800 // Translate this Itanium-based address in terms of local buffer address which
\r
801 // contains the image for Boot Strapped File. The relative address will be
\r
802 // the address of fit table VTF buffer.
\r
804 GetRelativeAddressInVtfBuffer (FitTableAddOffset, &RelativeAddress, FIRST_VTF);
\r
805 FitTableAdd = *(UINTN *) RelativeAddress;
\r
808 // The FitTableAdd is the extracted Itanium based address pointing to FIT
\r
809 // table. The relative address will return its actual location in VTF
\r
812 GetRelativeAddressInVtfBuffer (FitTableAdd, &RelativeAddress, FIRST_VTF);
\r
814 TmpFitPtr = (FIT_TABLE *) RelativeAddress;
\r
815 NumFitComponents = TmpFitPtr->CompSize;
\r
817 for (Index = 0; Index < NumFitComponents; Index++) {
\r
818 if ((TmpFitPtr->CvAndType & FIT_TYPE_MASK) == COMP_TYPE_FIT_UNUSED) {
\r
819 *FitPtr = TmpFitPtr;
\r
826 return EFI_SUCCESS;
\r
831 IN const VOID *Arg1,
\r
832 IN const VOID *Arg2
\r
836 Routine Description:
\r
838 This function is used by qsort to sort the FIT table based upon Component
\r
839 Type in their incresing order.
\r
843 Arg1 - Pointer to Arg1
\r
844 Arg2 - Pointer to Arg2
\r
852 if ((((FIT_TABLE *) Arg1)->CvAndType & FIT_TYPE_MASK) > (((FIT_TABLE *) Arg2)->CvAndType & FIT_TYPE_MASK)) {
\r
854 } else if ((((FIT_TABLE *) Arg1)->CvAndType & FIT_TYPE_MASK) < (((FIT_TABLE *) Arg2)->CvAndType & FIT_TYPE_MASK)) {
\r
867 Routine Description:
\r
869 This function is used by qsort to sort the FIT table based upon Component
\r
870 Type in their incresing order.
\r
882 FIT_TABLE *FitTable;
\r
883 FIT_TABLE *TmpFitPtr;
\r
884 UINTN NumFitComponents;
\r
887 GetFitTableStartAddress (&FitTable);
\r
888 TmpFitPtr = FitTable;
\r
889 NumFitComponents = 0;
\r
890 for (Index = 0; Index < FitTable->CompSize; Index++) {
\r
891 if ((TmpFitPtr->CvAndType & FIT_TYPE_MASK) != COMP_TYPE_FIT_UNUSED) {
\r
892 NumFitComponents += 1;
\r
896 qsort ((VOID *) FitTable, NumFitComponents, sizeof (FIT_TABLE), CompareItems);
\r
900 UpdateFitEntryForFwVolume (
\r
905 Routine Description:
\r
907 This function updates the information about Firmware Volume in FIT TABLE.
\r
908 This FIT table has to be immediately below the PAL_A Start and it contains
\r
909 component type and address information. Other informations can't be
\r
910 created this time so we would need to fix it up..
\r
915 Size - Firmware Volume Size
\r
923 FIT_TABLE *CompFitPtr;
\r
924 UINTN RelativeAddress;
\r
927 // FV Fit table will be located at PAL_A Startaddress - 16 byte location
\r
929 Vtf1LastStartAddress -= 0x10;
\r
930 Vtf1TotalSize += 0x10;
\r
932 GetRelativeAddressInVtfBuffer (Vtf1LastStartAddress, &RelativeAddress, FIRST_VTF);
\r
934 CompFitPtr = (FIT_TABLE *) RelativeAddress;
\r
935 CompFitPtr->CompAddress = Fv1BaseAddress;
\r
938 // Since we don't have any information about its location in Firmware Volume,
\r
939 // initialize address to 0. This will be updated once Firmware Volume is
\r
940 // being build and its current address will be fixed in FIT table. Currently
\r
941 // we haven't implemented it so far and working on architectural clarafication
\r
944 // Firmware Volume Size in 16 byte block
\r
946 CompFitPtr->CompSize = ((UINT32) Size) / 16;
\r
949 // Since Firmware Volume does not exist by the time we create this FIT info
\r
950 // this should be fixedup from Firmware Volume creation tool. We haven't
\r
951 // worked out a method so far.
\r
953 CompFitPtr->CompVersion = MAKE_VERSION (0, 0);
\r
956 // Since we don't have any info about this file, we are making sure that
\r
957 // checksum is not needed.
\r
959 CompFitPtr->CvAndType = CV_N_TYPE (0, COMP_TYPE_FIT_FV_BOOT);
\r
962 // Since non VTF component will reside outside the VTF, we will not have its
\r
963 // binary image while creating VTF, hence we will not perform checksum at
\r
964 // this time. Once Firmware Volume is being created which will contain this
\r
965 // VTF, it will fix the FIT table for all the non VTF component and hence
\r
968 CompFitPtr->CheckSum = 0;
\r
972 UpdateFitEntryForNonVTFComp (
\r
973 IN PARSED_VTF_INFO *VtfInfo
\r
977 Routine Description:
\r
979 This function updates the information about non VTF component in FIT TABLE.
\r
980 Since non VTF componets binaries are not part of VTF binary, we would still
\r
981 be required to update its location information in Firmware Volume, inside
\r
986 VtfInfo - Pointer to VTF Info Structure
\r
990 EFI_ABORTED - The function fails to update the component in FIT
\r
991 EFI_SUCCESS - The function completed successfully
\r
995 FIT_TABLE *CompFitPtr;
\r
998 // Scan the FIT table for available space
\r
1000 GetNextAvailableFitPtr (&CompFitPtr);
\r
1001 if (CompFitPtr == NULL) {
\r
1002 Error(NULL, 0, 5003, "Invalid", "Can't update this component in FIT");
\r
1003 return EFI_ABORTED;
\r
1007 // Since we don't have any information about its location in Firmware Volume,
\r
1008 // initialize address to 0. This will be updated once Firmware Volume is
\r
1009 // being build and its current address will be fixed in FIT table
\r
1011 CompFitPtr->CompAddress = 0;
\r
1012 CompFitPtr->CompSize = VtfInfo->CompSize;
\r
1013 CompFitPtr->CompVersion = MAKE_VERSION (VtfInfo->MajorVer, VtfInfo->MinorVer);
\r
1014 CompFitPtr->CvAndType = CV_N_TYPE (VtfInfo->CheckSumRequired, VtfInfo->CompType);
\r
1017 // Since non VTF component will reside outside the VTF, we will not have its
\r
1018 // binary image while creating VTF, hence we will not perform checksum at
\r
1019 // this time. Once Firmware Volume is being created which will contain this
\r
1020 // VTF, it will fix the FIT table for all the non VTF component and hence
\r
1023 CompFitPtr->CheckSum = 0;
\r
1026 // Fit Type is FV_BOOT which means Firmware Volume, we initialize this to base
\r
1027 // address of Firmware Volume in which this VTF will be attached.
\r
1029 if ((CompFitPtr->CvAndType & 0x7F) == COMP_TYPE_FIT_FV_BOOT) {
\r
1030 CompFitPtr->CompAddress = Fv1BaseAddress;
\r
1033 return EFI_SUCCESS;
\r
1038 // This function is updating the SALE_ENTRY in Itanium address space as per SAL
\r
1039 // spec. SALE_ENTRY is being read from SYM file of PEICORE. Once the PEI
\r
1040 // CORE moves in Firmware Volume, we would need to modify this function to be
\r
1041 // used with a API which will detect PEICORE component while building Firmware
\r
1042 // Volume and update its entry in FIT table as well as in Itanium address space
\r
1043 // as per Intel?Itanium(TM) SAL address space
\r
1046 UpdateEntryPoint (
\r
1047 IN PARSED_VTF_INFO *VtfInfo,
\r
1048 IN UINT64 *CompStartAddress
\r
1052 Routine Description:
\r
1054 This function updated the architectural entry point in IPF, SALE_ENTRY.
\r
1058 VtfInfo - Pointer to VTF Info Structure
\r
1059 CompStartAddress - Pointer to Component Start Address
\r
1063 EFI_INVALID_PARAMETER - The parameter is invalid
\r
1064 EFI_SUCCESS - The function completed successfully
\r
1068 UINTN RelativeAddress;
\r
1069 UINT64 SalEntryAdd;
\r
1073 CHAR8 Buff[FILE_NAME_SIZE];
\r
1076 CHAR8 OffsetStr[30];
\r
1082 Fp = fopen (VtfInfo->CompSymName, "rb");
\r
1085 Error (NULL, 0, 0001, "Error opening file", VtfInfo->CompSymName);
\r
1086 return EFI_INVALID_PARAMETER;
\r
1089 while (fgets (Buff, sizeof (Buff), Fp) != NULL) {
\r
1092 "%s %s %s %s %s %s %s",
\r
1101 if (strnicmp (Token, "SALE_ENTRY", 10) == 0) {
\r
1106 Offset = strtoul (OffsetStr, NULL, 16);
\r
1108 *CompStartAddress += Offset;
\r
1109 SalEntryAdd = Fv1EndAddress - (SIZE_IA32_RESET_VECT + SIZE_SALE_ENTRY_POINT);
\r
1111 GetRelativeAddressInVtfBuffer (SalEntryAdd, &RelativeAddress, FIRST_VTF);
\r
1113 memcpy ((VOID *) RelativeAddress, (VOID *) CompStartAddress, sizeof (UINT64));
\r
1115 return EFI_SUCCESS;
\r
1119 CreateAndUpdateComponent (
\r
1120 IN PARSED_VTF_INFO *VtfInfo
\r
1124 Routine Description:
\r
1126 This function reads the binary file for each components and update them
\r
1127 in VTF Buffer as well as in FIT table. If the component is located in non
\r
1128 VTF area, only the FIT table address will be updated
\r
1132 VtfInfo - Pointer to Parsed Info
\r
1136 EFI_SUCCESS - The function completed successful
\r
1137 EFI_ABORTED - Aborted due to one of the many reasons like:
\r
1138 (a) Component Size greater than the specified size.
\r
1139 (b) Error opening files.
\r
1141 EFI_INVALID_PARAMETER Value returned from call to UpdateEntryPoint()
\r
1142 EFI_OUT_OF_RESOURCES Memory allocation failure.
\r
1146 EFI_STATUS Status;
\r
1147 UINT64 CompStartAddress;
\r
1149 UINT64 NumByteRead;
\r
1150 UINT64 NumAdjustByte;
\r
1153 FIT_TABLE *CompFitPtr;
\r
1154 BOOLEAN Aligncheck;
\r
1156 if (VtfInfo->LocationType == NONE) {
\r
1157 UpdateFitEntryForNonVTFComp (VtfInfo);
\r
1158 return EFI_SUCCESS;
\r
1161 Fp = fopen (VtfInfo->CompBinName, "rb");
\r
1164 Error (NULL, 0, 0001, "Error opening file", VtfInfo->CompBinName);
\r
1165 return EFI_ABORTED;
\r
1168 FileSize = _filelength (fileno (Fp));
\r
1169 if ((VtfInfo->CompType == COMP_TYPE_FIT_PAL_B) || (VtfInfo->CompType == COMP_TYPE_FIT_PAL_A_SPECIFIC)) {
\r
1172 // BUGBUG: Satish to correct
\r
1174 FileSize -= SIZE_OF_PAL_HEADER;
\r
1177 if (VtfInfo->PreferredSize) {
\r
1178 if (FileSize > VtfInfo->CompSize) {
\r
1179 Error (NULL, 0, 2000, "Invalid paramter", "The component size is more than specified size");
\r
1180 return EFI_ABORTED;
\r
1183 FileSize = VtfInfo->CompSize;
\r
1186 Buffer = malloc ((UINTN) FileSize);
\r
1187 if (Buffer == NULL) {
\r
1188 return EFI_OUT_OF_RESOURCES;
\r
1190 memset (Buffer, 0, (UINTN) FileSize);
\r
1192 if ((VtfInfo->CompType == COMP_TYPE_FIT_PAL_B) || (VtfInfo->CompType == COMP_TYPE_FIT_PAL_A_SPECIFIC)) {
\r
1195 // Read first 64 bytes of PAL header and use it to find version info
\r
1197 NumByteRead = fread (Buffer, sizeof (UINT8), SIZE_OF_PAL_HEADER, Fp);
\r
1200 // PAL header contains the version info. Currently, we will use the header
\r
1201 // to read version info and then discard.
\r
1203 if (!VtfInfo->VersionPresent) {
\r
1204 GetComponentVersionInfo (VtfInfo, Buffer);
\r
1208 NumByteRead = fread (Buffer, sizeof (UINT8), (UINTN) FileSize, Fp);
\r
1212 // If it is non PAL_B component, pass the entire buffer to get the version
\r
1213 // info and implement any specific case inside GetComponentVersionInfo.
\r
1215 if (VtfInfo->CompType != COMP_TYPE_FIT_PAL_B) {
\r
1216 if (!VtfInfo->VersionPresent) {
\r
1217 GetComponentVersionInfo (VtfInfo, Buffer);
\r
1221 if (VtfInfo->LocationType == SECOND_VTF) {
\r
1223 CompStartAddress = (Vtf2LastStartAddress - FileSize);
\r
1225 CompStartAddress = (Vtf1LastStartAddress - FileSize);
\r
1228 if (VtfInfo->CompType == COMP_TYPE_FIT_PAL_B) {
\r
1229 Aligncheck = CheckAddressAlignment (CompStartAddress, 32 * 1024, &NumAdjustByte);
\r
1231 Aligncheck = CheckAddressAlignment (CompStartAddress, 8, &NumAdjustByte);
\r
1234 if (!Aligncheck) {
\r
1235 CompStartAddress -= NumAdjustByte;
\r
1238 if (VtfInfo->LocationType == SECOND_VTF && SecondVTF == TRUE) {
\r
1239 Vtf2LastStartAddress = CompStartAddress;
\r
1240 Vtf2TotalSize += (UINT32) (FileSize + NumAdjustByte);
\r
1241 Status = UpdateVtfBuffer (CompStartAddress, Buffer, FileSize, SECOND_VTF);
\r
1242 } else if (VtfInfo->LocationType == FIRST_VTF) {
\r
1243 Vtf1LastStartAddress = CompStartAddress;
\r
1244 Vtf1TotalSize += (UINT32) (FileSize + NumAdjustByte);
\r
1245 Status = UpdateVtfBuffer (CompStartAddress, Buffer, FileSize, FIRST_VTF);
\r
1247 Error(NULL, 0, 2000,"Invalid Parameter", "There's component in second VTF so second BaseAddress and Size must be specified!");
\r
1248 return EFI_INVALID_PARAMETER;
\r
1251 if (EFI_ERROR (Status)) {
\r
1252 return EFI_ABORTED;
\r
1255 GetNextAvailableFitPtr (&CompFitPtr);
\r
1257 CompFitPtr->CompAddress = CompStartAddress | IPF_CACHE_BIT;
\r
1258 if ((FileSize % 16) != 0) {
\r
1259 Error (NULL, 0, 2000, "Invalid paramter", "Binary FileSize must be multiple of 16");
\r
1260 return EFI_INVALID_PARAMETER;
\r
1262 //assert ((FileSize % 16) == 0);
\r
1263 CompFitPtr->CompSize = (UINT32) (FileSize / 16);
\r
1264 CompFitPtr->CompVersion = MAKE_VERSION (VtfInfo->MajorVer, VtfInfo->MinorVer);
\r
1265 CompFitPtr->CvAndType = CV_N_TYPE (VtfInfo->CheckSumRequired, VtfInfo->CompType);
\r
1266 if (VtfInfo->CheckSumRequired) {
\r
1267 CompFitPtr->CheckSum = 0;
\r
1268 CompFitPtr->CheckSum = CalculateChecksum8 (Buffer, (UINTN) FileSize);
\r
1272 // Free the buffer
\r
1279 // Update the SYM file for this component based on it's start address.
\r
1281 Status = UpdateSymFile (CompStartAddress, VTF_SYM_FILE, VtfInfo->CompSymName);
\r
1282 if (EFI_ERROR (Status)) {
\r
1285 // At this time, SYM files are not required, so continue on error.
\r
1289 // !!!!!!!!!!!!!!!!!!!!!
\r
1291 // This part of the code is a temporary line since PEICORE is going to be inside
\r
1292 // VTF till we work out how to determine the SALE_ENTRY through it. We will need
\r
1293 // to clarify so many related questions
\r
1294 // !!!!!!!!!!!!!!!!!!!!!!!
\r
1296 if (VtfInfo->CompType == COMP_TYPE_FIT_PEICORE) {
\r
1297 Status = UpdateEntryPoint (VtfInfo, &CompStartAddress);
\r
1304 CreateAndUpdatePAL_A (
\r
1305 IN PARSED_VTF_INFO *VtfInfo
\r
1309 Routine Description:
\r
1311 This function reads the binary file for each components and update them
\r
1312 in VTF Buffer as well as FIT table
\r
1316 VtfInfo - Pointer to Parsed Info
\r
1320 EFI_ABORTED - Due to one of the following reasons:
\r
1321 (a)Error Opening File
\r
1322 (b)The PAL_A Size is more than specified size status
\r
1323 One of the values mentioned below returned from
\r
1324 call to UpdateSymFile
\r
1325 EFI_SUCCESS - The function completed successfully.
\r
1326 EFI_INVALID_PARAMETER - One of the input parameters was invalid.
\r
1327 EFI_ABORTED - An error occurred.UpdateSymFile
\r
1328 EFI_OUT_OF_RESOURCES - Memory allocation failed.
\r
1332 EFI_STATUS Status;
\r
1333 UINT64 PalStartAddress;
\r
1334 UINT64 AbsAddress;
\r
1335 UINTN RelativeAddress;
\r
1337 UINT64 NumByteRead;
\r
1340 FIT_TABLE *PalFitPtr;
\r
1342 Fp = fopen (VtfInfo->CompBinName, "rb");
\r
1345 Error (NULL, 0, 0001, "Error opening file", VtfInfo->CompBinName);
\r
1346 return EFI_ABORTED;
\r
1349 FileSize = _filelength (fileno (Fp));
\r
1350 if (FileSize < 64) {
\r
1351 Error (NULL, 0, 2000, "Invalid paramter", "PAL_A bin header is 64 bytes, so the Bin size must be larger than 64 bytes!");
\r
1352 return EFI_INVALID_PARAMETER;
\r
1354 FileSize -= SIZE_OF_PAL_HEADER;
\r
1357 if (VtfInfo->PreferredSize) {
\r
1358 if (FileSize > VtfInfo->CompSize) {
\r
1359 Error (NULL, 0, 2000, "Invalid paramter", "The PAL_A Size is more than specified size");
\r
1360 return EFI_ABORTED;
\r
1363 FileSize = VtfInfo->CompSize;
\r
1366 Buffer = malloc ((UINTN) FileSize);
\r
1367 if (Buffer == NULL) {
\r
1368 return EFI_OUT_OF_RESOURCES;
\r
1370 memset (Buffer, 0, (UINTN) FileSize);
\r
1373 // Read, Get version Info and discard the PAL header.
\r
1375 NumByteRead = fread (Buffer, sizeof (UINT8), SIZE_OF_PAL_HEADER, Fp);
\r
1378 // Extract the version info from header of PAL_A. Once done, discrad this buffer
\r
1380 if (!VtfInfo->VersionPresent) {
\r
1381 GetComponentVersionInfo (VtfInfo, Buffer);
\r
1385 // Read PAL_A file in a buffer
\r
1387 NumByteRead = fread (Buffer, sizeof (UINT8), (UINTN) FileSize, Fp);
\r
1390 PalStartAddress = Fv1EndAddress - (SIZE_TO_OFFSET_PAL_A_END + FileSize);
\r
1391 Vtf1LastStartAddress = PalStartAddress;
\r
1392 Vtf1TotalSize += (UINT32) FileSize;
\r
1393 Status = UpdateVtfBuffer (PalStartAddress, Buffer, FileSize, FIRST_VTF);
\r
1395 AbsAddress = Fv1EndAddress - SIZE_TO_PAL_A_FIT;
\r
1396 GetRelativeAddressInVtfBuffer (AbsAddress, &RelativeAddress, FIRST_VTF);
\r
1397 PalFitPtr = (FIT_TABLE *) RelativeAddress;
\r
1398 PalFitPtr->CompAddress = PalStartAddress | IPF_CACHE_BIT;
\r
1399 //assert ((FileSize % 16) == 0);
\r
1400 if ((FileSize % 16) != 0) {
\r
1401 Error (NULL, 0, 2000, "Invalid paramter", "Binary FileSize must be multiple of 16");
\r
1402 return EFI_INVALID_PARAMETER;
\r
1405 PalFitPtr->CompSize = (UINT32) (FileSize / 16);
\r
1406 PalFitPtr->CompVersion = MAKE_VERSION (VtfInfo->MajorVer, VtfInfo->MinorVer);
\r
1407 PalFitPtr->CvAndType = CV_N_TYPE (VtfInfo->CheckSumRequired, VtfInfo->CompType);
\r
1408 if (VtfInfo->CheckSumRequired) {
\r
1409 PalFitPtr->CheckSum = 0;
\r
1410 PalFitPtr->CheckSum = CalculateChecksum8 (Buffer, (UINTN) FileSize);
\r
1418 // Update the SYM file for this component based on it's start address.
\r
1420 Status = UpdateSymFile (PalStartAddress, VTF_SYM_FILE, VtfInfo->CompSymName);
\r
1421 if (EFI_ERROR (Status)) {
\r
1424 // At this time, SYM files are not required, so continue on error.
\r
1432 CreateFitTableAndInitialize (
\r
1433 IN PARSED_VTF_INFO *VtfInfo
\r
1437 Routine Description:
\r
1439 This function creates and intializes FIT table which would be used to
\r
1440 add component info inside this
\r
1444 VtfInfo - Pointer to Parsed Info
\r
1448 EFI_ABORTED - Aborted due to no size information
\r
1449 EFI_SUCCESS - The function completed successfully
\r
1453 UINT64 PalFitTableAdd;
\r
1454 UINT64 FitTableAdd;
\r
1455 UINT64 FitTableAddressOffset;
\r
1456 FIT_TABLE *PalFitPtr;
\r
1457 FIT_TABLE *FitStartPtr;
\r
1459 UINTN RelativeAddress;
\r
1462 if (!VtfInfo->PreferredSize) {
\r
1463 Error (NULL, 0, 2000, "Invalid paramter", "FIT could not be allocated becuase there are no size information");
\r
1464 return EFI_ABORTED;
\r
1467 if ((VtfInfo->CompSize % 16) != 0) {
\r
1468 Error (NULL, 0, 2000, "Invalid paramter", "Invalid Fit Table Size, not multiple of 16 bytes. Please correct the size");
\r
1471 PalFitTableAdd = Fv1EndAddress - SIZE_TO_PAL_A_FIT;
\r
1472 GetRelativeAddressInVtfBuffer (PalFitTableAdd, &RelativeAddress, FIRST_VTF);
\r
1473 PalFitPtr = (FIT_TABLE *) RelativeAddress;
\r
1474 PalFitTableAdd = (PalFitPtr->CompAddress - VtfInfo->CompSize);
\r
1476 FitTableAdd = (PalFitPtr->CompAddress - 0x10) - VtfInfo->CompSize;
\r
1477 FitTableAddressOffset = Fv1EndAddress - (SIZE_IA32_RESET_VECT + SIZE_SALE_ENTRY_POINT + SIZE_FIT_TABLE_ADD);
\r
1478 GetRelativeAddressInVtfBuffer (FitTableAddressOffset, &RelativeAddress, FIRST_VTF);
\r
1479 *(UINT64 *) RelativeAddress = FitTableAdd;
\r
1481 GetRelativeAddressInVtfBuffer (FitTableAdd, &RelativeAddress, FIRST_VTF);
\r
1484 // Update Fit Table with FIT Signature and FIT info in first 16 bytes.
\r
1486 FitStartPtr = (FIT_TABLE *) RelativeAddress;
\r
1488 strncpy ((CHAR8 *) &FitStartPtr->CompAddress, FIT_SIGNATURE, 8); // "_FIT_ "
\r
1489 assert (((VtfInfo->CompSize & 0x00FFFFFF) % 16) == 0);
\r
1490 FitStartPtr->CompSize = (VtfInfo->CompSize & 0x00FFFFFF) / 16;
\r
1491 FitStartPtr->CompVersion = MAKE_VERSION (VtfInfo->MajorVer, VtfInfo->MinorVer);
\r
1494 // BUGBUG: If a checksum is required, add code to checksum the FIT table. Also
\r
1495 // determine what to do for things like the FV component that aren't easily checksummed.
\r
1496 // The checksum will be done once we are done with all the componet update in the FIT
\r
1499 FitStartPtr->CvAndType = CV_N_TYPE (VtfInfo->CheckSumRequired, VtfInfo->CompType);
\r
1501 NumFitComp = FitStartPtr->CompSize;
\r
1506 // Intialize remaining FIT table space to UNUSED fit component type
\r
1507 // so that when we need to create a FIT entry for a component, we can
\r
1508 // locate a free one and use it.
\r
1510 for (Index = 0; Index < (NumFitComp - 1); Index++) {
\r
1511 FitStartPtr->CvAndType = 0x7F; // Initialize all with UNUSED
\r
1515 Vtf1TotalSize += VtfInfo->CompSize;
\r
1516 Vtf1LastStartAddress -= VtfInfo->CompSize;
\r
1518 return EFI_SUCCESS;
\r
1523 IN CHAR8 *FileName,
\r
1524 IN UINT32 VtfSize,
\r
1525 IN LOC_TYPE LocType
\r
1529 Routine Description:
\r
1531 Write Firmware Volume from memory to a file.
\r
1535 FileName - Output File Name which needed to be created/
\r
1536 VtfSize - FileSize
\r
1537 LocType - The type of the VTF
\r
1541 EFI_ABORTED - Returned due to one of the following resons:
\r
1542 (a) Error Opening File
\r
1543 (b) Failing to copy buffers
\r
1544 EFI_SUCCESS - The fuction completes successfully
\r
1551 UINTN RelativeAddress;
\r
1553 if (LocType == FIRST_VTF) {
\r
1554 GetRelativeAddressInVtfBuffer (Vtf1LastStartAddress, &RelativeAddress, FIRST_VTF);
\r
1555 VtfBuffer = (VOID *) RelativeAddress;
\r
1557 GetRelativeAddressInVtfBuffer (Vtf2LastStartAddress, &RelativeAddress, SECOND_VTF);
\r
1558 VtfBuffer = (VOID *) RelativeAddress;
\r
1561 Fp = fopen (FileName, "wb");
\r
1563 Error (NULL, 0, 0001, "Error opening file", FileName);
\r
1564 return EFI_ABORTED;
\r
1567 NumByte = fwrite (VtfBuffer, sizeof (UINT8), (UINTN) VtfSize, Fp);
\r
1573 if (NumByte != (sizeof (UINT8) * VtfSize)) {
\r
1574 Error (NULL, 0, 0002, "Error writing file", FileName);
\r
1575 return EFI_ABORTED;
\r
1578 return EFI_SUCCESS;
\r
1583 IN UINT64 StartAddress,
\r
1585 IN UINT64 DataSize,
\r
1586 IN LOC_TYPE LocType
\r
1590 Routine Description:
\r
1592 Update the Firmware Volume Buffer with requested buffer data
\r
1596 StartAddress - StartAddress in buffer. This number will automatically
\r
1597 point to right address in buffer where data needed
\r
1599 Buffer - Buffer pointer from data will be copied to memory mapped buffer.
\r
1600 DataSize - Size of the data needed to be copied.
\r
1601 LocType - The type of the VTF: First or Second
\r
1605 EFI_ABORTED - The input parameter is error
\r
1606 EFI_SUCCESS - The function completed successfully
\r
1610 UINT8 *LocalBufferPtrToWrite;
\r
1612 if (LocType == FIRST_VTF) {
\r
1613 if ((StartAddress | IPF_CACHE_BIT) < (Vtf1LastStartAddress | IPF_CACHE_BIT)) {
\r
1614 Error (NULL, 0, 2000, "Invalid paramter", "Start Address is less then the VTF start address");
\r
1615 return EFI_ABORTED;
\r
1618 LocalBufferPtrToWrite = (UINT8 *) Vtf1EndBuffer;
\r
1620 LocalBufferPtrToWrite -= (Fv1EndAddress - StartAddress);
\r
1624 if ((StartAddress | IPF_CACHE_BIT) < (Vtf2LastStartAddress | IPF_CACHE_BIT)) {
\r
1625 Error (NULL, 0, 2000, "Invalid paramter", "Error StartAddress");
\r
1626 return EFI_ABORTED;
\r
1628 LocalBufferPtrToWrite = (UINT8 *) Vtf2EndBuffer;
\r
1629 LocalBufferPtrToWrite -= (Fv2EndAddress - StartAddress);
\r
1632 memcpy (LocalBufferPtrToWrite, Buffer, (UINTN) DataSize);
\r
1634 return EFI_SUCCESS;
\r
1639 IN UINT32 TotalVtfSize,
\r
1640 IN LOC_TYPE LocType
\r
1644 Routine Description:
\r
1646 Update the Firmware Volume Buffer with requested buffer data
\r
1650 TotalVtfSize - Size of the VTF
\r
1651 Fileoffset - The start of the file relative to the start of the FV.
\r
1652 LocType - The type of the VTF
\r
1656 EFI_SUCCESS - The function completed successfully
\r
1657 EFI_INVALID_PARAMETER - The Ffs File Header Pointer is NULL
\r
1661 EFI_FFS_FILE_HEADER *FileHeader;
\r
1662 UINTN RelativeAddress;
\r
1663 EFI_GUID EfiFirmwareVolumeTopFileGuid = EFI_FFS_VOLUME_TOP_FILE_GUID;
\r
1666 // Find the VTF file header location
\r
1668 if (LocType == FIRST_VTF) {
\r
1669 GetRelativeAddressInVtfBuffer (Vtf1LastStartAddress, &RelativeAddress, FIRST_VTF);
\r
1670 FileHeader = (EFI_FFS_FILE_HEADER *) RelativeAddress;
\r
1672 GetRelativeAddressInVtfBuffer (Vtf2LastStartAddress, &RelativeAddress, SECOND_VTF);
\r
1673 FileHeader = (EFI_FFS_FILE_HEADER *) RelativeAddress;
\r
1676 if (FileHeader == NULL) {
\r
1677 return EFI_INVALID_PARAMETER;
\r
1683 memset (FileHeader, 0, sizeof (EFI_FFS_FILE_HEADER));
\r
1684 memcpy (&FileHeader->Name, &EfiFirmwareVolumeTopFileGuid, sizeof (EFI_GUID));
\r
1685 FileHeader->Type = EFI_FV_FILETYPE_RAW;
\r
1686 FileHeader->Attributes = FFS_ATTRIB_CHECKSUM;
\r
1689 // Now FileSize includes the EFI_FFS_FILE_HEADER
\r
1691 FileHeader->Size[0] = (UINT8) (TotalVtfSize & 0x000000FF);
\r
1692 FileHeader->Size[1] = (UINT8) ((TotalVtfSize & 0x0000FF00) >> 8);
\r
1693 FileHeader->Size[2] = (UINT8) ((TotalVtfSize & 0x00FF0000) >> 16);
\r
1696 // Fill in checksums and state, all three must be zero for the checksums.
\r
1698 FileHeader->IntegrityCheck.Checksum.Header = 0;
\r
1699 FileHeader->IntegrityCheck.Checksum.File = 0;
\r
1700 FileHeader->State = 0;
\r
1701 FileHeader->IntegrityCheck.Checksum.Header = CalculateChecksum8 ((UINT8 *) FileHeader, sizeof (EFI_FFS_FILE_HEADER));
\r
1702 FileHeader->IntegrityCheck.Checksum.File = CalculateChecksum8 ((UINT8 *) FileHeader, TotalVtfSize);
\r
1703 FileHeader->State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID;
\r
1705 return EFI_SUCCESS;
\r
1709 ValidateAddressAndSize (
\r
1710 IN UINT64 BaseAddress,
\r
1711 IN UINT64 FwVolSize
\r
1715 Routine Description:
\r
1717 Update the Firmware Volume Buffer with requested buffer data
\r
1721 BaseAddress - Base address for the Fw Volume.
\r
1723 FwVolSize - Total Size of the FwVolume to which VTF will be attached..
\r
1727 EFI_SUCCESS - The function completed successfully
\r
1728 EFI_UNSUPPORTED - The input parameter is error
\r
1732 if ((BaseAddress >= 0) && (FwVolSize > 0x40) && ((BaseAddress + FwVolSize) % 8 == 0)) {
\r
1733 return EFI_SUCCESS;
\r
1736 return EFI_UNSUPPORTED;
\r
1740 UpdateIA32ResetVector (
\r
1741 IN CHAR8 *FileName,
\r
1742 IN UINT64 FirstFwVSize
\r
1746 Routine Description:
\r
1748 Update the 16 byte IA32 Reset vector to maintain the compatibility
\r
1752 FileName - Binary file name which contains the IA32 Reset vector info..
\r
1753 FirstFwVSize - Total Size of the FwVolume to which VTF will be attached..
\r
1757 EFI_SUCCESS - The function completed successfully
\r
1758 EFI_ABORTED - Invalid File Size
\r
1759 EFI_INVALID_PARAMETER - Bad File Name
\r
1760 EFI_OUT_OF_RESOURCES - Memory allocation failed.
\r
1765 UINT8 *LocalVtfBuffer;
\r
1767 UINTN NumByteRead;
\r
1770 if (!strcmp (FileName, "")) {
\r
1771 return EFI_INVALID_PARAMETER;
\r
1774 Fp = fopen (FileName, "rb");
\r
1777 Error (NULL, 0, 0001, "Error opening file", FileName);
\r
1780 FileSize = _filelength (fileno (Fp));
\r
1782 if (FileSize > 16) {
\r
1783 return EFI_ABORTED;
\r
1786 Buffer = malloc (FileSize);
\r
1787 if (Buffer == NULL) {
\r
1788 return EFI_OUT_OF_RESOURCES;
\r
1791 NumByteRead = fread (Buffer, sizeof (UINT8), FileSize, Fp);
\r
1793 LocalVtfBuffer = (UINT8 *) Vtf1EndBuffer - SIZE_IA32_RESET_VECT;
\r
1794 memcpy (LocalVtfBuffer, Buffer, FileSize);
\r
1800 return EFI_SUCCESS;
\r
1809 Routine Description:
\r
1811 This function cleans up any allocated buffer
\r
1823 PARSED_VTF_INFO *TempFileListPtr;
\r
1826 free (Vtf1Buffer);
\r
1830 free (Vtf2Buffer);
\r
1834 // Cleanup the buffer which was allocated to read the file names from FV.INF
\r
1836 FileListPtr = FileListHeadPtr;
\r
1837 while (FileListPtr != NULL) {
\r
1838 TempFileListPtr = FileListPtr->NextVtfInfo;
\r
1839 free (FileListPtr);
\r
1840 FileListPtr = TempFileListPtr;
\r
1845 ProcessAndCreateVtf (
\r
1850 Routine Description:
\r
1852 This function process the link list created during INF file parsing
\r
1853 and create component in VTF and updates its info in FIT table
\r
1857 Size - Size of the Firmware Volume of which, this VTF belongs to.
\r
1861 EFI_UNSUPPORTED - Unknown FIT type
\r
1862 EFI_SUCCESS - The function completed successfully
\r
1866 EFI_STATUS Status;
\r
1867 PARSED_VTF_INFO *ParsedInfoPtr;
\r
1869 Status = EFI_SUCCESS;
\r
1871 ParsedInfoPtr = FileListHeadPtr;
\r
1873 while (ParsedInfoPtr != NULL) {
\r
1875 switch (ParsedInfoPtr->CompType) {
\r
1877 // COMP_TYPE_FIT_HEADER is a special case, hence handle it here
\r
1879 case COMP_TYPE_FIT_HEADER:
\r
1880 //COMP_TYPE_FIT_HEADER 0x00
\r
1881 Status = CreateFitTableAndInitialize (ParsedInfoPtr);
\r
1885 // COMP_TYPE_FIT_PAL_A is a special case, hence handle it here
\r
1887 case COMP_TYPE_FIT_PAL_A:
\r
1888 //COMP_TYPE_FIT_PAL_A 0x0F
\r
1889 Status = CreateAndUpdatePAL_A (ParsedInfoPtr);
\r
1892 // Based on VTF specification, once the PAL_A component has been written,
\r
1893 // update the Firmware Volume info as FIT table. This will be utilized
\r
1894 // to extract the Firmware Volume Start address where this VTF will be
\r
1897 if (Status == EFI_SUCCESS) {
\r
1898 UpdateFitEntryForFwVolume (Size);
\r
1902 case COMP_TYPE_FIT_FV_BOOT:
\r
1903 //COMP_TYPE_FIT_FV_BOOT 0x7E
\r
1905 // Since FIT entry for Firmware Volume has been created and it is
\r
1906 // located at (PAL_A start - 16 byte). So we will not process any
\r
1907 // Firmware Volume related entry from INF file
\r
1909 Status = EFI_SUCCESS;
\r
1914 // Any other component type should be handled here. This will create the
\r
1915 // image in specified VTF and create appropriate entry about this
\r
1916 // component in FIT Entry.
\r
1918 Status = CreateAndUpdateComponent (ParsedInfoPtr);
\r
1919 if (EFI_ERROR (Status)) {
\r
1920 Error (NULL, 0, 0002, "Error updating component", ParsedInfoPtr->CompName);
\r
1921 return EFI_ABORTED;
\r
1926 ParsedInfoPtr = ParsedInfoPtr->NextVtfInfo;
\r
1932 GenerateVtfImage (
\r
1933 IN UINT64 StartAddress1,
\r
1935 IN UINT64 StartAddress2,
\r
1941 Routine Description:
\r
1943 This is the main function which will be called from application.
\r
1947 StartAddress1 - The start address of the first VTF
\r
1948 Size1 - The size of the first VTF
\r
1949 StartAddress2 - The start address of the second VTF
\r
1950 Size2 - The size of the second VTF
\r
1951 fp - The pointer to BSF inf file
\r
1955 EFI_OUT_OF_RESOURCES - Can not allocate memory
\r
1956 The return value can be any of the values
\r
1957 returned by the calls to following functions:
\r
1958 GetVtfRelatedInfoFromInfFile
\r
1959 ProcessAndCreateVtf
\r
1960 UpdateIA32ResetVector
\r
1966 EFI_STATUS Status;
\r
1969 Status = EFI_UNSUPPORTED;
\r
1972 if (StartAddress2 == 0) {
\r
1973 SecondVTF = FALSE;
\r
1978 Fv1BaseAddress = StartAddress1;
\r
1979 Fv1EndAddress = Fv1BaseAddress + Size1;
\r
1980 if (Fv1EndAddress != 0x100000000 || Size1 < 0x100000) {
\r
1981 Error (NULL, 0, 2000, "Invalid paramter", "Error BaseAddress and Size parameters!");
\r
1982 if (Size1 < 0x100000) {
\r
1983 Error (NULL, 0, 2000, "Invalid paramter", "The FwVolumeSize must be larger than 1M!");
\r
1984 } else if (SecondVTF != TRUE) {
\r
1985 Error (NULL, 0, 2000, "Invalid paramter", "BaseAddress + FwVolumeSize must equal 0x100000000!");
\r
1988 return EFI_INVALID_PARAMETER;
\r
1992 // The image buffer for the First VTF
\r
1994 Vtf1Buffer = malloc ((UINTN) Size1);
\r
1995 if (Vtf1Buffer == NULL) {
\r
1996 Error (NULL, 0, 4001, "Resource", "Not enough resource to create memory mapped file for Boot Strap File!");
\r
1997 return EFI_OUT_OF_RESOURCES;
\r
1999 memset (Vtf1Buffer, 0x00, (UINTN) Size1);
\r
2000 Vtf1EndBuffer = (UINT8 *) Vtf1Buffer + Size1;
\r
2001 Vtf1LastStartAddress = Fv1EndAddress | IPF_CACHE_BIT;
\r
2004 Fv2BaseAddress = StartAddress2;
\r
2005 Fv2EndAddress = Fv2BaseAddress + Size2;
\r
2006 if (Fv2EndAddress != StartAddress1) {
\r
2007 Error (NULL, 0, 2000, "Invalid paramter", "Error BaseAddress and Size parameters");
\r
2008 if (SecondVTF == TRUE) {
\r
2009 Error (NULL, 0, 2000, "Invalid paramter", "FirstBaseAddress + FirstFwVolumeSize must equal 0x100000000!");
\r
2010 Error (NULL, 0, 2000, "Invalid paramter", "SecondBaseAddress + SecondFwVolumeSize must equal FirstBaseAddress!");
\r
2013 return EFI_INVALID_PARAMETER;
\r
2017 // The image buffer for the second VTF
\r
2019 Vtf2Buffer = malloc ((UINTN) Size2);
\r
2020 if (Vtf2Buffer == NULL) {
\r
2021 Error (NULL, 0, 4001, "Resource", "Not enough resource to create memory mapped file for Boot Strap File!");
\r
2022 return EFI_OUT_OF_RESOURCES;
\r
2024 memset (Vtf2Buffer, 0x00, (UINTN) Size2);
\r
2025 Vtf2EndBuffer = (UINT8 *) Vtf2Buffer + Size2;
\r
2026 Vtf2LastStartAddress = Fv2EndAddress | IPF_CACHE_BIT;
\r
2029 Status = GetVtfRelatedInfoFromInfFile (VtfFP);
\r
2031 if (Status != EFI_SUCCESS) {
\r
2032 Error (NULL, 0, 0003, "Error parsing file", "the input file.");
\r
2037 Status = ProcessAndCreateVtf (Size1);
\r
2038 if (Status != EFI_SUCCESS) {
\r
2043 if (SectionOptionFlag) {
\r
2044 Status = UpdateIA32ResetVector (IA32BinFile, Vtf1TotalSize);
\r
2045 if (Status != EFI_SUCCESS) {
\r
2052 // Re arrange the FIT Table for Ascending order of their FIT Type..
\r
2057 // All components have been updated in FIT table. Now perform the FIT table
\r
2058 // checksum. The following function will check if Checksum is required,
\r
2059 // if yes, then it will perform the checksum otherwise not.
\r
2061 CalculateFitTableChecksum ();
\r
2064 // Write the FFS header
\r
2066 Vtf1TotalSize += sizeof (EFI_FFS_FILE_HEADER);
\r
2067 Vtf1LastStartAddress -= sizeof (EFI_FFS_FILE_HEADER);
\r
2069 Status = UpdateFfsHeader (Vtf1TotalSize, FIRST_VTF);
\r
2070 if (Status != EFI_SUCCESS) {
\r
2075 // Update the VTF buffer into specified VTF binary file
\r
2077 Status = WriteVtfBinary (OutFileName1, Vtf1TotalSize, FIRST_VTF);
\r
2080 Vtf2TotalSize += sizeof (EFI_FFS_FILE_HEADER);
\r
2081 Vtf2LastStartAddress -= sizeof (EFI_FFS_FILE_HEADER);
\r
2082 Status = UpdateFfsHeader (Vtf2TotalSize, SECOND_VTF);
\r
2083 if (Status != EFI_SUCCESS) {
\r
2089 // Update the VTF buffer into specified VTF binary file
\r
2091 Status = WriteVtfBinary (OutFileName2, Vtf2TotalSize, SECOND_VTF);
\r
2100 PeimFixupInFitTable (
\r
2101 IN UINT64 StartAddress
\r
2105 Routine Description:
\r
2107 This function is an entry point to fixup SAL-E entry point.
\r
2111 StartAddress - StartAddress for PEIM.....
\r
2115 EFI_SUCCESS - The function completed successfully
\r
2116 EFI_ABORTED - Error Opening File
\r
2117 EFI_OUT_OF_RESOURCES - System out of resources for memory allocation.
\r
2121 EFI_STATUS Status;
\r
2123 UINT64 *StartAddressPtr;
\r
2124 UINTN FirstFwVSize;
\r
2127 StartAddressPtr = malloc (sizeof (UINT64));
\r
2128 if (StartAddressPtr == NULL) {
\r
2129 return EFI_OUT_OF_RESOURCES;
\r
2131 *StartAddressPtr = StartAddress;
\r
2133 Fp = fopen (OutFileName1, "rb");
\r
2136 Error (NULL, 0, 0001, "Error opening file", OutFileName1);
\r
2137 if (StartAddressPtr) {
\r
2138 free (StartAddressPtr);
\r
2140 return EFI_ABORTED;
\r
2143 FirstFwVSize = _filelength (fileno (Fp));
\r
2144 fseek (Fp, (long) (FirstFwVSize - (UINTN) (SIZE_IA32_RESET_VECT + SIZE_SALE_ENTRY_POINT)), SEEK_SET);
\r
2145 NumByte = fwrite ((VOID *) StartAddressPtr, sizeof (UINT64), 1, Fp);
\r
2151 if (StartAddressPtr) {
\r
2152 free (StartAddressPtr);
\r
2155 Status = EFI_SUCCESS;
\r
2161 IN UINT64 BaseAddress,
\r
2162 IN CHAR8 *DestFileName,
\r
2163 IN CHAR8 *SourceFileName
\r
2167 Routine Description:
\r
2169 This function adds the SYM tokens in the source file to the destination file.
\r
2170 The SYM tokens are updated to reflect the base address.
\r
2174 BaseAddress - The base address for the new SYM tokens.
\r
2175 DestFileName - The destination file.
\r
2176 SourceFileName - The source file.
\r
2180 EFI_SUCCESS - The function completed successfully.
\r
2181 EFI_INVALID_PARAMETER - One of the input parameters was invalid.
\r
2182 EFI_ABORTED - An error occurred.
\r
2188 CHAR8 Buffer[_MAX_PATH];
\r
2189 CHAR8 Type[_MAX_PATH];
\r
2190 CHAR8 Address[_MAX_PATH];
\r
2191 CHAR8 Section[_MAX_PATH];
\r
2192 CHAR8 Token[_MAX_PATH];
\r
2193 CHAR8 BaseToken[_MAX_PATH];
\r
2194 UINT64 TokenAddress;
\r
2195 long StartLocation;
\r
2198 // Verify input parameters.
\r
2200 if (BaseAddress == 0 || DestFileName == NULL || SourceFileName == NULL) {
\r
2201 return EFI_INVALID_PARAMETER;
\r
2205 // Open the source file
\r
2207 SourceFile = fopen (SourceFileName, "r");
\r
2208 if (SourceFile == NULL) {
\r
2211 // SYM files are not required.
\r
2213 return EFI_SUCCESS;
\r
2217 // Use the file name minus extension as the base for tokens
\r
2219 strcpy (BaseToken, SourceFileName);
\r
2220 strtok (BaseToken, ". \t\n");
\r
2221 strcat (BaseToken, "__");
\r
2224 // Open the destination file
\r
2226 DestFile = fopen (DestFileName, "a+");
\r
2227 if (DestFile == NULL) {
\r
2228 fclose (SourceFile);
\r
2229 Error (NULL, 0, 0001, "Error opening file", DestFileName);
\r
2230 return EFI_ABORTED;
\r
2234 // If this is the beginning of the output file, write the symbol format info.
\r
2236 if (fseek (DestFile, 0, SEEK_END) != 0) {
\r
2237 fclose (SourceFile);
\r
2238 fclose (DestFile);
\r
2239 Error (NULL, 0, 2000, "Invalid paramter", "not the beginning of the output file");
\r
2240 return EFI_ABORTED;
\r
2243 StartLocation = ftell (DestFile);
\r
2245 if (StartLocation == 0) {
\r
2246 fprintf (DestFile, "TEXTSYM format | V1.0\n");
\r
2247 } else if (StartLocation == -1) {
\r
2248 fclose (SourceFile);
\r
2249 fclose (DestFile);
\r
2250 Error (NULL, 0, 2000, "Invalid paramter", "StartLocation error");
\r
2251 return EFI_ABORTED;
\r
2255 // Read the first line
\r
2257 if (fgets (Buffer, _MAX_PATH, SourceFile) == NULL) {
\r
2262 // Make sure it matches the expected sym format
\r
2264 if (strcmp (Buffer, "TEXTSYM format | V1.0\n")) {
\r
2265 fclose (SourceFile);
\r
2266 fclose (DestFile);
\r
2267 Error (NULL, 0, 2000, "Invalid paramter", "The symbol file does not match the expected sym format");
\r
2268 return EFI_ABORTED;
\r
2272 // Read in the file
\r
2274 while (feof (SourceFile) == 0) {
\r
2279 if (fscanf (SourceFile, "%s | %s | %s | %s\n", Type, Address, Section, Token) == 4) {
\r
2282 // Get the token address
\r
2284 AsciiStringToUint64 (Address, TRUE, &TokenAddress);
\r
2287 // Add the base address, the size of the FFS file header and the size of the peim header.
\r
2289 TokenAddress += BaseAddress &~IPF_CACHE_BIT;
\r
2291 fprintf (DestFile, "%s | %016I64X | %s | %s%s\n", Type, TokenAddress, Section, BaseToken, Token);
\r
2295 fclose (SourceFile);
\r
2296 fclose (DestFile);
\r
2297 return EFI_SUCCESS;
\r
2301 CalculateFitTableChecksum (
\r
2306 Routine Description:
\r
2308 This function will perform byte checksum on the FIT table, if the the checksum required
\r
2309 field is set to CheckSum required. If the checksum is not required then checksum byte
\r
2310 will have value as 0;.
\r
2318 Status - Value returned by call to CalculateChecksum8 ()
\r
2319 EFI_SUCCESS - The function completed successfully
\r
2323 FIT_TABLE *TmpFitPtr;
\r
2324 UINT64 FitTableAdd;
\r
2325 UINT64 FitTableAddOffset;
\r
2326 UINTN RelativeAddress;
\r
2330 // Read the Fit Table address from Itanium-based address map.
\r
2332 FitTableAddOffset = Fv1EndAddress - (SIZE_IA32_RESET_VECT + SIZE_SALE_ENTRY_POINT + SIZE_FIT_TABLE_ADD);
\r
2335 // Translate this Itanium-based address in terms of local buffer address which
\r
2336 // contains the image for Boot Strapped File
\r
2338 GetRelativeAddressInVtfBuffer (FitTableAddOffset, &RelativeAddress, FIRST_VTF);
\r
2339 FitTableAdd = *(UINTN *) RelativeAddress;
\r
2341 GetRelativeAddressInVtfBuffer (FitTableAdd, &RelativeAddress, FIRST_VTF);
\r
2343 TmpFitPtr = (FIT_TABLE *) RelativeAddress;
\r
2345 Size = TmpFitPtr->CompSize * 16;
\r
2347 if ((TmpFitPtr->CvAndType & CHECKSUM_BIT_MASK) >> 7) {
\r
2348 TmpFitPtr->CheckSum = 0;
\r
2349 TmpFitPtr->CheckSum = CalculateChecksum8 ((UINT8 *) TmpFitPtr, Size);
\r
2351 TmpFitPtr->CheckSum = 0;
\r
2354 return EFI_SUCCESS;
\r
2363 Routine Description:
\r
2365 Displays the standard utility information to SDTOUT
\r
2377 fprintf (stdout, "%s Version %d.%d\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION);
\r
2386 Routine Description:
\r
2388 Displays the utility usage syntax to STDOUT
\r
2403 fprintf (stdout, "Usage: %s [options] <-f input_file> <-r BaseAddress> <-s FwVolumeSize>\n\n", UTILITY_NAME);
\r
2406 // Copyright declaration
\r
2408 fprintf (stdout, "Copyright (c) 2007, Intel Corporation. All rights reserved.\n\n");
\r
2410 fprintf (stdout, " -f input_file\n\
\r
2411 input_file is name of the BS Image INF file to use.\n");
\r
2412 fprintf (stdout, " -r BaseAddress\n\
\r
2413 BaseAddress is the starting address of Firmware Volume where Boot Strapped Image will reside.\n");
\r
2414 fprintf (stdout, " -s FwVolumeSize\n\
\r
2415 FwVolumeSize is the size of Firmware Volume.\n");
\r
2419 fprintf (stdout, "Options:\n");
\r
2420 fprintf (stdout, " -o FileName, --output FileName\n\
\r
2421 File will be created to store the ouput content.\n");
\r
2422 fprintf (stdout, " -v, --verbose\n\
\r
2423 Turn on verbose output with informational messages.\n");
\r
2424 fprintf (stdout, " --version\n\
\r
2425 Show program's version number and exit.\n");
\r
2426 fprintf (stdout, " -h, --help\n\
\r
2427 Show this help message and exit.\n");
\r
2428 fprintf (stdout, " -q\n\
\r
2429 Disable all messages except FATAL ERRORS.\n");
\r
2430 fprintf (stdout, " -d [#, 0-9]\n\
\r
2431 Enable debug messages at level #.\n");
\r
2441 Routine Description:
\r
2443 This utility uses GenVtf.dll to build a Boot Strap File Image which will be
\r
2444 part of firmware volume image.
\r
2448 argc - The count of the parameters
\r
2449 argv - The parameters
\r
2454 0 - No error conditions detected.
\r
2455 1 - One or more of the input parameters is invalid.
\r
2456 2 - A resource required by the utility was unavailable.
\r
2457 - Most commonly this will be memory allocation or file creation.
\r
2458 3 - GenFvImage.dll could not be loaded.
\r
2459 4 - Error executing the GenFvImage dll.
\r
2460 5 - Now this tool does not support the IA32 platform
\r
2465 UINT64 StartAddress1;
\r
2466 UINT64 StartAddress2;
\r
2467 UINT64 FwVolSize1;
\r
2468 UINT64 FwVolSize2;
\r
2469 BOOLEAN FirstRoundO;
\r
2470 BOOLEAN FirstRoundB;
\r
2471 BOOLEAN FirstRoundS;
\r
2472 EFI_STATUS Status;
\r
2475 CHAR8 *OutputFileName;
\r
2476 CHAR8 *VtfFileName;
\r
2478 SetUtilityName (UTILITY_NAME);
\r
2481 // Initialize variables
\r
2483 StartAddress1 = 0;
\r
2484 StartAddress2 = 0;
\r
2487 FirstRoundB = TRUE;
\r
2488 FirstRoundS = TRUE;
\r
2489 FirstRoundO = TRUE;
\r
2490 DebugMode = FALSE;
\r
2491 OutFileName1 = NULL;
\r
2492 OutFileName2 = NULL;
\r
2497 // Verify the correct number of arguments
\r
2504 if ((strcmp(argv[1], "-h") == 0) || (strcmp(argv[1], "--help") == 0) ||
\r
2505 (strcmp(argv[1], "-?") == 0) || (strcmp(argv[1], "/?") == 0)) {
\r
2510 if ((strcmp(argv[1], "--version") == 0)) {
\r
2516 // Parse the command line arguments
\r
2518 for (Index = 1; Index < argc; Index += 2) {
\r
2520 // Make sure argument pair begin with - or /
\r
2522 if (argv[Index][0] != '-' && argv[Index][0] != '/') {
\r
2524 Error (NULL, 0, 2000, "Invalid paramter", "Argument pair must begin with \"-\" or \"/\"!");
\r
2529 // Make sure argument specifier is only one letter
\r
2531 if (argv[Index][2] != 0) {
\r
2533 Error (NULL, 0, 2000, "Invalid paramter", "Unrecognized argument %s", argv[Index]);
\r
2537 // Determine argument to read
\r
2539 switch (argv[Index][1]) {
\r
2544 // Get the output file name
\r
2546 VTF_OUTPUT = TRUE;
\r
2547 if (FirstRoundO) {
\r
2549 // It's the first output file name
\r
2551 OutFileName1 = (CHAR8 *)argv[Index+1];
\r
2552 FirstRoundO = FALSE;
\r
2556 //It's the second output file name
\r
2558 OutFileName2 = (CHAR8 *)argv[Index+1];
\r
2565 // Get the input VTF file name
\r
2567 VtfFileName = argv[Index+1];
\r
2568 VtfFP = fopen(VtfFileName, "rb");
\r
2569 if (VtfFP == NULL) {
\r
2570 Error (NULL, 0, 0001, "Error opening file", VtfFileName);
\r
2577 if (FirstRoundB) {
\r
2578 Status = AsciiStringToUint64 (argv[Index + 1], FALSE, &StartAddress1);
\r
2579 FirstRoundB = FALSE;
\r
2581 Status = AsciiStringToUint64 (argv[Index + 1], FALSE, &StartAddress2);
\r
2584 Error (NULL, 0, 2000, "Invalid paramter", "Bad start of address %s", argv[Index + 1]);
\r
2591 if (FirstRoundS) {
\r
2592 Status = AsciiStringToUint64 (argv[Index + 1], FALSE, &FwVolSize1);
\r
2593 FirstRoundS = FALSE;
\r
2595 Status = AsciiStringToUint64 (argv[Index + 1], FALSE, &FwVolSize2);
\r
2599 if (Status != EFI_SUCCESS) {
\r
2600 Error (NULL, 0, 2000, "Invalid paramter", "Bad size %s", argv[Index + 1]);
\r
2609 VerboseMode = TRUE;
\r
2614 // debug level specified
\r
2616 Status = AsciiStringToUint64(argv[Index + 1], FALSE, &DebugLevel);
\r
2617 if((DebugLevel > 9) || (DebugLevel < 0)) {
\r
2618 Error(NULL, 0, 2000, "Invalid parameter", "Unrecognized argument %s", argv[Index + 1]);
\r
2621 if((DebugLevel <= 9) &&(DebugLevel >= 5)) {
\r
2624 DebugMode = FALSE;
\r
2633 Error (NULL, 0, 2000, "Invalid paramter", "Unrecognized argument %s", argv[Index]);
\r
2639 if (VerboseMode) {
\r
2640 fprintf (stdout, "%s tool start.\n", UTILITY_NAME);
\r
2643 if (VTF_OUTPUT == FALSE) {
\r
2644 if (SecondVTF == TRUE) {
\r
2645 OutFileName1 = VTF_OUTPUT_FILE1;
\r
2646 OutFileName2 = VTF_OUTPUT_FILE2;
\r
2648 OutFileName1 = VTF_OUTPUT_FILE1;
\r
2653 // Call the GenVtfImage
\r
2656 fprintf(stdout, "Start to generate the VTF image\n");
\r
2658 Status = GenerateVtfImage (StartAddress1, FwVolSize1, StartAddress2, FwVolSize2, VtfFP);
\r
2660 if (EFI_ERROR (Status)) {
\r
2663 case EFI_INVALID_PARAMETER:
\r
2664 Error (NULL, 0, 2000, "Invalid paramter", "Invalid parameter passed to GenVtf function.");
\r
2668 Error (NULL, 0, 3000, "Invaild", "Error detected while creating the file image.");
\r
2671 case EFI_OUT_OF_RESOURCES:
\r
2672 Error (NULL, 0, 4002, "Resource", "GenVtfImage function could not allocate required resources.");
\r
2675 case EFI_VOLUME_CORRUPTED:
\r
2676 Error (NULL, 0, 3000, "Invaild", "No base address was specified");
\r
2680 Error (NULL, 0, 3000, "Invaild", "GenVtfImage function returned unknown status %x",Status );
\r
2684 if (VerboseMode) {
\r
2685 fprintf (stdout, "%s tool done with return code is 0x%x.\n", UTILITY_NAME, GetUtilityStatus ());
\r
2688 return GetUtilityStatus ();
\r
2691 fprintf(stdout, "VTF image generated successful\n");
\r