3 Copyright (c) 1999 - 2006, Intel Corporation. All rights reserved
4 This software and associated documentation (if any) is furnished
5 under a license and may only be used or copied in accordance
6 with the terms of the license. Except as permitted by such
7 license, no part of this software or documentation may be
8 reproduced, stored in a retrieval system, or transmitted in any
9 form or by any means without the express written consent of
19 This file contains functions required to generate a boot strap file (BSF)
20 also known as the Volume Top File (VTF)
25 // Module Coded to EFI 2.0 Coding Conventions
28 #include <Common/UefiBaseTypes.h>
29 #include "GenBsfImage.h"
30 #include <Guid/FirmwareFileSystem.h>
31 #include "CommonLib.h"
36 EFI_GUID Bsf1NameGuid
= EFI_IPF_VTF1_GUID
37 EFI_GUID Bsf2NameGuid
= EFI_IPF_VTF2_GUID
42 PARSED_BSF_INFO
*FileListPtr
;
43 PARSED_BSF_INFO
*FileListHeadPtr
;
50 UINTN ValidLineNum
= 0;
51 UINTN ValidFFDFileListNum
= 0;
54 // Section Description and their number of occurences in *.INF file
57 UINTN SectionOptionNum
= 0;
60 // Global flag which will check for BSF Present, if yes then will be used
61 // to decide about adding FFS header to pad data
63 BOOLEAN BSFPresent
= FALSE
;
66 // Address related information
68 UINT64 Fv1BaseAddress
= 0;
69 UINT64 Fv2BaseAddress
= 0;
70 UINT64 Fv1EndAddress
= 0;
71 UINT64 Fv2EndAddress
= 0;
72 UINT32 Bsf1TotalSize
= SIZE_TO_OFFSET_PAL_A_END
;
73 UINT64 Bsf1LastStartAddress
= 0;
74 UINT32 Bsf2TotalSize
= 0;
75 UINT64 Bsf2LastStartAddress
= 0;
77 UINT32 BufferToTop
= 0;
80 // IA32 Reset Vector Bin name
82 CHAR8 IA32BinFile
[FILE_NAME_SIZE
];
85 // Function Implementations
94 This function builds the token list in an array which will be parsed later
98 Token - The pointer of string
106 strcpy (*TokenStr
, Token
);
113 IN OUT UINT8
*MajorVer
,
114 IN OUT UINT8
*MinorVer
119 This function converts GUID string to GUID
123 Str - String representing in form XX.XX
124 MajorVer - The major vertion
125 MinorVer - The minor vertion
129 EFI_SUCCESS - The fuction completed successfully.
141 memset (StrPtr
, 0, 40);
142 Token
= strtok (Str
, ".");
144 while (Token
!= NULL
) {
145 strcat (StrPtr
, Token
);
146 Token
= strtok (NULL
, ".");
149 Length
= strlen (StrPtr
);
157 *MajorVer
= (UINT8
) Major
;
158 *MinorVer
= (UINT8
) Minor
;
169 This function cleans up the line by removing all whitespace and
174 Line - The pointer of the string
182 CHAR8 TmpLine
[FILE_NAME_SIZE
];
189 // Change '#' to '//' for Comment style
191 if (((Ptr0
= strchr (Line
, '#')) != NULL
) || ((Ptr0
= strstr (Line
, "//")) != NULL
)) {
192 Line
[Ptr0
- Line
] = 0;
196 // Initialize counters
201 while ((Char
= Line
[Index
]) != 0) {
202 if ((Char
!= ' ') && (Char
!= '\t') && (Char
!= '\n')) {
203 TmpLine
[Index2
++] = Char
;
209 strcpy (Line
, TmpLine
);
220 This function calculated number of valid lines in a input file.
224 Fp - Pointer to a file handle which has been opened.
232 CHAR8 Buff
[FILE_NAME_SIZE
];
234 while (fgets (Buff
, sizeof (Buff
), Fp
)) {
252 This function parses the input file and tokenize the string
256 Fp - Pointer to a file handle which has been opened.
265 CHAR8 Buff
[FILE_NAME_SIZE
];
266 CHAR8 OrgLine
[FILE_NAME_SIZE
];
267 CHAR8 Str
[FILE_NAME_SIZE
];
268 CHAR8 Delimit
[] = "=";
270 while (fgets (Buff
, sizeof (Buff
), Fp
) != NULL
) {
271 strcpy (OrgLine
, Buff
);
277 Token
= strtok (Buff
, Delimit
);
279 while (Token
!= NULL
) {
281 BuildTokenList (Str
);
282 Token
= strtok (NULL
, Delimit
);
295 This function intializes the relevant global variable which is being
296 used to store the information retrieved from INF file. This also initializes
305 EFI_SUCCESS - The function completed successfully
306 EFI_OUT_OF_RESOURCES - Malloc failed.
311 FileListPtr
= malloc (sizeof (PARSED_BSF_INFO
));
313 if (FileListPtr
== NULL
) {
314 return EFI_OUT_OF_RESOURCES
;
317 FileListHeadPtr
= FileListPtr
;
318 memset (FileListPtr
, 0, sizeof (PARSED_BSF_INFO
));
319 FileListPtr
->NextBsfInfo
= NULL
;
321 remove (BSF_SYM_FILE
);
326 ParseAndUpdateComponents (
327 IN PARSED_BSF_INFO
*BsfInfo
333 This function intializes the relevant global variable which is being
334 used to store the information retrieved from INF file.
338 BsfInfo - A pointer to the BSF Info Structure
349 while (*TokenStr
!= NULL
&& (_stricmp (*TokenStr
, "COMP_NAME") != 0)) {
351 if (_stricmp (*TokenStr
, "COMP_LOC") == 0) {
353 if (_stricmp (*TokenStr
, "F") == 0) {
354 BsfInfo
->LocationType
= FIRST_VTF
;
355 } else if (_stricmp (*TokenStr
, "S") == 0) {
356 BsfInfo
->LocationType
= SECOND_VTF
;
358 BsfInfo
->LocationType
= NONE
;
359 printf ("\nERROR: Unknown location for component %s", BsfInfo
->CompName
);
361 } else if (_stricmp (*TokenStr
, "COMP_TYPE") == 0) {
363 if (AsciiStringToUint64 (*TokenStr
, FALSE
, &StringValue
) != EFI_SUCCESS
) {
364 printf ("\nERROR: Could not read a numeric value from \"%s\".", TokenStr
);
368 BsfInfo
->CompType
= (UINT8
) StringValue
;
369 } else if (_stricmp (*TokenStr
, "COMP_VER") == 0) {
371 if (_stricmp (*TokenStr
, "-") == 0) {
372 BsfInfo
->VersionPresent
= FALSE
;
373 BsfInfo
->MajorVer
= 0;
374 BsfInfo
->MinorVer
= 0;
376 BsfInfo
->VersionPresent
= TRUE
;
377 ConvertVersionInfo (*TokenStr
, &BsfInfo
->MajorVer
, &BsfInfo
->MinorVer
);
379 } else if (_stricmp (*TokenStr
, "COMP_BIN") == 0) {
381 strcpy (BsfInfo
->CompBinName
, *TokenStr
);
382 } else if (_stricmp (*TokenStr
, "COMP_SYM") == 0) {
384 strcpy (BsfInfo
->CompSymName
, *TokenStr
);
385 } else if (_stricmp (*TokenStr
, "COMP_SIZE") == 0) {
387 if (_stricmp (*TokenStr
, "-") == 0) {
388 BsfInfo
->PreferredSize
= FALSE
;
389 BsfInfo
->CompSize
= 0;
391 BsfInfo
->PreferredSize
= TRUE
;
392 if (AsciiStringToUint64 (*TokenStr
, FALSE
, &StringValue
) != EFI_SUCCESS
) {
393 printf ("\nERROR: Could not read a numeric value from \"%s\".", TokenStr
);
397 BsfInfo
->CompSize
= (UINTN
) StringValue
;
400 } else if (_stricmp (*TokenStr
, "COMP_CS") == 0) {
402 if (_stricmp (*TokenStr
, "1") == 0) {
403 BsfInfo
->CheckSumRequired
= 1;
404 } else if (_stricmp (*TokenStr
, "0") == 0) {
405 BsfInfo
->CheckSumRequired
= 0;
407 printf ("\nERROR: Bad information in INF file about Checksum required field");
412 if (*TokenStr
== NULL
) {
419 InitializeInFileInfo (
426 This function intializes the relevant global variable which is being
427 used to store the information retrieved from INF file.
439 UINTN SectionOptionFlag
;
440 UINTN SectionCompFlag
;
442 SectionOptionFlag
= 0;
444 TokenStr
= OrgStrTokPtr
;
445 while (*TokenStr
!= NULL
) {
446 if (_stricmp (*TokenStr
, "[OPTIONS]") == 0) {
447 SectionOptionFlag
= 1;
451 if (_stricmp (*TokenStr
, "[COMPONENTS]") == 0) {
452 if (FileListPtr
== NULL
) {
453 FileListPtr
= FileListHeadPtr
;
457 SectionOptionFlag
= 0;
461 if (SectionOptionFlag
) {
462 if (_stricmp (*TokenStr
, "IA32_RST_BIN") == 0) {
464 strcpy (IA32BinFile
, *TokenStr
);
468 if (SectionCompFlag
) {
469 if (_stricmp (*TokenStr
, "COMP_NAME") == 0) {
471 strcpy (FileListPtr
->CompName
, *TokenStr
);
473 ParseAndUpdateComponents (FileListPtr
);
476 if (*TokenStr
!= NULL
) {
477 FileListPtr
->NextBsfInfo
= malloc (sizeof (PARSED_BSF_INFO
));
478 if (FileListPtr
->NextBsfInfo
== NULL
) {
479 printf ("Error: Out of memory resources.\n");
482 FileListPtr
= FileListPtr
->NextBsfInfo
;
483 memset (FileListPtr
, 0, sizeof (PARSED_BSF_INFO
));
484 FileListPtr
->NextBsfInfo
= NULL
;
496 GetBsfRelatedInfoFromInfFile (
503 This function reads the input file, parse it and create a list of tokens
504 which is parsed and used, to intialize the data related to BSF
508 FileName - FileName which needed to be read to parse data
512 EFI_ABORTED - Error in opening file
513 EFI_INVALID_PARAMETER - File doesn't contain any valid informations
514 EFI_OUT_OF_RESOURCES - Malloc Failed
515 EFI_SUCCESS - The function completed successfully
523 Fp
= fopen (FileName
, "r");
525 printf ("\nERROR: Error in opening %s file\n", FileName
);
531 if (ValidLineNum
== 0) {
532 printf ("\nERROR: File doesn't contain any valid informations");
533 return EFI_INVALID_PARAMETER
;
536 TokenStr
= (CHAR8
**) malloc (sizeof (UINTN
) * (2 * ValidLineNum
+ 1));
538 if (TokenStr
== NULL
) {
539 return EFI_OUT_OF_RESOURCES
;
542 memset (TokenStr
, 0, (sizeof (UINTN
) * (2 * ValidLineNum
+ 1)));
543 OrgStrTokPtr
= TokenStr
;
545 for (Index
= 0; Index
< (2 * ValidLineNum
); Index
++) {
546 *TokenStr
= (CHAR8
*)malloc (sizeof (CHAR8
) * FILE_NAME_SIZE
);
548 if (*TokenStr
== NULL
) {
550 return EFI_OUT_OF_RESOURCES
;
553 memset (*TokenStr
, 0, FILE_NAME_SIZE
);
559 TokenStr
= OrgStrTokPtr
;
560 fseek (Fp
, 0L, SEEK_SET
);
562 Status
= InitializeComps ();
564 if (Status
!= EFI_SUCCESS
) {
570 InitializeInFileInfo ();
580 GetRelativeAddressInBsfBuffer (
582 IN OUT UINTN
*RelativeAddress
,
589 This function checks for the address alignmnet for specified data boundary. In
590 case the address is not aligned, it returns FALSE and the amount of data in
591 terms of byte needed to adjust to get the boundary alignmnet. If data is
592 aligned, TRUE will be returned.
596 Address - The address of the flash map space
597 RelativeAddress - The relative address of the Buffer
598 LocType - The type of the BSF
609 if (LocType
== FIRST_VTF
) {
610 LocalBuff
= (UINT8
*) Bsf1EndBuffer
;
611 TempAddress
= Fv1EndAddress
- Address
;
612 *RelativeAddress
= (UINTN
) LocalBuff
- (UINTN
) TempAddress
;
614 LocalBuff
= (UINT8
*) Bsf2EndBuffer
;
615 TempAddress
= Fv2EndAddress
- Address
;
616 *RelativeAddress
= (UINTN
) LocalBuff
- (UINTN
) TempAddress
;
621 GetComponentVersionInfo (
622 IN OUT PARSED_BSF_INFO
*BsfInfo
,
628 This function will extract the version information from File
632 BsfInfo - A Pointer to the BSF Info Structure
633 Buffer - A Pointer to type UINT8
637 EFI_SUCCESS - The function completed successfully
638 EFI_INVALID_PARAMETER - The parameter is invalid
645 switch (BsfInfo
->CompType
) {
647 case COMP_TYPE_FIT_PAL_A
:
648 case COMP_TYPE_FIT_PAL_B
:
649 memcpy (&VersionInfo
, (Buffer
+ 8), sizeof (UINT16
));
650 BsfInfo
->MajorVer
= (UINT8
) ((VersionInfo
& 0xFF00) >> 8);
651 BsfInfo
->MinorVer
= (UINT8
) (VersionInfo
& 0x00FF);
652 Status
= EFI_SUCCESS
;
656 Status
= EFI_INVALID_PARAMETER
;
664 CheckAddressAlignment (
666 IN UINT64 AlignmentData
,
667 IN OUT UINT64
*AlignAdjustByte
673 This function checks for the address alignmnet for specified data boundary. In
674 case the address is not aligned, it returns FALSE and the amount of data in
675 terms of byte needed to adjust to get the boundary alignmnet. If data is
676 aligned, TRUE will be returned.
680 Address - Pointer to buffer containing byte data of component.
681 AlignmentData - DataSize for which address needed to be aligned
682 AlignAdjustByte - Number of bytes needed to adjust alignment.
686 TRUE - Address is aligned to specific data size boundary
687 FALSE - Address in not aligned to specified data size boundary
688 - Add/Subtract AlignAdjustByte to aling the address.
693 // Check if the assigned address is on address boundary. If not, it will
694 // return the remaining byte required to adjust the address for specified
697 *AlignAdjustByte
= (Address
% AlignmentData
);
699 if (*AlignAdjustByte
== 0) {
707 GetFitTableStartAddress (
708 IN OUT FIT_TABLE
**FitTable
714 Get the FIT table start address in BSF Buffer
718 FitTable - Pointer to available fit table where new component can be added
722 EFI_SUCCESS - The function completed successfully
727 UINT64 FitTableAddOffset
;
728 UINTN RelativeAddress
;
731 // Read the Fit Table address from Itanium-based address map.
733 FitTableAddOffset
= Fv1EndAddress
- (SIZE_IA32_RESET_VECT
+ SIZE_SALE_ENTRY_POINT
+ SIZE_FIT_TABLE_ADD
);
736 // Translate this Itanium-based address in terms of local buffer address which
737 // contains the image for Boot Strapped File. The relative address will be
738 // the address of fit table BSF buffer.
740 GetRelativeAddressInBsfBuffer (FitTableAddOffset
, &RelativeAddress
, FIRST_VTF
);
741 FitTableAdd
= *(UINTN
*) RelativeAddress
;
744 // The FitTableAdd is the extracted Itanium based address pointing to FIT
745 // table. The relative address will return its actual location in BSF
748 GetRelativeAddressInBsfBuffer (FitTableAdd
, &RelativeAddress
, FIRST_VTF
);
750 *FitTable
= (FIT_TABLE
*) RelativeAddress
;
756 GetNextAvailableFitPtr (
757 IN FIT_TABLE
**FitPtr
763 Get the FIT table address and locate the free space in fit where we can add
764 new component. In this process, this function locates the fit table using
765 Fit pointer in Itanium-based address map (as per Intel?Itanium(TM) SAL spec)
766 and locate the available location in FIT table to be used by new components.
767 If there are any Fit table which areg not being used contains ComponentType
768 field as 0x7F. If needed we can change this and spec this out.
772 FitPtr - Pointer to available fit table where new component can be added
776 EFI_SUCCESS - The function completed successfully
780 FIT_TABLE
*TmpFitPtr
;
782 UINT64 FitTableAddOffset
;
784 UINTN NumFitComponents
;
785 UINTN RelativeAddress
;
788 // Read the Fit Table address from Itanium-based address map.
790 FitTableAddOffset
= Fv1EndAddress
- (SIZE_IA32_RESET_VECT
+ SIZE_SALE_ENTRY_POINT
+ SIZE_FIT_TABLE_ADD
);
793 // Translate this Itanium-based address in terms of local buffer address which
794 // contains the image for Boot Strapped File. The relative address will be
795 // the address of fit table BSF buffer.
797 GetRelativeAddressInBsfBuffer (FitTableAddOffset
, &RelativeAddress
, FIRST_VTF
);
798 FitTableAdd
= *(UINTN
*) RelativeAddress
;
801 // The FitTableAdd is the extracted Itanium based address pointing to FIT
802 // table. The relative address will return its actual location in BSF
805 GetRelativeAddressInBsfBuffer (FitTableAdd
, &RelativeAddress
, FIRST_VTF
);
807 TmpFitPtr
= (FIT_TABLE
*) RelativeAddress
;
808 NumFitComponents
= TmpFitPtr
->CompSize
;
810 for (Index
= 0; Index
< NumFitComponents
; Index
++) {
811 if ((TmpFitPtr
->CvAndType
& FIT_TYPE_MASK
) == COMP_TYPE_FIT_UNUSED
) {
831 This function is used by qsort to sort the FIT table based upon Component
832 Type in their incresing order.
836 Arg1 - Pointer to Arg1
837 Arg2 - Pointer to Arg2
845 if ((((FIT_TABLE
*) Arg1
)->CvAndType
& FIT_TYPE_MASK
) > (((FIT_TABLE
*) Arg2
)->CvAndType
& FIT_TYPE_MASK
)) {
847 } else if ((((FIT_TABLE
*) Arg1
)->CvAndType
& FIT_TYPE_MASK
) < (((FIT_TABLE
*) Arg2
)->CvAndType
& FIT_TYPE_MASK
)) {
862 This function is used by qsort to sort the FIT table based upon Component
863 Type in their incresing order.
876 FIT_TABLE
*TmpFitPtr
;
877 UINTN NumFitComponents
;
880 GetFitTableStartAddress (&FitTable
);
881 TmpFitPtr
= FitTable
;
882 NumFitComponents
= 0;
883 for (Index
= 0; Index
< FitTable
->CompSize
; Index
++) {
884 if ((TmpFitPtr
->CvAndType
& FIT_TYPE_MASK
) != COMP_TYPE_FIT_UNUSED
) {
885 NumFitComponents
+= 1;
891 qsort ((VOID
*) FitTable
, NumFitComponents
, sizeof (FIT_TABLE
), CompareItems
);
895 UpdateFitEntryForFwVolume (
902 This function updates the information about Firmware Volume in FIT TABLE.
903 This FIT table has to be immediately below the PAL_A Start and it contains
904 component type and address information. Other informations can't be
905 created this time so we would need to fix it up..
910 Size - Firmware Volume Size
918 FIT_TABLE
*CompFitPtr
;
919 UINTN RelativeAddress
;
922 // FV Fit table will be located at PAL_A Startaddress - 16 byte location
924 Bsf1LastStartAddress
-= 0x10;
925 Bsf1TotalSize
+= 0x10;
927 GetRelativeAddressInBsfBuffer (Bsf1LastStartAddress
, &RelativeAddress
, FIRST_VTF
);
929 CompFitPtr
= (FIT_TABLE
*) RelativeAddress
;
930 CompFitPtr
->CompAddress
= Fv1BaseAddress
;
933 // Since we don't have any information about its location in Firmware Volume,
934 // initialize address to 0. This will be updated once Firmware Volume is
935 // being build and its current address will be fixed in FIT table. Currently
936 // we haven't implemented it so far and working on architectural clarafication
939 // Firmware Volume Size in 16 byte block
941 CompFitPtr
->CompSize
= ((UINT32
) Size
) / 16;
944 // Since Firmware Volume does not exist by the time we create this FIT info
945 // this should be fixedup from Firmware Volume creation tool. We haven't
946 // worked out a method so far.
948 CompFitPtr
->CompVersion
= MAKE_VERSION (0, 0);
951 // Since we don't have any info about this file, we are making sure that
952 // checksum is not needed.
954 CompFitPtr
->CvAndType
= CV_N_TYPE (0, COMP_TYPE_FIT_FV_BOOT
);
957 // Since non BSF component will reside outside the BSF, we will not have its
958 // binary image while creating BSF, hence we will not perform checksum at
959 // this time. Once Firmware Volume is being created which will contain this
960 // BSF, it will fix the FIT table for all the non BSF component and hence
963 CompFitPtr
->CheckSum
= 0;
967 UpdateFitEntryForNonBSFComp (
968 IN PARSED_BSF_INFO
*BsfInfo
974 This function updates the information about non BSF component in FIT TABLE.
975 Since non BSF componets binaries are not part of BSF binary, we would still
976 be required to update its location information in Firmware Volume, inside
981 BsfInfo - Pointer to BSF Info Structure
985 EFI_ABORTED - The function fails to update the component in FIT
986 EFI_SUCCESS - The function completed successfully
990 FIT_TABLE
*CompFitPtr
;
993 // Scan the FIT table for available space
995 GetNextAvailableFitPtr (&CompFitPtr
);
996 if (CompFitPtr
== NULL
) {
997 printf ("\nERROR: Can't update this component in FIT");
1002 // Since we don't have any information about its location in Firmware Volume,
1003 // initialize address to 0. This will be updated once Firmware Volume is
1004 // being build and its current address will be fixed in FIT table
1006 CompFitPtr
->CompAddress
= 0;
1007 CompFitPtr
->CompSize
= BsfInfo
->CompSize
;
1008 CompFitPtr
->CompVersion
= MAKE_VERSION (BsfInfo
->MajorVer
, BsfInfo
->MinorVer
);
1009 CompFitPtr
->CvAndType
= CV_N_TYPE (BsfInfo
->CheckSumRequired
, BsfInfo
->CompType
);
1012 // Since non BSF component will reside outside the BSF, we will not have its
1013 // binary image while creating BSF, hence we will not perform checksum at
1014 // this time. Once Firmware Volume is being created which will contain this
1015 // BSF, it will fix the FIT table for all the non BSF component and hence
1018 CompFitPtr
->CheckSum
= 0;
1021 // Fit Type is FV_BOOT which means Firmware Volume, we initialize this to base
1022 // address of Firmware Volume in which this BSF will be attached.
1024 if ((CompFitPtr
->CvAndType
& 0x7F) == COMP_TYPE_FIT_FV_BOOT
) {
1025 CompFitPtr
->CompAddress
= Fv1BaseAddress
;
1033 // This function is updating the SALE_ENTRY in Itanium address space as per SAL
1034 // spec. SALE_ENTRY is being read from SYM file of PEICORE. Once the PEI
1035 // CORE moves in Firmware Volume, we would need to modify this function to be
1036 // used with a API which will detect PEICORE component while building Firmware
1037 // Volume and update its entry in FIT table as well as in Itanium address space
1038 // as per Intel?Itanium(TM) SAL address space
1042 IN PARSED_BSF_INFO
*BsfInfo
,
1043 IN UINT64
*CompStartAddress
1047 Routine Description:
1049 This function updated the architectural entry point in IPF, SALE_ENTRY.
1053 BsfInfo - Pointer to BSF Info Structure
1054 CompStartAddress - Pointer to Component Start Address
1058 EFI_INVALID_PARAMETER - The parameter is invalid
1059 EFI_SUCCESS - The function completed successfully
1063 UINTN RelativeAddress
;
1068 CHAR8 Buff
[FILE_NAME_SIZE
];
1071 CHAR8 OffsetStr
[30];
1077 Fp
= fopen (BsfInfo
->CompSymName
, "r+b");
1080 printf ("\nERROR: Error in opening file");
1081 return EFI_INVALID_PARAMETER
;
1084 while (fgets (Buff
, sizeof (Buff
), Fp
) != NULL
) {
1087 "%s %s %s %s %s %s %s",
1096 if (_stricmp (Token
, "SALE_ENTRY") == 0) {
1101 Offset
= strtoul (OffsetStr
, NULL
, 16);
1103 *CompStartAddress
+= Offset
;
1104 SalEntryAdd
= Fv1EndAddress
- (SIZE_IA32_RESET_VECT
+ SIZE_SALE_ENTRY_POINT
);
1106 GetRelativeAddressInBsfBuffer (SalEntryAdd
, &RelativeAddress
, FIRST_VTF
);
1108 memcpy ((VOID
*) RelativeAddress
, (VOID
*) CompStartAddress
, sizeof (UINT64
));
1114 CreateAndUpdateComponent (
1115 IN PARSED_BSF_INFO
*BsfInfo
1119 Routine Description:
1121 This function reads the binary file for each components and update them
1122 in BSF Buffer as well as in FIT table. If the component is located in non
1123 BSF area, only the FIT table address will be updated
1127 BsfInfo - Pointer to Parsed Info
1131 EFI_SUCCESS - The function completed successful
1132 EFI_ABORTED - Aborted due to one of the many reasons like:
1133 (a) Component Size greater than the specified size.
1134 (b) Error opening files.
1136 EFI_INVALID_PARAMETER Value returned from call to UpdateEntryPoint()
1137 EFI_OUT_OF_RESOURCES Memory allocation failure.
1142 UINT64 CompStartAddress
;
1145 UINT64 NumAdjustByte
;
1148 FIT_TABLE
*CompFitPtr
;
1151 if (BsfInfo
->LocationType
== NONE
) {
1152 UpdateFitEntryForNonBSFComp (BsfInfo
);
1156 Fp
= fopen (BsfInfo
->CompBinName
, "r+b");
1159 printf ("\nERROR: Opening file %s", BsfInfo
->CompBinName
);
1163 FileSize
= _filelength (fileno (Fp
));
1165 if ((BsfInfo
->CompType
== COMP_TYPE_FIT_PAL_B
) || (BsfInfo
->CompType
== COMP_TYPE_FIT_PAL_A_SPECIFIC
)) {
1168 // BUGBUG: Satish to correct
1170 FileSize
-= SIZE_OF_PAL_HEADER
;
1173 if (BsfInfo
->PreferredSize
) {
1174 if (FileSize
> BsfInfo
->CompSize
) {
1175 printf ("\nERROR: The component size is more than specified size");
1179 FileSize
= BsfInfo
->CompSize
;
1182 Buffer
= malloc ((UINTN
) FileSize
);
1183 if (Buffer
== NULL
) {
1184 return EFI_OUT_OF_RESOURCES
;
1186 memset (Buffer
, 0, (UINTN
) FileSize
);
1188 if ((BsfInfo
->CompType
== COMP_TYPE_FIT_PAL_B
) || (BsfInfo
->CompType
== COMP_TYPE_FIT_PAL_A_SPECIFIC
)) {
1191 // Read first 64 bytes of PAL header and use it to find version info
1193 NumByteRead
= fread (Buffer
, sizeof (UINT8
), SIZE_OF_PAL_HEADER
, Fp
);
1196 // PAL header contains the version info. Currently, we will use the header
1197 // to read version info and then discard.
1199 if (!BsfInfo
->VersionPresent
) {
1200 GetComponentVersionInfo (BsfInfo
, Buffer
);
1204 NumByteRead
= fread (Buffer
, sizeof (UINT8
), (UINTN
) FileSize
, Fp
);
1208 // If it is non PAL_B component, pass the entire buffer to get the version
1209 // info and implement any specific case inside GetComponentVersionInfo.
1211 if (BsfInfo
->CompType
!= COMP_TYPE_FIT_PAL_B
) {
1212 if (!BsfInfo
->VersionPresent
) {
1213 GetComponentVersionInfo (BsfInfo
, Buffer
);
1217 if (BsfInfo
->LocationType
== SECOND_VTF
) {
1219 CompStartAddress
= (Bsf2LastStartAddress
- FileSize
);
1221 CompStartAddress
= (Bsf1LastStartAddress
- FileSize
);
1224 if (BsfInfo
->CompType
== COMP_TYPE_FIT_PAL_B
) {
1225 Aligncheck
= CheckAddressAlignment (CompStartAddress
, 32 * 1024, &NumAdjustByte
);
1227 Aligncheck
= CheckAddressAlignment (CompStartAddress
, 8, &NumAdjustByte
);
1231 CompStartAddress
-= NumAdjustByte
;
1234 if (BsfInfo
->LocationType
== SECOND_VTF
) {
1235 Bsf2LastStartAddress
= CompStartAddress
;
1236 Bsf2TotalSize
+= (UINT32
) (FileSize
+ NumAdjustByte
);
1237 Status
= UpdateBsfBuffer (CompStartAddress
, Buffer
, FileSize
, SECOND_VTF
);
1239 Bsf1LastStartAddress
= CompStartAddress
;
1240 Bsf1TotalSize
+= (UINT32
) (FileSize
+ NumAdjustByte
);
1241 Status
= UpdateBsfBuffer (CompStartAddress
, Buffer
, FileSize
, FIRST_VTF
);
1244 if (EFI_ERROR (Status
)) {
1248 GetNextAvailableFitPtr (&CompFitPtr
);
1250 CompFitPtr
->CompAddress
= CompStartAddress
| IPF_CACHE_BIT
;
1251 assert ((FileSize
% 16) == 0);
1252 CompFitPtr
->CompSize
= (UINT32
) (FileSize
/ 16);
1253 CompFitPtr
->CompVersion
= MAKE_VERSION (BsfInfo
->MajorVer
, BsfInfo
->MinorVer
);
1254 CompFitPtr
->CvAndType
= CV_N_TYPE (BsfInfo
->CheckSumRequired
, BsfInfo
->CompType
);
1255 if (BsfInfo
->CheckSumRequired
) {
1256 CompFitPtr
->CheckSum
= 0;
1257 CompFitPtr
->CheckSum
= CalculateChecksum8 (Buffer
, (UINTN
) FileSize
);
1268 // Update the SYM file for this component based on it's start address.
1270 Status
= UpdateSymFile (CompStartAddress
, BSF_SYM_FILE
, BsfInfo
->CompSymName
);
1271 if (EFI_ERROR (Status
)) {
1274 // At this time, SYM files are not required, so continue on error.
1278 // !!!!!!!!!!!!!!!!!!!!!
1280 // This part of the code is a temporary line since PEICORE is going to be inside
1281 // BSF till we work out how to determine the SALE_ENTRY through it. We will need
1282 // to clarify so many related questions
1283 // !!!!!!!!!!!!!!!!!!!!!!!
1284 if (BsfInfo
->CompType
== COMP_TYPE_FIT_PEICORE
) {
1285 Status
= UpdateEntryPoint (BsfInfo
, &CompStartAddress
);
1292 CreateAndUpdatePAL_A (
1293 IN PARSED_BSF_INFO
*BsfInfo
1297 Routine Description:
1299 This function reads the binary file for each components and update them
1300 in BSF Buffer as well as FIT table
1304 BsfInfo - Pointer to Parsed Info
1308 EFI_ABORTED - Due to one of the following reasons:
1309 (a)Error Opening File
1310 (b)The PAL_A Size is more than specified size status
1311 One of the values mentioned below returned from
1312 call to UpdateSymFile
1313 EFI_SUCCESS - The function completed successfully.
1314 EFI_INVALID_PARAMETER - One of the input parameters was invalid.
1315 EFI_ABORTED - An error occurred.UpdateSymFile
1316 EFI_OUT_OF_RESOURCES - Memory allocation failed.
1321 UINT64 PalStartAddress
;
1323 UINTN RelativeAddress
;
1328 FIT_TABLE
*PalFitPtr
;
1330 Fp
= fopen (BsfInfo
->CompBinName
, "r+b");
1333 printf ("\nERROR: Opening file %s", BsfInfo
->CompBinName
);
1337 FileSize
= _filelength (fileno (Fp
));
1338 FileSize
-= SIZE_OF_PAL_HEADER
;
1340 if (BsfInfo
->PreferredSize
) {
1341 if (FileSize
> BsfInfo
->CompSize
) {
1342 printf ("\nERROR: The PAL_A Size is more than specified size");
1346 FileSize
= BsfInfo
->CompSize
;
1349 Buffer
= malloc ((UINTN
) FileSize
);
1350 if (Buffer
== NULL
) {
1351 return EFI_OUT_OF_RESOURCES
;
1353 memset (Buffer
, 0, (UINTN
) FileSize
);
1356 // Read, Get version Info and discard the PAL header.
1358 NumByteRead
= fread (Buffer
, sizeof (UINT8
), SIZE_OF_PAL_HEADER
, Fp
);
1361 // Extract the version info from header of PAL_A. Once done, discrad this buffer
1363 if (!BsfInfo
->VersionPresent
) {
1364 GetComponentVersionInfo (BsfInfo
, Buffer
);
1368 // Read PAL_A file in a buffer
1370 NumByteRead
= fread (Buffer
, sizeof (UINT8
), (UINTN
) FileSize
, Fp
);
1373 PalStartAddress
= Fv1EndAddress
- (SIZE_TO_OFFSET_PAL_A_END
+ FileSize
);
1374 Bsf1LastStartAddress
= PalStartAddress
;
1375 Bsf1TotalSize
+= (UINT32
) FileSize
;
1376 Status
= UpdateBsfBuffer (PalStartAddress
, Buffer
, FileSize
, FIRST_VTF
);
1378 AbsAddress
= Fv1EndAddress
- SIZE_TO_PAL_A_FIT
;
1379 GetRelativeAddressInBsfBuffer (AbsAddress
, &RelativeAddress
, FIRST_VTF
);
1380 PalFitPtr
= (FIT_TABLE
*) RelativeAddress
;
1381 PalFitPtr
->CompAddress
= PalStartAddress
| IPF_CACHE_BIT
;
1382 assert ((FileSize
% 16) == 0);
1383 PalFitPtr
->CompSize
= (UINT32
) (FileSize
/ 16);
1384 PalFitPtr
->CompVersion
= MAKE_VERSION (BsfInfo
->MajorVer
, BsfInfo
->MinorVer
);
1385 PalFitPtr
->CvAndType
= CV_N_TYPE (BsfInfo
->CheckSumRequired
, BsfInfo
->CompType
);
1386 if (BsfInfo
->CheckSumRequired
) {
1387 PalFitPtr
->CheckSum
= 0;
1388 PalFitPtr
->CheckSum
= CalculateChecksum8 (Buffer
, (UINTN
) FileSize
);
1396 // Update the SYM file for this component based on it's start address.
1398 Status
= UpdateSymFile (PalStartAddress
, BSF_SYM_FILE
, BsfInfo
->CompSymName
);
1399 if (EFI_ERROR (Status
)) {
1402 // At this time, SYM files are not required, so continue on error.
1410 CreateFitTableAndInitialize (
1411 IN PARSED_BSF_INFO
*BsfInfo
1415 Routine Description:
1417 This function creates and intializes FIT table which would be used to
1418 add component info inside this
1422 BsfInfo - Pointer to Parsed Info
1426 EFI_ABORTED - Aborted due to no size information
1427 EFI_SUCCESS - The function completed successfully
1431 UINT64 PalFitTableAdd
;
1433 UINT64 FitTableAddressOffset
;
1434 FIT_TABLE
*PalFitPtr
;
1435 FIT_TABLE
*FitStartPtr
;
1437 UINTN RelativeAddress
;
1440 if (!BsfInfo
->PreferredSize
) {
1441 printf ("\nERROR: FIT could not be allocated becuase there are no size information");
1445 if ((BsfInfo
->CompSize
% 16) != 0) {
1446 printf ("\nERROR: Invalid Fit Table Size, not multiple of 16 bytes. Please correct the size");
1449 PalFitTableAdd
= Fv1EndAddress
- SIZE_TO_PAL_A_FIT
;
1450 GetRelativeAddressInBsfBuffer (PalFitTableAdd
, &RelativeAddress
, FIRST_VTF
);
1451 PalFitPtr
= (FIT_TABLE
*) RelativeAddress
;
1452 PalFitTableAdd
= (PalFitPtr
->CompAddress
- BsfInfo
->CompSize
);
1454 FitTableAdd
= (PalFitPtr
->CompAddress
- 0x10) - BsfInfo
->CompSize
;
1455 FitTableAddressOffset
= Fv1EndAddress
- (SIZE_IA32_RESET_VECT
+ SIZE_SALE_ENTRY_POINT
+ SIZE_FIT_TABLE_ADD
);
1456 GetRelativeAddressInBsfBuffer (FitTableAddressOffset
, &RelativeAddress
, FIRST_VTF
);
1457 *(UINT64
*) RelativeAddress
= FitTableAdd
;
1459 GetRelativeAddressInBsfBuffer (FitTableAdd
, &RelativeAddress
, FIRST_VTF
);
1462 // Update Fit Table with FIT Signature and FIT info in first 16 bytes.
1464 FitStartPtr
= (FIT_TABLE
*) RelativeAddress
;
1466 strncpy ((CHAR8
*) &FitStartPtr
->CompAddress
, FIT_SIGNATURE
, 8); // "_FIT_ "
1467 assert (((BsfInfo
->CompSize
& 0x00FFFFFF) % 16) == 0);
1468 FitStartPtr
->CompSize
= (BsfInfo
->CompSize
& 0x00FFFFFF) / 16;
1469 FitStartPtr
->CompVersion
= MAKE_VERSION (BsfInfo
->MajorVer
, BsfInfo
->MinorVer
);
1472 // BUGBUG: If a checksum is required, add code to checksum the FIT table. Also
1473 // determine what to do for things like the FV component that aren't easily checksummed.
1474 // The checksum will be done once we are done with all the componet update in the FIT
1477 FitStartPtr
->CvAndType
= CV_N_TYPE (BsfInfo
->CheckSumRequired
, BsfInfo
->CompType
);
1479 NumFitComp
= FitStartPtr
->CompSize
;
1484 // Intialize remaining FIT table space to UNUSED fit component type
1485 // so that when we need to create a FIT entry for a component, we can
1486 // locate a free one and use it.
1488 for (Index
= 0; Index
< (NumFitComp
- 1); Index
++) {
1489 FitStartPtr
->CvAndType
= 0x7F; // Initialize all with UNUSED
1493 Bsf1TotalSize
+= BsfInfo
->CompSize
;
1494 Bsf1LastStartAddress
-= BsfInfo
->CompSize
;
1507 Routine Description:
1509 Write Firmware Volume from memory to a file.
1513 FileName - Output File Name which needed to be created/
1515 LocType - The type of the BSF
1519 EFI_ABORTED - Returned due to one of the following resons:
1520 (a) Error Opening File
1521 (b) Failing to copy buffers
1522 EFI_SUCCESS - The fuction completes successfully
1529 UINTN RelativeAddress
;
1531 if (LocType
== FIRST_VTF
) {
1532 GetRelativeAddressInBsfBuffer (Bsf1LastStartAddress
, &RelativeAddress
, FIRST_VTF
);
1533 BsfBuffer
= (VOID
*) RelativeAddress
;
1535 GetRelativeAddressInBsfBuffer (Bsf2LastStartAddress
, &RelativeAddress
, SECOND_VTF
);
1536 BsfBuffer
= (VOID
*) RelativeAddress
;
1539 Fp
= fopen (FileName
, "w+b");
1541 printf ("Error in opening file %s\n", FileName
);
1545 NumByte
= fwrite (BsfBuffer
, sizeof (UINT8
), (UINTN
) BsfSize
, Fp
);
1551 if (NumByte
!= (sizeof (UINT8
) * BsfSize
)) {
1552 printf ("\nERROR: Could not copy buffer into file %s ", FileName
);
1561 IN UINT64 StartAddress
,
1568 Routine Description:
1570 Update the Firmware Volume Buffer with requested buffer data
1574 StartAddress - StartAddress in buffer. This number will automatically
1575 point to right address in buffer where data needed
1577 Buffer - Buffer pointer from data will be copied to memory mapped buffer.
1578 DataSize - Size of the data needed to be copied.
1579 LocType - The type of the BSF
1583 EFI_ABORTED - The input parameter is error
1584 EFI_SUCCESS - The function completed successfully
1588 UINT8
*LocalBufferPtrToWrite
;
1590 if (LocType
== FIRST_VTF
) {
1591 if ((StartAddress
| IPF_CACHE_BIT
) < (Bsf1LastStartAddress
| IPF_CACHE_BIT
)) {
1592 printf ("ERROR: Start Address is less then the BSF start address\n");
1596 LocalBufferPtrToWrite
= (UINT8
*) Bsf1EndBuffer
;
1597 LocalBufferPtrToWrite
-= (Fv1EndAddress
- StartAddress
);
1599 if ((StartAddress
| IPF_CACHE_BIT
) < (Bsf2LastStartAddress
| IPF_CACHE_BIT
)) {
1600 printf ("ERROR: Start Address is less then the BSF start address\n");
1603 LocalBufferPtrToWrite
= (UINT8
*) Bsf2EndBuffer
;
1604 LocalBufferPtrToWrite
-= (Fv2EndAddress
- StartAddress
);
1607 memcpy (LocalBufferPtrToWrite
, Buffer
, (UINTN
) DataSize
);
1614 IN UINT32 TotalBsfSize
,
1619 Routine Description:
1621 Update the Firmware Volume Buffer with requested buffer data
1625 TotalBsfSize - Size of the BSF
1626 Fileoffset - The start of the file relative to the start of the FV.
1627 LocType - The type of the BSF
1631 EFI_SUCCESS - The function completed successfully
1632 EFI_INVALID_PARAMETER - The Ffs File Header Pointer is NULL
1636 EFI_FFS_FILE_HEADER
*FileHeader
;
1637 UINTN RelativeAddress
;
1638 EFI_GUID EfiFirmwareVolumeTopFileGuid
= EFI_FFS_VOLUME_TOP_FILE_GUID
;
1641 // Find the BSF file header location
1643 if (LocType
== FIRST_VTF
) {
1644 GetRelativeAddressInBsfBuffer (Bsf1LastStartAddress
, &RelativeAddress
, FIRST_VTF
);
1645 FileHeader
= (EFI_FFS_FILE_HEADER
*) RelativeAddress
;
1647 GetRelativeAddressInBsfBuffer (Bsf2LastStartAddress
, &RelativeAddress
, SECOND_VTF
);
1648 FileHeader
= (EFI_FFS_FILE_HEADER
*) RelativeAddress
;
1651 if (FileHeader
== NULL
) {
1652 return EFI_INVALID_PARAMETER
;
1658 memset (FileHeader
, 0, sizeof (EFI_FFS_FILE_HEADER
));
1659 memcpy (&FileHeader
->Name
, &EfiFirmwareVolumeTopFileGuid
, sizeof (EFI_GUID
));
1660 FileHeader
->Type
= EFI_FV_FILETYPE_FREEFORM
;
1661 FileHeader
->Attributes
= FFS_ATTRIB_CHECKSUM
;
1664 // Now FileSize includes the EFI_FFS_FILE_HEADER
1666 FileHeader
->Size
[0] = (UINT8
) (TotalBsfSize
& 0x000000FF);
1667 FileHeader
->Size
[1] = (UINT8
) ((TotalBsfSize
& 0x0000FF00) >> 8);
1668 FileHeader
->Size
[2] = (UINT8
) ((TotalBsfSize
& 0x00FF0000) >> 16);
1671 // Fill in checksums and state, all three must be zero for the checksums.
1673 FileHeader
->IntegrityCheck
.Checksum
.Header
= 0;
1674 FileHeader
->IntegrityCheck
.Checksum
.File
= 0;
1675 FileHeader
->State
= 0;
1676 FileHeader
->IntegrityCheck
.Checksum
.Header
= CalculateChecksum8 ((UINT8
*) FileHeader
, sizeof (EFI_FFS_FILE_HEADER
));
1677 FileHeader
->IntegrityCheck
.Checksum
.File
= CalculateChecksum8 ((UINT8
*) FileHeader
, TotalBsfSize
);
1678 FileHeader
->State
= EFI_FILE_HEADER_CONSTRUCTION
| EFI_FILE_HEADER_VALID
| EFI_FILE_DATA_VALID
;
1684 ValidateAddressAndSize (
1685 IN UINT64 BaseAddress
,
1690 Routine Description:
1692 Update the Firmware Volume Buffer with requested buffer data
1696 BaseAddress - Base address for the Fw Volume.
1698 FwVolSize - Total Size of the FwVolume to which BSF will be attached..
1702 EFI_SUCCESS - The function completed successfully
1703 EFI_UNSUPPORTED - The input parameter is error
1707 if ((BaseAddress
>= 0) && (FwVolSize
> 0x40) && ((BaseAddress
+ FwVolSize
) % 8 == 0)) {
1711 return EFI_UNSUPPORTED
;
1715 UpdateIA32ResetVector (
1717 IN UINT64 FirstFwVSize
1721 Routine Description:
1723 Update the 16 byte IA32 Reset vector to maintain the compatibility
1727 FileName - Binary file name which contains the IA32 Reset vector info..
1728 FirstFwVSize - Total Size of the FwVolume to which BSF will be attached..
1732 EFI_SUCCESS - The function completed successfully
1733 EFI_ABORTED - Invalid File Size
1734 EFI_INVALID_PARAMETER - Bad File Name
1735 EFI_OUT_OF_RESOURCES - Memory allocation failed.
1740 UINT8
*LocalBsfBuffer
;
1745 if (!strcmp (FileName
, "")) {
1746 return EFI_INVALID_PARAMETER
;
1749 Fp
= fopen (FileName
, "r+b");
1752 printf ("\nERROR: Unable to open the file %s", FileName
);
1755 FileSize
= _filelength (fileno (Fp
));
1757 if (FileSize
> 16) {
1761 Buffer
= malloc (FileSize
);
1762 if (Buffer
== NULL
) {
1763 return EFI_OUT_OF_RESOURCES
;
1766 NumByteRead
= fread (Buffer
, sizeof (UINT8
), FileSize
, Fp
);
1768 LocalBsfBuffer
= (UINT8
*) Bsf1EndBuffer
- SIZE_IA32_RESET_VECT
;
1769 memcpy (LocalBsfBuffer
, Buffer
, FileSize
);
1784 Routine Description:
1786 This function cleans up any allocated buffer
1798 PARSED_BSF_INFO
*TempFileListPtr
;
1809 // Cleanup the buffer which was allocated to read the file names from FV.INF
1811 FileListPtr
= FileListHeadPtr
;
1812 while (FileListPtr
!= NULL
) {
1813 TempFileListPtr
= FileListPtr
->NextBsfInfo
;
1815 FileListPtr
= TempFileListPtr
;
1820 ProcessAndCreateBsf (
1825 Routine Description:
1827 This function process the link list created during INF file parsing
1828 and create component in BSF and updates its info in FIT table
1832 Size - Size of the Firmware Volume of which, this BSF belongs to.
1836 EFI_UNSUPPORTED - Unknown FIT type
1837 EFI_SUCCESS - The function completed successfully
1842 PARSED_BSF_INFO
*ParsedInfoPtr
;
1844 Status
= EFI_SUCCESS
;
1846 ParsedInfoPtr
= FileListHeadPtr
;
1848 while (ParsedInfoPtr
!= NULL
) {
1850 switch (ParsedInfoPtr
->CompType
) {
1852 // COMP_TYPE_FIT_HEADER is a special case, hence handle it here
1854 case COMP_TYPE_FIT_HEADER
:
1855 Status
= CreateFitTableAndInitialize (ParsedInfoPtr
);
1859 // COMP_TYPE_FIT_PAL_A is a special case, hence handle it here
1861 case COMP_TYPE_FIT_PAL_A
:
1862 Status
= CreateAndUpdatePAL_A (ParsedInfoPtr
);
1865 // Based on BSF specification, once the PAL_A component has been written,
1866 // update the Firmware Volume info as FIT table. This will be utilized
1867 // to extract the Firmware Volume Start address where this BSF will be
1870 if (Status
== EFI_SUCCESS
) {
1871 UpdateFitEntryForFwVolume (Size
);
1875 case COMP_TYPE_FIT_FV_BOOT
:
1877 // Since FIT entry for Firmware Volume has been created and it is
1878 // located at (PAL_A start - 16 byte). So we will not process any
1879 // Firmware Volume related entry from INF file
1881 Status
= EFI_SUCCESS
;
1886 // Any other component type should be handled here. This will create the
1887 // image in specified BSF and create appropriate entry about this
1888 // component in FIT Entry.
1890 Status
= CreateAndUpdateComponent (ParsedInfoPtr
);
1891 if (EFI_ERROR (Status
)) {
1892 printf ("ERROR: Updating %s component.\n", ParsedInfoPtr
->CompName
);
1897 ParsedInfoPtr
= ParsedInfoPtr
->NextBsfInfo
;
1905 IN UINT64 StartAddress1
,
1907 IN UINT64 StartAddress2
,
1912 Routine Description:
1914 This is the main function which will be called from application.
1918 StartAddress1 - The start address of the first BSF
1919 Size1 - The size of the first BSF
1920 StartAddress2 - The start address of the second BSF
1921 Size2 - The size of the second BSF
1925 EFI_OUT_OF_RESOURCES - Can not allocate memory
1926 The return value can be any of the values
1927 returned by the calls to following functions:
1928 GetBsfRelatedInfoFromInfFile
1930 UpdateIA32ResetVector
1937 CHAR8 OutFileName1
[FILE_NAME_SIZE
];
1938 CHAR8 OutFileName2
[FILE_NAME_SIZE
];
1941 Status
= EFI_UNSUPPORTED
;
1943 if (StartAddress2
== 0) {
1948 Fv1BaseAddress
= StartAddress1
;
1949 Fv1EndAddress
= Fv1BaseAddress
+ Size1
;
1951 memset (OutFileName1
, 0, FILE_NAME_SIZE
);
1954 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x-%s",
1958 Bsf1NameGuid
.Data4
[0],
1959 Bsf1NameGuid
.Data4
[1],
1960 Bsf1NameGuid
.Data4
[2],
1961 Bsf1NameGuid
.Data4
[3],
1962 Bsf1NameGuid
.Data4
[4],
1963 Bsf1NameGuid
.Data4
[5],
1964 Bsf1NameGuid
.Data4
[6],
1965 Bsf1NameGuid
.Data4
[7],
1970 // The image buffer for the First BSF
1972 Bsf1Buffer
= malloc ((UINTN
) Size1
);
1973 if (Bsf1Buffer
== NULL
) {
1974 printf ("\nERROR: Not enough resource to create memory mapped file for Boot Strap File");
1975 return EFI_OUT_OF_RESOURCES
;
1977 memset (Bsf1Buffer
, 0x00, (UINTN
) Size1
);
1978 Bsf1EndBuffer
= (UINT8
*) Bsf1Buffer
+ Size1
;
1979 Bsf1LastStartAddress
= Fv1EndAddress
| IPF_CACHE_BIT
;
1982 Fv2BaseAddress
= StartAddress2
;
1983 Fv2EndAddress
= Fv2BaseAddress
+ Size2
;
1985 memset (OutFileName2
, 0, FILE_NAME_SIZE
);
1988 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x-%s",
1992 Bsf2NameGuid
.Data4
[0],
1993 Bsf2NameGuid
.Data4
[1],
1994 Bsf2NameGuid
.Data4
[2],
1995 Bsf2NameGuid
.Data4
[3],
1996 Bsf2NameGuid
.Data4
[4],
1997 Bsf2NameGuid
.Data4
[5],
1998 Bsf2NameGuid
.Data4
[6],
1999 Bsf2NameGuid
.Data4
[7],
2004 // The image buffer for the second BSF
2006 Bsf2Buffer
= malloc ((UINTN
) Size2
);
2007 if (Bsf2Buffer
== NULL
) {
2008 printf ("\nERROR: Not enough resource to create memory mapped file for Boot Strap File");
2009 return EFI_OUT_OF_RESOURCES
;
2011 memset (Bsf2Buffer
, 0x00, (UINTN
) Size2
);
2012 Bsf2EndBuffer
= (UINT8
*) Bsf2Buffer
+ Size2
;
2013 Bsf2LastStartAddress
= Fv2EndAddress
| IPF_CACHE_BIT
;
2016 Status
= GetBsfRelatedInfoFromInfFile (BSF_INPUT_FILE
);
2017 if (Status
!= EFI_SUCCESS
) {
2018 printf ("\nERROR: Error in parsing input file");
2023 Status
= ProcessAndCreateBsf (Size1
);
2024 if (Status
!= EFI_SUCCESS
) {
2029 Status
= UpdateIA32ResetVector (IA32BinFile
, Bsf1TotalSize
);
2030 if (Status
!= EFI_SUCCESS
) {
2036 // Re arrange the FIT Table for Ascending order of their FIT Type..
2041 // All components have been updated in FIT table. Now perform the FIT table
2042 // checksum. The following function will check if Checksum is required,
2043 // if yes, then it will perform the checksum otherwise not.
2045 CalculateFitTableChecksum ();
2048 // Write the FFS header
2050 Bsf1TotalSize
+= sizeof (EFI_FFS_FILE_HEADER
);
2051 Bsf1LastStartAddress
-= sizeof (EFI_FFS_FILE_HEADER
);
2052 Status
= UpdateFfsHeader (Bsf1TotalSize
, FIRST_VTF
);
2053 if (Status
!= EFI_SUCCESS
) {
2058 // Update the BSF buffer into specified BSF binary file
2060 Status
= WriteBsfBinary (OutFileName1
, Bsf1TotalSize
, FIRST_VTF
);
2063 Bsf2TotalSize
+= sizeof (EFI_FFS_FILE_HEADER
);
2064 Bsf2LastStartAddress
-= sizeof (EFI_FFS_FILE_HEADER
);
2065 Status
= UpdateFfsHeader (Bsf2TotalSize
, SECOND_VTF
);
2066 if (Status
!= EFI_SUCCESS
) {
2072 // Update the BSF buffer into specified BSF binary file
2074 Status
= WriteBsfBinary (OutFileName2
, Bsf2TotalSize
, SECOND_VTF
);
2084 PeimFixupInFitTable (
2085 IN UINT64 StartAddress
2089 Routine Description:
2091 This function is an entry point to fixup SAL-E entry point.
2095 StartAddress - StartAddress for PEIM.....
2099 EFI_SUCCESS - The function completed successfully
2100 EFI_ABORTED - Error Opening File
2101 EFI_OUT_OF_RESOURCES - System out of resources for memory allocation.
2107 UINT64
*StartAddressPtr
;
2110 CHAR8 OutFileName1
[FILE_NAME_SIZE
];
2112 StartAddressPtr
= malloc (sizeof (UINT64
));
2113 if (StartAddressPtr
== NULL
) {
2114 return EFI_OUT_OF_RESOURCES
;
2116 *StartAddressPtr
= StartAddress
;
2118 memset (OutFileName1
, 0, FILE_NAME_SIZE
);
2122 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x-%s",
2126 Bsf1NameGuid
.Data4
[0],
2127 Bsf1NameGuid
.Data4
[1],
2128 Bsf1NameGuid
.Data4
[2],
2129 Bsf1NameGuid
.Data4
[3],
2130 Bsf1NameGuid
.Data4
[4],
2131 Bsf1NameGuid
.Data4
[5],
2132 Bsf1NameGuid
.Data4
[6],
2133 Bsf1NameGuid
.Data4
[7],
2137 Fp
= fopen (OutFileName1
, "r+b");
2140 printf ("\nERROR: Error opening file ");
2141 if (StartAddressPtr
) {
2142 free (StartAddressPtr
);
2148 FirstFwVSize
= _filelength (fileno (Fp
));
2149 fseek (Fp
, (long) (FirstFwVSize
- (UINTN
) (SIZE_IA32_RESET_VECT
+ SIZE_SALE_ENTRY_POINT
)), SEEK_SET
);
2150 NumByte
= fwrite ((VOID
*) StartAddressPtr
, sizeof (UINT64
), 1, Fp
);
2156 if (StartAddressPtr
) {
2157 free (StartAddressPtr
);
2161 Status
= EFI_SUCCESS
;
2167 IN UINT64 BaseAddress
,
2168 IN CHAR8
*DestFileName
,
2169 IN CHAR8
*SourceFileName
2173 Routine Description:
2175 This function adds the SYM tokens in the source file to the destination file.
2176 The SYM tokens are updated to reflect the base address.
2180 BaseAddress - The base address for the new SYM tokens.
2181 DestFileName - The destination file.
2182 SourceFileName - The source file.
2186 EFI_SUCCESS - The function completed successfully.
2187 EFI_INVALID_PARAMETER - One of the input parameters was invalid.
2188 EFI_ABORTED - An error occurred.
2194 CHAR8 Buffer
[_MAX_PATH
];
2195 CHAR8 Type
[_MAX_PATH
];
2196 CHAR8 Address
[_MAX_PATH
];
2197 CHAR8 Section
[_MAX_PATH
];
2198 CHAR8 Token
[_MAX_PATH
];
2199 CHAR8 BaseToken
[_MAX_PATH
];
2200 UINT64 TokenAddress
;
2204 // Verify input parameters.
2206 if (BaseAddress
== 0 || DestFileName
== NULL
|| SourceFileName
== NULL
) {
2207 return EFI_INVALID_PARAMETER
;
2211 // Open the source file
2213 SourceFile
= fopen (SourceFileName
, "r");
2214 if (SourceFile
== NULL
) {
2217 // SYM files are not required.
2223 // Use the file name minus extension as the base for tokens
2225 strcpy (BaseToken
, SourceFileName
);
2226 strtok (BaseToken
, ". \t\n");
2227 strcat (BaseToken
, "__");
2230 // Open the destination file
2232 DestFile
= fopen (DestFileName
, "a+");
2233 if (DestFile
== NULL
) {
2234 fclose (SourceFile
);
2239 // If this is the beginning of the output file, write the symbol format info.
2241 if (fseek (DestFile
, 0, SEEK_END
) != 0) {
2242 fclose (SourceFile
);
2247 StartLocation
= ftell (DestFile
);
2249 if (StartLocation
== 0) {
2250 fprintf (DestFile
, "TEXTSYM format | V1.0\n");
2251 } else if (StartLocation
== -1) {
2252 fclose (SourceFile
);
2258 // Read the first line
2260 if (fgets (Buffer
, _MAX_PATH
, SourceFile
) == NULL
) {
2265 // Make sure it matches the expected sym format
2267 if (strcmp (Buffer
, "TEXTSYM format | V1.0\n")) {
2268 fclose (SourceFile
);
2276 while (feof (SourceFile
) == 0) {
2281 if (fscanf (SourceFile
, "%s | %s | %s | %s\n", Type
, Address
, Section
, Token
) == 4) {
2284 // Get the token address
2286 AsciiStringToUint64 (Address
, TRUE
, &TokenAddress
);
2289 // Add the base address, the size of the FFS file header and the size of the peim header.
2291 TokenAddress
+= BaseAddress
&~IPF_CACHE_BIT
;
2293 fprintf (DestFile
, "%s | %016I64X | %s | %s%s\n", Type
, TokenAddress
, Section
, BaseToken
, Token
);
2297 fclose (SourceFile
);
2303 CalculateFitTableChecksum (
2308 Routine Description:
2310 This function will perform byte checksum on the FIT table, if the the checksum required
2311 field is set to CheckSum required. If the checksum is not required then checksum byte
2312 will have value as 0;.
2320 Status - Value returned by call to CalculateChecksum8 ()
2321 EFI_SUCCESS - The function completed successfully
2325 FIT_TABLE
*TmpFitPtr
;
2327 UINT64 FitTableAddOffset
;
2328 UINTN RelativeAddress
;
2332 // Read the Fit Table address from Itanium-based address map.
2334 FitTableAddOffset
= Fv1EndAddress
- (SIZE_IA32_RESET_VECT
+ SIZE_SALE_ENTRY_POINT
+ SIZE_FIT_TABLE_ADD
);
2337 // Translate this Itanium-based address in terms of local buffer address which
2338 // contains the image for Boot Strapped File
2340 GetRelativeAddressInBsfBuffer (FitTableAddOffset
, &RelativeAddress
, FIRST_VTF
);
2341 FitTableAdd
= *(UINTN
*) RelativeAddress
;
2343 GetRelativeAddressInBsfBuffer (FitTableAdd
, &RelativeAddress
, FIRST_VTF
);
2345 TmpFitPtr
= (FIT_TABLE
*) RelativeAddress
;
2347 Size
= TmpFitPtr
->CompSize
* 16;
2349 if ((TmpFitPtr
->CvAndType
& CHECKSUM_BIT_MASK
) >> 7) {
2350 TmpFitPtr
->CheckSum
= 0;
2351 TmpFitPtr
->CheckSum
= CalculateChecksum8 ((UINT8
*) TmpFitPtr
, Size
);
2353 TmpFitPtr
->CheckSum
= 0;
2365 Routine Description:
2367 Displays the standard utility information to SDTOUT
2380 "%s, EFI 2.0 BootStrap File Generation Utility. Version %i.%i.\n",
2382 UTILITY_MAJOR_VERSION
,
2383 UTILITY_MINOR_VERSION
2393 Routine Description:
2395 Displays the utility usage syntax to STDOUT
2410 "\nUsage: %s -B BaseAddress -S FwVolumeSize\n",
2413 printf (" Where:\n");
2414 printf (" BaseAddress is the starting address of Firmware Volume where Boot\n");
2415 printf (" Strapped Image will reside.\n");
2416 printf (" FwVolumeSize is the size of Firmware Volume.\n");
2426 Routine Description:
2428 This utility uses GenBsfImage.dll to build a Boot Strap File Image which will be
2429 part of firmware volume image.
2433 argc - The count of the parameters
2434 argv - The parameters
2439 0 - No error conditions detected.
2440 1 - One or more of the input parameters is invalid.
2441 2 - A resource required by the utility was unavailable.
2442 - Most commonly this will be memory allocation or file creation.
2443 3 - GenFvImage.dll could not be loaded.
2444 4 - Error executing the GenFvImage dll.
2445 5 - Now this tool does not support the IA32 platform
2450 UINT64 StartAddress1
;
2451 UINT64 StartAddress2
;
2454 BOOLEAN FirstRoundB
;
2455 BOOLEAN FirstRoundS
;
2460 // Verify the correct number of IA32 arguments
2463 if (argc
== IA32_ARGS
) {
2465 // Now this tool is not used for IA32 platform, if it will be used in future,
2466 // the IA32-specific functions need to be updated and verified, the updating can
2467 // refer to IPF relevant functions)
2469 printf ("ERROR: Now this tool does not support the IA32 platform!\n");
2470 printf ("ERROR: And the IA32-specific functions need to be updated and verified!\n");
2478 // Parse the command line arguments
2480 for (Index = 1; Index < IA32_ARGS; Index += 2) {
2483 // Make sure argument pair begin with - or /
2485 if (argv[Index][0] != '-' && argv[Index][0] != '/') {
2487 printf ("ERROR: Argument pair must begin with \"-\" or \"/\"\n");
2492 // Make sure argument specifier is only one letter
2494 if (argv[Index][2] != 0) {
2496 printf ("ERROR: Unrecognized argument \"%s\".\n", argv[Index]);
2501 // Determine argument to read
2503 switch (argv[Index][1]) {
2507 Status = AsciiStringToUint64 (argv[Index + 1], FALSE, &StartAddress1);
2508 if (Status != EFI_SUCCESS) {
2509 printf ("\nERROR: Bad start of address \"%s\"\n", argv[Index + 1]);
2516 printf ("Unrecognized IA32 argument \"%s\".\n", argv[Index]);
2524 // Call the GenBsfImage
2526 Status = Generate32BsfImage (StartAddress1);
2528 if (EFI_ERROR(Status)) {
2531 case EFI_INVALID_PARAMETER:
2532 printf ("\nERROR: Invalid parameter passed to GenBsfImage function .\n");
2536 printf ("\nERROR: Error detected while creating the file image.\n");
2539 case EFI_OUT_OF_RESOURCES:
2540 printf ("\nERROR: GenBsfImage function could not allocate required resources.\n");
2543 case EFI_VOLUME_CORRUPTED:
2544 printf ("\nERROR: No base address was specified \n");
2548 printf ("\nERROR: GenBsfImage function returned unknown status %X.\n", Status);
2560 // Verify the correct number of arguments
2567 if ((strcmp(argv
[1], "-h") == 0) || (strcmp(argv
[1], "--help") == 0) ||
2568 (strcmp(argv
[1], "-?") == 0) || (strcmp(argv
[1], "/?") == 0)) {
2573 if ((strcmp(argv
[1], "-V") == 0) || (strcmp(argv
[1], "--version") == 0)) {
2578 if (argc
!= ONE_BSF_ARGS
&& argc
!= TWO_BSF_ARGS
) {
2584 // Initialize variables
2594 // Parse the command line arguments
2596 for (Index
= 1; Index
< argc
; Index
+= 2) {
2599 // Make sure argument pair begin with - or /
2601 if (argv
[Index
][0] != '-' && argv
[Index
][0] != '/') {
2603 printf ("ERROR: Argument pair must begin with \"-\" or \"/\"\n");
2608 // Make sure argument specifier is only one letter
2610 if (argv
[Index
][2] != 0) {
2612 printf ("ERROR: Unrecognized argument \"%s\".\n", argv
[Index
]);
2617 // Determine argument to read
2619 switch (argv
[Index
][1]) {
2624 Status
= AsciiStringToUint64 (argv
[Index
+ 1], FALSE
, &StartAddress1
);
2625 FirstRoundB
= FALSE
;
2627 Status
= AsciiStringToUint64 (argv
[Index
+ 1], FALSE
, &StartAddress2
);
2630 if (Status
!= EFI_SUCCESS
) {
2631 printf ("\nERROR: Bad start of address \"%s\"\n", argv
[Index
+ 1]);
2639 Status
= AsciiStringToUint64 (argv
[Index
+ 1], FALSE
, &FwVolSize1
);
2640 FirstRoundS
= FALSE
;
2642 Status
= AsciiStringToUint64 (argv
[Index
+ 1], FALSE
, &FwVolSize2
);
2645 if (Status
!= EFI_SUCCESS
) {
2646 printf ("\nERROR: Bad size \"%s\"\n", argv
[Index
+ 1]);
2653 printf ("ERROR: Unrecognized argument \"%s\".\n", argv
[Index
]);
2660 // Call the GenBsfImage
2662 Status
= GenerateBsfImage (StartAddress1
, FwVolSize1
, StartAddress2
, FwVolSize2
);
2664 if (EFI_ERROR (Status
)) {
2667 case EFI_INVALID_PARAMETER
:
2668 printf ("\nERROR: Invalid parameter passed to GenBsfImage function .\n");
2672 printf ("\nERROR: Error detected while creating the file image.\n");
2675 case EFI_OUT_OF_RESOURCES
:
2676 printf ("\nERROR: GenBsfImage function could not allocate required resources.\n");
2679 case EFI_VOLUME_CORRUPTED
:
2680 printf ("\nERROR: No base address was specified \n");
2684 printf ("\nERROR: GenBsfImage function returned unknown status %X.\n", Status
);
2693 Generate32BsfImage (
2694 IN UINT64 BootFileStartAddress
2698 Routine Description:
2700 This is the main IA32 function which will be called from application.
2701 (Now this tool is not used for IA32 platform, if it will be used in future,
2702 the relative functions need to be updated, the updating can refer to IPF
2707 BootFileStartAddress - Top Address of Boot File
2711 The return value can be any of the values
2712 returned by the calls to following functions:
2713 Get32BsfRelatedInfoFromInfFile
2715 ProcessAndCreate32Bsf
2723 CHAR8 OutFileName
[FILE_NAME_SIZE
];
2725 EFI_GUID BsfNameGuid
= EFI_IA32_BOOT_STRAP_GUID
;
2727 Status
= EFI_UNSUPPORTED
;
2729 memset (OutFileName
, 0, FILE_NAME_SIZE
);
2732 OutFileName
, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x-%s",
2736 BsfNameGuid
.Data4
[0],
2737 BsfNameGuid
.Data4
[1],
2738 BsfNameGuid
.Data4
[2],
2739 BsfNameGuid
.Data4
[3],
2740 BsfNameGuid
.Data4
[4],
2741 BsfNameGuid
.Data4
[5],
2742 BsfNameGuid
.Data4
[6],
2743 BsfNameGuid
.Data4
[7],
2748 Status
= Get32BsfRelatedInfoFromInfFile (BSF_INPUT_FILE
);
2750 if (Status
!= EFI_SUCCESS
) {
2751 printf ("\nERROR: Error in parsing input file");
2756 if (GetTotal32BsfSize (&BsfSize
) == EFI_SUCCESS
) {
2757 Bsf1Buffer
= malloc ((UINTN
) BsfSize
);
2758 if (Bsf1Buffer
== NULL
) {
2759 printf ("\nERROR: Not enough resource to create memory mapped file for Boot Strap File");
2761 return EFI_OUT_OF_RESOURCES
;
2763 memset (Bsf1Buffer
, 0x00, (UINTN
) BsfSize
);
2765 printf ("\nERROR: Could not get BSF size.");
2771 //VTF must align properly
2773 Bsf1LastStartAddress
= BootFileStartAddress
- BsfSize
;
2774 Bsf1LastStartAddress
= Bsf1LastStartAddress
& -8;
2775 BsfSize
= (UINT32
)BootFileStartAddress
- (UINT32
)Bsf1LastStartAddress
;
2776 Bsf1LastStartAddress
= BsfSize
;
2777 BufferToTop
= (UINT32
)BootFileStartAddress
- BsfSize
;
2779 Status
= ProcessAndCreate32Bsf (BsfSize
);
2781 if (Status
!= EFI_SUCCESS
) {
2787 // Write the FFS header
2789 Status
= Update32FfsHeader (BsfSize
);
2791 if (Status
!= EFI_SUCCESS
) {
2797 // Calculate the Start address of this BSF
2799 Bsf1Buffer
= (UINT8
*)Bsf1Buffer
+ Bsf1LastStartAddress
;
2802 // Update the BSF buffer into specified BSF binary file
2804 Status
= WriteBsfBinary (OutFileName
, BsfSize
- (UINT32
)Bsf1LastStartAddress
, FIRST_VTF
);
2806 if (Status
!= EFI_SUCCESS
) {
2811 Status
= Write32SoftFit (IA32_SOFT_FIT
, FileListHeadPtr
);
2813 if (Status
!= EFI_SUCCESS
) {
2830 Routine Description:
2832 This function calculates total size for IA32 BSF which would be needed to create
2833 the buffer. This will be done using Passed Info link list and looking for the
2834 size of the components which belong to BSF. The addtional file header is accounted.
2838 BSFSize - Pointer to the size of IA32 BSF
2842 EFI_ABORTED - Returned due to one of the following resons:
2843 (a) Error Opening File
2844 EFI_SUCCESS - The fuction completes successfully
2848 PARSED_BSF_INFO
*BsfInfo
;
2855 BsfInfo
= FileListHeadPtr
;
2857 while (BsfInfo
!= NULL
) {
2858 if (BsfInfo
->LocationType
!= SECOND_VTF
) {
2860 if ( BsfInfo
->Align
) {
2862 // Create additional align to compensate for component boundary requirements
2864 Alignment
= 1 << BsfInfo
->Align
;
2865 *BsfSize
+= Alignment
;
2868 if (BsfInfo
->PreferredSize
) {
2869 *BsfSize
+= BsfInfo
->CompSize
;
2871 Fp
= fopen (BsfInfo
->CompBinName
,"r+b");
2874 printf ("\nERROR: Error in opening file %s", BsfInfo
->CompBinName
);
2878 *BsfSize
+= _filelength (fileno (Fp
));
2885 BsfInfo
= BsfInfo
->NextBsfInfo
;
2889 // Add file header space
2891 *BsfSize
+= sizeof (EFI_FFS_FILE_HEADER
);
2894 // Create additional to IA32 Seccore section header
2896 *BsfSize
+= sizeof (EFI_COMMON_SECTION_HEADER
);
2902 ProcessAndCreate32Bsf (
2907 Routine Description:
2909 This function process the link list created during INF file parsing
2910 and create component in IA32 BSF
2914 Size - Size of the Firmware Volume of which, this BSF belongs to.
2918 EFI_UNSUPPORTED - Unknown component type
2919 EFI_SUCCESS - The function completed successfully
2924 PARSED_BSF_INFO
*ParsedInfoPtr
;
2926 Status
= EFI_SUCCESS
;
2928 ParsedInfoPtr
= FileListHeadPtr
;
2930 while (ParsedInfoPtr
!= NULL
) {
2932 switch (ParsedInfoPtr
->CompType
) {
2934 case COMP_TYPE_SECCORE
:
2935 Status
= CreateAndUpdateSeccore (ParsedInfoPtr
);
2940 // Any other component type should be handled here. This will create the
2941 // image in specified BSF
2943 Status
= CreateAndUpdate32Component (ParsedInfoPtr
);
2944 if (EFI_ERROR(Status
)) {
2945 printf ("ERROR: Updating %s component.\n", ParsedInfoPtr
->CompName
);
2950 ParsedInfoPtr
= ParsedInfoPtr
->NextBsfInfo
;
2957 CreateAndUpdateSeccore (
2958 IN PARSED_BSF_INFO
*BsfInfo
2962 Routine Description:
2964 This function reads the binary file for seccore and update them
2969 BsfInfo - Pointer to Parsed Info
2973 EFI_ABORTED - Due to one of the following reasons:
2974 (a)Error Opening File
2975 (b)The PAL_A Size is more than specified size status
2976 One of the values mentioned below returned from
2977 call to UpdateSymFile
2978 EFI_SUCCESS - The function completed successfully.
2979 EFI_INVALID_PARAMETER - One of the input parameters was invalid.
2980 EFI_ABORTED - An error occurred.UpdateSymFile
2981 EFI_OUT_OF_RESOURCES - Memory allocation failed.
2985 UINT8
*SecbinStartAddress
;
2986 UINT8
*SecfileStartAddress
;
2992 EFI_COMMON_SECTION_HEADER
*SecHeader
;
2994 Fp
= fopen (BsfInfo
->CompBinName
, "r+b");
2997 printf ("\nERROR: Opening file %s", BsfInfo
->CompBinName
);
3001 FileSize
= _filelength (fileno (Fp
));
3003 if (BsfInfo
->PreferredSize
) {
3004 if (FileSize
> BsfInfo
->CompSize
) {
3005 printf("\nERROR: The Seccore Size is more than specified size");
3009 FileSize
= BsfInfo
->CompSize
;
3012 BsfInfo
->CompSize
= FileSize
;
3014 Buffer
= malloc ((UINTN
) FileSize
);
3015 if (Buffer
== NULL
) {
3016 return EFI_OUT_OF_RESOURCES
;
3018 memset (Buffer
, 0, (UINTN
) FileSize
);
3021 // Read seccore in a buffer
3023 NumByteRead
= fread (Buffer
, sizeof (UINT8
), (UINTN
) FileSize
, Fp
);
3026 SecfileStartAddress
= (UINT8
*) Bsf1Buffer
+ Bsf1LastStartAddress
- FileSize
- sizeof (EFI_COMMON_SECTION_HEADER
);
3027 if (SecfileStartAddress
== NULL
) {
3028 return EFI_INVALID_PARAMETER
;
3031 SecbinStartAddress
= SecfileStartAddress
+ sizeof (EFI_COMMON_SECTION_HEADER
);
3033 BsfInfo
->CompPreferredAddress
= Bsf1LastStartAddress
- FileSize
+ BufferToTop
;
3036 // write section header
3038 memset (SecfileStartAddress
, 0, sizeof (EFI_COMMON_SECTION_HEADER
));
3039 SecHeader
= (EFI_COMMON_SECTION_HEADER
*) SecfileStartAddress
;
3040 SecHeader
->Type
= EFI_SECTION_RAW
;
3041 TotalLength
= sizeof (EFI_COMMON_SECTION_HEADER
) + (UINT64
) FileSize
;
3042 memcpy (SecHeader
->Size
, &TotalLength
, 3);
3047 memcpy (SecbinStartAddress
, Buffer
, (UINTN
) FileSize
);
3053 Bsf1LastStartAddress
= SecfileStartAddress
- (UINT8
*) Bsf1Buffer
;
3059 CreateAndUpdate32Component (
3060 IN PARSED_BSF_INFO
*BsfInfo
3064 Routine Description:
3066 This function reads the binary file for each components. Add it at aligned address.
3070 BsfInfo - Pointer to Parsed Info
3074 EFI_SUCCESS - The function completed successful
3075 EFI_ABORTED - Aborted due to one of the many reasons like:
3076 (a) Component Size greater than the specified size.
3077 (b) Error opening files.
3078 EFI_INVALID_PARAMETER - Value returned from call to UpdateEntryPoint()
3079 EFI_OUT_OF_RESOURCES - Memory allocation failed.
3083 UINT64 CompStartAddress
;
3088 UINT8
*LocalBufferPtrToWrite
;
3091 Fp
= fopen (BsfInfo
->CompBinName
, "r+b");
3094 printf("\nERROR: Opening file %s", BsfInfo
->CompBinName
);
3098 FileSize
= _filelength (fileno (Fp
));
3100 if (BsfInfo
->PreferredSize
) {
3101 if (FileSize
> BsfInfo
->CompSize
) {
3102 printf("\nERROR: The component size is more than specified size");
3105 FileSize
= BsfInfo
->CompSize
;
3107 BsfInfo
->CompSize
= FileSize
;
3109 Buffer
= malloc ((UINTN
) FileSize
);
3110 if (Buffer
== NULL
) {
3111 return EFI_OUT_OF_RESOURCES
;
3113 memset (Buffer
,0, (UINTN
) FileSize
);
3115 NumByteRead
= fread (Buffer
, sizeof (UINT8
), (UINTN
) FileSize
, Fp
);
3118 CompStartAddress
= Bsf1LastStartAddress
- FileSize
+ BufferToTop
;
3120 if (BsfInfo
->Align
) {
3122 // Create additional align to compensate for component boundary requirements
3124 Alignment
= 0 - (1 << BsfInfo
->Align
);
3125 CompStartAddress
= CompStartAddress
& Alignment
;
3128 BsfInfo
->CompPreferredAddress
= CompStartAddress
;
3133 LocalBufferPtrToWrite
= (UINT8
*) Bsf1Buffer
;
3134 Bsf1LastStartAddress
= CompStartAddress
- BufferToTop
;
3135 LocalBufferPtrToWrite
+= Bsf1LastStartAddress
;
3136 memcpy (LocalBufferPtrToWrite
, Buffer
, (UINTN
) FileSize
);
3137 Bsf1LastStartAddress
= CompStartAddress
- BufferToTop
;
3155 Routine Description:
3157 Update the Firmware Volume Buffer with requested buffer data
3161 BsfSize - Size of the IA32 BSF
3165 EFI_SUCCESS - The function completed successfully
3166 EFI_INVALID_PARAMETER - The Ffs File Header Pointer is NULL
3170 EFI_FFS_FILE_HEADER
*FileHeader
;
3171 UINT32 TotalBsfSize
;
3172 EFI_GUID EfiFirmwareVolumeTopFileGuid
= EFI_FFS_VOLUME_TOP_FILE_GUID
;
3176 // Find the BSF file header location, the bsf file must be 8 bytes aligned
3178 Bsf1LastStartAddress
-= sizeof (EFI_FFS_FILE_HEADER
);
3179 Bsf1LastStartAddress
+= BufferToTop
;
3180 Bsf1LastStartAddress
= Bsf1LastStartAddress
& -8;
3181 Bsf1LastStartAddress
-= BufferToTop
;
3182 FileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)Bsf1Buffer
+ Bsf1LastStartAddress
);
3184 if (FileHeader
== NULL
) {
3185 return EFI_INVALID_PARAMETER
;
3191 memset (FileHeader
, 0, sizeof(EFI_FFS_FILE_HEADER
));
3192 memcpy (&FileHeader
->Name
, &EfiFirmwareVolumeTopFileGuid
, sizeof (EFI_GUID
));
3194 FileHeader
->Type
= EFI_FV_FILETYPE_FREEFORM
;
3195 FileHeader
->Attributes
= FFS_ATTRIB_CHECKSUM
;
3198 // Now FileSize includes the EFI_FFS_FILE_HEADER
3200 TotalBsfSize
= BsfSize
- (UINT32
)Bsf1LastStartAddress
;
3201 FileHeader
->Size
[0] = (UINT8
) (TotalBsfSize
& 0x000000FF);
3202 FileHeader
->Size
[1] = (UINT8
) ((TotalBsfSize
& 0x0000FF00) >> 8);
3203 FileHeader
->Size
[2] = (UINT8
) ((TotalBsfSize
& 0x00FF0000) >> 16);
3206 // Fill in checksums and state, all three must be zero for the checksums.
3208 FileHeader
->IntegrityCheck
.Checksum
.Header
= 0;
3209 FileHeader
->IntegrityCheck
.Checksum
.File
= 0;
3210 FileHeader
->State
= 0;
3211 FileHeader
->IntegrityCheck
.Checksum
.Header
= CalculateChecksum8 ((UINT8
*) FileHeader
, sizeof (EFI_FFS_FILE_HEADER
));
3212 FileHeader
->IntegrityCheck
.Checksum
.File
= CalculateChecksum8 ((UINT8
*) FileHeader
, TotalBsfSize
);
3213 FileHeader
->State
= EFI_FILE_HEADER_CONSTRUCTION
| EFI_FILE_HEADER_VALID
| EFI_FILE_DATA_VALID
;
3219 Get32BsfRelatedInfoFromInfFile (
3224 Routine Description:
3226 This function reads the input file, parse it and create a list of tokens
3227 which is parsed and used, to intialize the data related to IA32 BSF
3231 FileName FileName which needed to be read to parse data
3235 EFI_ABORTED Error in opening file
3236 EFI_INVALID_PARAMETER File doesn't contain any valid informations
3237 EFI_OUT_OF_RESOURCES Malloc Failed
3238 EFI_SUCCESS The function completed successfully
3246 Fp
= fopen (FileName
, "r");
3248 printf ("\nERROR: Error in opening %s file\n", FileName
);
3252 ValidLineCount (Fp
);
3254 if (ValidLineNum
== 0) {
3255 printf ("\nERROR: File doesn't contain any valid informations");
3256 return EFI_INVALID_PARAMETER
;
3259 TokenStr
= (CHAR8
**)malloc (sizeof (UINTN
) * (2 * ValidLineNum
+ 1));
3261 if (TokenStr
== NULL
) {
3262 return EFI_OUT_OF_RESOURCES
;
3264 memset (TokenStr
, 0, (sizeof (UINTN
) * (2 * ValidLineNum
+ 1)));
3265 OrgStrTokPtr
= TokenStr
;
3267 for (Index
= 0; Index
< (2 * ValidLineNum
); Index
++) {
3268 *TokenStr
= (CHAR8
*)malloc (sizeof (CHAR8
) * FILE_NAME_SIZE
);
3270 if (*TokenStr
== NULL
) {
3271 free (OrgStrTokPtr
);
3272 return EFI_OUT_OF_RESOURCES
;
3275 memset (*TokenStr
, 0, FILE_NAME_SIZE
);
3276 // free (*TokenStr);
3281 TokenStr
= OrgStrTokPtr
;
3282 fseek (Fp
, 0L, SEEK_SET
);
3284 Status
= InitializeComps();
3286 if (Status
!= EFI_SUCCESS
) {
3290 ParseInputFile (Fp
);
3291 Initialize32InFileInfo ();
3301 Initialize32InFileInfo (
3306 Routine Description:
3308 This function intializes the relevant global variable which is being
3309 used to store the information retrieved from IA32 INF file.
3321 UINTN SectionOptionFlag
;
3322 UINTN SectionCompFlag
;
3324 SectionOptionFlag
=0 ;
3325 SectionCompFlag
= 0;
3326 TokenStr
= OrgStrTokPtr
;
3327 while (*TokenStr
!= NULL
) {
3328 if (_stricmp (*TokenStr
, "[OPTIONS]") == 0) {
3329 SectionOptionFlag
= 1;
3330 SectionCompFlag
= 0;
3333 if (_stricmp (*TokenStr
, "[COMPONENTS]") == 0) {
3334 if (FileListPtr
== NULL
) {
3335 FileListPtr
= FileListHeadPtr
;
3338 SectionCompFlag
= 1;
3339 SectionOptionFlag
= 0;
3343 if (SectionOptionFlag
) {
3344 if (_stricmp (*TokenStr
, "IA32_RST_BIN") == 0) {
3346 strcpy (IA32BinFile
, *TokenStr
);
3350 if (SectionCompFlag
) {
3351 if (_stricmp (*TokenStr
, "COMP_NAME") == 0) {
3353 strcpy (FileListPtr
->CompName
, *TokenStr
);
3355 ParseAndUpdate32Components (FileListPtr
);
3358 if (*TokenStr
!= NULL
) {
3359 FileListPtr
->NextBsfInfo
= malloc (sizeof (PARSED_BSF_INFO
));
3360 if (FileListPtr
->NextBsfInfo
== NULL
) {
3361 printf ("Error: Out of memory resources.\n");
3364 FileListPtr
= FileListPtr
->NextBsfInfo
;
3365 memset (FileListPtr
, 0, sizeof(PARSED_BSF_INFO
));
3366 FileListPtr
->NextBsfInfo
= NULL
;
3378 ParseAndUpdate32Components (
3379 IN PARSED_BSF_INFO
*BsfInfo
3383 Routine Description:
3385 This function intializes the relevant global variable which is being
3386 used to store the information retrieved from INF file.
3390 BsfInfo - A pointer to the BSF Info Structure
3400 UINT64 AlignStringValue
;
3402 while (*TokenStr
!= NULL
&& (_stricmp (*TokenStr
, "COMP_NAME") != 0)) {
3404 if (_stricmp (*TokenStr
, "COMP_LOC") == 0) {
3406 if (_stricmp (*TokenStr
, "B") == 0) {
3407 BsfInfo
->LocationType
= FIRST_VTF
;
3408 } else if (_stricmp (*TokenStr
, "N") == 0) {
3409 BsfInfo
->LocationType
= SECOND_VTF
;
3411 BsfInfo
->LocationType
= NONE
;
3412 printf ("\nERROR: Unknown location for component %s", BsfInfo
->CompName
);
3414 } else if (_stricmp (*TokenStr
, "COMP_TYPE") == 0) {
3416 if (AsciiStringToUint64 (*TokenStr
, FALSE
, &StringValue
) != EFI_SUCCESS
) {
3417 printf ("\nERROR: Could not read a numeric value from \"%s\".", TokenStr
);
3420 BsfInfo
->CompType
= (UINT8
) StringValue
;
3421 } else if (_stricmp (*TokenStr
, "COMP_VER") == 0) {
3423 if (_stricmp (*TokenStr
, "-") == 0) {
3424 BsfInfo
->VersionPresent
= FALSE
;
3425 BsfInfo
->MajorVer
= 0;
3426 BsfInfo
->MinorVer
= 0;
3428 BsfInfo
->VersionPresent
= TRUE
;
3429 ConvertVersionInfo (*TokenStr
, &BsfInfo
->MajorVer
, &BsfInfo
->MinorVer
);
3431 } else if (_stricmp (*TokenStr
, "COMP_BIN") == 0) {
3433 strcpy (BsfInfo
->CompBinName
, *TokenStr
);
3434 } else if (_stricmp (*TokenStr
, "COMP_SYM") == 0) {
3436 strcpy (BsfInfo
->CompSymName
, *TokenStr
);
3437 } else if (_stricmp (*TokenStr
, "COMP_SIZE") == 0) {
3439 if (_stricmp (*TokenStr
, "-") == 0) {
3440 BsfInfo
->PreferredSize
= FALSE
;
3441 BsfInfo
->CompSize
= 0;
3443 BsfInfo
->PreferredSize
= TRUE
;
3444 if (AsciiStringToUint64 (*TokenStr
, FALSE
, &StringValue
) != EFI_SUCCESS
) {
3445 printf ("\nERROR: Could not read a numeric value from \"%s\".", TokenStr
);
3448 BsfInfo
->CompSize
= (UINTN
) StringValue
;
3451 } else if (_stricmp (*TokenStr
, "COMP_CS") == 0) {
3453 if (_stricmp (*TokenStr
, "1") == 0) {
3454 BsfInfo
->CheckSumRequired
= 1;
3455 } else if (_stricmp (*TokenStr
, "0") == 0) {
3456 BsfInfo
->CheckSumRequired
= 0;
3458 printf ("\nERROR: Bad information in INF file about Checksum required field");
3460 } else if (_stricmp (*TokenStr
, "COMP_ALIGN") == 0) {
3462 if (AsciiStringToUint64 (*TokenStr
, FALSE
, &AlignStringValue
) != EFI_SUCCESS
) {
3463 printf ("\nERROR: Could not read a numeric value from \"%s\".", TokenStr
);
3466 if (AlignStringValue
>= 0) {
3467 BsfInfo
->Align
= (UINT32
) AlignStringValue
;
3469 printf ("\nERROR: invalid align \"%s\".", AlignStringValue
);
3474 if (*TokenStr
== NULL
) {
3483 IN PARSED_BSF_INFO
*BsfInfo
3487 Routine Description:
3489 Write IA32 Firmware Volume component address from memory to a file.
3493 FileName Output File Name which needed to be created/
3494 BsfInfo Parsed info link
3498 EFI_ABORTED - Returned due to one of the following resons:
3499 (a) Error Opening File
3500 (b) Failing to copy buffers
3501 EFI_SUCCESS - The function completes successfully
3507 Fp
= fopen (FileName
, "w+t");
3509 printf ("Error in opening file %s\n", FileName
);
3513 while (BsfInfo
!= NULL
) {
3514 if (strlen (BsfInfo
->CompName
) != 0) {
3515 fprintf (Fp
, "\n%s\n", BsfInfo
->CompName
);
3517 fprintf (Fp
, "\n%s\n", "Name not available");
3520 fprintf (Fp
, "%d\n", BsfInfo
->CompPreferredAddress
);
3521 fprintf (Fp
, "%d\n", BsfInfo
->CompSize
);
3522 fprintf (Fp
, "%d\n", BsfInfo
->Align
);
3524 BsfInfo
= BsfInfo
->NextBsfInfo
;