]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Adding tools for IPF development.
authorbbahnsen <bbahnsen@6f19259b-4bc3-4df7-8a09-765794883524>
Mon, 30 Oct 2006 16:43:48 +0000 (16:43 +0000)
committerbbahnsen <bbahnsen@6f19259b-4bc3-4df7-8a09-765794883524>
Mon, 30 Oct 2006 16:43:48 +0000 (16:43 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1865 6f19259b-4bc3-4df7-8a09-765794883524

Tools/CCode/Source/GenBsfFixup/GenBsfFixup.c [new file with mode: 0644]
Tools/CCode/Source/GenBsfFixup/build.xml [new file with mode: 0644]
Tools/CCode/Source/GenBsfImage/GenBsfImage.c [new file with mode: 0644]
Tools/CCode/Source/GenBsfImage/GenBsfImage.h [new file with mode: 0644]
Tools/CCode/Source/GenBsfImage/build.xml [new file with mode: 0644]

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