From 71ea530c3742ec7a02058a9fab509a4c7a00886f Mon Sep 17 00:00:00 2001 From: bbahnsen Date: Mon, 30 Oct 2006 16:43:48 +0000 Subject: [PATCH] Adding tools for IPF development. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1865 6f19259b-4bc3-4df7-8a09-765794883524 --- Tools/CCode/Source/GenBsfFixup/GenBsfFixup.c | 490 +++ Tools/CCode/Source/GenBsfFixup/build.xml | 127 + Tools/CCode/Source/GenBsfImage/GenBsfImage.c | 3519 ++++++++++++++++++ Tools/CCode/Source/GenBsfImage/GenBsfImage.h | 633 ++++ Tools/CCode/Source/GenBsfImage/build.xml | 126 + 5 files changed, 4895 insertions(+) create mode 100644 Tools/CCode/Source/GenBsfFixup/GenBsfFixup.c create mode 100644 Tools/CCode/Source/GenBsfFixup/build.xml create mode 100644 Tools/CCode/Source/GenBsfImage/GenBsfImage.c create mode 100644 Tools/CCode/Source/GenBsfImage/GenBsfImage.h create mode 100644 Tools/CCode/Source/GenBsfImage/build.xml diff --git a/Tools/CCode/Source/GenBsfFixup/GenBsfFixup.c b/Tools/CCode/Source/GenBsfFixup/GenBsfFixup.c new file mode 100644 index 0000000000..462f97fa83 --- /dev/null +++ b/Tools/CCode/Source/GenBsfFixup/GenBsfFixup.c @@ -0,0 +1,490 @@ +/*++ + +Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved +This software and associated documentation (if any) is furnished +under a license and may only be used or copied in accordance +with the terms of the license. Except as permitted by such +license, no part of this software or documentation may be +reproduced, stored in a retrieval system, or transmitted in any +form or by any means without the express written consent of +Intel Corporation. + + +Module Name: + + GenBsfFixup.c + +Abstract: + + Utility to Fixup the SEC component for IA32. This is an + interim tool in place of the full GenBsfImage support for + IA32. + This tool supports the Synch3 update + +--*/ + +#include "BaseTypes.h" +#include "UefiBaseTypes.h" +#include "EfiImage.h" +#include "FirmwareVolumeHeader.h" +#include "FirmwareVolumeImageFormat.h" +#include "ParseInf.h" +#include "CommonLib.h" +#include "FirmwareFileSystem.h" +#include "FvLib.h" +#include +#include +#include +#include + +// +// BugBug -- this port to the new FFS is really weird. +// A lot of the file-header stuff has been ported, but +// not the section information. +// +#define TOOLVERSION "0.1" + +UINT32 gFixup; + +UINT32 +GetOccupiedSize ( + IN UINT32 ActualSize, + IN UINT32 Alignment + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + ActualSize - GC_TODO: add argument description + Alignment - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +{ + UINT32 OccupiedSize; + + OccupiedSize = ActualSize; + while ((OccupiedSize & (Alignment - 1)) != 0) { + OccupiedSize++; + } + + return OccupiedSize; +} + +int +ReadHeader ( + FILE *In, + UINT32 *FvSize + ) +/*++ + +Routine Description: + + Reads in Firmware Volume information from the volume header file. + +Arguments: + + In: Firmware Volume header file to read from + FvSize: Size of Firmware Volume + +Returns: + + int: Number of bytes read + +--*/ +{ + EFI_FIRMWARE_VOLUME_HEADER VolumeHeader; + EFI_FV_BLOCK_MAP_ENTRY BlockMap; + INT32 SigTemp[2]; + INT32 Invert; + INT32 bytesread; + UINT32 size; + + size = 0; + Invert = 0; + bytesread = 0; + + if (In == NULL) { + printf ("Error: Input file is NULL.\n"); + return -1; + } + + fread (&VolumeHeader, sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, In); + bytesread = sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY); + SigTemp[0] = VolumeHeader.Signature; + SigTemp[1] = 0; + + if (VolumeHeader.Attributes & EFI_FVB_ERASE_POLARITY) { + Invert = 1; + } + + do { + fread (&BlockMap, sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, In); + bytesread += sizeof (EFI_FV_BLOCK_MAP_ENTRY); + + if (BlockMap.NumBlocks != 0) { + size += BlockMap.NumBlocks * BlockMap.BlockLength; + } + + } while (BlockMap.NumBlocks != 0); + + *FvSize = size; + rewind (In); + + if (Invert == 1) { + bytesread *= -1; + } + + return bytesread; +} + +UINT32 +GetSectionLength ( + IN UINT32 *Length + ) +/*++ + +Routine Description: + + Converts a UINT8[3] array to a UINT32 + +Arguments: + + Length A pointer to a 3 byte array + +Returns: + + UINT32: The length. + +--*/ +{ + return *Length & 0x00FFFFFF; +} + +int +Readfile ( + UINT8 *FvImage, + int bytes, + int Invert + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + FvImage - GC_TODO: add argument description + bytes - GC_TODO: add argument description + Invert - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +{ + UINT32 FileLength; + UINT32 OccupiedFileLength; + EFI_FFS_FILE_HEADER *FileHeader; + UINT8 FileState; + UINT8 Checksum; + UINT8 *Ptr; + UINT32 SectionLength; + EFI_COMMON_SECTION_HEADER *SectionHeader; + EFI_IMAGE_NT_HEADERS *PeHeader; + UINT32 PeiCoreOffset; + + Ptr = FvImage + bytes; + + FileHeader = (EFI_FFS_FILE_HEADER *) Ptr; + + FileState = GetFileState ((UINT8) Invert, FileHeader); + + switch (FileState) { + case EFI_FILE_HEADER_CONSTRUCTION: + case EFI_FILE_HEADER_INVALID: + return sizeof (EFI_FFS_FILE_HEADER); + + case EFI_FILE_HEADER_VALID: + Checksum = CalculateSum8 ((UINT8 *) FileHeader, sizeof (EFI_FFS_FILE_HEADER)); + Checksum = (UINT8) (Checksum - FileHeader->IntegrityCheck.Checksum.File); + Checksum = (UINT8) (Checksum - FileHeader->State); + if (Checksum != 0) { + return -1; + } + // + // Now do the fixup stuff - begin + // + if (FileHeader->Type == EFI_FV_FILETYPE_PEI_CORE) { + SectionHeader = (EFI_COMMON_SECTION_HEADER *) FileHeader + sizeof (EFI_FFS_FILE_HEADER); + SectionLength = GetSectionLength ((UINT32 *) &SectionHeader->Size[0]); + + printf ("Section length is 0x%X\n", SectionLength); + + if (SectionHeader->Type == EFI_SECTION_PE32) { + + gFixup = bytes + sizeof (EFI_FFS_FILE_HEADER) + sizeof (EFI_COMMON_SECTION_HEADER); + + PeHeader = (EFI_IMAGE_NT_HEADERS *) Ptr + sizeof (EFI_FFS_FILE_HEADER) + sizeof (EFI_COMMON_SECTION_HEADER); + + if (((EFI_IMAGE_DOS_HEADER *) PeHeader)->e_magic == EFI_IMAGE_DOS_SIGNATURE) { + // + // DOS image header is present, so read the PE header after the DOS image header + // + PeHeader = (EFI_IMAGE_NT_HEADERS *) ((UINTN) PeHeader + (UINTN) ((((EFI_IMAGE_DOS_HEADER *) PeHeader)->e_lfanew) & 0x0ffff)); + + } + + PeiCoreOffset = (UINTN) ((UINTN) (PeHeader->OptionalHeader.AddressOfEntryPoint & 0x0ffffffff)); + + gFixup += PeiCoreOffset; + } + } + + FileLength = GetLength (FileHeader->Size); + OccupiedFileLength = GetOccupiedSize (FileLength, 8); + return OccupiedFileLength; + + case EFI_FILE_DATA_VALID: + // + // Calculate header checksum + // + Checksum = CalculateSum8 ((UINT8 *) FileHeader, sizeof (EFI_FFS_FILE_HEADER)); + Checksum = (UINT8) (Checksum - FileHeader->IntegrityCheck.Checksum.File); + Checksum = (UINT8) (Checksum - FileHeader->State); + if (Checksum != 0) { + return -1; + } + // + // Determine file length + // + FileLength = GetLength (FileHeader->Size); + OccupiedFileLength = GetOccupiedSize (FileLength, 8); + + // + // Determine if file checksum is valid or fixed + // + if (FileHeader->Attributes & FFS_ATTRIB_CHECKSUM) { + Checksum = CalculateSum8 (Ptr, FileLength); + Checksum = (UINT8) (Checksum - FileHeader->State); + if (Checksum != 0) { + return -1; + } + } else { + if (FileHeader->IntegrityCheck.Checksum.File != FFS_FIXED_CHECKSUM) { + return -1; + } + } + break; + + case EFI_FILE_MARKED_FOR_UPDATE: + case EFI_FILE_DELETED: + // + // Calculate header checksum + // + Checksum = CalculateSum8 ((UINT8 *) FileHeader, sizeof (EFI_FFS_FILE_HEADER)); + Checksum = (UINT8) (Checksum - FileHeader->IntegrityCheck.Checksum.File); + Checksum = (UINT8) (Checksum - FileHeader->State); + if (Checksum != 0) { + return -1; + } + // + // Determine file length + // + FileLength = GetLength (FileHeader->Size); + OccupiedFileLength = GetOccupiedSize (FileLength, 8); + + // + // Determine if file checksum is valid or fixed + // + if (FileHeader->Attributes & FFS_ATTRIB_CHECKSUM) { + Checksum = CalculateSum8 (Ptr, FileLength); + Checksum = (UINT8) (Checksum - FileHeader->State); + if (Checksum != 0) { + return -1; + } + } else { + if (FileHeader->IntegrityCheck.Checksum.File != FFS_FIXED_CHECKSUM) { + return -1; + } + } + + return OccupiedFileLength; + + default: + return sizeof (EFI_FFS_FILE_HEADER); + } + + return OccupiedFileLength; +} + +int +main ( + int argc, + char*argv[] + ) +/*++ + +Routine Description: + + Runs GenBsfFixup + +Arguments: + + argc: number of command line arguments + + arg[0] = This file name + arg[1] = Firmware Volume Name + arg[2] = Base Address to relocate + arg[3] = Relative offset of the fixup to perform + arg[4] = Output File Name + +Returns: + + int: 0 code success, -1 code failure + +--*/ +{ + FILE *In; + FILE *Out; + int ByteStart; + int Invert; + int Index; + int cnt; + UINT8 *FvImage; + int ByteRead; + UINT32 FvSize; + UINT64 delta; + UINT32 Idx; + UINT64 FvOffset; + EFI_STATUS Status; + + Index = 0; + Invert = 0; + printf ( + "GenBsfFixup EFI 2.0. Version %s, %s\n""Copyright (c) 2000-2001, Intel Corporation\n\n", + TOOLVERSION, + __DATE__ + ); + + if (argc != 5) { + printf ("Usage:\n"" GenBsfFixup FvVolumeImageFile AddressOfFvInMemory OffsetOfFixup OutputFileName\n"); + return -1; + } + + In = fopen (argv[1], "rb"); + + if (In == NULL) { + printf ("Unable to open FV image file \"%s\"\n", argv[1]); + return -1; + } + + ByteStart = ReadHeader (In, &FvSize); + + if (ByteStart < 0) { + Invert = 1; + ByteStart *= -1; + } + + FvImage = malloc (FvSize); + if (FvImage == NULL) { + printf ("Cannot allocate memory\n"); + fclose (In); + return -1; + } + + ByteRead = fread (FvImage, 1, FvSize, In); + + if ((unsigned int) ByteRead != FvSize) { + printf ("Read File error\n"); + fclose (In); + return -1; + } + + cnt = 0; + while ((unsigned int) ByteStart < FvSize && cnt != -1) { + cnt = Readfile (FvImage, ByteStart, Invert); + + if (cnt != -1) { + ByteStart += cnt; + } + + if (cnt != sizeof (EFI_FFS_FILE_HEADER)) { + Index++; + } + } + + if (cnt == -1) { + printf ("Firmware Volume image corrupted\n"); + return -1; + } + + fclose (In); + + Out = fopen (argv[4], "wb"); + + if (Out == NULL) { + printf ("Unable to open FV image file \"%s\"\n", argv[4]); + return -1; + } + + In = fopen (argv[1], "rb"); + + if (In == NULL) { + printf ("Unable to open FV image file \"%s\"\n", argv[1]); + return -1; + } + + if (gFixup != 0) { + + printf ("Fixup of 0x%X\n", gFixup); + + Status = AsciiStringToUint64 (argv[2], TRUE, &FvOffset); + + gFixup += (UINT32) FvOffset; + + ByteStart = ReadHeader (In, &FvSize); + + Readfile (FvImage, ByteStart, Invert); + + cnt = 0; + Status = AsciiStringToUint64 (argv[3], TRUE, &delta); + + fclose (In); + In = fopen (argv[1], "rb"); + + if (In == NULL) { + printf ("Unable to open FV image file \"%s\"\n", argv[1]); + return -1; + } + + for (Idx = 0; Idx < delta - FvOffset; Idx++) { + fputc (fgetc (In), Out); + } + + fwrite (&gFixup, sizeof (UINT32), 1, Out); + fseek (In, sizeof (UINT32), SEEK_CUR); + + for (Idx = 0; Idx < FvSize - (delta - FvOffset) - sizeof (UINT32); Idx++) { + fputc (fgetc (In), Out); + } + + fclose (In); + fclose (Out); + } else { + printf ("There was no fixup to perform\n"); + } + + free (FvImage); + + return 0; +} diff --git a/Tools/CCode/Source/GenBsfFixup/build.xml b/Tools/CCode/Source/GenBsfFixup/build.xml new file mode 100644 index 0000000000..1f35cf2948 --- /dev/null +++ b/Tools/CCode/Source/GenBsfFixup/build.xml @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/CCode/Source/GenBsfImage/GenBsfImage.c b/Tools/CCode/Source/GenBsfImage/GenBsfImage.c new file mode 100644 index 0000000000..59d20d08f0 --- /dev/null +++ b/Tools/CCode/Source/GenBsfImage/GenBsfImage.c @@ -0,0 +1,3519 @@ +/*++ + +Copyright (c) 1999 - 2006, Intel Corporation. All rights reserved +This software and associated documentation (if any) is furnished +under a license and may only be used or copied in accordance +with the terms of the license. Except as permitted by such +license, no part of this software or documentation may be +reproduced, stored in a retrieval system, or transmitted in any +form or by any means without the express written consent of +Intel Corporation. + + +Module Name: + + GenBsfImage.c + +Abstract: + + This file contains functions required to generate a boot strap file (BSF) + also known as the Volume Top File (VTF) + +--*/ + +// +// Module Coded to EFI 2.0 Coding Conventions +// +#include +#include +#include "GenBsfImage.h" +#include +#include "CommonLib.h" + +// +// Global variables +// +EFI_GUID Bsf1NameGuid = EFI_IPF_VTF1_GUID +EFI_GUID Bsf2NameGuid = EFI_IPF_VTF2_GUID + +CHAR8 **TokenStr; +CHAR8 **OrgStrTokPtr; + +PARSED_BSF_INFO *FileListPtr; +PARSED_BSF_INFO *FileListHeadPtr; + +VOID *Bsf1Buffer; +VOID *Bsf1EndBuffer; +VOID *Bsf2Buffer; +VOID *Bsf2EndBuffer; + +UINTN ValidLineNum = 0; +UINTN ValidFFDFileListNum = 0; + +// +// Section Description and their number of occurences in *.INF file +// +UINTN NumFvFiles = 0; +UINTN SectionOptionNum = 0; + +// +// Global flag which will check for BSF Present, if yes then will be used +// to decide about adding FFS header to pad data +// +BOOLEAN BSFPresent = FALSE; + +// +// Address related information +// +UINT64 Fv1BaseAddress = 0; +UINT64 Fv2BaseAddress = 0; +UINT64 Fv1EndAddress = 0; +UINT64 Fv2EndAddress = 0; +UINT32 Bsf1TotalSize = SIZE_TO_OFFSET_PAL_A_END; +UINT64 Bsf1LastStartAddress = 0; +UINT32 Bsf2TotalSize = 0; +UINT64 Bsf2LastStartAddress = 0; + +UINT32 BufferToTop = 0; + +// +// IA32 Reset Vector Bin name +// +CHAR8 IA32BinFile[FILE_NAME_SIZE]; + +// +// Function Implementations +// +VOID +BuildTokenList ( + IN CHAR8 *Token + ) +/*++ +Routine Description: + + This function builds the token list in an array which will be parsed later + +Arguments: + + Token - The pointer of string + +Returns: + + None + +--*/ +{ + strcpy (*TokenStr, Token); + TokenStr++; +} + +EFI_STATUS +ConvertVersionInfo ( + IN CHAR8 *Str, + IN OUT UINT8 *MajorVer, + IN OUT UINT8 *MinorVer + ) +/*++ +Routine Description: + + This function converts GUID string to GUID + +Arguments: + + Str - String representing in form XX.XX + MajorVer - The major vertion + MinorVer - The minor vertion + +Returns: + + EFI_SUCCESS - The fuction completed successfully. + +--*/ +{ + CHAR8 StrPtr[40]; + CHAR8 *Token; + UINTN Length; + UINTN Major; + UINTN Minor; + + Major = 0; + Minor = 0; + memset (StrPtr, 0, 40); + Token = strtok (Str, "."); + + while (Token != NULL) { + strcat (StrPtr, Token); + Token = strtok (NULL, "."); + } + + Length = strlen (StrPtr); + sscanf ( + StrPtr, + "%01x%02x", + &Major, + &Minor + ); + + *MajorVer = (UINT8) Major; + *MinorVer = (UINT8) Minor; + return EFI_SUCCESS; +} + +VOID +TrimLine ( + IN CHAR8 *Line + ) +/*++ +Routine Description: + + This function cleans up the line by removing all whitespace and + comments + +Arguments: + + Line - The pointer of the string + +Returns: + + None + +--*/ +{ + CHAR8 TmpLine[FILE_NAME_SIZE]; + CHAR8 Char; + CHAR8 *Ptr0; + UINTN Index; + UINTN Index2; + + // + // Change '#' to '//' for Comment style + // + if (((Ptr0 = strchr (Line, '#')) != NULL) || ((Ptr0 = strstr (Line, "//")) != NULL)) { + Line[Ptr0 - Line] = 0; + } + + // + // Initialize counters + // + Index = 0; + Index2 = 0; + + while ((Char = Line[Index]) != 0) { + if ((Char != ' ') && (Char != '\t') && (Char != '\n')) { + TmpLine[Index2++] = Char; + } + Index++; + } + + TmpLine[Index2] = 0; + strcpy (Line, TmpLine); +} + +VOID +ValidLineCount ( + IN FILE *Fp + ) +/*++ + +Routine Description: + + This function calculated number of valid lines in a input file. + +Arguments: + + Fp - Pointer to a file handle which has been opened. + +Returns: + + None + +--*/ +{ + CHAR8 Buff[FILE_NAME_SIZE]; + + while (fgets (Buff, sizeof (Buff), Fp)) { + TrimLine (Buff); + if (Buff[0] == 0) { + continue; + } + + ValidLineNum++; + } +} + +VOID +ParseInputFile ( + IN FILE *Fp + ) +/*++ + +Routine Description: + + This function parses the input file and tokenize the string + +Arguments: + + Fp - Pointer to a file handle which has been opened. + +Returns: + + None + +--*/ +{ + CHAR8 *Token; + CHAR8 Buff[FILE_NAME_SIZE]; + CHAR8 OrgLine[FILE_NAME_SIZE]; + CHAR8 Str[FILE_NAME_SIZE]; + CHAR8 Delimit[] = "="; + + while (fgets (Buff, sizeof (Buff), Fp) != NULL) { + strcpy (OrgLine, Buff); + TrimLine (Buff); + if (Buff[0] == 0) { + continue; + } + + Token = strtok (Buff, Delimit); + + while (Token != NULL) { + strcpy (Str, Token); + BuildTokenList (Str); + Token = strtok (NULL, Delimit); + } + } +} + +EFI_STATUS +InitializeComps ( + VOID + ) +/*++ + +Routine Description: + + This function intializes the relevant global variable which is being + used to store the information retrieved from INF file. This also initializes + the BSF symbol file. + +Arguments: + + None + +Returns: + + EFI_SUCCESS - The function completed successfully + EFI_OUT_OF_RESOURCES - Malloc failed. + +--*/ +{ + + FileListPtr = malloc (sizeof (PARSED_BSF_INFO)); + + if (FileListPtr == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + FileListHeadPtr = FileListPtr; + memset (FileListPtr, 0, sizeof (PARSED_BSF_INFO)); + FileListPtr->NextBsfInfo = NULL; + + remove (BSF_SYM_FILE); + return EFI_SUCCESS; +} + +VOID +ParseAndUpdateComponents ( + IN PARSED_BSF_INFO *BsfInfo + ) +/*++ + +Routine Description: + + This function intializes the relevant global variable which is being + used to store the information retrieved from INF file. + +Arguments: + + BsfInfo - A pointer to the BSF Info Structure + + +Returns: + + None + +--*/ +{ + UINT64 StringValue; + + while (*TokenStr != NULL && (_stricmp (*TokenStr, "COMP_NAME") != 0)) { + + if (_stricmp (*TokenStr, "COMP_LOC") == 0) { + TokenStr++; + if (_stricmp (*TokenStr, "F") == 0) { + BsfInfo->LocationType = FIRST_VTF; + } else if (_stricmp (*TokenStr, "S") == 0) { + BsfInfo->LocationType = SECOND_VTF; + } else { + BsfInfo->LocationType = NONE; + printf ("\nERROR: Unknown location for component %s", BsfInfo->CompName); + } + } else if (_stricmp (*TokenStr, "COMP_TYPE") == 0) { + TokenStr++; + if (AsciiStringToUint64 (*TokenStr, FALSE, &StringValue) != EFI_SUCCESS) { + printf ("\nERROR: Could not read a numeric value from \"%s\".", TokenStr); + return ; + } + + BsfInfo->CompType = (UINT8) StringValue; + } else if (_stricmp (*TokenStr, "COMP_VER") == 0) { + TokenStr++; + if (_stricmp (*TokenStr, "-") == 0) { + BsfInfo->VersionPresent = FALSE; + BsfInfo->MajorVer = 0; + BsfInfo->MinorVer = 0; + } else { + BsfInfo->VersionPresent = TRUE; + ConvertVersionInfo (*TokenStr, &BsfInfo->MajorVer, &BsfInfo->MinorVer); + } + } else if (_stricmp (*TokenStr, "COMP_BIN") == 0) { + TokenStr++; + strcpy (BsfInfo->CompBinName, *TokenStr); + } else if (_stricmp (*TokenStr, "COMP_SYM") == 0) { + TokenStr++; + strcpy (BsfInfo->CompSymName, *TokenStr); + } else if (_stricmp (*TokenStr, "COMP_SIZE") == 0) { + TokenStr++; + if (_stricmp (*TokenStr, "-") == 0) { + BsfInfo->PreferredSize = FALSE; + BsfInfo->CompSize = 0; + } else { + BsfInfo->PreferredSize = TRUE; + if (AsciiStringToUint64 (*TokenStr, FALSE, &StringValue) != EFI_SUCCESS) { + printf ("\nERROR: Could not read a numeric value from \"%s\".", TokenStr); + return ; + } + + BsfInfo->CompSize = (UINTN) StringValue; + } + + } else if (_stricmp (*TokenStr, "COMP_CS") == 0) { + TokenStr++; + if (_stricmp (*TokenStr, "1") == 0) { + BsfInfo->CheckSumRequired = 1; + } else if (_stricmp (*TokenStr, "0") == 0) { + BsfInfo->CheckSumRequired = 0; + } else { + printf ("\nERROR: Bad information in INF file about Checksum required field"); + } + } + + TokenStr++; + if (*TokenStr == NULL) { + break; + } + } +} + +VOID +InitializeInFileInfo ( + VOID + ) +/*++ + +Routine Description: + + This function intializes the relevant global variable which is being + used to store the information retrieved from INF file. + +Arguments: + + NONE + +Returns: + + NONE + +--*/ +{ + UINTN SectionOptionFlag; + UINTN SectionCompFlag; + + SectionOptionFlag = 0; + SectionCompFlag = 0; + TokenStr = OrgStrTokPtr; + while (*TokenStr != NULL) { + if (_stricmp (*TokenStr, "[OPTIONS]") == 0) { + SectionOptionFlag = 1; + SectionCompFlag = 0; + } + + if (_stricmp (*TokenStr, "[COMPONENTS]") == 0) { + if (FileListPtr == NULL) { + FileListPtr = FileListHeadPtr; + } + + SectionCompFlag = 1; + SectionOptionFlag = 0; + TokenStr++; + } + + if (SectionOptionFlag) { + if (_stricmp (*TokenStr, "IA32_RST_BIN") == 0) { + *TokenStr++; + strcpy (IA32BinFile, *TokenStr); + } + } + + if (SectionCompFlag) { + if (_stricmp (*TokenStr, "COMP_NAME") == 0) { + TokenStr++; + strcpy (FileListPtr->CompName, *TokenStr); + TokenStr++; + ParseAndUpdateComponents (FileListPtr); + } + + if (*TokenStr != NULL) { + FileListPtr->NextBsfInfo = malloc (sizeof (PARSED_BSF_INFO)); + if (FileListPtr->NextBsfInfo == NULL) { + printf ("Error: Out of memory resources.\n"); + break; + } + FileListPtr = FileListPtr->NextBsfInfo; + memset (FileListPtr, 0, sizeof (PARSED_BSF_INFO)); + FileListPtr->NextBsfInfo = NULL; + continue; + } else { + break; + } + } + + TokenStr++; + } +} + +EFI_STATUS +GetBsfRelatedInfoFromInfFile ( + IN CHAR8 *FileName + ) +/*++ + +Routine Description: + + This function reads the input file, parse it and create a list of tokens + which is parsed and used, to intialize the data related to BSF + +Arguments: + + FileName - FileName which needed to be read to parse data + +Returns: + + EFI_ABORTED - Error in opening file + EFI_INVALID_PARAMETER - File doesn't contain any valid informations + EFI_OUT_OF_RESOURCES - Malloc Failed + EFI_SUCCESS - The function completed successfully + +--*/ +{ + FILE *Fp; + UINTN Index; + EFI_STATUS Status; + + Fp = fopen (FileName, "r"); + if (Fp == NULL) { + printf ("\nERROR: Error in opening %s file\n", FileName); + return EFI_ABORTED; + } + + ValidLineCount (Fp); + + if (ValidLineNum == 0) { + printf ("\nERROR: File doesn't contain any valid informations"); + return EFI_INVALID_PARAMETER; + } + + TokenStr = (CHAR8 **) malloc (sizeof (UINTN) * (2 * ValidLineNum + 1)); + + if (TokenStr == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + memset (TokenStr, 0, (sizeof (UINTN) * (2 * ValidLineNum + 1))); + OrgStrTokPtr = TokenStr; + + for (Index = 0; Index < (2 * ValidLineNum); Index++) { + *TokenStr = (CHAR8*)malloc (sizeof (CHAR8) * FILE_NAME_SIZE); + + if (*TokenStr == NULL) { + free (OrgStrTokPtr); + return EFI_OUT_OF_RESOURCES; + } + + memset (*TokenStr, 0, FILE_NAME_SIZE); +// free (*TokenStr); + TokenStr++; + } + + TokenStr = NULL; + TokenStr = OrgStrTokPtr; + fseek (Fp, 0L, SEEK_SET); + + Status = InitializeComps (); + + if (Status != EFI_SUCCESS) { + free (OrgStrTokPtr); + return Status; + } + + ParseInputFile (Fp); + InitializeInFileInfo (); + + if (Fp) { + fclose (Fp); + } + free (OrgStrTokPtr); + return EFI_SUCCESS; +} + +VOID +GetRelativeAddressInBsfBuffer ( + IN UINT64 Address, + IN OUT UINTN *RelativeAddress, + IN LOC_TYPE LocType + ) +/*++ + +Routine Description: + + This function checks for the address alignmnet for specified data boundary. In + case the address is not aligned, it returns FALSE and the amount of data in + terms of byte needed to adjust to get the boundary alignmnet. If data is + aligned, TRUE will be returned. + +Arguments: + + Address - The address of the flash map space + RelativeAddress - The relative address of the Buffer + LocType - The type of the BSF + + +Returns: + + +--*/ +{ + UINT64 TempAddress; + UINT8 *LocalBuff; + + if (LocType == FIRST_VTF) { + LocalBuff = (UINT8 *) Bsf1EndBuffer; + TempAddress = Fv1EndAddress - Address; + *RelativeAddress = (UINTN) LocalBuff - (UINTN) TempAddress; + } else { + LocalBuff = (UINT8 *) Bsf2EndBuffer; + TempAddress = Fv2EndAddress - Address; + *RelativeAddress = (UINTN) LocalBuff - (UINTN) TempAddress; + } +} + +EFI_STATUS +GetComponentVersionInfo ( + IN OUT PARSED_BSF_INFO *BsfInfo, + IN UINT8 *Buffer + ) +/*++ +Routine Description: + + This function will extract the version information from File + +Arguments: + + BsfInfo - A Pointer to the BSF Info Structure + Buffer - A Pointer to type UINT8 + +Returns: + + EFI_SUCCESS - The function completed successfully + EFI_INVALID_PARAMETER - The parameter is invalid + +--*/ +{ + UINT16 VersionInfo; + EFI_STATUS Status; + + switch (BsfInfo->CompType) { + + case COMP_TYPE_FIT_PAL_A: + case COMP_TYPE_FIT_PAL_B: + memcpy (&VersionInfo, (Buffer + 8), sizeof (UINT16)); + BsfInfo->MajorVer = (UINT8) ((VersionInfo & 0xFF00) >> 8); + BsfInfo->MinorVer = (UINT8) (VersionInfo & 0x00FF); + Status = EFI_SUCCESS; + break; + + default: + Status = EFI_INVALID_PARAMETER; + break; + } + + return Status; +} + +BOOLEAN +CheckAddressAlignment ( + IN UINT64 Address, + IN UINT64 AlignmentData, + IN OUT UINT64 *AlignAdjustByte + ) +/*++ + +Routine Description: + + This function checks for the address alignmnet for specified data boundary. In + case the address is not aligned, it returns FALSE and the amount of data in + terms of byte needed to adjust to get the boundary alignmnet. If data is + aligned, TRUE will be returned. + +Arguments: + + Address - Pointer to buffer containing byte data of component. + AlignmentData - DataSize for which address needed to be aligned + AlignAdjustByte - Number of bytes needed to adjust alignment. + +Returns: + + TRUE - Address is aligned to specific data size boundary + FALSE - Address in not aligned to specified data size boundary + - Add/Subtract AlignAdjustByte to aling the address. + +--*/ +{ + // + // Check if the assigned address is on address boundary. If not, it will + // return the remaining byte required to adjust the address for specified + // address boundary + // + *AlignAdjustByte = (Address % AlignmentData); + + if (*AlignAdjustByte == 0) { + return TRUE; + } else { + return FALSE; + } +} + +EFI_STATUS +GetFitTableStartAddress ( + IN OUT FIT_TABLE **FitTable + ) +/*++ + +Routine Description: + + Get the FIT table start address in BSF Buffer + +Arguments: + + FitTable - Pointer to available fit table where new component can be added + +Returns: + + EFI_SUCCESS - The function completed successfully + +--*/ +{ + UINT64 FitTableAdd; + UINT64 FitTableAddOffset; + UINTN RelativeAddress; + + // + // Read the Fit Table address from Itanium-based address map. + // + FitTableAddOffset = Fv1EndAddress - (SIZE_IA32_RESET_VECT + SIZE_SALE_ENTRY_POINT + SIZE_FIT_TABLE_ADD); + + // + // Translate this Itanium-based address in terms of local buffer address which + // contains the image for Boot Strapped File. The relative address will be + // the address of fit table BSF buffer. + // + GetRelativeAddressInBsfBuffer (FitTableAddOffset, &RelativeAddress, FIRST_VTF); + FitTableAdd = *(UINTN *) RelativeAddress; + + // + // The FitTableAdd is the extracted Itanium based address pointing to FIT + // table. The relative address will return its actual location in BSF + // Buffer. + // + GetRelativeAddressInBsfBuffer (FitTableAdd, &RelativeAddress, FIRST_VTF); + + *FitTable = (FIT_TABLE *) RelativeAddress; + + return EFI_SUCCESS; +} + +EFI_STATUS +GetNextAvailableFitPtr ( + IN FIT_TABLE **FitPtr + ) +/*++ + +Routine Description: + + Get the FIT table address and locate the free space in fit where we can add + new component. In this process, this function locates the fit table using + Fit pointer in Itanium-based address map (as per Intel?Itanium(TM) SAL spec) + and locate the available location in FIT table to be used by new components. + If there are any Fit table which areg not being used contains ComponentType + field as 0x7F. If needed we can change this and spec this out. + +Arguments: + + FitPtr - Pointer to available fit table where new component can be added + +Returns: + + EFI_SUCCESS - The function completed successfully + +--*/ +{ + FIT_TABLE *TmpFitPtr; + UINT64 FitTableAdd; + UINT64 FitTableAddOffset; + UINTN Index; + UINTN NumFitComponents; + UINTN RelativeAddress; + + // + // Read the Fit Table address from Itanium-based address map. + // + FitTableAddOffset = Fv1EndAddress - (SIZE_IA32_RESET_VECT + SIZE_SALE_ENTRY_POINT + SIZE_FIT_TABLE_ADD); + + // + // Translate this Itanium-based address in terms of local buffer address which + // contains the image for Boot Strapped File. The relative address will be + // the address of fit table BSF buffer. + // + GetRelativeAddressInBsfBuffer (FitTableAddOffset, &RelativeAddress, FIRST_VTF); + FitTableAdd = *(UINTN *) RelativeAddress; + + // + // The FitTableAdd is the extracted Itanium based address pointing to FIT + // table. The relative address will return its actual location in BSF + // Buffer. + // + GetRelativeAddressInBsfBuffer (FitTableAdd, &RelativeAddress, FIRST_VTF); + + TmpFitPtr = (FIT_TABLE *) RelativeAddress; + NumFitComponents = TmpFitPtr->CompSize; + + for (Index = 0; Index < NumFitComponents; Index++) { + if ((TmpFitPtr->CvAndType & FIT_TYPE_MASK) == COMP_TYPE_FIT_UNUSED) { + *FitPtr = TmpFitPtr; + break; + } + + TmpFitPtr++; + } + + return EFI_SUCCESS; +} + +INTN +CompareItems ( + IN const VOID *Arg1, + IN const VOID *Arg2 + ) +/*++ + +Routine Description: + + This function is used by qsort to sort the FIT table based upon Component + Type in their incresing order. + +Arguments: + + Arg1 - Pointer to Arg1 + Arg2 - Pointer to Arg2 + +Returns: + + None + +--*/ +{ + if ((((FIT_TABLE *) Arg1)->CvAndType & FIT_TYPE_MASK) > (((FIT_TABLE *) Arg2)->CvAndType & FIT_TYPE_MASK)) { + return 1; + } else if ((((FIT_TABLE *) Arg1)->CvAndType & FIT_TYPE_MASK) < (((FIT_TABLE *) Arg2)->CvAndType & FIT_TYPE_MASK)) { + return -1; + } else { + return 0; + } +} + +VOID +SortFitTable ( + IN VOID + ) +/*++ + +Routine Description: + + This function is used by qsort to sort the FIT table based upon Component + Type in their incresing order. + +Arguments: + + VOID + +Returns: + + None + +--*/ +{ + FIT_TABLE *FitTable; + FIT_TABLE *TmpFitPtr; + UINTN NumFitComponents; + UINTN Index; + + GetFitTableStartAddress (&FitTable); + TmpFitPtr = FitTable; + NumFitComponents = 0; + for (Index = 0; Index < FitTable->CompSize; Index++) { + if ((TmpFitPtr->CvAndType & FIT_TYPE_MASK) != COMP_TYPE_FIT_UNUSED) { + NumFitComponents += 1; + } + + TmpFitPtr++; + } + + qsort ((VOID *) FitTable, NumFitComponents, sizeof (FIT_TABLE), CompareItems); +} + +VOID +UpdateFitEntryForFwVolume ( + IN UINT64 Size + ) +/*++ + +Routine Description: + + This function updates the information about Firmware Volume in FIT TABLE. + This FIT table has to be immediately below the PAL_A Start and it contains + component type and address information. Other informations can't be + created this time so we would need to fix it up.. + + +Arguments: + + Size - Firmware Volume Size + +Returns: + + VOID + +--*/ +{ + FIT_TABLE *CompFitPtr; + UINTN RelativeAddress; + + // + // FV Fit table will be located at PAL_A Startaddress - 16 byte location + // + Bsf1LastStartAddress -= 0x10; + Bsf1TotalSize += 0x10; + + GetRelativeAddressInBsfBuffer (Bsf1LastStartAddress, &RelativeAddress, FIRST_VTF); + + CompFitPtr = (FIT_TABLE *) RelativeAddress; + CompFitPtr->CompAddress = Fv1BaseAddress; + + // + // Since we don't have any information about its location in Firmware Volume, + // initialize address to 0. This will be updated once Firmware Volume is + // being build and its current address will be fixed in FIT table. Currently + // we haven't implemented it so far and working on architectural clarafication + // + // + // Firmware Volume Size in 16 byte block + // + CompFitPtr->CompSize = ((UINT32) Size) / 16; + + // + // Since Firmware Volume does not exist by the time we create this FIT info + // this should be fixedup from Firmware Volume creation tool. We haven't + // worked out a method so far. + // + CompFitPtr->CompVersion = MAKE_VERSION (0, 0); + + // + // Since we don't have any info about this file, we are making sure that + // checksum is not needed. + // + CompFitPtr->CvAndType = CV_N_TYPE (0, COMP_TYPE_FIT_FV_BOOT); + + // + // Since non BSF component will reside outside the BSF, we will not have its + // binary image while creating BSF, hence we will not perform checksum at + // this time. Once Firmware Volume is being created which will contain this + // BSF, it will fix the FIT table for all the non BSF component and hence + // checksum + // + CompFitPtr->CheckSum = 0; +} + +EFI_STATUS +UpdateFitEntryForNonBSFComp ( + IN PARSED_BSF_INFO *BsfInfo + ) +/*++ + +Routine Description: + + This function updates the information about non BSF component in FIT TABLE. + Since non BSF componets binaries are not part of BSF binary, we would still + be required to update its location information in Firmware Volume, inside + FIT table. + +Arguments: + + BsfInfo - Pointer to BSF Info Structure + +Returns: + + EFI_ABORTED - The function fails to update the component in FIT + EFI_SUCCESS - The function completed successfully + +--*/ +{ + FIT_TABLE *CompFitPtr; + + // + // Scan the FIT table for available space + // + GetNextAvailableFitPtr (&CompFitPtr); + if (CompFitPtr == NULL) { + printf ("\nERROR: Can't update this component in FIT"); + return EFI_ABORTED; + } + + // + // Since we don't have any information about its location in Firmware Volume, + // initialize address to 0. This will be updated once Firmware Volume is + // being build and its current address will be fixed in FIT table + // + CompFitPtr->CompAddress = 0; + CompFitPtr->CompSize = BsfInfo->CompSize; + CompFitPtr->CompVersion = MAKE_VERSION (BsfInfo->MajorVer, BsfInfo->MinorVer); + CompFitPtr->CvAndType = CV_N_TYPE (BsfInfo->CheckSumRequired, BsfInfo->CompType); + + // + // Since non BSF component will reside outside the BSF, we will not have its + // binary image while creating BSF, hence we will not perform checksum at + // this time. Once Firmware Volume is being created which will contain this + // BSF, it will fix the FIT table for all the non BSF component and hence + // checksum + // + CompFitPtr->CheckSum = 0; + + // + // Fit Type is FV_BOOT which means Firmware Volume, we initialize this to base + // address of Firmware Volume in which this BSF will be attached. + // + if ((CompFitPtr->CvAndType & 0x7F) == COMP_TYPE_FIT_FV_BOOT) { + CompFitPtr->CompAddress = Fv1BaseAddress; + } + + return EFI_SUCCESS; +} + +// +// !!!WARNING +// This function is updating the SALE_ENTRY in Itanium address space as per SAL +// spec. SALE_ENTRY is being read from SYM file of PEICORE. Once the PEI +// CORE moves in Firmware Volume, we would need to modify this function to be +// used with a API which will detect PEICORE component while building Firmware +// Volume and update its entry in FIT table as well as in Itanium address space +// as per Intel?Itanium(TM) SAL address space +// +EFI_STATUS +UpdateEntryPoint ( + IN PARSED_BSF_INFO *BsfInfo, + IN UINT64 *CompStartAddress + ) +/*++ + +Routine Description: + + This function updated the architectural entry point in IPF, SALE_ENTRY. + +Arguments: + + BsfInfo - Pointer to BSF Info Structure + CompStartAddress - Pointer to Component Start Address + +Returns: + + EFI_INVALID_PARAMETER - The parameter is invalid + EFI_SUCCESS - The function completed successfully + +--*/ +{ + UINTN RelativeAddress; + UINT64 SalEntryAdd; + FILE *Fp; + UINTN Offset; + + CHAR8 Buff[FILE_NAME_SIZE]; + CHAR8 Buff1[10]; + CHAR8 Buff2[10]; + CHAR8 OffsetStr[30]; + CHAR8 Buff3[10]; + CHAR8 Buff4[10]; + CHAR8 Buff5[10]; + CHAR8 Token[50]; + + Fp = fopen (BsfInfo->CompSymName, "r+b"); + + if (Fp == NULL) { + printf ("\nERROR: Error in opening file"); + return EFI_INVALID_PARAMETER; + } + + while (fgets (Buff, sizeof (Buff), Fp) != NULL) { + fscanf ( + Fp, + "%s %s %s %s %s %s %s", + &Buff1, + &Buff2, + &OffsetStr, + &Buff3, + &Buff4, + &Buff5, + &Token + ); + if (_stricmp (Token, "SALE_ENTRY") == 0) { + break; + } + } + + Offset = strtoul (OffsetStr, NULL, 16); + + *CompStartAddress += Offset; + SalEntryAdd = Fv1EndAddress - (SIZE_IA32_RESET_VECT + SIZE_SALE_ENTRY_POINT); + + GetRelativeAddressInBsfBuffer (SalEntryAdd, &RelativeAddress, FIRST_VTF); + + memcpy ((VOID *) RelativeAddress, (VOID *) CompStartAddress, sizeof (UINT64)); + + return EFI_SUCCESS; +} + +EFI_STATUS +CreateAndUpdateComponent ( + IN PARSED_BSF_INFO *BsfInfo + ) +/*++ + +Routine Description: + + This function reads the binary file for each components and update them + in BSF Buffer as well as in FIT table. If the component is located in non + BSF area, only the FIT table address will be updated + +Arguments: + + BsfInfo - Pointer to Parsed Info + +Returns: + + EFI_SUCCESS - The function completed successful + EFI_ABORTED - Aborted due to one of the many reasons like: + (a) Component Size greater than the specified size. + (b) Error opening files. + + EFI_INVALID_PARAMETER Value returned from call to UpdateEntryPoint() + EFI_OUT_OF_RESOURCES Memory allocation failure. + +--*/ +{ + EFI_STATUS Status; + UINT64 CompStartAddress; + UINT64 FileSize; + UINT64 NumByteRead; + UINT64 NumAdjustByte; + UINT8 *Buffer; + FILE *Fp; + FIT_TABLE *CompFitPtr; + BOOLEAN Aligncheck; + + if (BsfInfo->LocationType == NONE) { + UpdateFitEntryForNonBSFComp (BsfInfo); + return EFI_SUCCESS; + } + + Fp = fopen (BsfInfo->CompBinName, "r+b"); + + if (Fp == NULL) { + printf ("\nERROR: Opening file %s", BsfInfo->CompBinName); + return EFI_ABORTED; + } + + FileSize = _filelength (_fileno (Fp)); + + if ((BsfInfo->CompType == COMP_TYPE_FIT_PAL_B) || (BsfInfo->CompType == COMP_TYPE_FIT_PAL_A_SPECIFIC)) { + + // + // BUGBUG: Satish to correct + // + FileSize -= SIZE_OF_PAL_HEADER; + } + + if (BsfInfo->PreferredSize) { + if (FileSize > BsfInfo->CompSize) { + printf ("\nERROR: The component size is more than specified size"); + return EFI_ABORTED; + } + + FileSize = BsfInfo->CompSize; + } + + Buffer = malloc ((UINTN) FileSize); + if (Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + memset (Buffer, 0, (UINTN) FileSize); + + if ((BsfInfo->CompType == COMP_TYPE_FIT_PAL_B) || (BsfInfo->CompType == COMP_TYPE_FIT_PAL_A_SPECIFIC)) { + + // + // Read first 64 bytes of PAL header and use it to find version info + // + NumByteRead = fread (Buffer, sizeof (UINT8), SIZE_OF_PAL_HEADER, Fp); + + // + // PAL header contains the version info. Currently, we will use the header + // to read version info and then discard. + // + if (!BsfInfo->VersionPresent) { + GetComponentVersionInfo (BsfInfo, Buffer); + } + } + + NumByteRead = fread (Buffer, sizeof (UINT8), (UINTN) FileSize, Fp); + fclose (Fp); + + // + // If it is non PAL_B component, pass the entire buffer to get the version + // info and implement any specific case inside GetComponentVersionInfo. + // + if (BsfInfo->CompType != COMP_TYPE_FIT_PAL_B) { + if (!BsfInfo->VersionPresent) { + GetComponentVersionInfo (BsfInfo, Buffer); + } + } + + if (BsfInfo->LocationType == SECOND_VTF) { + + CompStartAddress = (Bsf2LastStartAddress - FileSize); + } else { + CompStartAddress = (Bsf1LastStartAddress - FileSize); + } + + if (BsfInfo->CompType == COMP_TYPE_FIT_PAL_B) { + Aligncheck = CheckAddressAlignment (CompStartAddress, 32 * 1024, &NumAdjustByte); + } else { + Aligncheck = CheckAddressAlignment (CompStartAddress, 8, &NumAdjustByte); + } + + if (!Aligncheck) { + CompStartAddress -= NumAdjustByte; + } + + if (BsfInfo->LocationType == SECOND_VTF) { + Bsf2LastStartAddress = CompStartAddress; + Bsf2TotalSize += (UINT32) (FileSize + NumAdjustByte); + Status = UpdateBsfBuffer (CompStartAddress, Buffer, FileSize, SECOND_VTF); + } else { + Bsf1LastStartAddress = CompStartAddress; + Bsf1TotalSize += (UINT32) (FileSize + NumAdjustByte); + Status = UpdateBsfBuffer (CompStartAddress, Buffer, FileSize, FIRST_VTF); + } + + if (EFI_ERROR (Status)) { + return EFI_ABORTED; + } + + GetNextAvailableFitPtr (&CompFitPtr); + + CompFitPtr->CompAddress = CompStartAddress | IPF_CACHE_BIT; + assert ((FileSize % 16) == 0); + CompFitPtr->CompSize = (UINT32) (FileSize / 16); + CompFitPtr->CompVersion = MAKE_VERSION (BsfInfo->MajorVer, BsfInfo->MinorVer); + CompFitPtr->CvAndType = CV_N_TYPE (BsfInfo->CheckSumRequired, BsfInfo->CompType); + if (BsfInfo->CheckSumRequired) { + CompFitPtr->CheckSum = 0; + CompFitPtr->CheckSum = CalculateChecksum8 (Buffer, (UINTN) FileSize); + } + + // + // Free the buffer + // + if (Buffer) { + free (Buffer); + } + + // + // Update the SYM file for this component based on it's start address. + // + Status = UpdateSymFile (CompStartAddress, BSF_SYM_FILE, BsfInfo->CompSymName); + if (EFI_ERROR (Status)) { + + // + // At this time, SYM files are not required, so continue on error. + // + } + + // !!!!!!!!!!!!!!!!!!!!! + // BUGBUG: + // This part of the code is a temporary line since PEICORE is going to be inside + // BSF till we work out how to determine the SALE_ENTRY through it. We will need + // to clarify so many related questions + // !!!!!!!!!!!!!!!!!!!!!!! + if (BsfInfo->CompType == COMP_TYPE_FIT_PEICORE) { + Status = UpdateEntryPoint (BsfInfo, &CompStartAddress); + } + + return Status; +} + +EFI_STATUS +CreateAndUpdatePAL_A ( + IN PARSED_BSF_INFO *BsfInfo + ) +/*++ + +Routine Description: + + This function reads the binary file for each components and update them + in BSF Buffer as well as FIT table + +Arguments: + + BsfInfo - Pointer to Parsed Info + +Returns: + + EFI_ABORTED - Due to one of the following reasons: + (a)Error Opening File + (b)The PAL_A Size is more than specified size status + One of the values mentioned below returned from + call to UpdateSymFile + EFI_SUCCESS - The function completed successfully. + EFI_INVALID_PARAMETER - One of the input parameters was invalid. + EFI_ABORTED - An error occurred.UpdateSymFile + EFI_OUT_OF_RESOURCES - Memory allocation failed. + +--*/ +{ + EFI_STATUS Status; + UINT64 PalStartAddress; + UINT64 AbsAddress; + UINTN RelativeAddress; + UINT64 FileSize; + UINT64 NumByteRead; + UINT8 *Buffer; + FILE *Fp; + FIT_TABLE *PalFitPtr; + + Fp = fopen (BsfInfo->CompBinName, "r+b"); + + if (Fp == NULL) { + printf ("\nERROR: Opening file %s", BsfInfo->CompBinName); + return EFI_ABORTED; + } + + FileSize = _filelength (_fileno (Fp)); + FileSize -= SIZE_OF_PAL_HEADER; + + if (BsfInfo->PreferredSize) { + if (FileSize > BsfInfo->CompSize) { + printf ("\nERROR: The PAL_A Size is more than specified size"); + return EFI_ABORTED; + } + + FileSize = BsfInfo->CompSize; + } + + Buffer = malloc ((UINTN) FileSize); + if (Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + memset (Buffer, 0, (UINTN) FileSize); + + // + // Read, Get version Info and discard the PAL header. + // + NumByteRead = fread (Buffer, sizeof (UINT8), SIZE_OF_PAL_HEADER, Fp); + + // + // Extract the version info from header of PAL_A. Once done, discrad this buffer + // + if (!BsfInfo->VersionPresent) { + GetComponentVersionInfo (BsfInfo, Buffer); + } + + // + // Read PAL_A file in a buffer + // + NumByteRead = fread (Buffer, sizeof (UINT8), (UINTN) FileSize, Fp); + fclose (Fp); + + PalStartAddress = Fv1EndAddress - (SIZE_TO_OFFSET_PAL_A_END + FileSize); + Bsf1LastStartAddress = PalStartAddress; + Bsf1TotalSize += (UINT32) FileSize; + Status = UpdateBsfBuffer (PalStartAddress, Buffer, FileSize, FIRST_VTF); + + AbsAddress = Fv1EndAddress - SIZE_TO_PAL_A_FIT; + GetRelativeAddressInBsfBuffer (AbsAddress, &RelativeAddress, FIRST_VTF); + PalFitPtr = (FIT_TABLE *) RelativeAddress; + PalFitPtr->CompAddress = PalStartAddress | IPF_CACHE_BIT; + assert ((FileSize % 16) == 0); + PalFitPtr->CompSize = (UINT32) (FileSize / 16); + PalFitPtr->CompVersion = MAKE_VERSION (BsfInfo->MajorVer, BsfInfo->MinorVer); + PalFitPtr->CvAndType = CV_N_TYPE (BsfInfo->CheckSumRequired, BsfInfo->CompType); + if (BsfInfo->CheckSumRequired) { + PalFitPtr->CheckSum = 0; + PalFitPtr->CheckSum = CalculateChecksum8 (Buffer, (UINTN) FileSize); + } + + if (Buffer) { + free (Buffer); + } + + // + // Update the SYM file for this component based on it's start address. + // + Status = UpdateSymFile (PalStartAddress, BSF_SYM_FILE, BsfInfo->CompSymName); + if (EFI_ERROR (Status)) { + + // + // At this time, SYM files are not required, so continue on error. + // + } + + return Status; +} + +EFI_STATUS +CreateFitTableAndInitialize ( + IN PARSED_BSF_INFO *BsfInfo + ) +/*++ + +Routine Description: + + This function creates and intializes FIT table which would be used to + add component info inside this + +Arguments: + + BsfInfo - Pointer to Parsed Info + +Returns: + + EFI_ABORTED - Aborted due to no size information + EFI_SUCCESS - The function completed successfully + +--*/ +{ + UINT64 PalFitTableAdd; + UINT64 FitTableAdd; + UINT64 FitTableAddressOffset; + FIT_TABLE *PalFitPtr; + FIT_TABLE *FitStartPtr; + UINTN NumFitComp; + UINTN RelativeAddress; + UINTN Index; + + if (!BsfInfo->PreferredSize) { + printf ("\nERROR: FIT could not be allocated becuase there are no size information"); + return EFI_ABORTED; + } + + if ((BsfInfo->CompSize % 16) != 0) { + printf ("\nERROR: Invalid Fit Table Size, not multiple of 16 bytes. Please correct the size"); + } + + PalFitTableAdd = Fv1EndAddress - SIZE_TO_PAL_A_FIT; + GetRelativeAddressInBsfBuffer (PalFitTableAdd, &RelativeAddress, FIRST_VTF); + PalFitPtr = (FIT_TABLE *) RelativeAddress; + PalFitTableAdd = (PalFitPtr->CompAddress - BsfInfo->CompSize); + + FitTableAdd = (PalFitPtr->CompAddress - 0x10) - BsfInfo->CompSize; + FitTableAddressOffset = Fv1EndAddress - (SIZE_IA32_RESET_VECT + SIZE_SALE_ENTRY_POINT + SIZE_FIT_TABLE_ADD); + GetRelativeAddressInBsfBuffer (FitTableAddressOffset, &RelativeAddress, FIRST_VTF); + *(UINT64 *) RelativeAddress = FitTableAdd; + + GetRelativeAddressInBsfBuffer (FitTableAdd, &RelativeAddress, FIRST_VTF); + + // + // Update Fit Table with FIT Signature and FIT info in first 16 bytes. + // + FitStartPtr = (FIT_TABLE *) RelativeAddress; + + strncpy ((CHAR8 *) &FitStartPtr->CompAddress, FIT_SIGNATURE, 8); // "_FIT_ " + assert (((BsfInfo->CompSize & 0x00FFFFFF) % 16) == 0); + FitStartPtr->CompSize = (BsfInfo->CompSize & 0x00FFFFFF) / 16; + FitStartPtr->CompVersion = MAKE_VERSION (BsfInfo->MajorVer, BsfInfo->MinorVer); + + // + // BUGBUG: If a checksum is required, add code to checksum the FIT table. Also + // determine what to do for things like the FV component that aren't easily checksummed. + // The checksum will be done once we are done with all the componet update in the FIT + // table + // + FitStartPtr->CvAndType = CV_N_TYPE (BsfInfo->CheckSumRequired, BsfInfo->CompType); + + NumFitComp = FitStartPtr->CompSize; + + FitStartPtr++; + + // + // Intialize remaining FIT table space to UNUSED fit component type + // so that when we need to create a FIT entry for a component, we can + // locate a free one and use it. + // + for (Index = 0; Index < (NumFitComp - 1); Index++) { + FitStartPtr->CvAndType = 0x7F; // Initialize all with UNUSED + FitStartPtr++; + } + + Bsf1TotalSize += BsfInfo->CompSize; + Bsf1LastStartAddress -= BsfInfo->CompSize; + + return EFI_SUCCESS; +} + +EFI_STATUS +WriteBsfBinary ( + IN CHAR8 *FileName, + IN UINT32 BsfSize, + IN LOC_TYPE LocType + ) +/*++ + +Routine Description: + + Write Firmware Volume from memory to a file. + +Arguments: + + FileName - Output File Name which needed to be created/ + BsfSize - FileSize + LocType - The type of the BSF + +Returns: + + EFI_ABORTED - Returned due to one of the following resons: + (a) Error Opening File + (b) Failing to copy buffers + EFI_SUCCESS - The fuction completes successfully + +--*/ +{ + FILE *Fp; + UINTN NumByte; + VOID *BsfBuffer; + UINTN RelativeAddress; + + if (LocType == FIRST_VTF) { + GetRelativeAddressInBsfBuffer (Bsf1LastStartAddress, &RelativeAddress, FIRST_VTF); + BsfBuffer = (VOID *) RelativeAddress; + } else { + GetRelativeAddressInBsfBuffer (Bsf2LastStartAddress, &RelativeAddress, SECOND_VTF); + BsfBuffer = (VOID *) RelativeAddress; + } + + Fp = fopen (FileName, "w+b"); + if (Fp == NULL) { + printf ("Error in opening file %s\n", FileName); + return EFI_ABORTED; + } + + NumByte = fwrite (BsfBuffer, sizeof (UINT8), (UINTN) BsfSize, Fp); + + if (Fp) { + fclose (Fp); + } + + if (NumByte != (sizeof (UINT8) * BsfSize)) { + printf ("\nERROR: Could not copy buffer into file %s ", FileName); + return EFI_ABORTED; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +UpdateBsfBuffer ( + IN UINT64 StartAddress, + IN UINT8 *Buffer, + IN UINT64 DataSize, + IN LOC_TYPE LocType + ) +/*++ + +Routine Description: + + Update the Firmware Volume Buffer with requested buffer data + +Arguments: + + StartAddress - StartAddress in buffer. This number will automatically + point to right address in buffer where data needed + to be updated. + Buffer - Buffer pointer from data will be copied to memory mapped buffer. + DataSize - Size of the data needed to be copied. + LocType - The type of the BSF + +Returns: + + EFI_ABORTED - The input parameter is error + EFI_SUCCESS - The function completed successfully + +--*/ +{ + UINT8 *LocalBufferPtrToWrite; + + if (LocType == FIRST_VTF) { + if ((StartAddress | IPF_CACHE_BIT) < (Bsf1LastStartAddress | IPF_CACHE_BIT)) { + printf ("ERROR: Start Address is less then the BSF start address\n"); + return EFI_ABORTED; + } + + LocalBufferPtrToWrite = (UINT8 *) Bsf1EndBuffer; + LocalBufferPtrToWrite -= (Fv1EndAddress - StartAddress); + } else { + if ((StartAddress | IPF_CACHE_BIT) < (Bsf2LastStartAddress | IPF_CACHE_BIT)) { + printf ("ERROR: Start Address is less then the BSF start address\n"); + return EFI_ABORTED; + } + LocalBufferPtrToWrite = (UINT8 *) Bsf2EndBuffer; + LocalBufferPtrToWrite -= (Fv2EndAddress - StartAddress); + } + + memcpy (LocalBufferPtrToWrite, Buffer, (UINTN) DataSize); + + return EFI_SUCCESS; +} + +EFI_STATUS +UpdateFfsHeader ( + IN UINT32 TotalBsfSize, + IN LOC_TYPE LocType + ) +/*++ + +Routine Description: + + Update the Firmware Volume Buffer with requested buffer data + +Arguments: + + TotalBsfSize - Size of the BSF + Fileoffset - The start of the file relative to the start of the FV. + LocType - The type of the BSF + +Returns: + + EFI_SUCCESS - The function completed successfully + EFI_INVALID_PARAMETER - The Ffs File Header Pointer is NULL + +--*/ +{ + EFI_FFS_FILE_HEADER *FileHeader; + UINTN RelativeAddress; + EFI_GUID EfiFirmwareVolumeTopFileGuid = EFI_FFS_VOLUME_TOP_FILE_GUID; + + // + // Find the BSF file header location + // + if (LocType == FIRST_VTF) { + GetRelativeAddressInBsfBuffer (Bsf1LastStartAddress, &RelativeAddress, FIRST_VTF); + FileHeader = (EFI_FFS_FILE_HEADER *) RelativeAddress; + } else { + GetRelativeAddressInBsfBuffer (Bsf2LastStartAddress, &RelativeAddress, SECOND_VTF); + FileHeader = (EFI_FFS_FILE_HEADER *) RelativeAddress; + } + + if (FileHeader == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // write header + // + memset (FileHeader, 0, sizeof (EFI_FFS_FILE_HEADER)); + memcpy (&FileHeader->Name, &EfiFirmwareVolumeTopFileGuid, sizeof (EFI_GUID)); + FileHeader->Type = EFI_FV_FILETYPE_FREEFORM; + FileHeader->Attributes = FFS_ATTRIB_CHECKSUM; + + // + // Now FileSize includes the EFI_FFS_FILE_HEADER + // + FileHeader->Size[0] = (UINT8) (TotalBsfSize & 0x000000FF); + FileHeader->Size[1] = (UINT8) ((TotalBsfSize & 0x0000FF00) >> 8); + FileHeader->Size[2] = (UINT8) ((TotalBsfSize & 0x00FF0000) >> 16); + + // + // Fill in checksums and state, all three must be zero for the checksums. + // + FileHeader->IntegrityCheck.Checksum.Header = 0; + FileHeader->IntegrityCheck.Checksum.File = 0; + FileHeader->State = 0; + FileHeader->IntegrityCheck.Checksum.Header = CalculateChecksum8 ((UINT8 *) FileHeader, sizeof (EFI_FFS_FILE_HEADER)); + FileHeader->IntegrityCheck.Checksum.File = CalculateChecksum8 ((UINT8 *) FileHeader, TotalBsfSize); + FileHeader->State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID; + + return EFI_SUCCESS; +} + +EFI_STATUS +ValidateAddressAndSize ( + IN UINT64 BaseAddress, + IN UINT64 FwVolSize + ) +/*++ + +Routine Description: + + Update the Firmware Volume Buffer with requested buffer data + +Arguments: + + BaseAddress - Base address for the Fw Volume. + + FwVolSize - Total Size of the FwVolume to which BSF will be attached.. + +Returns: + + EFI_SUCCESS - The function completed successfully + EFI_UNSUPPORTED - The input parameter is error + +--*/ +{ + if ((BaseAddress >= 0) && (FwVolSize > 0x40) && ((BaseAddress + FwVolSize) % 8 == 0)) { + return EFI_SUCCESS; + } + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +UpdateIA32ResetVector ( + IN CHAR8 *FileName, + IN UINT64 FirstFwVSize + ) +/*++ + +Routine Description: + + Update the 16 byte IA32 Reset vector to maintain the compatibility + +Arguments: + + FileName - Binary file name which contains the IA32 Reset vector info.. + FirstFwVSize - Total Size of the FwVolume to which BSF will be attached.. + +Returns: + + EFI_SUCCESS - The function completed successfully + EFI_ABORTED - Invalid File Size + EFI_INVALID_PARAMETER - Bad File Name + EFI_OUT_OF_RESOURCES - Memory allocation failed. + +--*/ +{ + UINT8 *Buffer; + UINT8 *LocalBsfBuffer; + UINTN FileSize; + UINTN NumByteRead; + FILE *Fp; + + if (!strcmp (FileName, "")) { + return EFI_INVALID_PARAMETER; + } + + Fp = fopen (FileName, "r+b"); + + if (Fp == NULL) { + printf ("\nERROR: Unable to open the file %s", FileName); + } + + FileSize = _filelength (_fileno (Fp)); + + if (FileSize > 16) { + return EFI_ABORTED; + } + + Buffer = malloc (FileSize); + if (Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + NumByteRead = fread (Buffer, sizeof (UINT8), FileSize, Fp); + + LocalBsfBuffer = (UINT8 *) Bsf1EndBuffer - SIZE_IA32_RESET_VECT; + memcpy (LocalBsfBuffer, Buffer, FileSize); + + if (Buffer) { + free (Buffer); + } + + return EFI_SUCCESS; +} + +VOID +CleanUpMemory ( + VOID + ) +/*++ + +Routine Description: + + This function cleans up any allocated buffer + +Arguments: + + NONE + +Returns: + + NONE + +--*/ +{ + PARSED_BSF_INFO *TempFileListPtr; + + if (Bsf1Buffer) { + free (Bsf1Buffer); + } + + if (Bsf2Buffer) { + free (Bsf2Buffer); + } + + // + // Cleanup the buffer which was allocated to read the file names from FV.INF + // + FileListPtr = FileListHeadPtr; + while (FileListPtr != NULL) { + TempFileListPtr = FileListPtr->NextBsfInfo; + free (FileListPtr); + FileListPtr = TempFileListPtr; + } +} + +EFI_STATUS +ProcessAndCreateBsf ( + IN UINT64 Size + ) +/*++ + +Routine Description: + + This function process the link list created during INF file parsing + and create component in BSF and updates its info in FIT table + +Arguments: + + Size - Size of the Firmware Volume of which, this BSF belongs to. + +Returns: + + EFI_UNSUPPORTED - Unknown FIT type + EFI_SUCCESS - The function completed successfully + +--*/ +{ + EFI_STATUS Status; + PARSED_BSF_INFO *ParsedInfoPtr; + + Status = EFI_SUCCESS; + + ParsedInfoPtr = FileListHeadPtr; + + while (ParsedInfoPtr != NULL) { + + switch (ParsedInfoPtr->CompType) { + // + // COMP_TYPE_FIT_HEADER is a special case, hence handle it here + // + case COMP_TYPE_FIT_HEADER: + Status = CreateFitTableAndInitialize (ParsedInfoPtr); + break; + + // + // COMP_TYPE_FIT_PAL_A is a special case, hence handle it here + // + case COMP_TYPE_FIT_PAL_A: + Status = CreateAndUpdatePAL_A (ParsedInfoPtr); + + // + // Based on BSF specification, once the PAL_A component has been written, + // update the Firmware Volume info as FIT table. This will be utilized + // to extract the Firmware Volume Start address where this BSF will be + // of part. + // + if (Status == EFI_SUCCESS) { + UpdateFitEntryForFwVolume (Size); + } + break; + + case COMP_TYPE_FIT_FV_BOOT: + // + // Since FIT entry for Firmware Volume has been created and it is + // located at (PAL_A start - 16 byte). So we will not process any + // Firmware Volume related entry from INF file + // + Status = EFI_SUCCESS; + break; + + default: + // + // Any other component type should be handled here. This will create the + // image in specified BSF and create appropriate entry about this + // component in FIT Entry. + // + Status = CreateAndUpdateComponent (ParsedInfoPtr); + if (EFI_ERROR (Status)) { + printf ("ERROR: Updating %s component.\n", ParsedInfoPtr->CompName); + } + break; + } + + ParsedInfoPtr = ParsedInfoPtr->NextBsfInfo; + } + + return Status; +} + +EFI_STATUS +GenerateBsfImage ( + IN UINT64 StartAddress1, + IN UINT64 Size1, + IN UINT64 StartAddress2, + IN UINT64 Size2 + ) +/*++ + +Routine Description: + + This is the main function which will be called from application. + +Arguments: + + StartAddress1 - The start address of the first BSF + Size1 - The size of the first BSF + StartAddress2 - The start address of the second BSF + Size2 - The size of the second BSF + +Returns: + + EFI_OUT_OF_RESOURCES - Can not allocate memory + The return value can be any of the values + returned by the calls to following functions: + GetBsfRelatedInfoFromInfFile + ProcessAndCreateBsf + UpdateIA32ResetVector + UpdateFfsHeader + WriteBsfBinary + +--*/ +{ + EFI_STATUS Status; + CHAR8 OutFileName1[FILE_NAME_SIZE]; + CHAR8 OutFileName2[FILE_NAME_SIZE]; + BOOLEAN SecondBSF; + + Status = EFI_UNSUPPORTED; + + if (StartAddress2 == 0) { + SecondBSF = FALSE; + } else { + SecondBSF = TRUE; + } + Fv1BaseAddress = StartAddress1; + Fv1EndAddress = Fv1BaseAddress + Size1; + + memset (OutFileName1, 0, FILE_NAME_SIZE); + sprintf ( + OutFileName1, + "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x-%s", + Bsf1NameGuid.Data1, + Bsf1NameGuid.Data2, + Bsf1NameGuid.Data3, + Bsf1NameGuid.Data4[0], + Bsf1NameGuid.Data4[1], + Bsf1NameGuid.Data4[2], + Bsf1NameGuid.Data4[3], + Bsf1NameGuid.Data4[4], + Bsf1NameGuid.Data4[5], + Bsf1NameGuid.Data4[6], + Bsf1NameGuid.Data4[7], + BSF_OUTPUT_FILE + ); + + // + // The image buffer for the First BSF + // + Bsf1Buffer = malloc ((UINTN) Size1); + if (Bsf1Buffer == NULL) { + printf ("\nERROR: Not enough resource to create memory mapped file for Boot Strap File"); + return EFI_OUT_OF_RESOURCES; + } + memset (Bsf1Buffer, 0x00, (UINTN) Size1); + Bsf1EndBuffer = (UINT8 *) Bsf1Buffer + Size1; + Bsf1LastStartAddress = Fv1EndAddress | IPF_CACHE_BIT; + + if (SecondBSF) { + Fv2BaseAddress = StartAddress2; + Fv2EndAddress = Fv2BaseAddress + Size2; + + memset (OutFileName2, 0, FILE_NAME_SIZE); + sprintf ( + OutFileName2, + "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x-%s", + Bsf2NameGuid.Data1, + Bsf2NameGuid.Data2, + Bsf2NameGuid.Data3, + Bsf2NameGuid.Data4[0], + Bsf2NameGuid.Data4[1], + Bsf2NameGuid.Data4[2], + Bsf2NameGuid.Data4[3], + Bsf2NameGuid.Data4[4], + Bsf2NameGuid.Data4[5], + Bsf2NameGuid.Data4[6], + Bsf2NameGuid.Data4[7], + BSF_OUTPUT_FILE + ); + + // + // The image buffer for the second BSF + // + Bsf2Buffer = malloc ((UINTN) Size2); + if (Bsf2Buffer == NULL) { + printf ("\nERROR: Not enough resource to create memory mapped file for Boot Strap File"); + return EFI_OUT_OF_RESOURCES; + } + memset (Bsf2Buffer, 0x00, (UINTN) Size2); + Bsf2EndBuffer = (UINT8 *) Bsf2Buffer + Size2; + Bsf2LastStartAddress = Fv2EndAddress | IPF_CACHE_BIT; + } + + Status = GetBsfRelatedInfoFromInfFile (BSF_INPUT_FILE); + if (Status != EFI_SUCCESS) { + printf ("\nERROR: Error in parsing input file"); + CleanUpMemory (); + return Status; + } + + Status = ProcessAndCreateBsf (Size1); + if (Status != EFI_SUCCESS) { + CleanUpMemory (); + return Status; + } + + Status = UpdateIA32ResetVector (IA32BinFile, Bsf1TotalSize); + if (Status != EFI_SUCCESS) { + CleanUpMemory (); + return Status; + } + + // + // Re arrange the FIT Table for Ascending order of their FIT Type.. + // + SortFitTable (); + + // + // All components have been updated in FIT table. Now perform the FIT table + // checksum. The following function will check if Checksum is required, + // if yes, then it will perform the checksum otherwise not. + // + CalculateFitTableChecksum (); + + // + // Write the FFS header + // + Bsf1TotalSize += sizeof (EFI_FFS_FILE_HEADER); + Bsf1LastStartAddress -= sizeof (EFI_FFS_FILE_HEADER); + Status = UpdateFfsHeader (Bsf1TotalSize, FIRST_VTF); + if (Status != EFI_SUCCESS) { + CleanUpMemory (); + return Status; + } + // + // Update the BSF buffer into specified BSF binary file + // + Status = WriteBsfBinary (OutFileName1, Bsf1TotalSize, FIRST_VTF); + + if (SecondBSF) { + Bsf2TotalSize += sizeof (EFI_FFS_FILE_HEADER); + Bsf2LastStartAddress -= sizeof (EFI_FFS_FILE_HEADER); + Status = UpdateFfsHeader (Bsf2TotalSize, SECOND_VTF); + if (Status != EFI_SUCCESS) { + CleanUpMemory (); + return Status; + } + + // + // Update the BSF buffer into specified BSF binary file + // + Status = WriteBsfBinary (OutFileName2, Bsf2TotalSize, SECOND_VTF); + } + + CleanUpMemory (); + printf ("\n"); + + return Status; +} + +EFI_STATUS +PeimFixupInFitTable ( + IN UINT64 StartAddress + ) +/*++ + +Routine Description: + + This function is an entry point to fixup SAL-E entry point. + +Arguments: + + StartAddress - StartAddress for PEIM..... + +Returns: + + EFI_SUCCESS - The function completed successfully + EFI_ABORTED - Error Opening File + EFI_OUT_OF_RESOURCES - System out of resources for memory allocation. + +--*/ +{ + EFI_STATUS Status; + FILE *Fp; + UINT64 *StartAddressPtr; + UINTN FirstFwVSize; + UINTN NumByte; + CHAR8 OutFileName1[FILE_NAME_SIZE]; + + StartAddressPtr = malloc (sizeof (UINT64)); + if (StartAddressPtr == NULL) { + return EFI_OUT_OF_RESOURCES; + } + *StartAddressPtr = StartAddress; + + memset (OutFileName1, 0, FILE_NAME_SIZE); + + sprintf ( + OutFileName1, + "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x-%s", + Bsf1NameGuid.Data1, + Bsf1NameGuid.Data2, + Bsf1NameGuid.Data3, + Bsf1NameGuid.Data4[0], + Bsf1NameGuid.Data4[1], + Bsf1NameGuid.Data4[2], + Bsf1NameGuid.Data4[3], + Bsf1NameGuid.Data4[4], + Bsf1NameGuid.Data4[5], + Bsf1NameGuid.Data4[6], + Bsf1NameGuid.Data4[7], + BSF_OUTPUT_FILE + ); + + Fp = fopen (OutFileName1, "r+b"); + + if (Fp == NULL) { + printf ("\nERROR: Error opening file "); + if (StartAddressPtr) { + free (StartAddressPtr); + } + + return EFI_ABORTED; + } + + FirstFwVSize = _filelength (_fileno (Fp)); + fseek (Fp, (long) (FirstFwVSize - (UINTN) (SIZE_IA32_RESET_VECT + SIZE_SALE_ENTRY_POINT)), SEEK_SET); + NumByte = fwrite ((VOID *) StartAddressPtr, sizeof (UINT64), 1, Fp); + + if (Fp) { + fclose (Fp); + } + + if (StartAddressPtr) { + free (StartAddressPtr); + } + + printf ("\n"); + Status = EFI_SUCCESS; + return Status; +} + +EFI_STATUS +UpdateSymFile ( + IN UINT64 BaseAddress, + IN CHAR8 *DestFileName, + IN CHAR8 *SourceFileName + ) +/*++ + +Routine Description: + + This function adds the SYM tokens in the source file to the destination file. + The SYM tokens are updated to reflect the base address. + +Arguments: + + BaseAddress - The base address for the new SYM tokens. + DestFileName - The destination file. + SourceFileName - The source file. + +Returns: + + EFI_SUCCESS - The function completed successfully. + EFI_INVALID_PARAMETER - One of the input parameters was invalid. + EFI_ABORTED - An error occurred. + +--*/ +{ + FILE *SourceFile; + FILE *DestFile; + CHAR8 Buffer[_MAX_PATH]; + CHAR8 Type[_MAX_PATH]; + CHAR8 Address[_MAX_PATH]; + CHAR8 Section[_MAX_PATH]; + CHAR8 Token[_MAX_PATH]; + CHAR8 BaseToken[_MAX_PATH]; + UINT64 TokenAddress; + long StartLocation; + + // + // Verify input parameters. + // + if (BaseAddress == 0 || DestFileName == NULL || SourceFileName == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Open the source file + // + SourceFile = fopen (SourceFileName, "r"); + if (SourceFile == NULL) { + + // + // SYM files are not required. + // + return EFI_SUCCESS; + } + + // + // Use the file name minus extension as the base for tokens + // + strcpy (BaseToken, SourceFileName); + strtok (BaseToken, ". \t\n"); + strcat (BaseToken, "__"); + + // + // Open the destination file + // + DestFile = fopen (DestFileName, "a+"); + if (DestFile == NULL) { + fclose (SourceFile); + return EFI_ABORTED; + } + + // + // If this is the beginning of the output file, write the symbol format info. + // + if (fseek (DestFile, 0, SEEK_END) != 0) { + fclose (SourceFile); + fclose (DestFile); + return EFI_ABORTED; + } + + StartLocation = ftell (DestFile); + + if (StartLocation == 0) { + fprintf (DestFile, "TEXTSYM format | V1.0\n"); + } else if (StartLocation == -1) { + fclose (SourceFile); + fclose (DestFile); + return EFI_ABORTED; + } + + // + // Read the first line + // + if (fgets (Buffer, _MAX_PATH, SourceFile) == NULL) { + Buffer[0] = 0; + } + + // + // Make sure it matches the expected sym format + // + if (strcmp (Buffer, "TEXTSYM format | V1.0\n")) { + fclose (SourceFile); + fclose (DestFile); + return EFI_ABORTED; + } + + // + // Read in the file + // + while (feof (SourceFile) == 0) { + + // + // Read a line + // + if (fscanf (SourceFile, "%s | %s | %s | %s\n", Type, Address, Section, Token) == 4) { + + // + // Get the token address + // + AsciiStringToUint64 (Address, TRUE, &TokenAddress); + + // + // Add the base address, the size of the FFS file header and the size of the peim header. + // + TokenAddress += BaseAddress &~IPF_CACHE_BIT; + + fprintf (DestFile, "%s | %016I64X | %s | %s%s\n", Type, TokenAddress, Section, BaseToken, Token); + } + } + + fclose (SourceFile); + fclose (DestFile); + return EFI_SUCCESS; +} + +EFI_STATUS +CalculateFitTableChecksum ( + VOID + ) +/*++ + +Routine Description: + + This function will perform byte checksum on the FIT table, if the the checksum required + field is set to CheckSum required. If the checksum is not required then checksum byte + will have value as 0;. + +Arguments: + + NONE + +Returns: + + Status - Value returned by call to CalculateChecksum8 () + EFI_SUCCESS - The function completed successfully + +--*/ +{ + FIT_TABLE *TmpFitPtr; + UINT64 FitTableAdd; + UINT64 FitTableAddOffset; + UINTN RelativeAddress; + UINTN Size; + + // + // Read the Fit Table address from Itanium-based address map. + // + FitTableAddOffset = Fv1EndAddress - (SIZE_IA32_RESET_VECT + SIZE_SALE_ENTRY_POINT + SIZE_FIT_TABLE_ADD); + + // + // Translate this Itanium-based address in terms of local buffer address which + // contains the image for Boot Strapped File + // + GetRelativeAddressInBsfBuffer (FitTableAddOffset, &RelativeAddress, FIRST_VTF); + FitTableAdd = *(UINTN *) RelativeAddress; + + GetRelativeAddressInBsfBuffer (FitTableAdd, &RelativeAddress, FIRST_VTF); + + TmpFitPtr = (FIT_TABLE *) RelativeAddress; + + Size = TmpFitPtr->CompSize * 16; + + if ((TmpFitPtr->CvAndType & CHECKSUM_BIT_MASK) >> 7) { + TmpFitPtr->CheckSum = 0; + TmpFitPtr->CheckSum = CalculateChecksum8 ((UINT8 *) TmpFitPtr, Size); + } else { + TmpFitPtr->CheckSum = 0; + } + + return EFI_SUCCESS; +} + +VOID +PrintUtilityInfo ( + VOID + ) +/*++ + +Routine Description: + + Displays the standard utility information to SDTOUT + +Arguments: + + None + +Returns: + + None + +--*/ +{ + printf ( + "%s, EFI 2.0 BootStrap File Generation Utility. Version %i.%i, %s.\n\n", + UTILITY_NAME, + UTILITY_MAJOR_VERSION, + UTILITY_MINOR_VERSION, + UTILITY_DATE + ); +} + +VOID +PrintUsage ( + VOID + ) +/*++ + +Routine Description: + + Displays the utility usage syntax to STDOUT + +Arguments: + + None + +Returns: + + None + +--*/ +{ + printf ( + "Usage: %s -B BaseAddress -S FwVolumeSize\n", + UTILITY_NAME + ); + printf (" Where:\n"); + printf ("\tBaseAddress is the starting address of Firmware Volume where\n\tBoot Strapped Image will reside.\n\n"); + printf ("\tFwVolumeSize is the size of Firmware Volume.\n\n"); +} + +EFI_STATUS +main ( + IN UINTN argc, + IN CHAR8 **argv + ) +/*++ + +Routine Description: + + This utility uses GenBsfImage.dll to build a Boot Strap File Image which will be + part of firmware volume image. + +Arguments: + + argc - The count of the parameters + argv - The parameters + + +Returns: + + 0 - No error conditions detected. + 1 - One or more of the input parameters is invalid. + 2 - A resource required by the utility was unavailable. + - Most commonly this will be memory allocation or file creation. + 3 - GenFvImage.dll could not be loaded. + 4 - Error executing the GenFvImage dll. + 5 - Now this tool does not support the IA32 platform + +--*/ +{ + UINT8 Index; + UINT64 StartAddress1; + UINT64 StartAddress2; + UINT64 FwVolSize1; + UINT64 FwVolSize2; + BOOLEAN FirstRoundB; + BOOLEAN FirstRoundS; + EFI_STATUS Status; + BOOLEAN IsIA32; + + // + // Display utility information + // + PrintUtilityInfo (); + + // + // Verify the correct number of IA32 arguments + // + IsIA32 = FALSE; + if (argc == IA32_ARGS) { + // + // Now this tool is not used for IA32 platform, if it will be used in future, + // the IA32-specific functions need to be updated and verified, the updating can + // refer to IPF relevant functions) + // + printf ("ERROR: Now this tool does not support the IA32 platform!\n"); + printf ("ERROR: And the IA32-specific functions need to be updated and verified!\n"); + return 5; + + /* + StartAddress1 = 0; + IsIA32 = TRUE; + + // + // Parse the command line arguments + // + for (Index = 1; Index < IA32_ARGS; Index += 2) { + + // + // Make sure argument pair begin with - or / + // + if (argv[Index][0] != '-' && argv[Index][0] != '/') { + PrintUsage (); + printf ("ERROR: Argument pair must begin with \"-\" or \"/\"\n"); + return 1; + } + + // + // Make sure argument specifier is only one letter + // + if (argv[Index][2] != 0) { + PrintUsage (); + printf ("ERROR: Unrecognized argument \"%s\".\n", argv[Index]); + return 1; + } + + // + // Determine argument to read + // + switch (argv[Index][1]) { + + case 't': + case 'T': + Status = AsciiStringToUint64 (argv[Index + 1], FALSE, &StartAddress1); + if (Status != EFI_SUCCESS) { + printf ("\nERROR: Bad start of address \"%s\"\n", argv[Index + 1]); + return 1; + } + break; + + default: + PrintUsage (); + printf ("Unrecognized IA32 argument \"%s\".\n", argv[Index]); + IsIA32 = FALSE; + break; + } + } + + if (IsIA32) { + // + // Call the GenBsfImage + // + Status = Generate32BsfImage (StartAddress1); + + if (EFI_ERROR(Status)) { + switch (Status) { + + case EFI_INVALID_PARAMETER: + printf ("\nERROR: Invalid parameter passed to GenBsfImage function .\n"); + break; + + case EFI_ABORTED: + printf ("\nERROR: Error detected while creating the file image.\n"); + break; + + case EFI_OUT_OF_RESOURCES: + printf ("\nERROR: GenBsfImage function could not allocate required resources.\n"); + break; + + case EFI_VOLUME_CORRUPTED: + printf ("\nERROR: No base address was specified \n"); + break; + + default: + printf ("\nERROR: GenBsfImage function returned unknown status %X.\n", Status); + break; + } + return 2; + } + + return 0; + } + */ + } + + // + // Verify the correct number of arguments + // + if (argc != ONE_BSF_ARGS && argc != TWO_BSF_ARGS) { + PrintUsage (); + return 1; + } + + // + // Initialize variables + // + StartAddress1 = 0; + StartAddress2 = 0; + FwVolSize1 = 0; + FwVolSize2 = 0; + FirstRoundB = TRUE; + FirstRoundS = TRUE; + + // + // Parse the command line arguments + // + for (Index = 1; Index < argc; Index += 2) { + + // + // Make sure argument pair begin with - or / + // + if (argv[Index][0] != '-' && argv[Index][0] != '/') { + PrintUsage (); + printf ("ERROR: Argument pair must begin with \"-\" or \"/\"\n"); + return 1; + } + + // + // Make sure argument specifier is only one letter + // + if (argv[Index][2] != 0) { + PrintUsage (); + printf ("ERROR: Unrecognized argument \"%s\".\n", argv[Index]); + return 1; + } + + // + // Determine argument to read + // + switch (argv[Index][1]) { + + case 'B': + case 'b': + if (FirstRoundB) { + Status = AsciiStringToUint64 (argv[Index + 1], FALSE, &StartAddress1); + FirstRoundB = FALSE; + } else { + Status = AsciiStringToUint64 (argv[Index + 1], FALSE, &StartAddress2); + } + + if (Status != EFI_SUCCESS) { + printf ("\nERROR: Bad start of address \"%s\"\n", argv[Index + 1]); + return 1; + } + break; + + case 'S': + case 's': + if (FirstRoundS) { + Status = AsciiStringToUint64 (argv[Index + 1], FALSE, &FwVolSize1); + FirstRoundS = FALSE; + } else { + Status = AsciiStringToUint64 (argv[Index + 1], FALSE, &FwVolSize2); + } + + if (Status != EFI_SUCCESS) { + printf ("\nERROR: Bad size \"%s\"\n", argv[Index + 1]); + return 1; + } + break; + + default: + PrintUsage (); + printf ("ERROR: Unrecognized argument \"%s\".\n", argv[Index]); + return 1; + break; + } + } + + // + // Call the GenBsfImage + // + Status = GenerateBsfImage (StartAddress1, FwVolSize1, StartAddress2, FwVolSize2); + + if (EFI_ERROR (Status)) { + switch (Status) { + + case EFI_INVALID_PARAMETER: + printf ("\nERROR: Invalid parameter passed to GenBsfImage function .\n"); + break; + + case EFI_ABORTED: + printf ("\nERROR: Error detected while creating the file image.\n"); + break; + + case EFI_OUT_OF_RESOURCES: + printf ("\nERROR: GenBsfImage function could not allocate required resources.\n"); + break; + + case EFI_VOLUME_CORRUPTED: + printf ("\nERROR: No base address was specified \n"); + break; + + default: + printf ("\nERROR: GenBsfImage function returned unknown status %X.\n", Status); + break; + } + return 2; + } + return 0; +} + +EFI_STATUS +Generate32BsfImage ( +IN UINT64 BootFileStartAddress + ) +/*++ + +Routine Description: + + This is the main IA32 function which will be called from application. + (Now this tool is not used for IA32 platform, if it will be used in future, + the relative functions need to be updated, the updating can refer to IPF + functions) + +Arguments: + + BootFileStartAddress - Top Address of Boot File + +Returns: + + The return value can be any of the values + returned by the calls to following functions: + Get32BsfRelatedInfoFromInfFile + CreateBsfBuffer + ProcessAndCreate32Bsf + Update32FfsHeader + WriteBsfBinary + +--*/ +{ + EFI_STATUS Status; + UINT32 BsfSize; + CHAR8 OutFileName[FILE_NAME_SIZE]; + + EFI_GUID BsfNameGuid = EFI_IA32_BOOT_STRAP_GUID; + + Status = EFI_UNSUPPORTED; + + memset (OutFileName, 0, FILE_NAME_SIZE); + + sprintf ( + OutFileName, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x-%s", + BsfNameGuid.Data1, + BsfNameGuid.Data2, + BsfNameGuid.Data3, + BsfNameGuid.Data4[0], + BsfNameGuid.Data4[1], + BsfNameGuid.Data4[2], + BsfNameGuid.Data4[3], + BsfNameGuid.Data4[4], + BsfNameGuid.Data4[5], + BsfNameGuid.Data4[6], + BsfNameGuid.Data4[7], + BSF_OUTPUT_FILE + ); + + + Status = Get32BsfRelatedInfoFromInfFile (BSF_INPUT_FILE); + + if (Status != EFI_SUCCESS) { + printf ("\nERROR: Error in parsing input file"); + CleanUpMemory (); + return Status; + } + + if (GetTotal32BsfSize (&BsfSize) == EFI_SUCCESS) { + Bsf1Buffer = malloc ((UINTN) BsfSize); + if (Bsf1Buffer == NULL) { + printf ("\nERROR: Not enough resource to create memory mapped file for Boot Strap File"); + CleanUpMemory (); + return EFI_OUT_OF_RESOURCES; + } + memset (Bsf1Buffer, 0x00, (UINTN) BsfSize); + } else { + printf ("\nERROR: Could not get BSF size."); + CleanUpMemory (); + return EFI_ABORTED; + } + + // + //VTF must align properly + // + Bsf1LastStartAddress = BootFileStartAddress - BsfSize; + Bsf1LastStartAddress = Bsf1LastStartAddress & -8; + BsfSize = (UINT32)BootFileStartAddress - (UINT32)Bsf1LastStartAddress; + Bsf1LastStartAddress = BsfSize; + BufferToTop = (UINT32)BootFileStartAddress - BsfSize; + + Status = ProcessAndCreate32Bsf (BsfSize); + + if (Status != EFI_SUCCESS) { + CleanUpMemory(); + return Status; + } + + // + // Write the FFS header + // + Status = Update32FfsHeader (BsfSize); + + if (Status != EFI_SUCCESS) { + CleanUpMemory(); + return Status; + } + + // + // Calculate the Start address of this BSF + // + Bsf1Buffer = (UINT8 *)Bsf1Buffer + Bsf1LastStartAddress; + + // + // Update the BSF buffer into specified BSF binary file + // + Status = WriteBsfBinary (OutFileName, BsfSize - (UINT32)Bsf1LastStartAddress, FIRST_VTF); + + if (Status != EFI_SUCCESS) { + CleanUpMemory(); + return Status; + } + + Status = Write32SoftFit (IA32_SOFT_FIT, FileListHeadPtr); + + if (Status != EFI_SUCCESS) { + CleanUpMemory(); + return Status; + } + + CleanUpMemory (); + printf ("\n"); + + return Status; +} + +EFI_STATUS +GetTotal32BsfSize( + IN UINT32 *BsfSize + ) +/*++ + +Routine Description: + + This function calculates total size for IA32 BSF which would be needed to create + the buffer. This will be done using Passed Info link list and looking for the + size of the components which belong to BSF. The addtional file header is accounted. + +Arguments: + + BSFSize - Pointer to the size of IA32 BSF + +Returns: + + EFI_ABORTED - Returned due to one of the following resons: + (a) Error Opening File + EFI_SUCCESS - The fuction completes successfully + +--*/ +{ + PARSED_BSF_INFO *BsfInfo; + FILE *Fp; + UINT32 Alignment; + + *BsfSize = 0; + Alignment = 0; + + BsfInfo = FileListHeadPtr; + + while (BsfInfo != NULL) { + if (BsfInfo->LocationType != SECOND_VTF) { + + if ( BsfInfo->Align ) { + // + // Create additional align to compensate for component boundary requirements + // + Alignment = 1 << BsfInfo->Align; + *BsfSize += Alignment; + } + + if (BsfInfo->PreferredSize) { + *BsfSize += BsfInfo->CompSize; + } else { + Fp = fopen (BsfInfo->CompBinName,"r+b"); + + if (Fp == NULL) { + printf ("\nERROR: Error in opening file %s", BsfInfo->CompBinName); + return EFI_ABORTED; + } + + *BsfSize += _filelength (_fileno (Fp)); + + if (Fp) { + fclose (Fp); + } + } + } + BsfInfo = BsfInfo->NextBsfInfo; + } + + // + // Add file header space + // + *BsfSize += sizeof (EFI_FFS_FILE_HEADER); + + // + // Create additional to IA32 Seccore section header + // + *BsfSize += sizeof (EFI_COMMON_SECTION_HEADER); + + return EFI_SUCCESS; +} + +EFI_STATUS +ProcessAndCreate32Bsf ( + IN UINT64 Size + ) +/*++ + +Routine Description: + + This function process the link list created during INF file parsing + and create component in IA32 BSF + +Arguments: + + Size - Size of the Firmware Volume of which, this BSF belongs to. + +Returns: + + EFI_UNSUPPORTED - Unknown component type + EFI_SUCCESS - The function completed successfully + +--*/ +{ + EFI_STATUS Status; + PARSED_BSF_INFO *ParsedInfoPtr; + + Status = EFI_SUCCESS; + + ParsedInfoPtr = FileListHeadPtr; + + while (ParsedInfoPtr != NULL) { + + switch (ParsedInfoPtr->CompType) { + + case COMP_TYPE_SECCORE: + Status = CreateAndUpdateSeccore (ParsedInfoPtr); + break; + + default: + // + // Any other component type should be handled here. This will create the + // image in specified BSF + // + Status = CreateAndUpdate32Component (ParsedInfoPtr); + if (EFI_ERROR(Status)) { + printf ("ERROR: Updating %s component.\n", ParsedInfoPtr->CompName); + } + break; + } + + ParsedInfoPtr = ParsedInfoPtr->NextBsfInfo; + } + + return Status; +} + +EFI_STATUS +CreateAndUpdateSeccore ( + IN PARSED_BSF_INFO *BsfInfo + ) +/*++ + +Routine Description: + + This function reads the binary file for seccore and update them + in IA32 BSF Buffer + +Arguments: + + BsfInfo - Pointer to Parsed Info + +Returns: + + EFI_ABORTED - Due to one of the following reasons: + (a)Error Opening File + (b)The PAL_A Size is more than specified size status + One of the values mentioned below returned from + call to UpdateSymFile + EFI_SUCCESS - The function completed successfully. + EFI_INVALID_PARAMETER - One of the input parameters was invalid. + EFI_ABORTED - An error occurred.UpdateSymFile + EFI_OUT_OF_RESOURCES - Memory allocation failed. + +--*/ +{ + UINT8 *SecbinStartAddress; + UINT8 *SecfileStartAddress; + UINT32 FileSize; + UINT64 NumByteRead; + UINT8 *Buffer; + FILE *Fp; + UINT64 TotalLength; + EFI_COMMON_SECTION_HEADER *SecHeader; + + Fp = fopen (BsfInfo->CompBinName, "r+b"); + + if (Fp == NULL) { + printf ("\nERROR: Opening file %s", BsfInfo->CompBinName); + return EFI_ABORTED; + } + + FileSize = _filelength (_fileno (Fp)); + + if (BsfInfo->PreferredSize) { + if (FileSize > BsfInfo->CompSize) { + printf("\nERROR: The Seccore Size is more than specified size"); + return EFI_ABORTED; + } + + FileSize = BsfInfo->CompSize; + } + + BsfInfo->CompSize = FileSize; + + Buffer = malloc ((UINTN) FileSize); + if (Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + memset (Buffer, 0, (UINTN) FileSize); + + // + // Read seccore in a buffer + // + NumByteRead = fread (Buffer, sizeof (UINT8), (UINTN) FileSize, Fp); + fclose (Fp); + + SecfileStartAddress = (UINT8 *) Bsf1Buffer + Bsf1LastStartAddress - FileSize - sizeof (EFI_COMMON_SECTION_HEADER); + if (SecfileStartAddress == NULL) { + return EFI_INVALID_PARAMETER; + } + + SecbinStartAddress = SecfileStartAddress + sizeof (EFI_COMMON_SECTION_HEADER); + + BsfInfo->CompPreferredAddress = Bsf1LastStartAddress - FileSize + BufferToTop; + + // + // write section header + // + memset (SecfileStartAddress, 0, sizeof (EFI_COMMON_SECTION_HEADER)); + SecHeader = (EFI_COMMON_SECTION_HEADER *) SecfileStartAddress; + SecHeader->Type = EFI_SECTION_RAW; + TotalLength = sizeof (EFI_COMMON_SECTION_HEADER) + (UINT64) FileSize; + memcpy (SecHeader->Size, &TotalLength, 3); + + // + // write seccore + // + memcpy (SecbinStartAddress, Buffer, (UINTN) FileSize); + + if (Buffer) { + free (Buffer); + } + + Bsf1LastStartAddress = SecfileStartAddress - (UINT8 *) Bsf1Buffer; + + return EFI_SUCCESS; +} + +EFI_STATUS +CreateAndUpdate32Component ( + IN PARSED_BSF_INFO *BsfInfo + ) +/*++ + +Routine Description: + + This function reads the binary file for each components. Add it at aligned address. + +Arguments: + + BsfInfo - Pointer to Parsed Info + +Returns: + + EFI_SUCCESS - The function completed successful + EFI_ABORTED - Aborted due to one of the many reasons like: + (a) Component Size greater than the specified size. + (b) Error opening files. + EFI_INVALID_PARAMETER - Value returned from call to UpdateEntryPoint() + EFI_OUT_OF_RESOURCES - Memory allocation failed. + +--*/ +{ + UINT64 CompStartAddress; + UINT32 FileSize; + UINT64 NumByteRead; + UINT8 *Buffer; + FILE *Fp; + UINT8 *LocalBufferPtrToWrite; + UINT64 Alignment; + + Fp = fopen (BsfInfo->CompBinName, "r+b"); + + if (Fp == NULL) { + printf("\nERROR: Opening file %s", BsfInfo->CompBinName); + return EFI_ABORTED; + } + + FileSize = _filelength (_fileno (Fp)); + + if (BsfInfo->PreferredSize) { + if (FileSize > BsfInfo->CompSize) { + printf("\nERROR: The component size is more than specified size"); + return EFI_ABORTED; + } + FileSize = BsfInfo->CompSize; + } + BsfInfo->CompSize = FileSize; + + Buffer = malloc ((UINTN) FileSize); + if (Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + memset (Buffer,0, (UINTN) FileSize); + + NumByteRead = fread (Buffer, sizeof (UINT8), (UINTN) FileSize, Fp); + fclose (Fp); + + CompStartAddress = Bsf1LastStartAddress - FileSize + BufferToTop; + + if (BsfInfo->Align) { + // + // Create additional align to compensate for component boundary requirements + // + Alignment = 0 - (1 << BsfInfo->Align); + CompStartAddress = CompStartAddress & Alignment; + } + + BsfInfo->CompPreferredAddress = CompStartAddress; + + // + // write bin + // + LocalBufferPtrToWrite = (UINT8 *) Bsf1Buffer; + Bsf1LastStartAddress = CompStartAddress - BufferToTop; + LocalBufferPtrToWrite += Bsf1LastStartAddress; + memcpy (LocalBufferPtrToWrite, Buffer, (UINTN) FileSize); + Bsf1LastStartAddress = CompStartAddress - BufferToTop; + + // + // Free the buffer + // + if (Buffer) { + free (Buffer); + } + + return EFI_SUCCESS; +} + +EFI_STATUS +Update32FfsHeader( + IN UINT32 BsfSize + ) +/*++ + +Routine Description: + + Update the Firmware Volume Buffer with requested buffer data + +Arguments: + + BsfSize - Size of the IA32 BSF + +Returns: + + EFI_SUCCESS - The function completed successfully + EFI_INVALID_PARAMETER - The Ffs File Header Pointer is NULL + +--*/ +{ + EFI_FFS_FILE_HEADER *FileHeader; + UINT32 TotalBsfSize; + EFI_GUID EfiFirmwareVolumeTopFileGuid = EFI_FFS_VOLUME_TOP_FILE_GUID; + + + // + // Find the BSF file header location, the bsf file must be 8 bytes aligned + // + Bsf1LastStartAddress -= sizeof (EFI_FFS_FILE_HEADER); + Bsf1LastStartAddress += BufferToTop; + Bsf1LastStartAddress = Bsf1LastStartAddress & -8; + Bsf1LastStartAddress -= BufferToTop; + FileHeader = (EFI_FFS_FILE_HEADER*)((UINT8*)Bsf1Buffer + Bsf1LastStartAddress); + + if (FileHeader == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // write header + // + memset (FileHeader, 0, sizeof(EFI_FFS_FILE_HEADER)); + memcpy (&FileHeader->Name, &EfiFirmwareVolumeTopFileGuid, sizeof (EFI_GUID)); + + FileHeader->Type = EFI_FV_FILETYPE_FREEFORM; + FileHeader->Attributes = FFS_ATTRIB_CHECKSUM; + + // + // Now FileSize includes the EFI_FFS_FILE_HEADER + // + TotalBsfSize = BsfSize - (UINT32)Bsf1LastStartAddress; + FileHeader->Size[0] = (UINT8) (TotalBsfSize & 0x000000FF); + FileHeader->Size[1] = (UINT8) ((TotalBsfSize & 0x0000FF00) >> 8); + FileHeader->Size[2] = (UINT8) ((TotalBsfSize & 0x00FF0000) >> 16); + + // + // Fill in checksums and state, all three must be zero for the checksums. + // + FileHeader->IntegrityCheck.Checksum.Header = 0; + FileHeader->IntegrityCheck.Checksum.File = 0; + FileHeader->State = 0; + FileHeader->IntegrityCheck.Checksum.Header = CalculateChecksum8 ((UINT8*) FileHeader, sizeof (EFI_FFS_FILE_HEADER)); + FileHeader->IntegrityCheck.Checksum.File = CalculateChecksum8 ((UINT8*) FileHeader, TotalBsfSize); + FileHeader->State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID; + + return EFI_SUCCESS; +} + +EFI_STATUS +Get32BsfRelatedInfoFromInfFile ( + IN CHAR8 *FileName + ) +/*++ + +Routine Description: + + This function reads the input file, parse it and create a list of tokens + which is parsed and used, to intialize the data related to IA32 BSF + +Arguments: + + FileName FileName which needed to be read to parse data + +Returns: + + EFI_ABORTED Error in opening file + EFI_INVALID_PARAMETER File doesn't contain any valid informations + EFI_OUT_OF_RESOURCES Malloc Failed + EFI_SUCCESS The function completed successfully + +--*/ +{ + FILE *Fp; + UINTN Index; + EFI_STATUS Status; + + Fp = fopen (FileName, "r"); + if (Fp == NULL) { + printf ("\nERROR: Error in opening %s file\n", FileName); + return EFI_ABORTED; + } + + ValidLineCount (Fp); + + if (ValidLineNum == 0) { + printf ("\nERROR: File doesn't contain any valid informations"); + return EFI_INVALID_PARAMETER; + } + + TokenStr = (CHAR8 **)malloc (sizeof (UINTN) * (2 * ValidLineNum + 1)); + + if (TokenStr == NULL) { + return EFI_OUT_OF_RESOURCES; + } + memset (TokenStr, 0, (sizeof (UINTN) * (2 * ValidLineNum + 1))); + OrgStrTokPtr = TokenStr; + + for (Index = 0; Index < (2 * ValidLineNum); Index++) { + *TokenStr = (CHAR8 *)malloc (sizeof (CHAR8) * FILE_NAME_SIZE); + + if (*TokenStr == NULL) { + free (OrgStrTokPtr); + return EFI_OUT_OF_RESOURCES; + } + + memset (*TokenStr, 0, FILE_NAME_SIZE); +// free (*TokenStr); + TokenStr++; + } + + TokenStr = NULL; + TokenStr = OrgStrTokPtr; + fseek (Fp, 0L, SEEK_SET); + + Status = InitializeComps(); + + if (Status != EFI_SUCCESS) { + free (TokenStr); + return Status; + } + ParseInputFile (Fp); + Initialize32InFileInfo (); + + if (Fp) { + fclose (Fp); + } + free (TokenStr); + return EFI_SUCCESS; +} + +VOID +Initialize32InFileInfo ( + VOID + ) +/*++ + +Routine Description: + + This function intializes the relevant global variable which is being + used to store the information retrieved from IA32 INF file. + +Arguments: + + NONE + +Returns: + + NONE + +--*/ +{ + UINTN SectionOptionFlag; + UINTN SectionCompFlag; + + SectionOptionFlag =0 ; + SectionCompFlag = 0; + TokenStr = OrgStrTokPtr; + while (*TokenStr != NULL) { + if (_stricmp (*TokenStr, "[OPTIONS]") == 0) { + SectionOptionFlag = 1; + SectionCompFlag = 0; + } + + if (_stricmp (*TokenStr, "[COMPONENTS]") == 0) { + if (FileListPtr == NULL) { + FileListPtr = FileListHeadPtr; + } + + SectionCompFlag = 1; + SectionOptionFlag = 0; + TokenStr++; + } + + if (SectionOptionFlag) { + if (_stricmp (*TokenStr, "IA32_RST_BIN") == 0) { + *TokenStr++; + strcpy (IA32BinFile, *TokenStr); + } + } + + if (SectionCompFlag) { + if (_stricmp (*TokenStr, "COMP_NAME") == 0) { + TokenStr++; + strcpy (FileListPtr->CompName, *TokenStr); + TokenStr++; + ParseAndUpdate32Components (FileListPtr); + } + + if (*TokenStr != NULL) { + FileListPtr->NextBsfInfo = malloc (sizeof (PARSED_BSF_INFO)); + if (FileListPtr->NextBsfInfo == NULL) { + printf ("Error: Out of memory resources.\n"); + break; + } + FileListPtr = FileListPtr->NextBsfInfo; + memset (FileListPtr, 0, sizeof(PARSED_BSF_INFO)); + FileListPtr->NextBsfInfo = NULL; + continue; + } else { + break; + } + } + + TokenStr++; + } +} + +VOID +ParseAndUpdate32Components ( + IN PARSED_BSF_INFO *BsfInfo + ) +/*++ + +Routine Description: + + This function intializes the relevant global variable which is being + used to store the information retrieved from INF file. + +Arguments: + + BsfInfo - A pointer to the BSF Info Structure + + +Returns: + + None + +--*/ +{ + UINT64 StringValue; + UINT64 AlignStringValue; + + while (*TokenStr != NULL && (_stricmp (*TokenStr, "COMP_NAME") != 0)) { + + if (_stricmp (*TokenStr, "COMP_LOC") == 0) { + TokenStr++; + if (_stricmp (*TokenStr, "B") == 0) { + BsfInfo->LocationType = FIRST_VTF; + } else if (_stricmp (*TokenStr, "N") == 0) { + BsfInfo->LocationType = SECOND_VTF; + } else { + BsfInfo->LocationType = NONE; + printf ("\nERROR: Unknown location for component %s", BsfInfo->CompName); + } + } else if (_stricmp (*TokenStr, "COMP_TYPE") == 0) { + TokenStr++; + if (AsciiStringToUint64 (*TokenStr, FALSE, &StringValue) != EFI_SUCCESS) { + printf ("\nERROR: Could not read a numeric value from \"%s\".", TokenStr); + return; + } + BsfInfo->CompType = (UINT8) StringValue; + } else if (_stricmp (*TokenStr, "COMP_VER") == 0) { + TokenStr++; + if (_stricmp (*TokenStr, "-") == 0) { + BsfInfo->VersionPresent = FALSE; + BsfInfo->MajorVer = 0; + BsfInfo->MinorVer = 0; + } else { + BsfInfo->VersionPresent = TRUE; + ConvertVersionInfo (*TokenStr, &BsfInfo->MajorVer, &BsfInfo->MinorVer); + } + } else if (_stricmp (*TokenStr, "COMP_BIN") == 0) { + TokenStr++; + strcpy (BsfInfo->CompBinName, *TokenStr); + } else if (_stricmp (*TokenStr, "COMP_SYM") == 0) { + TokenStr++; + strcpy (BsfInfo->CompSymName, *TokenStr); + } else if (_stricmp (*TokenStr, "COMP_SIZE") == 0) { + TokenStr++; + if (_stricmp (*TokenStr, "-") == 0) { + BsfInfo->PreferredSize = FALSE; + BsfInfo->CompSize = 0; + } else { + BsfInfo->PreferredSize = TRUE; + if (AsciiStringToUint64 (*TokenStr, FALSE, &StringValue) != EFI_SUCCESS) { + printf ("\nERROR: Could not read a numeric value from \"%s\".", TokenStr); + return; + } + BsfInfo->CompSize = (UINTN) StringValue; + } + + } else if (_stricmp (*TokenStr, "COMP_CS") == 0) { + TokenStr++; + if (_stricmp (*TokenStr, "1") == 0) { + BsfInfo->CheckSumRequired = 1; + } else if (_stricmp (*TokenStr, "0") == 0) { + BsfInfo->CheckSumRequired = 0; + } else { + printf ("\nERROR: Bad information in INF file about Checksum required field"); + } + } else if (_stricmp (*TokenStr, "COMP_ALIGN") == 0) { + TokenStr++; + if (AsciiStringToUint64 (*TokenStr, FALSE, &AlignStringValue) != EFI_SUCCESS) { + printf ("\nERROR: Could not read a numeric value from \"%s\".", TokenStr); + return; + } + if (AlignStringValue >= 0) { + BsfInfo->Align = (UINT32) AlignStringValue; + } else { + printf ("\nERROR: invalid align \"%s\".", AlignStringValue); + return; + } + } + TokenStr++; + if (*TokenStr == NULL) { + break; + } + } +} + +EFI_STATUS +Write32SoftFit( + IN CHAR8 *FileName, + IN PARSED_BSF_INFO *BsfInfo + ) +/*++ + +Routine Description: + + Write IA32 Firmware Volume component address from memory to a file. + +Arguments: + + FileName Output File Name which needed to be created/ + BsfInfo Parsed info link + +Returns: + + EFI_ABORTED - Returned due to one of the following resons: + (a) Error Opening File + (b) Failing to copy buffers + EFI_SUCCESS - The function completes successfully + +--*/ +{ + FILE *Fp; + + Fp = fopen (FileName, "w+t"); + if (Fp == NULL) { + printf ("Error in opening file %s\n", FileName); + return EFI_ABORTED; + } + + while (BsfInfo != NULL) { + if (strlen (BsfInfo->CompName) != 0) { + fprintf (Fp, "\n%s\n", BsfInfo->CompName); + } else { + fprintf (Fp, "\n%s\n", "Name not available"); + } + + fprintf (Fp, "%d\n", BsfInfo->CompPreferredAddress); + fprintf (Fp, "%d\n", BsfInfo->CompSize); + fprintf (Fp, "%d\n", BsfInfo->Align); + + BsfInfo = BsfInfo->NextBsfInfo; + } + + if (Fp) { + fclose (Fp); + } + + return EFI_SUCCESS; +} diff --git a/Tools/CCode/Source/GenBsfImage/GenBsfImage.h b/Tools/CCode/Source/GenBsfImage/GenBsfImage.h new file mode 100644 index 0000000000..1efbebcb18 --- /dev/null +++ b/Tools/CCode/Source/GenBsfImage/GenBsfImage.h @@ -0,0 +1,633 @@ +/*++ + +Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved +This software and associated documentation (if any) is furnished +under a license and may only be used or copied in accordance +with the terms of the license. Except as permitted by such +license, no part of this software or documentation may be +reproduced, stored in a retrieval system, or transmitted in any +form or by any means without the express written consent of +Intel Corporation. + + +Module Name: + + GenBsfImage.h + +Abstract: + + This file contains the relevant declarations required + to generate Boot Strap File + +--*/ + +// +// Module Coded to EFI 2.0 Coding Conventions +// +#ifndef _EFI_GEN_BSF_IMAGE_H +#define _EFI_GEN_BSF_IMAGE_H + +// +// External Files Referenced +// +#include +#include +#include +#include +#include "assert.h" +// #include "TianoCommon.h" +#include "Common/FirmwareFileSystem.h" +#include "Common/FirmwareVolumeHeader.h" +#include "ParseInf.h" + +// +// Internal Constants +// +#define EFI_IPF_VTF1_GUID \ + { \ + 0xfa371c9b, 0x5a86, 0x4198, 0xab, 0xc2, 0xed, 0x3f, 0xaa, 0xce, 0xb0, 0x8b \ + }; + +#define EFI_IPF_VTF2_GUID \ + { \ + 0x624a0d5a, 0x315f, 0x40b6, 0xa6, 0x33, 0xe5, 0xf7, 0xde, 0x58, 0x20, 0xa0 \ + }; + +#define EFI_IA32_BOOT_STRAP_GUID \ + { \ + 0xd4260a8d, 0x356, 0x4f45, 0x85, 0xe9, 0xad, 0x1d, 0x79, 0x22, 0x79, 0xf0 \ + }; + +#define CV_N_TYPE(a,b) (UINT8)(((UINT8)a << 7) + (UINT8)b) // Keeps the CV and Type in same byte field +#define MAKE_VERSION(a,b) (UINT16)(((UINT16)a << 8) + (UINT16)b) + +#define FILE_NAME_SIZE 256 +#define COMPONENT_NAME_SIZE 128 +#define BSF_INPUT_FILE "BSF.INF" +#define BSF_OUTPUT_FILE "Bsf.RAW" +#define BSF_SYM_FILE "Bsf.SYM" +#define FIT_SIGNATURE "_FIT_ " + +// +// This is IA32 seccore +// +#define COMP_TYPE_SECCORE 0x0F + +// +//Fit Type Definition +// +#define COMP_TYPE_FIT_HEADER 0x00 +#define COMP_TYPE_FIT_PAL_B 0x01 + +// +// This is generic PAL_A +// +#define COMP_TYPE_FIT_PAL_A 0x0F +#define COMP_TYPE_FIT_PEICORE 0x10 +#define COMP_TYPE_FIT_AUTOSCAN 0x30 +#define COMP_TYPE_FIT_FV_BOOT 0x7E + +// +//This is processor Specific PAL_A +// +#define COMP_TYPE_FIT_PAL_A_SPECIFIC 0x0E +#define COMP_TYPE_FIT_UNUSED 0x7F + +#define FIT_TYPE_MASK 0x7F +#define CHECKSUM_BIT_MASK 0x80 + +// +// IPF processor address is cached bit +// +#define IPF_CACHE_BIT 0x8000000000000000 + +// +// Size definition to calculate the location from top of address for +// each component +// +#define SIZE_IA32_RESET_VECT 0x10 // 16 Bytes +#define SIZE_SALE_ENTRY_POINT 0x08 // 8 Byte +#define SIZE_FIT_TABLE_ADD 0x08 // 8 Byte +#define SIZE_FIT_TABLE_PAL_A 0x10 +#define SIZE_RESERVED 0x10 + + +#define SIZE_TO_OFFSET_PAL_A_END (SIZE_IA32_RESET_VECT + SIZE_SALE_ENTRY_POINT + \ + SIZE_FIT_TABLE_ADD + SIZE_FIT_TABLE_PAL_A + \ + SIZE_RESERVED) +#define SIZE_TO_PAL_A_FIT (SIZE_IA32_RESET_VECT + SIZE_SALE_ENTRY_POINT + \ + SIZE_FIT_TABLE_ADD + SIZE_FIT_TABLE_PAL_A) + +#define SIZE_OF_PAL_HEADER 0x40 //PAL has 64 byte header + +// +// Utility Name +// +#define UTILITY_NAME "GenBsfImage" + +// +// Utility version information +// +#define UTILITY_MAJOR_VERSION 0 +#define UTILITY_MINOR_VERSION 0 +#define UTILITY_DATE __DATE__ + +// +// The maximum number of arguments accepted from the command line. +// +#define ONE_BSF_ARGS 5 +#define TWO_BSF_ARGS 9 + +// +// The number of IA32 bsf arguments accepted from the command line. +// +#define IA32_ARGS 3 + +#define IA32_SOFT_FIT "IA32BsfAddress.inf" + +// +// Internal Data Structure +// +typedef enum _LOC_TYPE +{ + NONE, // In case there is - INF file + FIRST_VTF, // First VTF + SECOND_VTF, // Outside BSF +} LOC_TYPE; + +typedef struct _PARSED_BSF_INFO { + CHAR8 CompName[COMPONENT_NAME_SIZE]; + LOC_TYPE LocationType; + UINT8 CompType; + UINT8 MajorVer; + UINT8 MinorVer; + UINT8 CheckSumRequired; + BOOLEAN VersionPresent; // If it is TRUE, then, Version is in INF file + BOOLEAN PreferredSize; + BOOLEAN PreferredAddress; + CHAR8 CompBinName[FILE_NAME_SIZE]; + CHAR8 CompSymName[FILE_NAME_SIZE]; + UINTN CompSize; + UINT64 CompPreferredAddress; + UINT32 Align; + + // + // Fixed - warning C4133: '=' : incompatible types - from 'struct _ParsedBsfInfo *' to 'struct _PARSED_BSF_INFO *' + // Fixed - warning C4133: '=' : incompatible types - from 'struct _ParsedBsfInfo *' to 'struct _PARSED_BSF_INFO *' + // Fixed - warning C4133: '=' : incompatible types - from 'struct _ParsedBsfInfo *' to 'struct _PARSED_BSF_INFO *' + // Fixed - warning C4133: '=' : incompatible types - from 'struct _ParsedBsfInfo *' to 'struct _PARSED_BSF_INFO *' + // + struct _PARSED_BSF_INFO *NextBsfInfo; +} PARSED_BSF_INFO; + +#pragma pack (1) +typedef struct { + UINT64 CompAddress; + UINT32 CompSize; + UINT16 CompVersion; + UINT8 CvAndType; + UINT8 CheckSum; +} FIT_TABLE; +#pragma pack () + +// +// The function that displays general utility information +// +VOID +PrintUtilityInfo ( + VOID + ) +/*++ + +Routine Description: + + Displays the standard utility information to SDTOUT + +Arguments: + + None + +Returns: + + None + +--*/ +; + +// +// The function that displays the utility usage message. +// +VOID +PrintUsage ( + VOID + ) +/*++ + +Routine Description: + + Displays the utility usage syntax to STDOUT + +Arguments: + + None + +Returns: + + None + +--*/ +; + +// +// Other Function Prototype Declarations +// + +EFI_STATUS +UpdateBsfBuffer( + IN UINT64 StartAddress, + IN UINT8 *Buffer, + IN UINT64 DataSize, + IN LOC_TYPE LocType + ) +/*++ + +Routine Description: + + Update the Firmware Volume Buffer with requested buffer data + +Arguments: + + StartAddress - StartAddress in buffer. This number will automatically + point to right address in buffer where data needed + to be updated. + Buffer - Buffer pointer from data will be copied to memory mapped buffer. + DataSize - Size of the data needed to be copied. + LocType - The type of the BSF + +Returns: + + EFI_ABORTED - The input parameter is error + EFI_SUCCESS - The function completed successfully + +--*/ +; + +EFI_STATUS +UpdateSymFile ( + IN UINT64 BaseAddress, + IN CHAR8 *DestFileName, + IN CHAR8 *SourceFileName + ) +/*++ + +Routine Description: + + This function adds the SYM tokens in the source file to the destination file. + The SYM tokens are updated to reflect the base address. + +Arguments: + + BaseAddress - The base address for the new SYM tokens. + DestFileName - The destination file. + SourceFileName - The source file. + +Returns: + + EFI_SUCCESS - The function completed successfully. + EFI_INVALID_PARAMETER - One of the input parameters was invalid. + EFI_ABORTED - An error occurred. + +--*/ +; + +EFI_STATUS +CalculateFitTableChecksum ( + VOID + ) +/*++ + +Routine Description: + + This function will perform byte checksum on the FIT table, if the the checksum required + field is set to CheckSum required. If the checksum is not required then checksum byte + will have value as 0;. + +Arguments: + + NONE + +Returns: + + Status - Value returned by call to CalculateChecksum8 () + EFI_SUCCESS - The function completed successfully + +--*/ +; + +EFI_STATUS +GenerateBsfImage ( + IN UINT64 StartAddress1, + IN UINT64 Size1, + IN UINT64 StartAddress2, + IN UINT64 Size2 + ) +/*++ + +Routine Description: + + This is the main function which will be called from application. + +Arguments: + + StartAddress1 - The start address of the first BSF + Size1 - The size of the first BSF + StartAddress2 - The start address of the second BSF + Size2 - The size of the second BSF + +Returns: + + EFI_OUT_OF_RESOURCES - Can not allocate memory + The return value can be any of the values + returned by the calls to following functions: + GetBsfRelatedInfoFromInfFile + ProcessAndCreateBsf + UpdateIA32ResetVector + UpdateFfsHeader + WriteBsfBinary + +--*/ +; + +EFI_STATUS +PeimFixupInFitTable ( + IN UINT64 StartAddress + ) +/*++ + +Routine Description: + + This function is an entry point to fixup SAL-E entry point. + +Arguments: + + StartAddress - StartAddress for PEIM..... + +Returns: + + EFI_SUCCESS - The function completed successfully + EFI_ABORTED - Error Opening File + +--*/ +; + +EFI_STATUS +Generate32BsfImage ( +IN UINT64 BootFileStartAddress + ) +/*++ + +Routine Description: + + This is the main IA32 function which will be called from application. + (Now this tool is not used for IA32 platform, if it will be used in future, + the relative functions need to be updated, the updating can refer to IPF + functions) + +Arguments: + + BootFileStartAddress - Top Address of Boot File + +Returns: + + The return value can be any of the values + returned by the calls to following functions: + Get32BsfRelatedInfoFromInfFile + CreateBsfBuffer + ProcessAndCreate32Bsf + Update32FfsHeader + WriteBsfBinary + +--*/ +; + +EFI_STATUS +GetTotal32BsfSize( + IN UINT32 *BsfSize + ) +/*++ + +Routine Description: + + This function calculates total size for IA32 BSF which would be needed to create + the buffer. This will be done using Passed Info link list and looking for the + size of the components which belong to BSF. The addtional file header is accounted. + +Arguments: + + BSFSize - Pointer to the size of IA32 BSF + +Returns: + + EFI_ABORTED - Returned due to one of the following resons: + (a) Error Opening File + EFI_SUCCESS - The fuction completes successfully + +--*/ +; + +EFI_STATUS +ProcessAndCreate32Bsf ( + IN UINT64 Size + ) +/*++ + +Routine Description: + + This function process the link list created during INF file parsing + and create component in IA32 BSF + +Arguments: + + Size - Size of the Firmware Volume of which, this BSF belongs to. + +Returns: + + EFI_UNSUPPORTED - Unknown component type + EFI_SUCCESS - The function completed successfully + +--*/ +; + +EFI_STATUS +CreateAndUpdateSeccore ( + IN PARSED_BSF_INFO *BsfInfo + ) +/*++ + +Routine Description: + + This function reads the binary file for seccore and update them + in IA32 BSF Buffer + +Arguments: + + BsfInfo - Pointer to Parsed Info + +Returns: + + EFI_ABORTED - Due to one of the following reasons: + (a)Error Opening File + (b)The PAL_A Size is more than specified size status + One of the values mentioned below returned from + call to UpdateSymFile + EFI_SUCCESS - The function completed successfully. + EFI_INVALID_PARAMETER - One of the input parameters was invalid. + EFI_ABORTED - An error occurred.UpdateSymFile + +--*/ +; + +EFI_STATUS +CreateAndUpdate32Component ( + IN PARSED_BSF_INFO *BsfInfo + ) +/*++ + +Routine Description: + + This function reads the binary file for each components. Add it at aligned address. + +Arguments: + + BsfInfo - Pointer to Parsed Info + +Returns: + + EFI_SUCCESS - The function completed successful + EFI_ABORTED - Aborted due to one of the many reasons like: + (a) Component Size greater than the specified size. + (b) Error opening files. + EFI_INVALID_PARAMETER - Value returned from call to UpdateEntryPoint() + +--*/ +; + +EFI_STATUS +Update32FfsHeader( + IN UINT32 BsfSize + ) +/*++ + +Routine Description: + + Update the Firmware Volume Buffer with requested buffer data + +Arguments: + + BsfSize - Size of the IA32 BSF + +Returns: + + EFI_SUCCESS - The function completed successfully + EFI_INVALID_PARAMETER - The Ffs File Header Pointer is NULL + +--*/ +; + +EFI_STATUS +Get32BsfRelatedInfoFromInfFile ( + IN CHAR8 *FileName + ) +/*++ + +Routine Description: + + This function reads the input file, parse it and create a list of tokens + which is parsed and used, to intialize the data related to IA32 BSF + +Arguments: + + FileName FileName which needed to be read to parse data + +Returns: + + EFI_ABORTED Error in opening file + EFI_INVALID_PARAMETER File doesn't contain any valid informations + EFI_OUT_OF_RESOURCES Malloc Failed + EFI_SUCCESS The function completed successfully + +--*/ +; + +VOID +Initialize32InFileInfo ( + VOID + ) +/*++ + +Routine Description: + + This function intializes the relevant global variable which is being + used to store the information retrieved from IA32 INF file. + +Arguments: + + NONE + +Returns: + + NONE + +--*/ +; + +VOID +ParseAndUpdate32Components ( + IN PARSED_BSF_INFO *BsfInfo + ) +/*++ + +Routine Description: + + This function intializes the relevant global variable which is being + used to store the information retrieved from INF file. + +Arguments: + + BsfInfo - A pointer to the BSF Info Structure + + +Returns: + + None + +--*/ +; + +EFI_STATUS +Write32SoftFit( + IN CHAR8 *FileName, + IN PARSED_BSF_INFO *BsfInfo + ) +/*++ + +Routine Description: + + Write IA32 Firmware Volume component address from memory to a file. + +Arguments: + + FileName Output File Name which needed to be created/ + BsfInfo Parsed info link + +Returns: + + EFI_ABORTED - Returned due to one of the following resons: + (a) Error Opening File + (b) Failing to copy buffers + EFI_SUCCESS - The fuction completes successfully + +--*/ +; + +#endif diff --git a/Tools/CCode/Source/GenBsfImage/build.xml b/Tools/CCode/Source/GenBsfImage/build.xml new file mode 100644 index 0000000000..fe8f202099 --- /dev/null +++ b/Tools/CCode/Source/GenBsfImage/build.xml @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +