+++ /dev/null
-/*++\r
-\r
-Copyright (c) 1999 - 2006, Intel Corporation. All rights reserved\r
-This software and associated documentation (if any) is furnished\r
-under a license and may only be used or copied in accordance\r
-with the terms of the license. Except as permitted by such\r
-license, no part of this software or documentation may be\r
-reproduced, stored in a retrieval system, or transmitted in any\r
-form or by any means without the express written consent of\r
-Intel Corporation.\r
-\r
-\r
-Module Name:\r
-\r
- GenBsfImage.c\r
-\r
-Abstract:\r
-\r
- This file contains functions required to generate a boot strap file (BSF) \r
- also known as the Volume Top File (VTF)\r
-\r
---*/\r
-\r
-//\r
-// Module Coded to EFI 2.0 Coding Conventions\r
-//\r
-#include <FvLib.h>\r
-#include <Common/UefiBaseTypes.h>\r
-#include "GenBsfImage.h"\r
-#include <Guid/FirmwareFileSystem.h>\r
-#include "CommonLib.h"\r
-\r
-//\r
-// Global variables\r
-//\r
-EFI_GUID Bsf1NameGuid = EFI_IPF_VTF1_GUID\r
-EFI_GUID Bsf2NameGuid = EFI_IPF_VTF2_GUID\r
-\r
-CHAR8 **TokenStr;\r
-CHAR8 **OrgStrTokPtr;\r
-\r
-PARSED_BSF_INFO *FileListPtr;\r
-PARSED_BSF_INFO *FileListHeadPtr;\r
-\r
-VOID *Bsf1Buffer;\r
-VOID *Bsf1EndBuffer;\r
-VOID *Bsf2Buffer;\r
-VOID *Bsf2EndBuffer;\r
-\r
-UINTN ValidLineNum = 0;\r
-UINTN ValidFFDFileListNum = 0;\r
-\r
-//\r
-// Section Description and their number of occurences in *.INF file\r
-//\r
-UINTN NumFvFiles = 0;\r
-UINTN SectionOptionNum = 0;\r
-\r
-//\r
-// Global flag which will check for BSF Present, if yes then will be used\r
-// to decide about adding FFS header to pad data\r
-//\r
-BOOLEAN BSFPresent = FALSE;\r
-\r
-//\r
-// Address related information\r
-//\r
-UINT64 Fv1BaseAddress = 0;\r
-UINT64 Fv2BaseAddress = 0;\r
-UINT64 Fv1EndAddress = 0;\r
-UINT64 Fv2EndAddress = 0;\r
-UINT32 Bsf1TotalSize = SIZE_TO_OFFSET_PAL_A_END;\r
-UINT64 Bsf1LastStartAddress = 0;\r
-UINT32 Bsf2TotalSize = 0;\r
-UINT64 Bsf2LastStartAddress = 0;\r
-\r
-UINT32 BufferToTop = 0;\r
-\r
-//\r
-// IA32 Reset Vector Bin name\r
-//\r
-CHAR8 IA32BinFile[FILE_NAME_SIZE];\r
-\r
-//\r
-// Function Implementations\r
-//\r
-VOID\r
-BuildTokenList (\r
- IN CHAR8 *Token\r
- )\r
-/*++\r
-Routine Description:\r
-\r
- This function builds the token list in an array which will be parsed later\r
-\r
-Arguments:\r
-\r
- Token - The pointer of string\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- strcpy (*TokenStr, Token);\r
- TokenStr++;\r
-}\r
-\r
-EFI_STATUS\r
-ConvertVersionInfo (\r
- IN CHAR8 *Str,\r
- IN OUT UINT8 *MajorVer,\r
- IN OUT UINT8 *MinorVer\r
- )\r
-/*++\r
-Routine Description:\r
-\r
- This function converts GUID string to GUID\r
-\r
-Arguments:\r
-\r
- Str - String representing in form XX.XX\r
- MajorVer - The major vertion\r
- MinorVer - The minor vertion\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS - The fuction completed successfully.\r
-\r
---*/\r
-{\r
- CHAR8 StrPtr[40];\r
- CHAR8 *Token;\r
- UINTN Length;\r
- UINTN Major;\r
- UINTN Minor;\r
-\r
- Major = 0;\r
- Minor = 0;\r
- memset (StrPtr, 0, 40);\r
- Token = strtok (Str, ".");\r
-\r
- while (Token != NULL) {\r
- strcat (StrPtr, Token);\r
- Token = strtok (NULL, ".");\r
- }\r
-\r
- Length = strlen (StrPtr);\r
- sscanf (\r
- StrPtr,\r
- "%01x%02x",\r
- &Major,\r
- &Minor\r
- );\r
-\r
- *MajorVer = (UINT8) Major;\r
- *MinorVer = (UINT8) Minor;\r
- return EFI_SUCCESS;\r
-}\r
-\r
-VOID\r
-TrimLine (\r
- IN CHAR8 *Line\r
- )\r
-/*++\r
-Routine Description:\r
-\r
- This function cleans up the line by removing all whitespace and \r
- comments\r
-\r
-Arguments:\r
-\r
- Line - The pointer of the string\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- CHAR8 TmpLine[FILE_NAME_SIZE];\r
- CHAR8 Char;\r
- CHAR8 *Ptr0;\r
- UINTN Index;\r
- UINTN Index2;\r
-\r
- //\r
- // Change '#' to '//' for Comment style\r
- //\r
- if (((Ptr0 = strchr (Line, '#')) != NULL) || ((Ptr0 = strstr (Line, "//")) != NULL)) {\r
- Line[Ptr0 - Line] = 0;\r
- }\r
-\r
- //\r
- // Initialize counters\r
- //\r
- Index = 0;\r
- Index2 = 0;\r
-\r
- while ((Char = Line[Index]) != 0) {\r
- if ((Char != ' ') && (Char != '\t') && (Char != '\n')) {\r
- TmpLine[Index2++] = Char;\r
- }\r
- Index++;\r
- }\r
-\r
- TmpLine[Index2] = 0;\r
- strcpy (Line, TmpLine);\r
-}\r
-\r
-VOID\r
-ValidLineCount (\r
- IN FILE *Fp\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This function calculated number of valid lines in a input file.\r
- \r
-Arguments:\r
-\r
- Fp - Pointer to a file handle which has been opened.\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- CHAR8 Buff[FILE_NAME_SIZE];\r
-\r
- while (fgets (Buff, sizeof (Buff), Fp)) {\r
- TrimLine (Buff);\r
- if (Buff[0] == 0) {\r
- continue;\r
- }\r
-\r
- ValidLineNum++;\r
- }\r
-}\r
-\r
-VOID\r
-ParseInputFile (\r
- IN FILE *Fp\r
- )\r
-/*++\r
- \r
-Routine Description:\r
-\r
- This function parses the input file and tokenize the string\r
- \r
-Arguments:\r
-\r
- Fp - Pointer to a file handle which has been opened.\r
- \r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- CHAR8 *Token;\r
- CHAR8 Buff[FILE_NAME_SIZE];\r
- CHAR8 OrgLine[FILE_NAME_SIZE];\r
- CHAR8 Str[FILE_NAME_SIZE];\r
- CHAR8 Delimit[] = "=";\r
-\r
- while (fgets (Buff, sizeof (Buff), Fp) != NULL) {\r
- strcpy (OrgLine, Buff);\r
- TrimLine (Buff);\r
- if (Buff[0] == 0) {\r
- continue;\r
- }\r
-\r
- Token = strtok (Buff, Delimit);\r
-\r
- while (Token != NULL) {\r
- strcpy (Str, Token);\r
- BuildTokenList (Str);\r
- Token = strtok (NULL, Delimit);\r
- }\r
- }\r
-}\r
-\r
-EFI_STATUS\r
-InitializeComps (\r
- VOID\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This function intializes the relevant global variable which is being\r
- used to store the information retrieved from INF file. This also initializes\r
- the BSF symbol file.\r
- \r
-Arguments:\r
-\r
- None\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS - The function completed successfully\r
- EFI_OUT_OF_RESOURCES - Malloc failed.\r
-\r
---*/\r
-{\r
-\r
- FileListPtr = malloc (sizeof (PARSED_BSF_INFO));\r
-\r
- if (FileListPtr == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- FileListHeadPtr = FileListPtr;\r
- memset (FileListPtr, 0, sizeof (PARSED_BSF_INFO));\r
- FileListPtr->NextBsfInfo = NULL;\r
-\r
- remove (BSF_SYM_FILE);\r
- return EFI_SUCCESS;\r
-}\r
-\r
-VOID\r
-ParseAndUpdateComponents (\r
- IN PARSED_BSF_INFO *BsfInfo\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This function intializes the relevant global variable which is being\r
- used to store the information retrieved from INF file.\r
- \r
-Arguments:\r
-\r
- BsfInfo - A pointer to the BSF Info Structure\r
- \r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- UINT64 StringValue;\r
-\r
- while (*TokenStr != NULL && (_stricmp (*TokenStr, "COMP_NAME") != 0)) {\r
-\r
- if (_stricmp (*TokenStr, "COMP_LOC") == 0) {\r
- TokenStr++;\r
- if (_stricmp (*TokenStr, "F") == 0) {\r
- BsfInfo->LocationType = FIRST_VTF;\r
- } else if (_stricmp (*TokenStr, "S") == 0) {\r
- BsfInfo->LocationType = SECOND_VTF;\r
- } else {\r
- BsfInfo->LocationType = NONE;\r
- printf ("\nERROR: Unknown location for component %s", BsfInfo->CompName);\r
- }\r
- } else if (_stricmp (*TokenStr, "COMP_TYPE") == 0) {\r
- TokenStr++;\r
- if (AsciiStringToUint64 (*TokenStr, FALSE, &StringValue) != EFI_SUCCESS) {\r
- printf ("\nERROR: Could not read a numeric value from \"%s\".", TokenStr);\r
- return ;\r
- }\r
-\r
- BsfInfo->CompType = (UINT8) StringValue;\r
- } else if (_stricmp (*TokenStr, "COMP_VER") == 0) {\r
- TokenStr++;\r
- if (_stricmp (*TokenStr, "-") == 0) {\r
- BsfInfo->VersionPresent = FALSE;\r
- BsfInfo->MajorVer = 0;\r
- BsfInfo->MinorVer = 0;\r
- } else {\r
- BsfInfo->VersionPresent = TRUE;\r
- ConvertVersionInfo (*TokenStr, &BsfInfo->MajorVer, &BsfInfo->MinorVer);\r
- }\r
- } else if (_stricmp (*TokenStr, "COMP_BIN") == 0) {\r
- TokenStr++;\r
- strcpy (BsfInfo->CompBinName, *TokenStr);\r
- } else if (_stricmp (*TokenStr, "COMP_SYM") == 0) {\r
- TokenStr++;\r
- strcpy (BsfInfo->CompSymName, *TokenStr);\r
- } else if (_stricmp (*TokenStr, "COMP_SIZE") == 0) {\r
- TokenStr++;\r
- if (_stricmp (*TokenStr, "-") == 0) {\r
- BsfInfo->PreferredSize = FALSE;\r
- BsfInfo->CompSize = 0;\r
- } else {\r
- BsfInfo->PreferredSize = TRUE;\r
- if (AsciiStringToUint64 (*TokenStr, FALSE, &StringValue) != EFI_SUCCESS) {\r
- printf ("\nERROR: Could not read a numeric value from \"%s\".", TokenStr);\r
- return ;\r
- }\r
-\r
- BsfInfo->CompSize = (UINTN) StringValue;\r
- }\r
-\r
- } else if (_stricmp (*TokenStr, "COMP_CS") == 0) {\r
- TokenStr++;\r
- if (_stricmp (*TokenStr, "1") == 0) {\r
- BsfInfo->CheckSumRequired = 1;\r
- } else if (_stricmp (*TokenStr, "0") == 0) {\r
- BsfInfo->CheckSumRequired = 0;\r
- } else {\r
- printf ("\nERROR: Bad information in INF file about Checksum required field");\r
- }\r
- }\r
-\r
- TokenStr++;\r
- if (*TokenStr == NULL) {\r
- break;\r
- }\r
- }\r
-}\r
-\r
-VOID\r
-InitializeInFileInfo (\r
- VOID\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This function intializes the relevant global variable which is being\r
- used to store the information retrieved from INF file.\r
-\r
-Arguments:\r
-\r
- NONE\r
-\r
-Returns:\r
-\r
- NONE\r
-\r
---*/\r
-{\r
- UINTN SectionOptionFlag;\r
- UINTN SectionCompFlag;\r
-\r
- SectionOptionFlag = 0;\r
- SectionCompFlag = 0;\r
- TokenStr = OrgStrTokPtr;\r
- while (*TokenStr != NULL) {\r
- if (_stricmp (*TokenStr, "[OPTIONS]") == 0) {\r
- SectionOptionFlag = 1;\r
- SectionCompFlag = 0;\r
- }\r
-\r
- if (_stricmp (*TokenStr, "[COMPONENTS]") == 0) {\r
- if (FileListPtr == NULL) {\r
- FileListPtr = FileListHeadPtr;\r
- }\r
-\r
- SectionCompFlag = 1;\r
- SectionOptionFlag = 0;\r
- TokenStr++;\r
- }\r
-\r
- if (SectionOptionFlag) {\r
- if (_stricmp (*TokenStr, "IA32_RST_BIN") == 0) {\r
- *TokenStr++;\r
- strcpy (IA32BinFile, *TokenStr);\r
- }\r
- }\r
-\r
- if (SectionCompFlag) {\r
- if (_stricmp (*TokenStr, "COMP_NAME") == 0) {\r
- TokenStr++;\r
- strcpy (FileListPtr->CompName, *TokenStr);\r
- TokenStr++;\r
- ParseAndUpdateComponents (FileListPtr);\r
- }\r
-\r
- if (*TokenStr != NULL) {\r
- FileListPtr->NextBsfInfo = malloc (sizeof (PARSED_BSF_INFO));\r
- if (FileListPtr->NextBsfInfo == NULL) {\r
- printf ("Error: Out of memory resources.\n");\r
- break;\r
- }\r
- FileListPtr = FileListPtr->NextBsfInfo;\r
- memset (FileListPtr, 0, sizeof (PARSED_BSF_INFO));\r
- FileListPtr->NextBsfInfo = NULL;\r
- continue;\r
- } else {\r
- break;\r
- }\r
- }\r
-\r
- TokenStr++;\r
- }\r
-}\r
-\r
-EFI_STATUS\r
-GetBsfRelatedInfoFromInfFile (\r
- IN CHAR8 *FileName\r
- )\r
-/*++\r
- \r
-Routine Description:\r
-\r
- This function reads the input file, parse it and create a list of tokens\r
- which is parsed and used, to intialize the data related to BSF\r
- \r
-Arguments:\r
-\r
- FileName - FileName which needed to be read to parse data\r
-\r
-Returns:\r
- \r
- EFI_ABORTED - Error in opening file\r
- EFI_INVALID_PARAMETER - File doesn't contain any valid informations\r
- EFI_OUT_OF_RESOURCES - Malloc Failed\r
- EFI_SUCCESS - The function completed successfully \r
-\r
---*/\r
-{\r
- FILE *Fp;\r
- UINTN Index;\r
- EFI_STATUS Status;\r
-\r
- Fp = fopen (FileName, "r");\r
- if (Fp == NULL) {\r
- printf ("\nERROR: Error in opening %s file\n", FileName);\r
- return EFI_ABORTED;\r
- }\r
-\r
- ValidLineCount (Fp);\r
-\r
- if (ValidLineNum == 0) {\r
- printf ("\nERROR: File doesn't contain any valid informations");\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- TokenStr = (CHAR8 **) malloc (sizeof (UINTN) * (2 * ValidLineNum + 1));\r
-\r
- if (TokenStr == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- memset (TokenStr, 0, (sizeof (UINTN) * (2 * ValidLineNum + 1)));\r
- OrgStrTokPtr = TokenStr;\r
-\r
- for (Index = 0; Index < (2 * ValidLineNum); Index++) {\r
- *TokenStr = (CHAR8*)malloc (sizeof (CHAR8) * FILE_NAME_SIZE);\r
-\r
- if (*TokenStr == NULL) {\r
- free (OrgStrTokPtr);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- memset (*TokenStr, 0, FILE_NAME_SIZE);\r
-// free (*TokenStr);\r
- TokenStr++;\r
- }\r
-\r
- TokenStr = NULL;\r
- TokenStr = OrgStrTokPtr;\r
- fseek (Fp, 0L, SEEK_SET);\r
-\r
- Status = InitializeComps ();\r
-\r
- if (Status != EFI_SUCCESS) {\r
- free (OrgStrTokPtr);\r
- return Status;\r
- }\r
-\r
- ParseInputFile (Fp);\r
- InitializeInFileInfo ();\r
-\r
- if (Fp) {\r
- fclose (Fp);\r
- }\r
- free (OrgStrTokPtr);\r
- return EFI_SUCCESS;\r
-}\r
-\r
-VOID\r
-GetRelativeAddressInBsfBuffer (\r
- IN UINT64 Address,\r
- IN OUT UINTN *RelativeAddress,\r
- IN LOC_TYPE LocType\r
- )\r
-/*++\r
- \r
-Routine Description:\r
-\r
- This function checks for the address alignmnet for specified data boundary. In\r
- case the address is not aligned, it returns FALSE and the amount of data in \r
- terms of byte needed to adjust to get the boundary alignmnet. If data is \r
- aligned, TRUE will be returned.\r
- \r
-Arguments:\r
-\r
- Address - The address of the flash map space\r
- RelativeAddress - The relative address of the Buffer\r
- LocType - The type of the BSF\r
-\r
-\r
-Returns:\r
-\r
- \r
---*/\r
-{\r
- UINT64 TempAddress;\r
- UINT8 *LocalBuff;\r
-\r
- if (LocType == FIRST_VTF) {\r
- LocalBuff = (UINT8 *) Bsf1EndBuffer;\r
- TempAddress = Fv1EndAddress - Address;\r
- *RelativeAddress = (UINTN) LocalBuff - (UINTN) TempAddress;\r
- } else {\r
- LocalBuff = (UINT8 *) Bsf2EndBuffer;\r
- TempAddress = Fv2EndAddress - Address;\r
- *RelativeAddress = (UINTN) LocalBuff - (UINTN) TempAddress;\r
- }\r
-}\r
-\r
-EFI_STATUS\r
-GetComponentVersionInfo (\r
- IN OUT PARSED_BSF_INFO *BsfInfo,\r
- IN UINT8 *Buffer\r
- )\r
-/*++\r
-Routine Description:\r
-\r
- This function will extract the version information from File\r
- \r
-Arguments:\r
-\r
- BsfInfo - A Pointer to the BSF Info Structure\r
- Buffer - A Pointer to type UINT8 \r
-\r
-Returns:\r
- \r
- EFI_SUCCESS - The function completed successfully\r
- EFI_INVALID_PARAMETER - The parameter is invalid\r
- \r
---*/\r
-{\r
- UINT16 VersionInfo;\r
- EFI_STATUS Status;\r
-\r
- switch (BsfInfo->CompType) {\r
-\r
- case COMP_TYPE_FIT_PAL_A:\r
- case COMP_TYPE_FIT_PAL_B:\r
- memcpy (&VersionInfo, (Buffer + 8), sizeof (UINT16));\r
- BsfInfo->MajorVer = (UINT8) ((VersionInfo & 0xFF00) >> 8);\r
- BsfInfo->MinorVer = (UINT8) (VersionInfo & 0x00FF);\r
- Status = EFI_SUCCESS;\r
- break;\r
-\r
- default:\r
- Status = EFI_INVALID_PARAMETER;\r
- break;\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-BOOLEAN\r
-CheckAddressAlignment (\r
- IN UINT64 Address,\r
- IN UINT64 AlignmentData,\r
- IN OUT UINT64 *AlignAdjustByte\r
- )\r
-/*++\r
- \r
-Routine Description:\r
-\r
- This function checks for the address alignmnet for specified data boundary. In\r
- case the address is not aligned, it returns FALSE and the amount of data in \r
- terms of byte needed to adjust to get the boundary alignmnet. If data is \r
- aligned, TRUE will be returned.\r
- \r
-Arguments:\r
-\r
- Address - Pointer to buffer containing byte data of component.\r
- AlignmentData - DataSize for which address needed to be aligned\r
- AlignAdjustByte - Number of bytes needed to adjust alignment.\r
-\r
-Returns:\r
-\r
- TRUE - Address is aligned to specific data size boundary\r
- FALSE - Address in not aligned to specified data size boundary\r
- - Add/Subtract AlignAdjustByte to aling the address.\r
- \r
---*/\r
-{\r
- //\r
- // Check if the assigned address is on address boundary. If not, it will\r
- // return the remaining byte required to adjust the address for specified\r
- // address boundary\r
- //\r
- *AlignAdjustByte = (Address % AlignmentData);\r
-\r
- if (*AlignAdjustByte == 0) {\r
- return TRUE;\r
- } else {\r
- return FALSE;\r
- }\r
-}\r
-\r
-EFI_STATUS\r
-GetFitTableStartAddress (\r
- IN OUT FIT_TABLE **FitTable\r
- )\r
-/*++\r
- \r
-Routine Description:\r
-\r
- Get the FIT table start address in BSF Buffer\r
- \r
-Arguments:\r
-\r
- FitTable - Pointer to available fit table where new component can be added\r
- \r
-Returns:\r
-\r
- EFI_SUCCESS - The function completed successfully\r
- \r
---*/\r
-{\r
- UINT64 FitTableAdd;\r
- UINT64 FitTableAddOffset;\r
- UINTN RelativeAddress;\r
-\r
- //\r
- // Read the Fit Table address from Itanium-based address map.\r
- //\r
- FitTableAddOffset = Fv1EndAddress - (SIZE_IA32_RESET_VECT + SIZE_SALE_ENTRY_POINT + SIZE_FIT_TABLE_ADD);\r
-\r
- //\r
- // Translate this Itanium-based address in terms of local buffer address which\r
- // contains the image for Boot Strapped File. The relative address will be\r
- // the address of fit table BSF buffer.\r
- //\r
- GetRelativeAddressInBsfBuffer (FitTableAddOffset, &RelativeAddress, FIRST_VTF);\r
- FitTableAdd = *(UINTN *) RelativeAddress;\r
-\r
- //\r
- // The FitTableAdd is the extracted Itanium based address pointing to FIT\r
- // table. The relative address will return its actual location in BSF\r
- // Buffer.\r
- //\r
- GetRelativeAddressInBsfBuffer (FitTableAdd, &RelativeAddress, FIRST_VTF);\r
-\r
- *FitTable = (FIT_TABLE *) RelativeAddress;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-GetNextAvailableFitPtr (\r
- IN FIT_TABLE **FitPtr\r
- )\r
-/*++\r
- \r
-Routine Description:\r
-\r
- Get the FIT table address and locate the free space in fit where we can add\r
- new component. In this process, this function locates the fit table using\r
- Fit pointer in Itanium-based address map (as per Intel?Itanium(TM) SAL spec) \r
- and locate the available location in FIT table to be used by new components. \r
- If there are any Fit table which areg not being used contains ComponentType \r
- field as 0x7F. If needed we can change this and spec this out.\r
- \r
-Arguments:\r
-\r
- FitPtr - Pointer to available fit table where new component can be added\r
- \r
-Returns:\r
-\r
- EFI_SUCCESS - The function completed successfully\r
- \r
---*/\r
-{\r
- FIT_TABLE *TmpFitPtr;\r
- UINT64 FitTableAdd;\r
- UINT64 FitTableAddOffset;\r
- UINTN Index;\r
- UINTN NumFitComponents;\r
- UINTN RelativeAddress;\r
-\r
- //\r
- // Read the Fit Table address from Itanium-based address map.\r
- //\r
- FitTableAddOffset = Fv1EndAddress - (SIZE_IA32_RESET_VECT + SIZE_SALE_ENTRY_POINT + SIZE_FIT_TABLE_ADD);\r
-\r
- //\r
- // Translate this Itanium-based address in terms of local buffer address which\r
- // contains the image for Boot Strapped File. The relative address will be\r
- // the address of fit table BSF buffer.\r
- //\r
- GetRelativeAddressInBsfBuffer (FitTableAddOffset, &RelativeAddress, FIRST_VTF);\r
- FitTableAdd = *(UINTN *) RelativeAddress;\r
-\r
- //\r
- // The FitTableAdd is the extracted Itanium based address pointing to FIT\r
- // table. The relative address will return its actual location in BSF\r
- // Buffer.\r
- //\r
- GetRelativeAddressInBsfBuffer (FitTableAdd, &RelativeAddress, FIRST_VTF);\r
-\r
- TmpFitPtr = (FIT_TABLE *) RelativeAddress;\r
- NumFitComponents = TmpFitPtr->CompSize;\r
-\r
- for (Index = 0; Index < NumFitComponents; Index++) {\r
- if ((TmpFitPtr->CvAndType & FIT_TYPE_MASK) == COMP_TYPE_FIT_UNUSED) {\r
- *FitPtr = TmpFitPtr;\r
- break;\r
- }\r
-\r
- TmpFitPtr++;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-INTN\r
-CompareItems (\r
- IN const VOID *Arg1,\r
- IN const VOID *Arg2\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This function is used by qsort to sort the FIT table based upon Component\r
- Type in their incresing order.\r
-\r
-Arguments:\r
- \r
- Arg1 - Pointer to Arg1\r
- Arg2 - Pointer to Arg2\r
- \r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- if ((((FIT_TABLE *) Arg1)->CvAndType & FIT_TYPE_MASK) > (((FIT_TABLE *) Arg2)->CvAndType & FIT_TYPE_MASK)) {\r
- return 1;\r
- } else if ((((FIT_TABLE *) Arg1)->CvAndType & FIT_TYPE_MASK) < (((FIT_TABLE *) Arg2)->CvAndType & FIT_TYPE_MASK)) {\r
- return -1;\r
- } else {\r
- return 0;\r
- }\r
-}\r
-\r
-VOID\r
-SortFitTable (\r
- IN VOID\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This function is used by qsort to sort the FIT table based upon Component\r
- Type in their incresing order.\r
-\r
-Arguments:\r
- \r
- VOID\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- FIT_TABLE *FitTable;\r
- FIT_TABLE *TmpFitPtr;\r
- UINTN NumFitComponents;\r
- UINTN Index;\r
-\r
- GetFitTableStartAddress (&FitTable);\r
- TmpFitPtr = FitTable;\r
- NumFitComponents = 0;\r
- for (Index = 0; Index < FitTable->CompSize; Index++) {\r
- if ((TmpFitPtr->CvAndType & FIT_TYPE_MASK) != COMP_TYPE_FIT_UNUSED) {\r
- NumFitComponents += 1;\r
- }\r
-\r
- TmpFitPtr++;\r
- }\r
-\r
- qsort ((VOID *) FitTable, NumFitComponents, sizeof (FIT_TABLE), CompareItems);\r
-}\r
-\r
-VOID\r
-UpdateFitEntryForFwVolume (\r
- IN UINT64 Size\r
- )\r
-/*++\r
- \r
-Routine Description:\r
-\r
- This function updates the information about Firmware Volume in FIT TABLE.\r
- This FIT table has to be immediately below the PAL_A Start and it contains\r
- component type and address information. Other informations can't be\r
- created this time so we would need to fix it up..\r
- \r
- \r
-Arguments:\r
-\r
- Size - Firmware Volume Size\r
- \r
-Returns:\r
-\r
- VOID\r
-\r
---*/\r
-{\r
- FIT_TABLE *CompFitPtr;\r
- UINTN RelativeAddress;\r
-\r
- //\r
- // FV Fit table will be located at PAL_A Startaddress - 16 byte location\r
- //\r
- Bsf1LastStartAddress -= 0x10;\r
- Bsf1TotalSize += 0x10;\r
-\r
- GetRelativeAddressInBsfBuffer (Bsf1LastStartAddress, &RelativeAddress, FIRST_VTF);\r
-\r
- CompFitPtr = (FIT_TABLE *) RelativeAddress;\r
- CompFitPtr->CompAddress = Fv1BaseAddress;\r
-\r
- //\r
- // Since we don't have any information about its location in Firmware Volume,\r
- // initialize address to 0. This will be updated once Firmware Volume is\r
- // being build and its current address will be fixed in FIT table. Currently\r
- // we haven't implemented it so far and working on architectural clarafication\r
- //\r
- //\r
- // Firmware Volume Size in 16 byte block\r
- //\r
- CompFitPtr->CompSize = ((UINT32) Size) / 16;\r
-\r
- //\r
- // Since Firmware Volume does not exist by the time we create this FIT info\r
- // this should be fixedup from Firmware Volume creation tool. We haven't\r
- // worked out a method so far.\r
- //\r
- CompFitPtr->CompVersion = MAKE_VERSION (0, 0);\r
-\r
- //\r
- // Since we don't have any info about this file, we are making sure that\r
- // checksum is not needed.\r
- //\r
- CompFitPtr->CvAndType = CV_N_TYPE (0, COMP_TYPE_FIT_FV_BOOT);\r
-\r
- //\r
- // Since non BSF component will reside outside the BSF, we will not have its\r
- // binary image while creating BSF, hence we will not perform checksum at\r
- // this time. Once Firmware Volume is being created which will contain this\r
- // BSF, it will fix the FIT table for all the non BSF component and hence\r
- // checksum\r
- //\r
- CompFitPtr->CheckSum = 0;\r
-}\r
-\r
-EFI_STATUS\r
-UpdateFitEntryForNonBSFComp (\r
- IN PARSED_BSF_INFO *BsfInfo\r
- )\r
-/*++\r
- \r
-Routine Description:\r
-\r
- This function updates the information about non BSF component in FIT TABLE.\r
- Since non BSF componets binaries are not part of BSF binary, we would still\r
- be required to update its location information in Firmware Volume, inside\r
- FIT table.\r
- \r
-Arguments:\r
-\r
- BsfInfo - Pointer to BSF Info Structure\r
- \r
-Returns:\r
-\r
- EFI_ABORTED - The function fails to update the component in FIT \r
- EFI_SUCCESS - The function completed successfully\r
-\r
---*/\r
-{\r
- FIT_TABLE *CompFitPtr;\r
-\r
- //\r
- // Scan the FIT table for available space\r
- //\r
- GetNextAvailableFitPtr (&CompFitPtr);\r
- if (CompFitPtr == NULL) {\r
- printf ("\nERROR: Can't update this component in FIT");\r
- return EFI_ABORTED;\r
- }\r
-\r
- //\r
- // Since we don't have any information about its location in Firmware Volume,\r
- // initialize address to 0. This will be updated once Firmware Volume is\r
- // being build and its current address will be fixed in FIT table\r
- //\r
- CompFitPtr->CompAddress = 0;\r
- CompFitPtr->CompSize = BsfInfo->CompSize;\r
- CompFitPtr->CompVersion = MAKE_VERSION (BsfInfo->MajorVer, BsfInfo->MinorVer);\r
- CompFitPtr->CvAndType = CV_N_TYPE (BsfInfo->CheckSumRequired, BsfInfo->CompType);\r
-\r
- //\r
- // Since non BSF component will reside outside the BSF, we will not have its\r
- // binary image while creating BSF, hence we will not perform checksum at\r
- // this time. Once Firmware Volume is being created which will contain this\r
- // BSF, it will fix the FIT table for all the non BSF component and hence\r
- // checksum\r
- //\r
- CompFitPtr->CheckSum = 0;\r
-\r
- //\r
- // Fit Type is FV_BOOT which means Firmware Volume, we initialize this to base\r
- // address of Firmware Volume in which this BSF will be attached.\r
- //\r
- if ((CompFitPtr->CvAndType & 0x7F) == COMP_TYPE_FIT_FV_BOOT) {\r
- CompFitPtr->CompAddress = Fv1BaseAddress;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-//\r
-// !!!WARNING\r
-// This function is updating the SALE_ENTRY in Itanium address space as per SAL\r
-// spec. SALE_ENTRY is being read from SYM file of PEICORE. Once the PEI\r
-// CORE moves in Firmware Volume, we would need to modify this function to be\r
-// used with a API which will detect PEICORE component while building Firmware\r
-// Volume and update its entry in FIT table as well as in Itanium address space\r
-// as per Intel?Itanium(TM) SAL address space\r
-//\r
-EFI_STATUS\r
-UpdateEntryPoint (\r
- IN PARSED_BSF_INFO *BsfInfo,\r
- IN UINT64 *CompStartAddress\r
- )\r
-/*++\r
- \r
-Routine Description:\r
-\r
- This function updated the architectural entry point in IPF, SALE_ENTRY.\r
- \r
-Arguments:\r
-\r
- BsfInfo - Pointer to BSF Info Structure \r
- CompStartAddress - Pointer to Component Start Address\r
- \r
-Returns:\r
-\r
- EFI_INVALID_PARAMETER - The parameter is invalid\r
- EFI_SUCCESS - The function completed successfully\r
-\r
---*/\r
-{\r
- UINTN RelativeAddress;\r
- UINT64 SalEntryAdd;\r
- FILE *Fp;\r
- UINTN Offset;\r
-\r
- CHAR8 Buff[FILE_NAME_SIZE];\r
- CHAR8 Buff1[10];\r
- CHAR8 Buff2[10];\r
- CHAR8 OffsetStr[30];\r
- CHAR8 Buff3[10];\r
- CHAR8 Buff4[10];\r
- CHAR8 Buff5[10];\r
- CHAR8 Token[50];\r
-\r
- Fp = fopen (BsfInfo->CompSymName, "r+b");\r
-\r
- if (Fp == NULL) {\r
- printf ("\nERROR: Error in opening file");\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- while (fgets (Buff, sizeof (Buff), Fp) != NULL) {\r
- fscanf (\r
- Fp,\r
- "%s %s %s %s %s %s %s",\r
- &Buff1,\r
- &Buff2,\r
- &OffsetStr,\r
- &Buff3,\r
- &Buff4,\r
- &Buff5,\r
- &Token\r
- );\r
- if (_stricmp (Token, "SALE_ENTRY") == 0) {\r
- break;\r
- }\r
- }\r
-\r
- Offset = strtoul (OffsetStr, NULL, 16);\r
-\r
- *CompStartAddress += Offset;\r
- SalEntryAdd = Fv1EndAddress - (SIZE_IA32_RESET_VECT + SIZE_SALE_ENTRY_POINT);\r
-\r
- GetRelativeAddressInBsfBuffer (SalEntryAdd, &RelativeAddress, FIRST_VTF);\r
-\r
- memcpy ((VOID *) RelativeAddress, (VOID *) CompStartAddress, sizeof (UINT64));\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-CreateAndUpdateComponent (\r
- IN PARSED_BSF_INFO *BsfInfo\r
- )\r
-/*++\r
- \r
-Routine Description:\r
-\r
- This function reads the binary file for each components and update them\r
- in BSF Buffer as well as in FIT table. If the component is located in non\r
- BSF area, only the FIT table address will be updated\r
- \r
-Arguments:\r
-\r
- BsfInfo - Pointer to Parsed Info\r
- \r
-Returns:\r
-\r
- EFI_SUCCESS - The function completed successful\r
- EFI_ABORTED - Aborted due to one of the many reasons like:\r
- (a) Component Size greater than the specified size.\r
- (b) Error opening files.\r
- \r
- EFI_INVALID_PARAMETER Value returned from call to UpdateEntryPoint()\r
- EFI_OUT_OF_RESOURCES Memory allocation failure.\r
- \r
---*/\r
-{\r
- EFI_STATUS Status;\r
- UINT64 CompStartAddress;\r
- UINT64 FileSize;\r
- UINT64 NumByteRead;\r
- UINT64 NumAdjustByte;\r
- UINT8 *Buffer;\r
- FILE *Fp;\r
- FIT_TABLE *CompFitPtr;\r
- BOOLEAN Aligncheck;\r
-\r
- if (BsfInfo->LocationType == NONE) {\r
- UpdateFitEntryForNonBSFComp (BsfInfo);\r
- return EFI_SUCCESS;\r
- }\r
-\r
- Fp = fopen (BsfInfo->CompBinName, "r+b");\r
-\r
- if (Fp == NULL) {\r
- printf ("\nERROR: Opening file %s", BsfInfo->CompBinName);\r
- return EFI_ABORTED;\r
- }\r
-\r
- FileSize = _filelength (fileno (Fp));\r
-\r
- if ((BsfInfo->CompType == COMP_TYPE_FIT_PAL_B) || (BsfInfo->CompType == COMP_TYPE_FIT_PAL_A_SPECIFIC)) {\r
-\r
- //\r
- // BUGBUG: Satish to correct\r
- //\r
- FileSize -= SIZE_OF_PAL_HEADER;\r
- }\r
-\r
- if (BsfInfo->PreferredSize) {\r
- if (FileSize > BsfInfo->CompSize) {\r
- printf ("\nERROR: The component size is more than specified size");\r
- return EFI_ABORTED;\r
- }\r
-\r
- FileSize = BsfInfo->CompSize;\r
- }\r
-\r
- Buffer = malloc ((UINTN) FileSize);\r
- if (Buffer == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- memset (Buffer, 0, (UINTN) FileSize);\r
-\r
- if ((BsfInfo->CompType == COMP_TYPE_FIT_PAL_B) || (BsfInfo->CompType == COMP_TYPE_FIT_PAL_A_SPECIFIC)) {\r
-\r
- //\r
- // Read first 64 bytes of PAL header and use it to find version info\r
- //\r
- NumByteRead = fread (Buffer, sizeof (UINT8), SIZE_OF_PAL_HEADER, Fp);\r
-\r
- //\r
- // PAL header contains the version info. Currently, we will use the header\r
- // to read version info and then discard.\r
- //\r
- if (!BsfInfo->VersionPresent) {\r
- GetComponentVersionInfo (BsfInfo, Buffer);\r
- }\r
- }\r
-\r
- NumByteRead = fread (Buffer, sizeof (UINT8), (UINTN) FileSize, Fp);\r
- fclose (Fp);\r
-\r
- //\r
- // If it is non PAL_B component, pass the entire buffer to get the version\r
- // info and implement any specific case inside GetComponentVersionInfo.\r
- //\r
- if (BsfInfo->CompType != COMP_TYPE_FIT_PAL_B) {\r
- if (!BsfInfo->VersionPresent) {\r
- GetComponentVersionInfo (BsfInfo, Buffer);\r
- }\r
- }\r
-\r
- if (BsfInfo->LocationType == SECOND_VTF) {\r
-\r
- CompStartAddress = (Bsf2LastStartAddress - FileSize);\r
- } else {\r
- CompStartAddress = (Bsf1LastStartAddress - FileSize);\r
- }\r
-\r
- if (BsfInfo->CompType == COMP_TYPE_FIT_PAL_B) {\r
- Aligncheck = CheckAddressAlignment (CompStartAddress, 32 * 1024, &NumAdjustByte);\r
- } else {\r
- Aligncheck = CheckAddressAlignment (CompStartAddress, 8, &NumAdjustByte);\r
- }\r
-\r
- if (!Aligncheck) {\r
- CompStartAddress -= NumAdjustByte;\r
- }\r
-\r
- if (BsfInfo->LocationType == SECOND_VTF) {\r
- Bsf2LastStartAddress = CompStartAddress;\r
- Bsf2TotalSize += (UINT32) (FileSize + NumAdjustByte);\r
- Status = UpdateBsfBuffer (CompStartAddress, Buffer, FileSize, SECOND_VTF);\r
- } else {\r
- Bsf1LastStartAddress = CompStartAddress;\r
- Bsf1TotalSize += (UINT32) (FileSize + NumAdjustByte);\r
- Status = UpdateBsfBuffer (CompStartAddress, Buffer, FileSize, FIRST_VTF);\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- GetNextAvailableFitPtr (&CompFitPtr);\r
-\r
- CompFitPtr->CompAddress = CompStartAddress | IPF_CACHE_BIT;\r
- assert ((FileSize % 16) == 0);\r
- CompFitPtr->CompSize = (UINT32) (FileSize / 16);\r
- CompFitPtr->CompVersion = MAKE_VERSION (BsfInfo->MajorVer, BsfInfo->MinorVer);\r
- CompFitPtr->CvAndType = CV_N_TYPE (BsfInfo->CheckSumRequired, BsfInfo->CompType);\r
- if (BsfInfo->CheckSumRequired) {\r
- CompFitPtr->CheckSum = 0;\r
- CompFitPtr->CheckSum = CalculateChecksum8 (Buffer, (UINTN) FileSize);\r
- }\r
-\r
- //\r
- // Free the buffer\r
- //\r
- if (Buffer) {\r
- free (Buffer);\r
- }\r
-\r
- //\r
- // Update the SYM file for this component based on it's start address.\r
- //\r
- Status = UpdateSymFile (CompStartAddress, BSF_SYM_FILE, BsfInfo->CompSymName);\r
- if (EFI_ERROR (Status)) {\r
-\r
- //\r
- // At this time, SYM files are not required, so continue on error.\r
- //\r
- }\r
-\r
- // !!!!!!!!!!!!!!!!!!!!!\r
- // BUGBUG:\r
- // This part of the code is a temporary line since PEICORE is going to be inside\r
- // BSF till we work out how to determine the SALE_ENTRY through it. We will need\r
- // to clarify so many related questions\r
- // !!!!!!!!!!!!!!!!!!!!!!!\r
- if (BsfInfo->CompType == COMP_TYPE_FIT_PEICORE) {\r
- Status = UpdateEntryPoint (BsfInfo, &CompStartAddress);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-CreateAndUpdatePAL_A (\r
- IN PARSED_BSF_INFO *BsfInfo\r
- )\r
-/*++\r
- \r
-Routine Description:\r
-\r
- This function reads the binary file for each components and update them\r
- in BSF Buffer as well as FIT table\r
- \r
-Arguments:\r
-\r
- BsfInfo - Pointer to Parsed Info\r
- \r
-Returns:\r
-\r
- EFI_ABORTED - Due to one of the following reasons:\r
- (a)Error Opening File\r
- (b)The PAL_A Size is more than specified size status\r
- One of the values mentioned below returned from \r
- call to UpdateSymFile\r
- EFI_SUCCESS - The function completed successfully.\r
- EFI_INVALID_PARAMETER - One of the input parameters was invalid.\r
- EFI_ABORTED - An error occurred.UpdateSymFile\r
- EFI_OUT_OF_RESOURCES - Memory allocation failed.\r
- \r
---*/\r
-{\r
- EFI_STATUS Status;\r
- UINT64 PalStartAddress;\r
- UINT64 AbsAddress;\r
- UINTN RelativeAddress;\r
- UINT64 FileSize;\r
- UINT64 NumByteRead;\r
- UINT8 *Buffer;\r
- FILE *Fp;\r
- FIT_TABLE *PalFitPtr;\r
-\r
- Fp = fopen (BsfInfo->CompBinName, "r+b");\r
-\r
- if (Fp == NULL) {\r
- printf ("\nERROR: Opening file %s", BsfInfo->CompBinName);\r
- return EFI_ABORTED;\r
- }\r
-\r
- FileSize = _filelength (fileno (Fp));\r
- FileSize -= SIZE_OF_PAL_HEADER;\r
-\r
- if (BsfInfo->PreferredSize) {\r
- if (FileSize > BsfInfo->CompSize) {\r
- printf ("\nERROR: The PAL_A Size is more than specified size");\r
- return EFI_ABORTED;\r
- }\r
-\r
- FileSize = BsfInfo->CompSize;\r
- }\r
-\r
- Buffer = malloc ((UINTN) FileSize);\r
- if (Buffer == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- memset (Buffer, 0, (UINTN) FileSize);\r
-\r
- //\r
- // Read, Get version Info and discard the PAL header.\r
- //\r
- NumByteRead = fread (Buffer, sizeof (UINT8), SIZE_OF_PAL_HEADER, Fp);\r
-\r
- //\r
- // Extract the version info from header of PAL_A. Once done, discrad this buffer\r
- //\r
- if (!BsfInfo->VersionPresent) {\r
- GetComponentVersionInfo (BsfInfo, Buffer);\r
- }\r
-\r
- //\r
- // Read PAL_A file in a buffer\r
- //\r
- NumByteRead = fread (Buffer, sizeof (UINT8), (UINTN) FileSize, Fp);\r
- fclose (Fp);\r
-\r
- PalStartAddress = Fv1EndAddress - (SIZE_TO_OFFSET_PAL_A_END + FileSize);\r
- Bsf1LastStartAddress = PalStartAddress;\r
- Bsf1TotalSize += (UINT32) FileSize;\r
- Status = UpdateBsfBuffer (PalStartAddress, Buffer, FileSize, FIRST_VTF);\r
-\r
- AbsAddress = Fv1EndAddress - SIZE_TO_PAL_A_FIT;\r
- GetRelativeAddressInBsfBuffer (AbsAddress, &RelativeAddress, FIRST_VTF);\r
- PalFitPtr = (FIT_TABLE *) RelativeAddress;\r
- PalFitPtr->CompAddress = PalStartAddress | IPF_CACHE_BIT;\r
- assert ((FileSize % 16) == 0);\r
- PalFitPtr->CompSize = (UINT32) (FileSize / 16);\r
- PalFitPtr->CompVersion = MAKE_VERSION (BsfInfo->MajorVer, BsfInfo->MinorVer);\r
- PalFitPtr->CvAndType = CV_N_TYPE (BsfInfo->CheckSumRequired, BsfInfo->CompType);\r
- if (BsfInfo->CheckSumRequired) {\r
- PalFitPtr->CheckSum = 0;\r
- PalFitPtr->CheckSum = CalculateChecksum8 (Buffer, (UINTN) FileSize);\r
- }\r
-\r
- if (Buffer) {\r
- free (Buffer);\r
- }\r
-\r
- //\r
- // Update the SYM file for this component based on it's start address.\r
- //\r
- Status = UpdateSymFile (PalStartAddress, BSF_SYM_FILE, BsfInfo->CompSymName);\r
- if (EFI_ERROR (Status)) {\r
-\r
- //\r
- // At this time, SYM files are not required, so continue on error.\r
- //\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-CreateFitTableAndInitialize (\r
- IN PARSED_BSF_INFO *BsfInfo\r
- )\r
-/*++\r
- \r
-Routine Description:\r
-\r
- This function creates and intializes FIT table which would be used to\r
- add component info inside this\r
- \r
-Arguments:\r
-\r
- BsfInfo - Pointer to Parsed Info\r
- \r
-Returns:\r
-\r
- EFI_ABORTED - Aborted due to no size information\r
- EFI_SUCCESS - The function completed successfully\r
-\r
---*/\r
-{\r
- UINT64 PalFitTableAdd;\r
- UINT64 FitTableAdd;\r
- UINT64 FitTableAddressOffset;\r
- FIT_TABLE *PalFitPtr;\r
- FIT_TABLE *FitStartPtr;\r
- UINTN NumFitComp;\r
- UINTN RelativeAddress;\r
- UINTN Index;\r
-\r
- if (!BsfInfo->PreferredSize) {\r
- printf ("\nERROR: FIT could not be allocated becuase there are no size information");\r
- return EFI_ABORTED;\r
- }\r
-\r
- if ((BsfInfo->CompSize % 16) != 0) {\r
- printf ("\nERROR: Invalid Fit Table Size, not multiple of 16 bytes. Please correct the size");\r
- }\r
-\r
- PalFitTableAdd = Fv1EndAddress - SIZE_TO_PAL_A_FIT;\r
- GetRelativeAddressInBsfBuffer (PalFitTableAdd, &RelativeAddress, FIRST_VTF);\r
- PalFitPtr = (FIT_TABLE *) RelativeAddress;\r
- PalFitTableAdd = (PalFitPtr->CompAddress - BsfInfo->CompSize);\r
-\r
- FitTableAdd = (PalFitPtr->CompAddress - 0x10) - BsfInfo->CompSize;\r
- FitTableAddressOffset = Fv1EndAddress - (SIZE_IA32_RESET_VECT + SIZE_SALE_ENTRY_POINT + SIZE_FIT_TABLE_ADD);\r
- GetRelativeAddressInBsfBuffer (FitTableAddressOffset, &RelativeAddress, FIRST_VTF);\r
- *(UINT64 *) RelativeAddress = FitTableAdd;\r
-\r
- GetRelativeAddressInBsfBuffer (FitTableAdd, &RelativeAddress, FIRST_VTF);\r
-\r
- //\r
- // Update Fit Table with FIT Signature and FIT info in first 16 bytes.\r
- //\r
- FitStartPtr = (FIT_TABLE *) RelativeAddress;\r
-\r
- strncpy ((CHAR8 *) &FitStartPtr->CompAddress, FIT_SIGNATURE, 8); // "_FIT_ "\r
- assert (((BsfInfo->CompSize & 0x00FFFFFF) % 16) == 0);\r
- FitStartPtr->CompSize = (BsfInfo->CompSize & 0x00FFFFFF) / 16;\r
- FitStartPtr->CompVersion = MAKE_VERSION (BsfInfo->MajorVer, BsfInfo->MinorVer);\r
-\r
- //\r
- // BUGBUG: If a checksum is required, add code to checksum the FIT table. Also\r
- // determine what to do for things like the FV component that aren't easily checksummed.\r
- // The checksum will be done once we are done with all the componet update in the FIT\r
- // table\r
- //\r
- FitStartPtr->CvAndType = CV_N_TYPE (BsfInfo->CheckSumRequired, BsfInfo->CompType);\r
-\r
- NumFitComp = FitStartPtr->CompSize;\r
-\r
- FitStartPtr++;\r
-\r
- //\r
- // Intialize remaining FIT table space to UNUSED fit component type\r
- // so that when we need to create a FIT entry for a component, we can\r
- // locate a free one and use it.\r
- //\r
- for (Index = 0; Index < (NumFitComp - 1); Index++) {\r
- FitStartPtr->CvAndType = 0x7F; // Initialize all with UNUSED\r
- FitStartPtr++;\r
- }\r
-\r
- Bsf1TotalSize += BsfInfo->CompSize;\r
- Bsf1LastStartAddress -= BsfInfo->CompSize;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-WriteBsfBinary (\r
- IN CHAR8 *FileName,\r
- IN UINT32 BsfSize,\r
- IN LOC_TYPE LocType\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Write Firmware Volume from memory to a file.\r
- \r
-Arguments:\r
-\r
- FileName - Output File Name which needed to be created/\r
- BsfSize - FileSize\r
- LocType - The type of the BSF\r
- \r
-Returns:\r
-\r
- EFI_ABORTED - Returned due to one of the following resons:\r
- (a) Error Opening File\r
- (b) Failing to copy buffers\r
- EFI_SUCCESS - The fuction completes successfully\r
-\r
---*/\r
-{\r
- FILE *Fp;\r
- UINTN NumByte;\r
- VOID *BsfBuffer;\r
- UINTN RelativeAddress;\r
-\r
- if (LocType == FIRST_VTF) {\r
- GetRelativeAddressInBsfBuffer (Bsf1LastStartAddress, &RelativeAddress, FIRST_VTF);\r
- BsfBuffer = (VOID *) RelativeAddress;\r
- } else {\r
- GetRelativeAddressInBsfBuffer (Bsf2LastStartAddress, &RelativeAddress, SECOND_VTF);\r
- BsfBuffer = (VOID *) RelativeAddress;\r
- }\r
-\r
- Fp = fopen (FileName, "w+b");\r
- if (Fp == NULL) {\r
- printf ("Error in opening file %s\n", FileName);\r
- return EFI_ABORTED;\r
- }\r
-\r
- NumByte = fwrite (BsfBuffer, sizeof (UINT8), (UINTN) BsfSize, Fp);\r
-\r
- if (Fp) {\r
- fclose (Fp);\r
- }\r
-\r
- if (NumByte != (sizeof (UINT8) * BsfSize)) {\r
- printf ("\nERROR: Could not copy buffer into file %s ", FileName);\r
- return EFI_ABORTED;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-UpdateBsfBuffer (\r
- IN UINT64 StartAddress,\r
- IN UINT8 *Buffer,\r
- IN UINT64 DataSize,\r
- IN LOC_TYPE LocType\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Update the Firmware Volume Buffer with requested buffer data\r
- \r
-Arguments:\r
-\r
- StartAddress - StartAddress in buffer. This number will automatically\r
- point to right address in buffer where data needed \r
- to be updated.\r
- Buffer - Buffer pointer from data will be copied to memory mapped buffer.\r
- DataSize - Size of the data needed to be copied.\r
- LocType - The type of the BSF\r
-\r
-Returns:\r
- \r
- EFI_ABORTED - The input parameter is error\r
- EFI_SUCCESS - The function completed successfully\r
-\r
---*/\r
-{\r
- UINT8 *LocalBufferPtrToWrite;\r
-\r
- if (LocType == FIRST_VTF) {\r
- if ((StartAddress | IPF_CACHE_BIT) < (Bsf1LastStartAddress | IPF_CACHE_BIT)) {\r
- printf ("ERROR: Start Address is less then the BSF start address\n");\r
- return EFI_ABORTED;\r
- }\r
-\r
- LocalBufferPtrToWrite = (UINT8 *) Bsf1EndBuffer;\r
- LocalBufferPtrToWrite -= (Fv1EndAddress - StartAddress);\r
- } else {\r
- if ((StartAddress | IPF_CACHE_BIT) < (Bsf2LastStartAddress | IPF_CACHE_BIT)) {\r
- printf ("ERROR: Start Address is less then the BSF start address\n");\r
- return EFI_ABORTED;\r
- }\r
- LocalBufferPtrToWrite = (UINT8 *) Bsf2EndBuffer;\r
- LocalBufferPtrToWrite -= (Fv2EndAddress - StartAddress);\r
- }\r
-\r
- memcpy (LocalBufferPtrToWrite, Buffer, (UINTN) DataSize);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-UpdateFfsHeader (\r
- IN UINT32 TotalBsfSize,\r
- IN LOC_TYPE LocType \r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Update the Firmware Volume Buffer with requested buffer data\r
- \r
-Arguments:\r
-\r
- TotalBsfSize - Size of the BSF\r
- Fileoffset - The start of the file relative to the start of the FV.\r
- LocType - The type of the BSF\r
-\r
-Returns:\r
- \r
- EFI_SUCCESS - The function completed successfully\r
- EFI_INVALID_PARAMETER - The Ffs File Header Pointer is NULL\r
-\r
---*/\r
-{\r
- EFI_FFS_FILE_HEADER *FileHeader;\r
- UINTN RelativeAddress;\r
- EFI_GUID EfiFirmwareVolumeTopFileGuid = EFI_FFS_VOLUME_TOP_FILE_GUID;\r
-\r
- //\r
- // Find the BSF file header location\r
- //\r
- if (LocType == FIRST_VTF) {\r
- GetRelativeAddressInBsfBuffer (Bsf1LastStartAddress, &RelativeAddress, FIRST_VTF);\r
- FileHeader = (EFI_FFS_FILE_HEADER *) RelativeAddress;\r
- } else {\r
- GetRelativeAddressInBsfBuffer (Bsf2LastStartAddress, &RelativeAddress, SECOND_VTF);\r
- FileHeader = (EFI_FFS_FILE_HEADER *) RelativeAddress;\r
- }\r
-\r
- if (FileHeader == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // write header\r
- //\r
- memset (FileHeader, 0, sizeof (EFI_FFS_FILE_HEADER));\r
- memcpy (&FileHeader->Name, &EfiFirmwareVolumeTopFileGuid, sizeof (EFI_GUID));\r
- FileHeader->Type = EFI_FV_FILETYPE_FREEFORM;\r
- FileHeader->Attributes = FFS_ATTRIB_CHECKSUM;\r
-\r
- //\r
- // Now FileSize includes the EFI_FFS_FILE_HEADER\r
- //\r
- FileHeader->Size[0] = (UINT8) (TotalBsfSize & 0x000000FF);\r
- FileHeader->Size[1] = (UINT8) ((TotalBsfSize & 0x0000FF00) >> 8);\r
- FileHeader->Size[2] = (UINT8) ((TotalBsfSize & 0x00FF0000) >> 16);\r
-\r
- //\r
- // Fill in checksums and state, all three must be zero for the checksums.\r
- //\r
- FileHeader->IntegrityCheck.Checksum.Header = 0;\r
- FileHeader->IntegrityCheck.Checksum.File = 0;\r
- FileHeader->State = 0;\r
- FileHeader->IntegrityCheck.Checksum.Header = CalculateChecksum8 ((UINT8 *) FileHeader, sizeof (EFI_FFS_FILE_HEADER));\r
- FileHeader->IntegrityCheck.Checksum.File = CalculateChecksum8 ((UINT8 *) FileHeader, TotalBsfSize);\r
- FileHeader->State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-ValidateAddressAndSize (\r
- IN UINT64 BaseAddress,\r
- IN UINT64 FwVolSize\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Update the Firmware Volume Buffer with requested buffer data\r
- \r
-Arguments:\r
-\r
- BaseAddress - Base address for the Fw Volume.\r
- \r
- FwVolSize - Total Size of the FwVolume to which BSF will be attached..\r
-\r
-Returns:\r
- \r
- EFI_SUCCESS - The function completed successfully\r
- EFI_UNSUPPORTED - The input parameter is error\r
-\r
---*/\r
-{\r
- if ((BaseAddress >= 0) && (FwVolSize > 0x40) && ((BaseAddress + FwVolSize) % 8 == 0)) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- return EFI_UNSUPPORTED;\r
-}\r
-\r
-EFI_STATUS\r
-UpdateIA32ResetVector (\r
- IN CHAR8 *FileName,\r
- IN UINT64 FirstFwVSize\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Update the 16 byte IA32 Reset vector to maintain the compatibility\r
- \r
-Arguments:\r
-\r
- FileName - Binary file name which contains the IA32 Reset vector info..\r
- FirstFwVSize - Total Size of the FwVolume to which BSF will be attached..\r
-\r
-Returns:\r
- \r
- EFI_SUCCESS - The function completed successfully\r
- EFI_ABORTED - Invalid File Size\r
- EFI_INVALID_PARAMETER - Bad File Name\r
- EFI_OUT_OF_RESOURCES - Memory allocation failed.\r
-\r
---*/\r
-{\r
- UINT8 *Buffer;\r
- UINT8 *LocalBsfBuffer;\r
- UINTN FileSize;\r
- UINTN NumByteRead;\r
- FILE *Fp;\r
-\r
- if (!strcmp (FileName, "")) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Fp = fopen (FileName, "r+b");\r
-\r
- if (Fp == NULL) {\r
- printf ("\nERROR: Unable to open the file %s", FileName);\r
- }\r
-\r
- FileSize = _filelength (fileno (Fp));\r
-\r
- if (FileSize > 16) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- Buffer = malloc (FileSize);\r
- if (Buffer == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- NumByteRead = fread (Buffer, sizeof (UINT8), FileSize, Fp);\r
-\r
- LocalBsfBuffer = (UINT8 *) Bsf1EndBuffer - SIZE_IA32_RESET_VECT;\r
- memcpy (LocalBsfBuffer, Buffer, FileSize);\r
-\r
- if (Buffer) {\r
- free (Buffer);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-VOID\r
-CleanUpMemory (\r
- VOID\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This function cleans up any allocated buffer\r
- \r
-Arguments:\r
-\r
- NONE\r
-\r
-Returns:\r
- \r
- NONE\r
-\r
---*/\r
-{\r
- PARSED_BSF_INFO *TempFileListPtr;\r
-\r
- if (Bsf1Buffer) {\r
- free (Bsf1Buffer);\r
- }\r
-\r
- if (Bsf2Buffer) {\r
- free (Bsf2Buffer);\r
- }\r
-\r
- //\r
- // Cleanup the buffer which was allocated to read the file names from FV.INF\r
- //\r
- FileListPtr = FileListHeadPtr;\r
- while (FileListPtr != NULL) {\r
- TempFileListPtr = FileListPtr->NextBsfInfo;\r
- free (FileListPtr);\r
- FileListPtr = TempFileListPtr;\r
- }\r
-}\r
-\r
-EFI_STATUS\r
-ProcessAndCreateBsf (\r
- IN UINT64 Size\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This function process the link list created during INF file parsing\r
- and create component in BSF and updates its info in FIT table\r
- \r
-Arguments:\r
-\r
- Size - Size of the Firmware Volume of which, this BSF belongs to.\r
-\r
-Returns:\r
- \r
- EFI_UNSUPPORTED - Unknown FIT type\r
- EFI_SUCCESS - The function completed successfully \r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- PARSED_BSF_INFO *ParsedInfoPtr;\r
-\r
- Status = EFI_SUCCESS;\r
-\r
- ParsedInfoPtr = FileListHeadPtr;\r
-\r
- while (ParsedInfoPtr != NULL) {\r
-\r
- switch (ParsedInfoPtr->CompType) {\r
- //\r
- // COMP_TYPE_FIT_HEADER is a special case, hence handle it here\r
- //\r
- case COMP_TYPE_FIT_HEADER:\r
- Status = CreateFitTableAndInitialize (ParsedInfoPtr);\r
- break;\r
-\r
- //\r
- // COMP_TYPE_FIT_PAL_A is a special case, hence handle it here\r
- //\r
- case COMP_TYPE_FIT_PAL_A:\r
- Status = CreateAndUpdatePAL_A (ParsedInfoPtr);\r
-\r
- //\r
- // Based on BSF specification, once the PAL_A component has been written,\r
- // update the Firmware Volume info as FIT table. This will be utilized\r
- // to extract the Firmware Volume Start address where this BSF will be\r
- // of part.\r
- //\r
- if (Status == EFI_SUCCESS) {\r
- UpdateFitEntryForFwVolume (Size);\r
- }\r
- break;\r
-\r
- case COMP_TYPE_FIT_FV_BOOT:\r
- //\r
- // Since FIT entry for Firmware Volume has been created and it is\r
- // located at (PAL_A start - 16 byte). So we will not process any\r
- // Firmware Volume related entry from INF file\r
- //\r
- Status = EFI_SUCCESS;\r
- break;\r
-\r
- default:\r
- //\r
- // Any other component type should be handled here. This will create the\r
- // image in specified BSF and create appropriate entry about this\r
- // component in FIT Entry.\r
- //\r
- Status = CreateAndUpdateComponent (ParsedInfoPtr);\r
- if (EFI_ERROR (Status)) {\r
- printf ("ERROR: Updating %s component.\n", ParsedInfoPtr->CompName);\r
- }\r
- break;\r
- }\r
-\r
- ParsedInfoPtr = ParsedInfoPtr->NextBsfInfo;\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-GenerateBsfImage (\r
- IN UINT64 StartAddress1,\r
- IN UINT64 Size1,\r
- IN UINT64 StartAddress2,\r
- IN UINT64 Size2\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This is the main function which will be called from application.\r
-\r
-Arguments:\r
-\r
- StartAddress1 - The start address of the first BSF \r
- Size1 - The size of the first BSF\r
- StartAddress2 - The start address of the second BSF \r
- Size2 - The size of the second BSF\r
-\r
-Returns:\r
- \r
- EFI_OUT_OF_RESOURCES - Can not allocate memory\r
- The return value can be any of the values \r
- returned by the calls to following functions:\r
- GetBsfRelatedInfoFromInfFile\r
- ProcessAndCreateBsf\r
- UpdateIA32ResetVector\r
- UpdateFfsHeader\r
- WriteBsfBinary\r
- \r
---*/\r
-{\r
- EFI_STATUS Status;\r
- CHAR8 OutFileName1[FILE_NAME_SIZE];\r
- CHAR8 OutFileName2[FILE_NAME_SIZE];\r
- BOOLEAN SecondBSF;\r
-\r
- Status = EFI_UNSUPPORTED;\r
- \r
- if (StartAddress2 == 0) {\r
- SecondBSF = FALSE;\r
- } else {\r
- SecondBSF = TRUE;\r
- }\r
- Fv1BaseAddress = StartAddress1;\r
- Fv1EndAddress = Fv1BaseAddress + Size1;\r
- \r
- memset (OutFileName1, 0, FILE_NAME_SIZE);\r
- sprintf (\r
- OutFileName1,\r
- "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x-%s",\r
- Bsf1NameGuid.Data1,\r
- Bsf1NameGuid.Data2,\r
- Bsf1NameGuid.Data3,\r
- Bsf1NameGuid.Data4[0],\r
- Bsf1NameGuid.Data4[1],\r
- Bsf1NameGuid.Data4[2],\r
- Bsf1NameGuid.Data4[3],\r
- Bsf1NameGuid.Data4[4],\r
- Bsf1NameGuid.Data4[5],\r
- Bsf1NameGuid.Data4[6],\r
- Bsf1NameGuid.Data4[7],\r
- BSF_OUTPUT_FILE\r
- );\r
- \r
- //\r
- // The image buffer for the First BSF\r
- //\r
- Bsf1Buffer = malloc ((UINTN) Size1);\r
- if (Bsf1Buffer == NULL) {\r
- printf ("\nERROR: Not enough resource to create memory mapped file for Boot Strap File");\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- memset (Bsf1Buffer, 0x00, (UINTN) Size1);\r
- Bsf1EndBuffer = (UINT8 *) Bsf1Buffer + Size1;\r
- Bsf1LastStartAddress = Fv1EndAddress | IPF_CACHE_BIT;\r
- \r
- if (SecondBSF) {\r
- Fv2BaseAddress = StartAddress2;\r
- Fv2EndAddress = Fv2BaseAddress + Size2;\r
- \r
- memset (OutFileName2, 0, FILE_NAME_SIZE);\r
- sprintf (\r
- OutFileName2,\r
- "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x-%s",\r
- Bsf2NameGuid.Data1,\r
- Bsf2NameGuid.Data2,\r
- Bsf2NameGuid.Data3,\r
- Bsf2NameGuid.Data4[0],\r
- Bsf2NameGuid.Data4[1],\r
- Bsf2NameGuid.Data4[2],\r
- Bsf2NameGuid.Data4[3],\r
- Bsf2NameGuid.Data4[4],\r
- Bsf2NameGuid.Data4[5],\r
- Bsf2NameGuid.Data4[6],\r
- Bsf2NameGuid.Data4[7],\r
- BSF_OUTPUT_FILE\r
- );\r
- \r
- //\r
- // The image buffer for the second BSF\r
- //\r
- Bsf2Buffer = malloc ((UINTN) Size2);\r
- if (Bsf2Buffer == NULL) {\r
- printf ("\nERROR: Not enough resource to create memory mapped file for Boot Strap File");\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- memset (Bsf2Buffer, 0x00, (UINTN) Size2);\r
- Bsf2EndBuffer = (UINT8 *) Bsf2Buffer + Size2;\r
- Bsf2LastStartAddress = Fv2EndAddress | IPF_CACHE_BIT;\r
- }\r
- \r
- Status = GetBsfRelatedInfoFromInfFile (BSF_INPUT_FILE);\r
- if (Status != EFI_SUCCESS) {\r
- printf ("\nERROR: Error in parsing input file");\r
- CleanUpMemory ();\r
- return Status;\r
- }\r
-\r
- Status = ProcessAndCreateBsf (Size1);\r
- if (Status != EFI_SUCCESS) {\r
- CleanUpMemory ();\r
- return Status;\r
- }\r
-\r
- Status = UpdateIA32ResetVector (IA32BinFile, Bsf1TotalSize);\r
- if (Status != EFI_SUCCESS) {\r
- CleanUpMemory ();\r
- return Status;\r
- }\r
-\r
- //\r
- // Re arrange the FIT Table for Ascending order of their FIT Type..\r
- //\r
- SortFitTable ();\r
-\r
- //\r
- // All components have been updated in FIT table. Now perform the FIT table\r
- // checksum. The following function will check if Checksum is required,\r
- // if yes, then it will perform the checksum otherwise not.\r
- //\r
- CalculateFitTableChecksum ();\r
-\r
- //\r
- // Write the FFS header\r
- //\r
- Bsf1TotalSize += sizeof (EFI_FFS_FILE_HEADER);\r
- Bsf1LastStartAddress -= sizeof (EFI_FFS_FILE_HEADER);\r
- Status = UpdateFfsHeader (Bsf1TotalSize, FIRST_VTF);\r
- if (Status != EFI_SUCCESS) {\r
- CleanUpMemory ();\r
- return Status;\r
- }\r
- //\r
- // Update the BSF buffer into specified BSF binary file\r
- //\r
- Status = WriteBsfBinary (OutFileName1, Bsf1TotalSize, FIRST_VTF);\r
-\r
- if (SecondBSF) {\r
- Bsf2TotalSize += sizeof (EFI_FFS_FILE_HEADER);\r
- Bsf2LastStartAddress -= sizeof (EFI_FFS_FILE_HEADER);\r
- Status = UpdateFfsHeader (Bsf2TotalSize, SECOND_VTF);\r
- if (Status != EFI_SUCCESS) {\r
- CleanUpMemory ();\r
- return Status;\r
- }\r
- \r
- //\r
- // Update the BSF buffer into specified BSF binary file\r
- //\r
- Status = WriteBsfBinary (OutFileName2, Bsf2TotalSize, SECOND_VTF);\r
- }\r
- \r
- CleanUpMemory ();\r
- printf ("\n");\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-PeimFixupInFitTable (\r
- IN UINT64 StartAddress\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This function is an entry point to fixup SAL-E entry point.\r
-\r
-Arguments:\r
-\r
- StartAddress - StartAddress for PEIM.....\r
- \r
-Returns:\r
- \r
- EFI_SUCCESS - The function completed successfully\r
- EFI_ABORTED - Error Opening File\r
- EFI_OUT_OF_RESOURCES - System out of resources for memory allocation.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- FILE *Fp;\r
- UINT64 *StartAddressPtr;\r
- UINTN FirstFwVSize;\r
- UINTN NumByte;\r
- CHAR8 OutFileName1[FILE_NAME_SIZE];\r
-\r
- StartAddressPtr = malloc (sizeof (UINT64));\r
- if (StartAddressPtr == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- *StartAddressPtr = StartAddress;\r
-\r
- memset (OutFileName1, 0, FILE_NAME_SIZE);\r
-\r
- sprintf (\r
- OutFileName1,\r
- "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x-%s",\r
- Bsf1NameGuid.Data1,\r
- Bsf1NameGuid.Data2,\r
- Bsf1NameGuid.Data3,\r
- Bsf1NameGuid.Data4[0],\r
- Bsf1NameGuid.Data4[1],\r
- Bsf1NameGuid.Data4[2],\r
- Bsf1NameGuid.Data4[3],\r
- Bsf1NameGuid.Data4[4],\r
- Bsf1NameGuid.Data4[5],\r
- Bsf1NameGuid.Data4[6],\r
- Bsf1NameGuid.Data4[7],\r
- BSF_OUTPUT_FILE\r
- );\r
-\r
- Fp = fopen (OutFileName1, "r+b");\r
-\r
- if (Fp == NULL) {\r
- printf ("\nERROR: Error opening file ");\r
- if (StartAddressPtr) {\r
- free (StartAddressPtr);\r
- }\r
-\r
- return EFI_ABORTED;\r
- }\r
-\r
- FirstFwVSize = _filelength (fileno (Fp));\r
- fseek (Fp, (long) (FirstFwVSize - (UINTN) (SIZE_IA32_RESET_VECT + SIZE_SALE_ENTRY_POINT)), SEEK_SET);\r
- NumByte = fwrite ((VOID *) StartAddressPtr, sizeof (UINT64), 1, Fp);\r
-\r
- if (Fp) {\r
- fclose (Fp);\r
- }\r
-\r
- if (StartAddressPtr) {\r
- free (StartAddressPtr);\r
- }\r
-\r
- printf ("\n");\r
- Status = EFI_SUCCESS;\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-UpdateSymFile (\r
- IN UINT64 BaseAddress,\r
- IN CHAR8 *DestFileName,\r
- IN CHAR8 *SourceFileName\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This function adds the SYM tokens in the source file to the destination file.\r
- The SYM tokens are updated to reflect the base address.\r
-\r
-Arguments:\r
-\r
- BaseAddress - The base address for the new SYM tokens.\r
- DestFileName - The destination file.\r
- SourceFileName - The source file.\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS - The function completed successfully.\r
- EFI_INVALID_PARAMETER - One of the input parameters was invalid.\r
- EFI_ABORTED - An error occurred.\r
-\r
---*/\r
-{\r
- FILE *SourceFile;\r
- FILE *DestFile;\r
- CHAR8 Buffer[_MAX_PATH];\r
- CHAR8 Type[_MAX_PATH];\r
- CHAR8 Address[_MAX_PATH];\r
- CHAR8 Section[_MAX_PATH];\r
- CHAR8 Token[_MAX_PATH];\r
- CHAR8 BaseToken[_MAX_PATH];\r
- UINT64 TokenAddress;\r
- long StartLocation;\r
-\r
- //\r
- // Verify input parameters.\r
- //\r
- if (BaseAddress == 0 || DestFileName == NULL || SourceFileName == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // Open the source file\r
- //\r
- SourceFile = fopen (SourceFileName, "r");\r
- if (SourceFile == NULL) {\r
-\r
- //\r
- // SYM files are not required.\r
- //\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // Use the file name minus extension as the base for tokens\r
- //\r
- strcpy (BaseToken, SourceFileName);\r
- strtok (BaseToken, ". \t\n");\r
- strcat (BaseToken, "__");\r
-\r
- //\r
- // Open the destination file\r
- //\r
- DestFile = fopen (DestFileName, "a+");\r
- if (DestFile == NULL) {\r
- fclose (SourceFile);\r
- return EFI_ABORTED;\r
- }\r
-\r
- //\r
- // If this is the beginning of the output file, write the symbol format info.\r
- //\r
- if (fseek (DestFile, 0, SEEK_END) != 0) {\r
- fclose (SourceFile);\r
- fclose (DestFile);\r
- return EFI_ABORTED;\r
- }\r
-\r
- StartLocation = ftell (DestFile);\r
-\r
- if (StartLocation == 0) {\r
- fprintf (DestFile, "TEXTSYM format | V1.0\n");\r
- } else if (StartLocation == -1) {\r
- fclose (SourceFile);\r
- fclose (DestFile);\r
- return EFI_ABORTED;\r
- }\r
-\r
- //\r
- // Read the first line\r
- //\r
- if (fgets (Buffer, _MAX_PATH, SourceFile) == NULL) {\r
- Buffer[0] = 0;\r
- }\r
-\r
- //\r
- // Make sure it matches the expected sym format\r
- //\r
- if (strcmp (Buffer, "TEXTSYM format | V1.0\n")) {\r
- fclose (SourceFile);\r
- fclose (DestFile);\r
- return EFI_ABORTED;\r
- }\r
-\r
- //\r
- // Read in the file\r
- //\r
- while (feof (SourceFile) == 0) {\r
-\r
- //\r
- // Read a line\r
- //\r
- if (fscanf (SourceFile, "%s | %s | %s | %s\n", Type, Address, Section, Token) == 4) {\r
-\r
- //\r
- // Get the token address\r
- //\r
- AsciiStringToUint64 (Address, TRUE, &TokenAddress);\r
-\r
- //\r
- // Add the base address, the size of the FFS file header and the size of the peim header.\r
- //\r
- TokenAddress += BaseAddress &~IPF_CACHE_BIT;\r
-\r
- fprintf (DestFile, "%s | %016I64X | %s | %s%s\n", Type, TokenAddress, Section, BaseToken, Token);\r
- }\r
- }\r
-\r
- fclose (SourceFile);\r
- fclose (DestFile);\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-CalculateFitTableChecksum (\r
- VOID\r
- )\r
-/*++\r
- \r
-Routine Description:\r
-\r
- This function will perform byte checksum on the FIT table, if the the checksum required\r
- field is set to CheckSum required. If the checksum is not required then checksum byte\r
- will have value as 0;.\r
- \r
-Arguments:\r
-\r
- NONE\r
- \r
-Returns:\r
-\r
- Status - Value returned by call to CalculateChecksum8 ()\r
- EFI_SUCCESS - The function completed successfully\r
- \r
---*/\r
-{\r
- FIT_TABLE *TmpFitPtr;\r
- UINT64 FitTableAdd;\r
- UINT64 FitTableAddOffset;\r
- UINTN RelativeAddress;\r
- UINTN Size;\r
-\r
- //\r
- // Read the Fit Table address from Itanium-based address map.\r
- //\r
- FitTableAddOffset = Fv1EndAddress - (SIZE_IA32_RESET_VECT + SIZE_SALE_ENTRY_POINT + SIZE_FIT_TABLE_ADD);\r
-\r
- //\r
- // Translate this Itanium-based address in terms of local buffer address which\r
- // contains the image for Boot Strapped File\r
- //\r
- GetRelativeAddressInBsfBuffer (FitTableAddOffset, &RelativeAddress, FIRST_VTF);\r
- FitTableAdd = *(UINTN *) RelativeAddress;\r
-\r
- GetRelativeAddressInBsfBuffer (FitTableAdd, &RelativeAddress, FIRST_VTF);\r
-\r
- TmpFitPtr = (FIT_TABLE *) RelativeAddress;\r
-\r
- Size = TmpFitPtr->CompSize * 16;\r
-\r
- if ((TmpFitPtr->CvAndType & CHECKSUM_BIT_MASK) >> 7) {\r
- TmpFitPtr->CheckSum = 0;\r
- TmpFitPtr->CheckSum = CalculateChecksum8 ((UINT8 *) TmpFitPtr, Size);\r
- } else {\r
- TmpFitPtr->CheckSum = 0;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-VOID\r
-Version (\r
- VOID\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Displays the standard utility information to SDTOUT\r
-\r
-Arguments:\r
-\r
- None\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- printf (\r
- "%s, EFI 2.0 BootStrap File Generation Utility. Version %i.%i.\n",\r
- UTILITY_NAME,\r
- UTILITY_MAJOR_VERSION,\r
- UTILITY_MINOR_VERSION\r
- );\r
-}\r
-\r
-VOID\r
-Usage (\r
- VOID\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Displays the utility usage syntax to STDOUT\r
-\r
-Arguments:\r
-\r
- None\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- Version();\r
- \r
- printf (\r
- "\nUsage: %s -B BaseAddress -S FwVolumeSize\n",\r
- UTILITY_NAME\r
- );\r
- printf (" Where:\n");\r
- printf (" BaseAddress is the starting address of Firmware Volume where Boot\n");\r
- printf (" Strapped Image will reside.\n");\r
- printf (" FwVolumeSize is the size of Firmware Volume.\n");\r
-}\r
-\r
-EFI_STATUS\r
-main (\r
- IN UINTN argc,\r
- IN CHAR8 **argv\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This utility uses GenBsfImage.dll to build a Boot Strap File Image which will be\r
- part of firmware volume image.\r
-\r
-Arguments:\r
-\r
- argc - The count of the parameters\r
- argv - The parameters\r
-\r
-\r
-Returns:\r
-\r
- 0 - No error conditions detected.\r
- 1 - One or more of the input parameters is invalid.\r
- 2 - A resource required by the utility was unavailable. \r
- - Most commonly this will be memory allocation or file creation.\r
- 3 - GenFvImage.dll could not be loaded.\r
- 4 - Error executing the GenFvImage dll.\r
- 5 - Now this tool does not support the IA32 platform\r
-\r
---*/\r
-{\r
- UINT8 Index;\r
- UINT64 StartAddress1;\r
- UINT64 StartAddress2;\r
- UINT64 FwVolSize1;\r
- UINT64 FwVolSize2;\r
- BOOLEAN FirstRoundB;\r
- BOOLEAN FirstRoundS;\r
- EFI_STATUS Status;\r
- BOOLEAN IsIA32;\r
-\r
- //\r
- // Verify the correct number of IA32 arguments\r
- //\r
- IsIA32 = FALSE;\r
- if (argc == IA32_ARGS) {\r
- //\r
- // Now this tool is not used for IA32 platform, if it will be used in future,\r
- // the IA32-specific functions need to be updated and verified, the updating can \r
- // refer to IPF relevant functions)\r
- //\r
- printf ("ERROR: Now this tool does not support the IA32 platform!\n");\r
- printf ("ERROR: And the IA32-specific functions need to be updated and verified!\n");\r
- return 5;\r
- \r
- /*\r
- StartAddress1 = 0;\r
- IsIA32 = TRUE;\r
-\r
- //\r
- // Parse the command line arguments\r
- //\r
- for (Index = 1; Index < IA32_ARGS; Index += 2) {\r
-\r
- //\r
- // Make sure argument pair begin with - or /\r
- //\r
- if (argv[Index][0] != '-' && argv[Index][0] != '/') {\r
- Usage ();\r
- printf ("ERROR: Argument pair must begin with \"-\" or \"/\"\n");\r
- return 1;\r
- }\r
-\r
- //\r
- // Make sure argument specifier is only one letter\r
- //\r
- if (argv[Index][2] != 0) {\r
- Usage ();\r
- printf ("ERROR: Unrecognized argument \"%s\".\n", argv[Index]);\r
- return 1;\r
- }\r
-\r
- //\r
- // Determine argument to read\r
- //\r
- switch (argv[Index][1]) {\r
-\r
- case 't':\r
- case 'T':\r
- Status = AsciiStringToUint64 (argv[Index + 1], FALSE, &StartAddress1);\r
- if (Status != EFI_SUCCESS) {\r
- printf ("\nERROR: Bad start of address \"%s\"\n", argv[Index + 1]);\r
- return 1;\r
- }\r
- break;\r
-\r
- default:\r
- Usage ();\r
- printf ("Unrecognized IA32 argument \"%s\".\n", argv[Index]);\r
- IsIA32 = FALSE;\r
- break;\r
- }\r
- }\r
-\r
- if (IsIA32) {\r
- //\r
- // Call the GenBsfImage \r
- //\r
- Status = Generate32BsfImage (StartAddress1);\r
-\r
- if (EFI_ERROR(Status)) {\r
- switch (Status) {\r
-\r
- case EFI_INVALID_PARAMETER:\r
- printf ("\nERROR: Invalid parameter passed to GenBsfImage function .\n");\r
- break;\r
-\r
- case EFI_ABORTED:\r
- printf ("\nERROR: Error detected while creating the file image.\n");\r
- break;\r
-\r
- case EFI_OUT_OF_RESOURCES:\r
- printf ("\nERROR: GenBsfImage function could not allocate required resources.\n");\r
- break;\r
-\r
- case EFI_VOLUME_CORRUPTED:\r
- printf ("\nERROR: No base address was specified \n");\r
- break;\r
-\r
- default:\r
- printf ("\nERROR: GenBsfImage function returned unknown status %X.\n", Status);\r
- break;\r
- }\r
- return 2;\r
- }\r
-\r
- return 0;\r
- }\r
- */\r
- } \r
-\r
- //\r
- // Verify the correct number of arguments\r
- //\r
- if (argc == 1) {\r
- Usage();\r
- return 1;\r
- }\r
- \r
- if ((strcmp(argv[1], "-h") == 0) || (strcmp(argv[1], "--help") == 0) ||\r
- (strcmp(argv[1], "-?") == 0) || (strcmp(argv[1], "/?") == 0)) {\r
- Usage();\r
- return 1;\r
- }\r
- \r
- if ((strcmp(argv[1], "-V") == 0) || (strcmp(argv[1], "--version") == 0)) {\r
- Version();\r
- return 1;\r
- }\r
- \r
- if (argc != ONE_BSF_ARGS && argc != TWO_BSF_ARGS) {\r
- Usage ();\r
- return 1;\r
- }\r
-\r
- //\r
- // Initialize variables\r
- //\r
- StartAddress1 = 0;\r
- StartAddress2 = 0;\r
- FwVolSize1 = 0;\r
- FwVolSize2 = 0;\r
- FirstRoundB = TRUE;\r
- FirstRoundS = TRUE;\r
-\r
- //\r
- // Parse the command line arguments\r
- //\r
- for (Index = 1; Index < argc; Index += 2) {\r
-\r
- //\r
- // Make sure argument pair begin with - or /\r
- //\r
- if (argv[Index][0] != '-' && argv[Index][0] != '/') {\r
- Usage ();\r
- printf ("ERROR: Argument pair must begin with \"-\" or \"/\"\n");\r
- return 1;\r
- }\r
-\r
- //\r
- // Make sure argument specifier is only one letter\r
- //\r
- if (argv[Index][2] != 0) {\r
- Usage ();\r
- printf ("ERROR: Unrecognized argument \"%s\".\n", argv[Index]);\r
- return 1;\r
- }\r
-\r
- //\r
- // Determine argument to read\r
- //\r
- switch (argv[Index][1]) {\r
-\r
- case 'B':\r
- case 'b':\r
- if (FirstRoundB) {\r
- Status = AsciiStringToUint64 (argv[Index + 1], FALSE, &StartAddress1);\r
- FirstRoundB = FALSE;\r
- } else {\r
- Status = AsciiStringToUint64 (argv[Index + 1], FALSE, &StartAddress2);\r
- }\r
-\r
- if (Status != EFI_SUCCESS) {\r
- printf ("\nERROR: Bad start of address \"%s\"\n", argv[Index + 1]);\r
- return 1;\r
- }\r
- break;\r
-\r
- case 'S':\r
- case 's':\r
- if (FirstRoundS) {\r
- Status = AsciiStringToUint64 (argv[Index + 1], FALSE, &FwVolSize1);\r
- FirstRoundS = FALSE;\r
- } else {\r
- Status = AsciiStringToUint64 (argv[Index + 1], FALSE, &FwVolSize2);\r
- }\r
-\r
- if (Status != EFI_SUCCESS) {\r
- printf ("\nERROR: Bad size \"%s\"\n", argv[Index + 1]);\r
- return 1;\r
- }\r
- break;\r
-\r
- default:\r
- Usage ();\r
- printf ("ERROR: Unrecognized argument \"%s\".\n", argv[Index]);\r
- return 1;\r
- break;\r
- }\r
- }\r
-\r
- //\r
- // Call the GenBsfImage\r
- //\r
- Status = GenerateBsfImage (StartAddress1, FwVolSize1, StartAddress2, FwVolSize2);\r
-\r
- if (EFI_ERROR (Status)) {\r
- switch (Status) {\r
-\r
- case EFI_INVALID_PARAMETER:\r
- printf ("\nERROR: Invalid parameter passed to GenBsfImage function .\n");\r
- break;\r
-\r
- case EFI_ABORTED:\r
- printf ("\nERROR: Error detected while creating the file image.\n");\r
- break;\r
-\r
- case EFI_OUT_OF_RESOURCES:\r
- printf ("\nERROR: GenBsfImage function could not allocate required resources.\n");\r
- break;\r
-\r
- case EFI_VOLUME_CORRUPTED:\r
- printf ("\nERROR: No base address was specified \n");\r
- break;\r
-\r
- default:\r
- printf ("\nERROR: GenBsfImage function returned unknown status %X.\n", Status);\r
- break;\r
- }\r
- return 2;\r
- }\r
- return 0;\r
-}\r
-\r
-EFI_STATUS\r
-Generate32BsfImage (\r
-IN UINT64 BootFileStartAddress\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This is the main IA32 function which will be called from application.\r
- (Now this tool is not used for IA32 platform, if it will be used in future,\r
- the relative functions need to be updated, the updating can refer to IPF \r
- functions)\r
-\r
-Arguments:\r
-\r
- BootFileStartAddress - Top Address of Boot File\r
-\r
-Returns:\r
- \r
- The return value can be any of the values \r
- returned by the calls to following functions:\r
- Get32BsfRelatedInfoFromInfFile\r
- CreateBsfBuffer\r
- ProcessAndCreate32Bsf\r
- Update32FfsHeader\r
- WriteBsfBinary\r
- \r
---*/\r
-{\r
- EFI_STATUS Status;\r
- UINT32 BsfSize;\r
- CHAR8 OutFileName[FILE_NAME_SIZE];\r
-\r
- EFI_GUID BsfNameGuid = EFI_IA32_BOOT_STRAP_GUID;\r
-\r
- Status = EFI_UNSUPPORTED;\r
-\r
- memset (OutFileName, 0, FILE_NAME_SIZE);\r
-\r
- sprintf (\r
- OutFileName, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x-%s",\r
- BsfNameGuid.Data1,\r
- BsfNameGuid.Data2,\r
- BsfNameGuid.Data3,\r
- BsfNameGuid.Data4[0],\r
- BsfNameGuid.Data4[1],\r
- BsfNameGuid.Data4[2],\r
- BsfNameGuid.Data4[3],\r
- BsfNameGuid.Data4[4],\r
- BsfNameGuid.Data4[5],\r
- BsfNameGuid.Data4[6],\r
- BsfNameGuid.Data4[7],\r
- BSF_OUTPUT_FILE\r
- );\r
-\r
-\r
- Status = Get32BsfRelatedInfoFromInfFile (BSF_INPUT_FILE);\r
-\r
- if (Status != EFI_SUCCESS) {\r
- printf ("\nERROR: Error in parsing input file");\r
- CleanUpMemory ();\r
- return Status;\r
- }\r
-\r
- if (GetTotal32BsfSize (&BsfSize) == EFI_SUCCESS) {\r
- Bsf1Buffer = malloc ((UINTN) BsfSize);\r
- if (Bsf1Buffer == NULL) {\r
- printf ("\nERROR: Not enough resource to create memory mapped file for Boot Strap File");\r
- CleanUpMemory ();\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- memset (Bsf1Buffer, 0x00, (UINTN) BsfSize);\r
- } else {\r
- printf ("\nERROR: Could not get BSF size.");\r
- CleanUpMemory ();\r
- return EFI_ABORTED;\r
- }\r
-\r
- //\r
- //VTF must align properly\r
- //\r
- Bsf1LastStartAddress = BootFileStartAddress - BsfSize;\r
- Bsf1LastStartAddress = Bsf1LastStartAddress & -8;\r
- BsfSize = (UINT32)BootFileStartAddress - (UINT32)Bsf1LastStartAddress;\r
- Bsf1LastStartAddress = BsfSize;\r
- BufferToTop = (UINT32)BootFileStartAddress - BsfSize;\r
-\r
- Status = ProcessAndCreate32Bsf (BsfSize);\r
-\r
- if (Status != EFI_SUCCESS) {\r
- CleanUpMemory();\r
- return Status;\r
- }\r
-\r
- //\r
- // Write the FFS header\r
- //\r
- Status = Update32FfsHeader (BsfSize);\r
-\r
- if (Status != EFI_SUCCESS) {\r
- CleanUpMemory();\r
- return Status;\r
- }\r
-\r
- // \r
- // Calculate the Start address of this BSF\r
- //\r
- Bsf1Buffer = (UINT8 *)Bsf1Buffer + Bsf1LastStartAddress;\r
-\r
- //\r
- // Update the BSF buffer into specified BSF binary file\r
- //\r
- Status = WriteBsfBinary (OutFileName, BsfSize - (UINT32)Bsf1LastStartAddress, FIRST_VTF);\r
-\r
- if (Status != EFI_SUCCESS) {\r
- CleanUpMemory();\r
- return Status;\r
- }\r
-\r
- Status = Write32SoftFit (IA32_SOFT_FIT, FileListHeadPtr);\r
-\r
- if (Status != EFI_SUCCESS) {\r
- CleanUpMemory();\r
- return Status;\r
- }\r
- \r
- CleanUpMemory ();\r
- printf ("\n"); \r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-GetTotal32BsfSize(\r
- IN UINT32 *BsfSize \r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This function calculates total size for IA32 BSF which would be needed to create\r
- the buffer. This will be done using Passed Info link list and looking for the\r
- size of the components which belong to BSF. The addtional file header is accounted.\r
-\r
-Arguments:\r
-\r
- BSFSize - Pointer to the size of IA32 BSF \r
-\r
-Returns:\r
-\r
- EFI_ABORTED - Returned due to one of the following resons:\r
- (a) Error Opening File\r
- EFI_SUCCESS - The fuction completes successfully\r
-\r
---*/\r
-{\r
- PARSED_BSF_INFO *BsfInfo;\r
- FILE *Fp;\r
- UINT32 Alignment;\r
-\r
- *BsfSize = 0;\r
- Alignment = 0;\r
- \r
- BsfInfo = FileListHeadPtr;\r
-\r
- while (BsfInfo != NULL) {\r
- if (BsfInfo->LocationType != SECOND_VTF) {\r
-\r
- if ( BsfInfo->Align ) {\r
- //\r
- // Create additional align to compensate for component boundary requirements\r
- //\r
- Alignment = 1 << BsfInfo->Align;\r
- *BsfSize += Alignment;\r
- }\r
- \r
- if (BsfInfo->PreferredSize) {\r
- *BsfSize += BsfInfo->CompSize;\r
- } else {\r
- Fp = fopen (BsfInfo->CompBinName,"r+b");\r
-\r
- if (Fp == NULL) {\r
- printf ("\nERROR: Error in opening file %s", BsfInfo->CompBinName);\r
- return EFI_ABORTED;\r
- }\r
- \r
- *BsfSize += _filelength (fileno (Fp));\r
- \r
- if (Fp) {\r
- fclose (Fp);\r
- }\r
- } \r
- }\r
- BsfInfo = BsfInfo->NextBsfInfo;\r
- }\r
-\r
- //\r
- // Add file header space\r
- //\r
- *BsfSize += sizeof (EFI_FFS_FILE_HEADER);\r
-\r
- //\r
- // Create additional to IA32 Seccore section header\r
- //\r
- *BsfSize += sizeof (EFI_COMMON_SECTION_HEADER);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-ProcessAndCreate32Bsf (\r
- IN UINT64 Size\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This function process the link list created during INF file parsing\r
- and create component in IA32 BSF\r
- \r
-Arguments:\r
-\r
- Size - Size of the Firmware Volume of which, this BSF belongs to.\r
-\r
-Returns:\r
- \r
- EFI_UNSUPPORTED - Unknown component type\r
- EFI_SUCCESS - The function completed successfully \r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- PARSED_BSF_INFO *ParsedInfoPtr;\r
-\r
- Status = EFI_SUCCESS;\r
-\r
- ParsedInfoPtr = FileListHeadPtr;\r
-\r
- while (ParsedInfoPtr != NULL) {\r
- \r
- switch (ParsedInfoPtr->CompType) {\r
-\r
- case COMP_TYPE_SECCORE:\r
- Status = CreateAndUpdateSeccore (ParsedInfoPtr);\r
- break;\r
-\r
- default:\r
- //\r
- // Any other component type should be handled here. This will create the\r
- // image in specified BSF\r
- //\r
- Status = CreateAndUpdate32Component (ParsedInfoPtr);\r
- if (EFI_ERROR(Status)) {\r
- printf ("ERROR: Updating %s component.\n", ParsedInfoPtr->CompName);\r
- }\r
- break;\r
- }\r
-\r
- ParsedInfoPtr = ParsedInfoPtr->NextBsfInfo;\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-CreateAndUpdateSeccore (\r
- IN PARSED_BSF_INFO *BsfInfo\r
- )\r
-/*++\r
- \r
-Routine Description:\r
-\r
- This function reads the binary file for seccore and update them\r
- in IA32 BSF Buffer\r
- \r
-Arguments:\r
-\r
- BsfInfo - Pointer to Parsed Info\r
- \r
-Returns:\r
-\r
- EFI_ABORTED - Due to one of the following reasons:\r
- (a)Error Opening File\r
- (b)The PAL_A Size is more than specified size status\r
- One of the values mentioned below returned from \r
- call to UpdateSymFile\r
- EFI_SUCCESS - The function completed successfully.\r
- EFI_INVALID_PARAMETER - One of the input parameters was invalid.\r
- EFI_ABORTED - An error occurred.UpdateSymFile\r
- EFI_OUT_OF_RESOURCES - Memory allocation failed.\r
- \r
---*/\r
-{\r
- UINT8 *SecbinStartAddress;\r
- UINT8 *SecfileStartAddress;\r
- UINT32 FileSize;\r
- UINT64 NumByteRead;\r
- UINT8 *Buffer;\r
- FILE *Fp;\r
- UINT64 TotalLength;\r
- EFI_COMMON_SECTION_HEADER *SecHeader;\r
-\r
- Fp = fopen (BsfInfo->CompBinName, "r+b");\r
-\r
- if (Fp == NULL) {\r
- printf ("\nERROR: Opening file %s", BsfInfo->CompBinName);\r
- return EFI_ABORTED;\r
- }\r
-\r
- FileSize = _filelength (fileno (Fp));\r
-\r
- if (BsfInfo->PreferredSize) {\r
- if (FileSize > BsfInfo->CompSize) {\r
- printf("\nERROR: The Seccore Size is more than specified size");\r
- return EFI_ABORTED;\r
- }\r
-\r
- FileSize = BsfInfo->CompSize;\r
- }\r
-\r
- BsfInfo->CompSize = FileSize;\r
-\r
- Buffer = malloc ((UINTN) FileSize);\r
- if (Buffer == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- memset (Buffer, 0, (UINTN) FileSize);\r
-\r
- //\r
- // Read seccore in a buffer\r
- //\r
- NumByteRead = fread (Buffer, sizeof (UINT8), (UINTN) FileSize, Fp);\r
- fclose (Fp);\r
-\r
- SecfileStartAddress = (UINT8 *) Bsf1Buffer + Bsf1LastStartAddress - FileSize - sizeof (EFI_COMMON_SECTION_HEADER); \r
- if (SecfileStartAddress == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- SecbinStartAddress = SecfileStartAddress + sizeof (EFI_COMMON_SECTION_HEADER);\r
-\r
- BsfInfo->CompPreferredAddress = Bsf1LastStartAddress - FileSize + BufferToTop;\r
-\r
- //\r
- // write section header\r
- //\r
- memset (SecfileStartAddress, 0, sizeof (EFI_COMMON_SECTION_HEADER));\r
- SecHeader = (EFI_COMMON_SECTION_HEADER *) SecfileStartAddress;\r
- SecHeader->Type = EFI_SECTION_RAW;\r
- TotalLength = sizeof (EFI_COMMON_SECTION_HEADER) + (UINT64) FileSize;\r
- memcpy (SecHeader->Size, &TotalLength, 3);\r
-\r
- //\r
- // write seccore\r
- //\r
- memcpy (SecbinStartAddress, Buffer, (UINTN) FileSize);\r
-\r
- if (Buffer) {\r
- free (Buffer);\r
- }\r
-\r
- Bsf1LastStartAddress = SecfileStartAddress - (UINT8 *) Bsf1Buffer;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-CreateAndUpdate32Component (\r
- IN PARSED_BSF_INFO *BsfInfo\r
- )\r
-/*++\r
- \r
-Routine Description:\r
-\r
- This function reads the binary file for each components. Add it at aligned address.\r
- \r
-Arguments:\r
-\r
- BsfInfo - Pointer to Parsed Info\r
- \r
-Returns:\r
-\r
- EFI_SUCCESS - The function completed successful\r
- EFI_ABORTED - Aborted due to one of the many reasons like:\r
- (a) Component Size greater than the specified size.\r
- (b) Error opening files.\r
- EFI_INVALID_PARAMETER - Value returned from call to UpdateEntryPoint()\r
- EFI_OUT_OF_RESOURCES - Memory allocation failed.\r
- \r
---*/\r
-{\r
- UINT64 CompStartAddress;\r
- UINT32 FileSize;\r
- UINT64 NumByteRead;\r
- UINT8 *Buffer;\r
- FILE *Fp;\r
- UINT8 *LocalBufferPtrToWrite;\r
- UINT64 Alignment;\r
-\r
- Fp = fopen (BsfInfo->CompBinName, "r+b");\r
-\r
- if (Fp == NULL) {\r
- printf("\nERROR: Opening file %s", BsfInfo->CompBinName);\r
- return EFI_ABORTED;\r
- }\r
-\r
- FileSize = _filelength (fileno (Fp));\r
-\r
- if (BsfInfo->PreferredSize) {\r
- if (FileSize > BsfInfo->CompSize) {\r
- printf("\nERROR: The component size is more than specified size");\r
- return EFI_ABORTED;\r
- }\r
- FileSize = BsfInfo->CompSize;\r
- }\r
- BsfInfo->CompSize = FileSize;\r
-\r
- Buffer = malloc ((UINTN) FileSize);\r
- if (Buffer == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- memset (Buffer,0, (UINTN) FileSize);\r
-\r
- NumByteRead = fread (Buffer, sizeof (UINT8), (UINTN) FileSize, Fp);\r
- fclose (Fp);\r
-\r
- CompStartAddress = Bsf1LastStartAddress - FileSize + BufferToTop;\r
-\r
- if (BsfInfo->Align) {\r
- //\r
- // Create additional align to compensate for component boundary requirements\r
- //\r
- Alignment = 0 - (1 << BsfInfo->Align);\r
- CompStartAddress = CompStartAddress & Alignment; \r
- }\r
-\r
- BsfInfo->CompPreferredAddress = CompStartAddress;\r
-\r
- //\r
- // write bin\r
- //\r
- LocalBufferPtrToWrite = (UINT8 *) Bsf1Buffer;\r
- Bsf1LastStartAddress = CompStartAddress - BufferToTop;\r
- LocalBufferPtrToWrite += Bsf1LastStartAddress;\r
- memcpy (LocalBufferPtrToWrite, Buffer, (UINTN) FileSize); \r
- Bsf1LastStartAddress = CompStartAddress - BufferToTop;\r
-\r
- //\r
- // Free the buffer\r
- //\r
- if (Buffer) {\r
- free (Buffer);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-Update32FfsHeader(\r
- IN UINT32 BsfSize\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Update the Firmware Volume Buffer with requested buffer data\r
-\r
-Arguments:\r
-\r
- BsfSize - Size of the IA32 BSF\r
-\r
-Returns:\r
- \r
- EFI_SUCCESS - The function completed successfully\r
- EFI_INVALID_PARAMETER - The Ffs File Header Pointer is NULL\r
-\r
---*/\r
-{\r
- EFI_FFS_FILE_HEADER *FileHeader;\r
- UINT32 TotalBsfSize;\r
- EFI_GUID EfiFirmwareVolumeTopFileGuid = EFI_FFS_VOLUME_TOP_FILE_GUID;\r
-\r
- \r
- //\r
- // Find the BSF file header location, the bsf file must be 8 bytes aligned\r
- //\r
- Bsf1LastStartAddress -= sizeof (EFI_FFS_FILE_HEADER);\r
- Bsf1LastStartAddress += BufferToTop;\r
- Bsf1LastStartAddress = Bsf1LastStartAddress & -8;\r
- Bsf1LastStartAddress -= BufferToTop;\r
- FileHeader = (EFI_FFS_FILE_HEADER*)((UINT8*)Bsf1Buffer + Bsf1LastStartAddress);\r
-\r
- if (FileHeader == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // write header\r
- //\r
- memset (FileHeader, 0, sizeof(EFI_FFS_FILE_HEADER));\r
- memcpy (&FileHeader->Name, &EfiFirmwareVolumeTopFileGuid, sizeof (EFI_GUID));\r
-\r
- FileHeader->Type = EFI_FV_FILETYPE_FREEFORM;\r
- FileHeader->Attributes = FFS_ATTRIB_CHECKSUM;\r
-\r
- //\r
- // Now FileSize includes the EFI_FFS_FILE_HEADER\r
- //\r
- TotalBsfSize = BsfSize - (UINT32)Bsf1LastStartAddress;\r
- FileHeader->Size[0] = (UINT8) (TotalBsfSize & 0x000000FF);\r
- FileHeader->Size[1] = (UINT8) ((TotalBsfSize & 0x0000FF00) >> 8);\r
- FileHeader->Size[2] = (UINT8) ((TotalBsfSize & 0x00FF0000) >> 16);\r
-\r
- //\r
- // Fill in checksums and state, all three must be zero for the checksums.\r
- //\r
- FileHeader->IntegrityCheck.Checksum.Header = 0;\r
- FileHeader->IntegrityCheck.Checksum.File = 0;\r
- FileHeader->State = 0;\r
- FileHeader->IntegrityCheck.Checksum.Header = CalculateChecksum8 ((UINT8*) FileHeader, sizeof (EFI_FFS_FILE_HEADER));\r
- FileHeader->IntegrityCheck.Checksum.File = CalculateChecksum8 ((UINT8*) FileHeader, TotalBsfSize);\r
- FileHeader->State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-Get32BsfRelatedInfoFromInfFile (\r
- IN CHAR8 *FileName\r
- )\r
-/*++\r
- \r
-Routine Description:\r
-\r
- This function reads the input file, parse it and create a list of tokens\r
- which is parsed and used, to intialize the data related to IA32 BSF\r
- \r
-Arguments:\r
-\r
- FileName FileName which needed to be read to parse data\r
-\r
-Returns:\r
- \r
- EFI_ABORTED Error in opening file\r
- EFI_INVALID_PARAMETER File doesn't contain any valid informations\r
- EFI_OUT_OF_RESOURCES Malloc Failed\r
- EFI_SUCCESS The function completed successfully \r
-\r
---*/\r
-{\r
- FILE *Fp;\r
- UINTN Index;\r
- EFI_STATUS Status;\r
- \r
- Fp = fopen (FileName, "r");\r
- if (Fp == NULL) {\r
- printf ("\nERROR: Error in opening %s file\n", FileName);\r
- return EFI_ABORTED;\r
- }\r
- \r
- ValidLineCount (Fp);\r
- \r
- if (ValidLineNum == 0) {\r
- printf ("\nERROR: File doesn't contain any valid informations");\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- \r
- TokenStr = (CHAR8 **)malloc (sizeof (UINTN) * (2 * ValidLineNum + 1));\r
-\r
- if (TokenStr == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- memset (TokenStr, 0, (sizeof (UINTN) * (2 * ValidLineNum + 1)));\r
- OrgStrTokPtr = TokenStr;\r
- \r
- for (Index = 0; Index < (2 * ValidLineNum); Index++) {\r
- *TokenStr = (CHAR8 *)malloc (sizeof (CHAR8) * FILE_NAME_SIZE);\r
-\r
- if (*TokenStr == NULL) {\r
- free (OrgStrTokPtr);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- \r
- memset (*TokenStr, 0, FILE_NAME_SIZE);\r
-// free (*TokenStr);\r
- TokenStr++;\r
- }\r
- \r
- TokenStr = NULL;\r
- TokenStr = OrgStrTokPtr;\r
- fseek (Fp, 0L, SEEK_SET);\r
- \r
- Status = InitializeComps();\r
-\r
- if (Status != EFI_SUCCESS) {\r
- free (TokenStr);\r
- return Status;\r
- }\r
- ParseInputFile (Fp);\r
- Initialize32InFileInfo ();\r
- \r
- if (Fp) {\r
- fclose (Fp);\r
- }\r
- free (TokenStr);\r
- return EFI_SUCCESS;\r
-}\r
-\r
-VOID\r
-Initialize32InFileInfo (\r
- VOID \r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This function intializes the relevant global variable which is being\r
- used to store the information retrieved from IA32 INF file.\r
-\r
-Arguments:\r
-\r
- NONE\r
-\r
-Returns:\r
-\r
- NONE\r
-\r
---*/\r
-{\r
- UINTN SectionOptionFlag;\r
- UINTN SectionCompFlag;\r
-\r
- SectionOptionFlag =0 ;\r
- SectionCompFlag = 0; \r
- TokenStr = OrgStrTokPtr;\r
- while (*TokenStr != NULL) {\r
- if (_stricmp (*TokenStr, "[OPTIONS]") == 0) {\r
- SectionOptionFlag = 1;\r
- SectionCompFlag = 0;\r
- }\r
- \r
- if (_stricmp (*TokenStr, "[COMPONENTS]") == 0) {\r
- if (FileListPtr == NULL) {\r
- FileListPtr = FileListHeadPtr;\r
- }\r
- \r
- SectionCompFlag = 1;\r
- SectionOptionFlag = 0;\r
- TokenStr++;\r
- }\r
- \r
- if (SectionOptionFlag) {\r
- if (_stricmp (*TokenStr, "IA32_RST_BIN") == 0) {\r
- *TokenStr++;\r
- strcpy (IA32BinFile, *TokenStr);\r
- }\r
- }\r
- \r
- if (SectionCompFlag) {\r
- if (_stricmp (*TokenStr, "COMP_NAME") == 0) {\r
- TokenStr++;\r
- strcpy (FileListPtr->CompName, *TokenStr);\r
- TokenStr++;\r
- ParseAndUpdate32Components (FileListPtr);\r
- }\r
- \r
- if (*TokenStr != NULL) {\r
- FileListPtr->NextBsfInfo = malloc (sizeof (PARSED_BSF_INFO));\r
- if (FileListPtr->NextBsfInfo == NULL) {\r
- printf ("Error: Out of memory resources.\n");\r
- break;\r
- }\r
- FileListPtr = FileListPtr->NextBsfInfo;\r
- memset (FileListPtr, 0, sizeof(PARSED_BSF_INFO));\r
- FileListPtr->NextBsfInfo = NULL;\r
- continue;\r
- } else {\r
- break;\r
- }\r
- }\r
- \r
- TokenStr++;\r
- }\r
-}\r
-\r
-VOID \r
-ParseAndUpdate32Components (\r
- IN PARSED_BSF_INFO *BsfInfo\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This function intializes the relevant global variable which is being\r
- used to store the information retrieved from INF file.\r
- \r
-Arguments:\r
-\r
- BsfInfo - A pointer to the BSF Info Structure\r
- \r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- UINT64 StringValue;\r
- UINT64 AlignStringValue;\r
-\r
- while (*TokenStr != NULL && (_stricmp (*TokenStr, "COMP_NAME") != 0)) {\r
-\r
- if (_stricmp (*TokenStr, "COMP_LOC") == 0) {\r
- TokenStr++;\r
- if (_stricmp (*TokenStr, "B") == 0) {\r
- BsfInfo->LocationType = FIRST_VTF;\r
- } else if (_stricmp (*TokenStr, "N") == 0) {\r
- BsfInfo->LocationType = SECOND_VTF;\r
- } else {\r
- BsfInfo->LocationType = NONE;\r
- printf ("\nERROR: Unknown location for component %s", BsfInfo->CompName);\r
- }\r
- } else if (_stricmp (*TokenStr, "COMP_TYPE") == 0) {\r
- TokenStr++;\r
- if (AsciiStringToUint64 (*TokenStr, FALSE, &StringValue) != EFI_SUCCESS) {\r
- printf ("\nERROR: Could not read a numeric value from \"%s\".", TokenStr); \r
- return;\r
- }\r
- BsfInfo->CompType = (UINT8) StringValue;\r
- } else if (_stricmp (*TokenStr, "COMP_VER") == 0) {\r
- TokenStr++;\r
- if (_stricmp (*TokenStr, "-") == 0) {\r
- BsfInfo->VersionPresent = FALSE;\r
- BsfInfo->MajorVer = 0;\r
- BsfInfo->MinorVer = 0;\r
- } else {\r
- BsfInfo->VersionPresent = TRUE;\r
- ConvertVersionInfo (*TokenStr, &BsfInfo->MajorVer, &BsfInfo->MinorVer);\r
- }\r
- } else if (_stricmp (*TokenStr, "COMP_BIN") == 0) {\r
- TokenStr++;\r
- strcpy (BsfInfo->CompBinName, *TokenStr);\r
- } else if (_stricmp (*TokenStr, "COMP_SYM") == 0) {\r
- TokenStr++;\r
- strcpy (BsfInfo->CompSymName, *TokenStr);\r
- } else if (_stricmp (*TokenStr, "COMP_SIZE") == 0) {\r
- TokenStr++;\r
- if (_stricmp (*TokenStr, "-") == 0) {\r
- BsfInfo->PreferredSize = FALSE;\r
- BsfInfo->CompSize = 0;\r
- } else {\r
- BsfInfo->PreferredSize = TRUE;\r
- if (AsciiStringToUint64 (*TokenStr, FALSE, &StringValue) != EFI_SUCCESS) {\r
- printf ("\nERROR: Could not read a numeric value from \"%s\".", TokenStr); \r
- return;\r
- }\r
- BsfInfo->CompSize = (UINTN) StringValue;\r
- }\r
-\r
- } else if (_stricmp (*TokenStr, "COMP_CS") == 0) {\r
- TokenStr++;\r
- if (_stricmp (*TokenStr, "1") == 0) {\r
- BsfInfo->CheckSumRequired = 1;\r
- } else if (_stricmp (*TokenStr, "0") == 0) {\r
- BsfInfo->CheckSumRequired = 0;\r
- } else {\r
- printf ("\nERROR: Bad information in INF file about Checksum required field");\r
- }\r
- } else if (_stricmp (*TokenStr, "COMP_ALIGN") == 0) {\r
- TokenStr++;\r
- if (AsciiStringToUint64 (*TokenStr, FALSE, &AlignStringValue) != EFI_SUCCESS) {\r
- printf ("\nERROR: Could not read a numeric value from \"%s\".", TokenStr); \r
- return;\r
- }\r
- if (AlignStringValue >= 0) {\r
- BsfInfo->Align = (UINT32) AlignStringValue;\r
- } else {\r
- printf ("\nERROR: invalid align \"%s\".", AlignStringValue); \r
- return;\r
- }\r
- }\r
- TokenStr++;\r
- if (*TokenStr == NULL) {\r
- break;\r
- }\r
- }\r
-}\r
-\r
-EFI_STATUS\r
-Write32SoftFit(\r
- IN CHAR8 *FileName,\r
- IN PARSED_BSF_INFO *BsfInfo\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Write IA32 Firmware Volume component address from memory to a file.\r
- \r
-Arguments:\r
-\r
- FileName Output File Name which needed to be created/\r
- BsfInfo Parsed info link\r
- \r
-Returns:\r
-\r
- EFI_ABORTED - Returned due to one of the following resons:\r
- (a) Error Opening File\r
- (b) Failing to copy buffers\r
- EFI_SUCCESS - The function completes successfully\r
-\r
---*/\r
-{\r
- FILE *Fp;\r
-\r
- Fp = fopen (FileName, "w+t");\r
- if (Fp == NULL) {\r
- printf ("Error in opening file %s\n", FileName);\r
- return EFI_ABORTED;\r
- }\r
-\r
- while (BsfInfo != NULL) {\r
- if (strlen (BsfInfo->CompName) != 0) {\r
- fprintf (Fp, "\n%s\n", BsfInfo->CompName);\r
- } else {\r
- fprintf (Fp, "\n%s\n", "Name not available"); \r
- }\r
- \r
- fprintf (Fp, "%d\n", BsfInfo->CompPreferredAddress);\r
- fprintf (Fp, "%d\n", BsfInfo->CompSize);\r
- fprintf (Fp, "%d\n", BsfInfo->Align);\r
- \r
- BsfInfo = BsfInfo->NextBsfInfo;\r
- }\r
-\r
- if (Fp) {\r
- fclose (Fp);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r