summaryrefslogtreecommitdiff
path: root/Tools/CCode/Source
diff options
context:
space:
mode:
authorbbahnsen <bbahnsen@6f19259b-4bc3-4df7-8a09-765794883524>2006-10-30 16:43:48 +0000
committerbbahnsen <bbahnsen@6f19259b-4bc3-4df7-8a09-765794883524>2006-10-30 16:43:48 +0000
commit71ea530c3742ec7a02058a9fab509a4c7a00886f (patch)
treef75b27071b5ff610422f009a6d3d1e7847638fab /Tools/CCode/Source
parenta7a7033316a1ca8cf316daf636b78336146df514 (diff)
downloadedk2-71ea530c3742ec7a02058a9fab509a4c7a00886f.zip
edk2-71ea530c3742ec7a02058a9fab509a4c7a00886f.tar.gz
edk2-71ea530c3742ec7a02058a9fab509a4c7a00886f.tar.bz2
Adding tools for IPF development.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1865 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'Tools/CCode/Source')
-rw-r--r--Tools/CCode/Source/GenBsfFixup/GenBsfFixup.c490
-rw-r--r--Tools/CCode/Source/GenBsfFixup/build.xml127
-rw-r--r--Tools/CCode/Source/GenBsfImage/GenBsfImage.c3519
-rw-r--r--Tools/CCode/Source/GenBsfImage/GenBsfImage.h633
-rw-r--r--Tools/CCode/Source/GenBsfImage/build.xml126
5 files changed, 4895 insertions, 0 deletions
diff --git a/Tools/CCode/Source/GenBsfFixup/GenBsfFixup.c b/Tools/CCode/Source/GenBsfFixup/GenBsfFixup.c
new file mode 100644
index 0000000..462f97f
--- /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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+//
+// 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 0000000..1f35cf2
--- /dev/null
+++ b/Tools/CCode/Source/GenBsfFixup/build.xml
@@ -0,0 +1,127 @@
+<?xml version="1.0" ?>
+<!--
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+-->
+<project default="GenTool" basedir=".">
+<!--
+ EDK GenFvImage Tool
+ Copyright (c) 2006, Intel Corporation
+-->
+ <property name="ToolName" value="GenBsfFixup"/>
+ <property name="FileSet" value="GenBsfFixup.c"/>
+
+ <taskdef resource="net/sf/antcontrib/antlib.xml"/>
+
+ <property name="LINK_OUTPUT_TYPE" value="static"/>
+ <property name="BUILD_DIR" value="${PACKAGE_DIR}/${ToolName}/tmp"/>
+
+ <target name="GenTool" depends="init, Tool">
+ <echo message="The EDK Tool: ${ToolName} build has completed"/>
+ </target>
+
+ <target name="init">
+ <echo message="Building the EDK Tool: ${ToolName}"/>
+ <mkdir dir="${BUILD_DIR}"/>
+ <if>
+ <istrue value="${OSX}"/>
+ <then>
+ <property name="syslibdirs" value=""/>
+ <property name="syslibs" value=""/>
+ </then>
+ </if>
+
+ <if>
+ <istrue value="${cygwin}"/>
+ <then>
+ <property name="syslibdirs" value="${env.CYGWIN_HOME}/lib/e2fsprogs"/>
+ <property name="syslibs" value="uuid"/>
+ </then>
+ </if>
+
+ <if>
+ <istrue value="${msft}"/>
+ <then>
+ <property name="syslibdirs" value=""/>
+ <property name="syslibs" value="uuid"/>
+ </then>
+ </if>
+
+ <if>
+ <istrue value="${linux}"/>
+ <then>
+ <if>
+ <istrue value="${x86_64_linux}"/>
+ <then>
+ <property name="syslibdirs" value="/lib64"/>
+ </then>
+ <else>
+ <property name="syslibdirs" value="/usr/lib"/>
+ </else>
+ </if>
+ <property name="syslibs" value="uuid"/>
+ </then>
+ </if>
+ <echo message="syslibdirs set to: ${syslibdirs}"/>
+ </target>
+
+ <target name="Tool" depends="init, GenBsfFixup"/>
+
+ <target name="GenBsfFixup" >
+ <cc name="${ToolChain}" objdir="${BUILD_DIR}"
+ outfile="${BIN_DIR}/${ToolName}"
+ outtype="executable"
+ debug="true"
+ optimize="speed">
+ <compilerarg value="${ExtraArgus}" if="ExtraArgus" />
+
+ <defineset>
+ <define name="BUILDING_TOOLS"/>
+ <define name="TOOL_BUILD_IA32_TARGET"/>
+ </defineset>
+
+ <fileset dir="${basedir}/${ToolName}"
+ includes="${FileSet}"/>
+
+ <includepath path="${PACKAGE_DIR}/${ToolName}"/>
+ <includepath path="${PACKAGE_DIR}/Include"/>
+ <includepath path="${PACKAGE_DIR}/Include/Common"/>
+ <includepath path="${PACKAGE_DIR}/Include/${HostArch}"/>
+ <includepath path="${PACKAGE_DIR}/Common"/>
+ <libset dir="${LIB_DIR}" libs="CommonTools"/>
+
+ <linkerarg value="/nodefaultlib:libc.lib" if="msft"/>
+ <syslibset dir="${syslibdirs}" libs="${syslibs}" if="cyglinux"/>
+ <syslibset libs="RpcRT4" if="msft"/>
+ </cc>
+ </target>
+
+ <target name="clean">
+ <echo message="Removing Intermediate Files Only"/>
+ <delete>
+ <fileset dir="${BUILD_DIR}" includes="*.obj"/>
+ </delete>
+ </target>
+
+ <target name="cleanall">
+ <echo message="Removing Object Files and the Executable: ${ToolName}${ext_exe}"/>
+ <delete failonerror="false" quiet="true" includeEmptyDirs="true">
+ <fileset dir="${BUILD_DIR}"/>
+ <fileset file="${BIN_DIR}/${ToolName}_Ia32${ext_exe}"/>
+ <fileset file="${BIN_DIR}/${ToolName}_X64${ext_exe}"/>
+ <fileset file="${BIN_DIR}/${ToolName}${ext_exe}"/>
+ <fileset file="${BIN_DIR}/${ToolName}_Ipf${ext_exe}"/>
+ <fileset file="${BIN_DIR}/${ToolName}_Ia32.pdb"/>
+ <fileset file="${BIN_DIR}/${ToolName}_X64.pdb"/>
+ <fileset file="${BIN_DIR}/${ToolName}.pdb"/>
+ <fileset file="${BIN_DIR}/${ToolName}_Ipf.pdb"/>
+ </delete>
+ </target>
+
+</project>
diff --git a/Tools/CCode/Source/GenBsfImage/GenBsfImage.c b/Tools/CCode/Source/GenBsfImage/GenBsfImage.c
new file mode 100644
index 0000000..59d20d0
--- /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 <FvLib.h>
+#include <Common/UefiBaseTypes.h>
+#include "GenBsfImage.h"
+#include <Guid/FirmwareFileSystem.h>
+#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 0000000..1efbebc
--- /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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <io.h>
+#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 0000000..fe8f202
--- /dev/null
+++ b/Tools/CCode/Source/GenBsfImage/build.xml
@@ -0,0 +1,126 @@
+<?xml version="1.0" ?>
+<!--
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+-->
+<project default="GenTool" basedir=".">
+<!--
+ EDK GenFvImage Tool
+ Copyright (c) 2006, Intel Corporation
+-->
+ <property name="ToolName" value="GenBsfImage"/>
+ <property name="FileSet" value="GenBsfImage.c"/>
+
+ <taskdef resource="net/sf/antcontrib/antlib.xml"/>
+
+ <property name="LINK_OUTPUT_TYPE" value="static"/>
+ <property name="BUILD_DIR" value="${PACKAGE_DIR}/${ToolName}/tmp"/>
+
+ <target name="GenTool" depends="init, Tool">
+ <echo message="The EDK Tool: ${ToolName} build has completed"/>
+ </target>
+
+ <target name="init">
+ <echo message="Building the EDK Tool: ${ToolName}"/>
+ <mkdir dir="${BUILD_DIR}"/>
+ <if>
+ <istrue value="${OSX}"/>
+ <then>
+ <property name="syslibdirs" value=""/>
+ <property name="syslibs" value=""/>
+ </then>
+ </if>
+
+ <if>
+ <istrue value="${cygwin}"/>
+ <then>
+ <property name="syslibdirs" value="${env.CYGWIN_HOME}/lib/e2fsprogs"/>
+ <property name="syslibs" value="uuid"/>
+ </then>
+ </if>
+
+ <if>
+ <istrue value="${msft}"/>
+ <then>
+ <property name="syslibdirs" value=""/>
+ <property name="syslibs" value="uuid"/>
+ </then>
+ </if>
+
+ <if>
+ <istrue value="${linux}"/>
+ <then>
+ <if>
+ <istrue value="${x86_64_linux}"/>
+ <then>
+ <property name="syslibdirs" value="/lib64"/>
+ </then>
+ <else>
+ <property name="syslibdirs" value="/usr/lib"/>
+ </else>
+ </if>
+ <property name="syslibs" value="uuid"/>
+ </then>
+ </if>
+ <echo message="syslibdirs set to: ${syslibdirs}"/>
+ </target>
+
+ <target name="Tool" depends="init, GenBsfImage"/>
+
+ <target name="GenBsfImage" >
+ <cc name="${ToolChain}" objdir="${BUILD_DIR}"
+ outfile="${BIN_DIR}/${ToolName}"
+ outtype="executable"
+ debug="true"
+ optimize="speed">
+ <compilerarg value="${ExtraArgus}" if="ExtraArgus" />
+
+ <defineset>
+ <define name="BUILDING_TOOLS"/>
+ <define name="TOOL_BUILD_IA32_TARGET"/>
+ </defineset>
+
+ <fileset dir="${basedir}/${ToolName}"
+ includes="${FileSet}"/>
+
+ <includepath path="${PACKAGE_DIR}/${ToolName}"/>
+ <includepath path="${PACKAGE_DIR}/Include"/>
+ <includepath path="${PACKAGE_DIR}/Include/${HostArch}"/>
+ <includepath path="${PACKAGE_DIR}/Common"/>
+ <libset dir="${LIB_DIR}" libs="CommonTools"/>
+
+ <!-- <linkerarg value="/nodefaultlib:libc.lib" if="msft"/>
+ <syslibset dir="${syslibdirs}" libs="${syslibs}" if="cyglinux"/>
+ <syslibset libs="RpcRT4" if="msft"/> -->
+ </cc>
+ </target>
+
+ <target name="clean">
+ <echo message="Removing Intermediate Files Only"/>
+ <delete>
+ <fileset dir="${BUILD_DIR}" includes="*.obj"/>
+ </delete>
+ </target>
+
+ <target name="cleanall">
+ <echo message="Removing Object Files and the Executable: ${ToolName}${ext_exe}"/>
+ <delete failonerror="false" quiet="true" includeEmptyDirs="true">
+ <fileset dir="${BUILD_DIR}"/>
+ <fileset file="${BIN_DIR}/${ToolName}_Ia32${ext_exe}"/>
+ <fileset file="${BIN_DIR}/${ToolName}_X64${ext_exe}"/>
+ <fileset file="${BIN_DIR}/${ToolName}${ext_exe}"/>
+ <fileset file="${BIN_DIR}/${ToolName}_Ipf${ext_exe}"/>
+ <fileset file="${BIN_DIR}/${ToolName}_Ia32.pdb"/>
+ <fileset file="${BIN_DIR}/${ToolName}_X64.pdb"/>
+ <fileset file="${BIN_DIR}/${ToolName}.pdb"/>
+ <fileset file="${BIN_DIR}/${ToolName}_Ipf.pdb"/>
+ </delete>
+ </target>
+
+</project>