git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11057 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			2725 lines
		
	
	
		
			69 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			2725 lines
		
	
	
		
			69 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/**
 | 
						|
 | 
						|
Copyright (c) 1999 - 2010, Intel Corporation. All rights reserved.<BR>
 | 
						|
This program and the accompanying materials are licensed and made available 
 | 
						|
under the terms and conditions of the BSD License which accompanies this 
 | 
						|
distribution.  The full text of the license may be found at
 | 
						|
http://opensource.org/licenses/bsd-license.php
 | 
						|
 | 
						|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | 
						|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | 
						|
 | 
						|
 | 
						|
Module Name:
 | 
						|
 | 
						|
  GenVtf.c
 | 
						|
 | 
						|
Abstract:
 | 
						|
 | 
						|
  This file contains functions required to generate a boot strap file (BSF)
 | 
						|
  also known as the Volume Top File (VTF)
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
//
 | 
						|
//
 | 
						|
//
 | 
						|
#include <FvLib.h>
 | 
						|
#include <Common/UefiBaseTypes.h>
 | 
						|
#include "GenVtf.h"
 | 
						|
#include <Guid/PiFirmwareFileSystem.h>
 | 
						|
#include "CommonLib.h"
 | 
						|
#include "EfiUtilityMsgs.h"
 | 
						|
 | 
						|
//
 | 
						|
// Global variables
 | 
						|
//
 | 
						|
UINTN SectionOptionFlag = 0;
 | 
						|
UINTN SectionCompFlag = 0;
 | 
						|
 | 
						|
UINT64        DebugLevel;
 | 
						|
BOOLEAN       DebugMode;
 | 
						|
 | 
						|
BOOLEAN     QuietMode = FALSE;
 | 
						|
 | 
						|
BOOLEAN     VTF_OUTPUT = FALSE;
 | 
						|
CHAR8       *OutFileName1;
 | 
						|
CHAR8       *OutFileName2;
 | 
						|
CHAR8       *SymFileName;
 | 
						|
 | 
						|
CHAR8           **TokenStr;
 | 
						|
CHAR8           **OrgStrTokPtr;
 | 
						|
 | 
						|
PARSED_VTF_INFO *FileListPtr;
 | 
						|
PARSED_VTF_INFO *FileListHeadPtr;
 | 
						|
 | 
						|
VOID            *Vtf1Buffer;
 | 
						|
VOID            *Vtf1EndBuffer;
 | 
						|
VOID            *Vtf2Buffer;
 | 
						|
VOID            *Vtf2EndBuffer;
 | 
						|
 | 
						|
UINTN           ValidLineNum        = 0;
 | 
						|
UINTN           ValidFFDFileListNum = 0;
 | 
						|
 | 
						|
//
 | 
						|
// Section Description and their number of occurences in *.INF file
 | 
						|
//
 | 
						|
UINTN           NumFvFiles        = 0;
 | 
						|
UINTN           SectionOptionNum  = 0;
 | 
						|
 | 
						|
//
 | 
						|
// Global flag which will check for VTF Present, if yes then will be used
 | 
						|
// to decide about adding FFS header to pad data
 | 
						|
//
 | 
						|
BOOLEAN         VTFPresent = FALSE;
 | 
						|
BOOLEAN         SecondVTF = FALSE;
 | 
						|
 | 
						|
//
 | 
						|
// Address related information
 | 
						|
//
 | 
						|
UINT64          Fv1BaseAddress        = 0;
 | 
						|
UINT64          Fv2BaseAddress        = 0;
 | 
						|
UINT64          Fv1EndAddress         = 0;
 | 
						|
UINT64          Fv2EndAddress         = 0;
 | 
						|
UINT32          Vtf1TotalSize         = SIZE_TO_OFFSET_PAL_A_END;
 | 
						|
UINT64          Vtf1LastStartAddress  = 0;
 | 
						|
UINT32          Vtf2TotalSize         = 0;
 | 
						|
UINT64          Vtf2LastStartAddress  = 0;
 | 
						|
 | 
						|
UINT32          BufferToTop           = 0;
 | 
						|
 | 
						|
//
 | 
						|
// IA32 Reset Vector Bin name
 | 
						|
//
 | 
						|
CHAR8           IA32BinFile[FILE_NAME_SIZE];
 | 
						|
 | 
						|
//
 | 
						|
// Function Implementations
 | 
						|
//
 | 
						|
EFI_STATUS
 | 
						|
ConvertVersionInfo (
 | 
						|
  IN      CHAR8     *Str,
 | 
						|
  IN OUT  UINT8     *MajorVer,
 | 
						|
  IN OUT  UINT8     *MinorVer
 | 
						|
  )
 | 
						|
/*++
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  This function split version to major version and minor version
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  Str      - String representing in form XX.XX
 | 
						|
  MajorVer - The major version
 | 
						|
  MinorVer - The minor version
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  EFI_SUCCESS  - The function completed successfully.
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  CHAR8  StrPtr[40];
 | 
						|
  CHAR8  *Token;
 | 
						|
  unsigned Major;
 | 
						|
  unsigned Minor;
 | 
						|
 | 
						|
  Major = 0;
 | 
						|
  Minor = 0;
 | 
						|
  memset (StrPtr, 0, 40);
 | 
						|
  Token = strtok (Str, ".");
 | 
						|
 | 
						|
  while (Token != NULL) {
 | 
						|
    strcat (StrPtr, Token);
 | 
						|
    Token = strtok (NULL, ".");
 | 
						|
  }
 | 
						|
 | 
						|
  sscanf (
 | 
						|
    StrPtr,
 | 
						|
    "%02d%02d",
 | 
						|
    &Major,
 | 
						|
    &Minor
 | 
						|
    );
 | 
						|
 | 
						|
  *MajorVer = (UINT8) Major;
 | 
						|
  *MinorVer = (UINT8) Minor;
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
TrimLine (
 | 
						|
  IN  CHAR8 *Line
 | 
						|
  )
 | 
						|
/*++
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  This function cleans up the line by removing all whitespace and
 | 
						|
  comments
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  Line   - The pointer of the string
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  None
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  CHAR8 TmpLine[FILE_NAME_SIZE];
 | 
						|
  CHAR8 Char;
 | 
						|
  CHAR8 *Ptr0;
 | 
						|
  UINTN Index;
 | 
						|
  UINTN Index2;
 | 
						|
 | 
						|
  //
 | 
						|
  // Change '#' to '//' for Comment style
 | 
						|
  //
 | 
						|
  if (((Ptr0 = strchr (Line, '#')) != NULL) || ((Ptr0 = strstr (Line, "//")) != NULL)) {
 | 
						|
    Line[Ptr0 - Line] = 0;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Initialize counters
 | 
						|
  //
 | 
						|
  Index   = 0;
 | 
						|
  Index2  = 0;
 | 
						|
 | 
						|
  while ((Char = Line[Index]) != 0) {
 | 
						|
    if ((Char != ' ') && (Char != '\t') && (Char != '\n') && (Char != '\r')) {
 | 
						|
      TmpLine[Index2++] = Char;
 | 
						|
    }
 | 
						|
    Index++;
 | 
						|
  }
 | 
						|
 | 
						|
  TmpLine[Index2] = 0;
 | 
						|
  strcpy (Line, TmpLine);
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
ValidLineCount (
 | 
						|
  IN  FILE *Fp
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  This function calculated number of valid lines in a input file.
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  Fp    - Pointer to a file handle which has been opened.
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  None
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  CHAR8 Buff[FILE_NAME_SIZE];
 | 
						|
  while (fgets(Buff, sizeof (Buff), Fp)) {
 | 
						|
    TrimLine (Buff);
 | 
						|
    if (Buff[0] == 0) {
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
    ValidLineNum++;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
ParseInputFile (
 | 
						|
  IN  FILE *Fp
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  This function parses the input file and tokenize the string
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  Fp    - Pointer to a file handle which has been opened.
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  None
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  CHAR8 *Token;
 | 
						|
  CHAR8 Buff[FILE_NAME_SIZE + 1];
 | 
						|
  CHAR8 Delimit[] = "=";
 | 
						|
 | 
						|
  Buff [FILE_NAME_SIZE] = '\0';
 | 
						|
  Token = NULL;
 | 
						|
 | 
						|
  while (fgets (Buff, FILE_NAME_SIZE, Fp) != NULL) {
 | 
						|
    TrimLine (Buff);
 | 
						|
    if (Buff[0] == 0) {
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
    Token = strtok (Buff, Delimit);
 | 
						|
    while (Token != NULL) {
 | 
						|
      strcpy (*TokenStr, Token);
 | 
						|
      TokenStr ++;
 | 
						|
      Token = strtok (NULL, Delimit);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
InitializeComps (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  This function initializes the relevant global variable which is being
 | 
						|
  used to store the information retrieved from INF file.  This also initializes
 | 
						|
  the VTF symbol file.
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  None
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  EFI_SUCCESS            - The function completed successfully
 | 
						|
  EFI_OUT_OF_RESOURCES   - Malloc failed.
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
 | 
						|
  FileListPtr = malloc (sizeof (PARSED_VTF_INFO));
 | 
						|
 | 
						|
  if (FileListPtr == NULL) {
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
 | 
						|
  FileListHeadPtr = FileListPtr;
 | 
						|
  memset (FileListPtr, 0, sizeof (PARSED_VTF_INFO));
 | 
						|
  FileListPtr->NextVtfInfo = NULL;
 | 
						|
 | 
						|
  remove (SymFileName);
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
ParseAndUpdateComponents (
 | 
						|
  IN  PARSED_VTF_INFO   *VtfInfo
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  This function initializes the relevant global variable which is being
 | 
						|
  used to store the information retrieved from INF file.
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  VtfInfo  - A pointer to the VTF Info Structure
 | 
						|
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  None
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  UINT64  StringValue;
 | 
						|
 | 
						|
  while (*TokenStr != NULL && (strnicmp (*TokenStr, "COMP_NAME", 9) != 0)) {
 | 
						|
 | 
						|
    if (strnicmp (*TokenStr, "COMP_LOC", 8) == 0) {
 | 
						|
      TokenStr++;
 | 
						|
      if (strnicmp (*TokenStr, "F", 1) == 0) {
 | 
						|
        VtfInfo->LocationType = FIRST_VTF;
 | 
						|
      } else if (strnicmp (*TokenStr, "S", 1) == 0) {
 | 
						|
        VtfInfo->LocationType = SECOND_VTF;
 | 
						|
      } else {
 | 
						|
        VtfInfo->LocationType = NONE;
 | 
						|
      }
 | 
						|
    } else if (strnicmp (*TokenStr, "COMP_TYPE", 9) == 0) {
 | 
						|
      TokenStr++;
 | 
						|
      if (AsciiStringToUint64 (*TokenStr, FALSE, &StringValue) != EFI_SUCCESS) {
 | 
						|
        Error (NULL, 0, 5001, "Cannot get: \"0x%s\".", *TokenStr);
 | 
						|
        return ;
 | 
						|
      }
 | 
						|
 | 
						|
      VtfInfo->CompType = (UINT8) StringValue;
 | 
						|
    } else if (strnicmp (*TokenStr, "COMP_VER", 8) == 0) {
 | 
						|
      TokenStr++;
 | 
						|
      if (strnicmp (*TokenStr, "-", 1) == 0) {
 | 
						|
        VtfInfo->VersionPresent = FALSE;
 | 
						|
        VtfInfo->MajorVer       = 0;
 | 
						|
        VtfInfo->MinorVer       = 0;
 | 
						|
      } else {
 | 
						|
        VtfInfo->VersionPresent = TRUE;
 | 
						|
        ConvertVersionInfo (*TokenStr, &VtfInfo->MajorVer, &VtfInfo->MinorVer);
 | 
						|
      }
 | 
						|
    } else if (strnicmp (*TokenStr, "COMP_BIN", 8) == 0) {
 | 
						|
      TokenStr++;
 | 
						|
      strcpy (VtfInfo->CompBinName, *TokenStr);
 | 
						|
    } else if (strnicmp (*TokenStr, "COMP_SYM", 8) == 0) {
 | 
						|
      TokenStr++;
 | 
						|
      strcpy (VtfInfo->CompSymName, *TokenStr);
 | 
						|
    } else if (strnicmp (*TokenStr, "COMP_SIZE", 9) == 0) {
 | 
						|
      TokenStr++;
 | 
						|
      if (strnicmp (*TokenStr, "-", 1) == 0) {
 | 
						|
        VtfInfo->PreferredSize  = FALSE;
 | 
						|
        VtfInfo->CompSize       = 0;
 | 
						|
      } else {
 | 
						|
        VtfInfo->PreferredSize = TRUE;
 | 
						|
        if (AsciiStringToUint64 (*TokenStr, FALSE, &StringValue) != EFI_SUCCESS) {
 | 
						|
          Error (NULL, 0, 5001, "Parse error", "Cannot get: %s.", TokenStr);
 | 
						|
          return ;
 | 
						|
        }
 | 
						|
 | 
						|
        VtfInfo->CompSize = (UINTN) StringValue;
 | 
						|
      }
 | 
						|
 | 
						|
    } else if (strnicmp (*TokenStr, "COMP_CS", 7) == 0) {
 | 
						|
      TokenStr++;
 | 
						|
      if (strnicmp (*TokenStr, "1", 1) == 0) {
 | 
						|
        VtfInfo->CheckSumRequired = 1;
 | 
						|
      } else if (strnicmp (*TokenStr, "0", 1) == 0) {
 | 
						|
        VtfInfo->CheckSumRequired = 0;
 | 
						|
      } else {
 | 
						|
        Error (NULL, 0, 3000, "Invaild", "Bad value in INF file required field: Checksum, the value must be '0' or '1'.");
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    TokenStr++;
 | 
						|
    if (*TokenStr == NULL) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
InitializeInFileInfo (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  This function intializes the relevant global variable which is being
 | 
						|
  used to store the information retrieved from INF file.
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  NONE
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  NONE
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
 | 
						|
  SectionOptionFlag = 0;
 | 
						|
  SectionCompFlag   = 0;
 | 
						|
  TokenStr          = OrgStrTokPtr;
 | 
						|
 | 
						|
  while (*TokenStr != NULL) {
 | 
						|
    if (strnicmp (*TokenStr, "[OPTIONS]", 9) == 0) {
 | 
						|
      SectionOptionFlag = 1;
 | 
						|
      SectionCompFlag   = 0;
 | 
						|
    }
 | 
						|
 | 
						|
    if (strnicmp (*TokenStr, "[COMPONENTS]", 12) == 0) {
 | 
						|
      if (FileListPtr == NULL) {
 | 
						|
        FileListPtr = FileListHeadPtr;
 | 
						|
      }
 | 
						|
 | 
						|
      SectionCompFlag   = 1;
 | 
						|
      SectionOptionFlag = 0;
 | 
						|
      TokenStr++;
 | 
						|
    }
 | 
						|
 | 
						|
    if (SectionOptionFlag) {
 | 
						|
      if (stricmp (*TokenStr, "IA32_RST_BIN") == 0) {
 | 
						|
        TokenStr++;
 | 
						|
        strcpy (IA32BinFile, *TokenStr);
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if (SectionCompFlag) {
 | 
						|
      if (stricmp (*TokenStr, "COMP_NAME") == 0) {
 | 
						|
        TokenStr++;
 | 
						|
        strcpy (FileListPtr->CompName, *TokenStr);
 | 
						|
        TokenStr++;
 | 
						|
        ParseAndUpdateComponents (FileListPtr);
 | 
						|
      }
 | 
						|
 | 
						|
      if (*TokenStr != NULL) {
 | 
						|
        FileListPtr->NextVtfInfo  = malloc (sizeof (PARSED_VTF_INFO));
 | 
						|
        if (FileListPtr->NextVtfInfo == NULL) {
 | 
						|
          Error (NULL, 0, 4003, "Resource", "Out of memory resources.", NULL);
 | 
						|
          break;
 | 
						|
        }
 | 
						|
        FileListPtr = FileListPtr->NextVtfInfo;
 | 
						|
        memset (FileListPtr, 0, sizeof (PARSED_VTF_INFO));
 | 
						|
        FileListPtr->NextVtfInfo = NULL;
 | 
						|
        continue;
 | 
						|
      } else {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    TokenStr++;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
GetVtfRelatedInfoFromInfFile (
 | 
						|
  IN FILE *FilePointer
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  This function reads the input file, parse it and create a list of tokens
 | 
						|
  which is parsed and used, to intialize the data related to VTF
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  FileName  - FileName which needed to be read to parse data
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  EFI_ABORTED           - Error in opening file
 | 
						|
  EFI_INVALID_PARAMETER - File doesn't contain any valid information
 | 
						|
  EFI_OUT_OF_RESOURCES  - Malloc Failed
 | 
						|
  EFI_SUCCESS           - The function completed successfully
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  FILE        *Fp;
 | 
						|
  UINTN       Index;
 | 
						|
  UINTN       Index1;
 | 
						|
  EFI_STATUS  Status;
 | 
						|
 | 
						|
  Status = EFI_SUCCESS;
 | 
						|
  Fp = FilePointer;
 | 
						|
  if (Fp == NULL) {
 | 
						|
    Error (NULL, 0, 2000, "Invalid parameter", "BSF INF file is invalid!");
 | 
						|
    return EFI_ABORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  ValidLineCount (Fp);
 | 
						|
 | 
						|
  if (ValidLineNum == 0) {
 | 
						|
    Error (NULL, 0, 2000, "Invalid parameter", "File does not contain any valid information!");
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  TokenStr = (CHAR8 **) malloc (sizeof (UINTN) * (2 * ValidLineNum + 1));
 | 
						|
 | 
						|
  if (TokenStr == NULL) {
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
 | 
						|
  memset (TokenStr, 0, (sizeof (UINTN) * (2 * ValidLineNum + 1)));
 | 
						|
  OrgStrTokPtr = TokenStr;
 | 
						|
 | 
						|
  for (Index = 0; Index < (2 * ValidLineNum); Index++) {
 | 
						|
    *TokenStr = (CHAR8*)malloc (sizeof (CHAR8) * FILE_NAME_SIZE);
 | 
						|
 | 
						|
    if (*TokenStr == NULL) {
 | 
						|
      Status = EFI_OUT_OF_RESOURCES;
 | 
						|
      goto ParseFileError;
 | 
						|
    }
 | 
						|
 | 
						|
    memset (*TokenStr, 0, FILE_NAME_SIZE);
 | 
						|
    TokenStr++;
 | 
						|
  }
 | 
						|
 | 
						|
  TokenStr  = OrgStrTokPtr;
 | 
						|
  fseek (Fp, 0L, SEEK_SET);
 | 
						|
 | 
						|
  Status = InitializeComps ();
 | 
						|
 | 
						|
  if (Status != EFI_SUCCESS) {
 | 
						|
    goto ParseFileError;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = ParseInputFile (Fp);
 | 
						|
  if (Status != EFI_SUCCESS) {
 | 
						|
    goto ParseFileError;
 | 
						|
  }
 | 
						|
 | 
						|
  InitializeInFileInfo ();
 | 
						|
 | 
						|
ParseFileError:
 | 
						|
 | 
						|
  for (Index1 = 0; Index1 < Index; Index1 ++) {
 | 
						|
    free (OrgStrTokPtr[Index1]);
 | 
						|
  }
 | 
						|
 | 
						|
  free (OrgStrTokPtr);
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
GetRelativeAddressInVtfBuffer (
 | 
						|
  IN      UINT64     Address,
 | 
						|
  IN OUT  UINTN      *RelativeAddress,
 | 
						|
  IN      LOC_TYPE   LocType
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  This function checks for the address alignmnet for specified data boundary. In
 | 
						|
  case the address is not aligned, it returns FALSE and the amount of data in
 | 
						|
  terms of byte needed to adjust to get the boundary alignmnet. If data is
 | 
						|
  aligned, TRUE will be returned.
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  Address             - The address of the flash map space
 | 
						|
  RelativeAddress     - The relative address of the Buffer
 | 
						|
  LocType             - The type of the VTF
 | 
						|
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  UINT64  TempAddress;
 | 
						|
  UINT8   *LocalBuff;
 | 
						|
 | 
						|
  if (LocType == FIRST_VTF) {
 | 
						|
    LocalBuff         = (UINT8 *) Vtf1EndBuffer;
 | 
						|
    TempAddress       = Fv1EndAddress - Address;
 | 
						|
    *RelativeAddress  = (UINTN) LocalBuff - (UINTN) TempAddress;
 | 
						|
  } else {
 | 
						|
    LocalBuff         = (UINT8 *) Vtf2EndBuffer;
 | 
						|
    TempAddress       = Fv2EndAddress - Address;
 | 
						|
    *RelativeAddress  = (UINTN) LocalBuff - (UINTN) TempAddress;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
GetComponentVersionInfo (
 | 
						|
  IN  OUT PARSED_VTF_INFO   *VtfInfo,
 | 
						|
  IN      UINT8             *Buffer
 | 
						|
  )
 | 
						|
/*++
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  This function will extract the version information from File
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  VtfInfo  - A Pointer to the VTF Info Structure
 | 
						|
  Buffer   - A Pointer to type UINT8
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
   EFI_SUCCESS           - The function completed successfully
 | 
						|
   EFI_INVALID_PARAMETER - The parameter is invalid
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  UINT16      VersionInfo;
 | 
						|
  EFI_STATUS  Status;
 | 
						|
 | 
						|
  switch (VtfInfo->CompType) {
 | 
						|
 | 
						|
  case COMP_TYPE_FIT_PAL_A:
 | 
						|
  case COMP_TYPE_FIT_PAL_B:
 | 
						|
    memcpy (&VersionInfo, (Buffer + 8), sizeof (UINT16));
 | 
						|
    VtfInfo->MajorVer = (UINT8) ((VersionInfo & 0xFF00) >> 8);
 | 
						|
    VtfInfo->MinorVer = (UINT8) (VersionInfo & 0x00FF);
 | 
						|
    Status            = EFI_SUCCESS;
 | 
						|
    break;
 | 
						|
 | 
						|
  default:
 | 
						|
    Status = EFI_INVALID_PARAMETER;
 | 
						|
    break;
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
BOOLEAN
 | 
						|
CheckAddressAlignment (
 | 
						|
  IN      UINT64  Address,
 | 
						|
  IN      UINT64  AlignmentData,
 | 
						|
  IN OUT  UINT64  *AlignAdjustByte
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  This function checks for the address alignmnet for specified data boundary. In
 | 
						|
  case the address is not aligned, it returns FALSE and the amount of data in
 | 
						|
  terms of byte needed to adjust to get the boundary alignmnet. If data is
 | 
						|
  aligned, TRUE will be returned.
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  Address              - Pointer to buffer containing byte data of component.
 | 
						|
  AlignmentData        - DataSize for which address needed to be aligned
 | 
						|
  AlignAdjustByte      - Number of bytes needed to adjust alignment.
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  TRUE                 - Address is aligned to specific data size boundary
 | 
						|
  FALSE                - Address in not aligned to specified data size boundary
 | 
						|
                       - Add/Subtract AlignAdjustByte to aling the address.
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  //
 | 
						|
  // Check if the assigned address is on address boundary. If not, it will
 | 
						|
  // return the remaining byte required to adjust the address for specified
 | 
						|
  // address boundary
 | 
						|
  //
 | 
						|
  *AlignAdjustByte = (Address % AlignmentData);
 | 
						|
 | 
						|
  if (*AlignAdjustByte == 0) {
 | 
						|
    return TRUE;
 | 
						|
  } else {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
GetFitTableStartAddress (
 | 
						|
  IN OUT  FIT_TABLE   **FitTable
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  Get the FIT table start address in VTF Buffer
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  FitTable    - Pointer to available fit table where new component can be added
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  EFI_SUCCESS - The function completed successfully
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  UINT64  FitTableAdd;
 | 
						|
  UINT64  FitTableAddOffset;
 | 
						|
  UINTN   RelativeAddress;
 | 
						|
 | 
						|
  //
 | 
						|
  // Read the Fit Table address from Itanium-based address map.
 | 
						|
  //
 | 
						|
  FitTableAddOffset = Fv1EndAddress - (SIZE_IA32_RESET_VECT + SIZE_SALE_ENTRY_POINT + SIZE_FIT_TABLE_ADD);
 | 
						|
 | 
						|
  //
 | 
						|
  // Translate this Itanium-based address in terms of local buffer address which
 | 
						|
  // contains the image for Boot Strapped File. The relative address will be
 | 
						|
  // the address of fit table VTF buffer.
 | 
						|
  //
 | 
						|
  GetRelativeAddressInVtfBuffer (FitTableAddOffset, &RelativeAddress, FIRST_VTF);
 | 
						|
  FitTableAdd = *(UINTN *) RelativeAddress;
 | 
						|
 | 
						|
  //
 | 
						|
  // The FitTableAdd is the extracted Itanium based address pointing to FIT
 | 
						|
  // table. The relative address will return its actual location in VTF
 | 
						|
  // Buffer.
 | 
						|
  //
 | 
						|
  GetRelativeAddressInVtfBuffer (FitTableAdd, &RelativeAddress, FIRST_VTF);
 | 
						|
 | 
						|
  *FitTable = (FIT_TABLE *) RelativeAddress;
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
GetNextAvailableFitPtr (
 | 
						|
  IN  FIT_TABLE   **FitPtr
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  Get the FIT table address and locate the free space in fit where we can add
 | 
						|
  new component. In this process, this function locates the fit table using
 | 
						|
  Fit pointer in Itanium-based address map (as per Intel?Itanium(TM) SAL spec)
 | 
						|
  and locate the available location in FIT table to be used by new components.
 | 
						|
  If there are any Fit table which areg not being used contains ComponentType
 | 
						|
  field as 0x7F. If needed we can change this and spec this out.
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  FitPtr    - Pointer to available fit table where new component can be added
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  EFI_SUCCESS  - The function completed successfully
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  FIT_TABLE *TmpFitPtr;
 | 
						|
  UINT64    FitTableAdd;
 | 
						|
  UINT64    FitTableAddOffset;
 | 
						|
  UINTN     Index;
 | 
						|
  UINTN     NumFitComponents;
 | 
						|
  UINTN     RelativeAddress;
 | 
						|
 | 
						|
  //
 | 
						|
  // Read the Fit Table address from Itanium-based address map.
 | 
						|
  //
 | 
						|
  FitTableAddOffset = Fv1EndAddress - (SIZE_IA32_RESET_VECT + SIZE_SALE_ENTRY_POINT + SIZE_FIT_TABLE_ADD);
 | 
						|
 | 
						|
  //
 | 
						|
  // Translate this Itanium-based address in terms of local buffer address which
 | 
						|
  // contains the image for Boot Strapped File. The relative address will be
 | 
						|
  // the address of fit table VTF buffer.
 | 
						|
  //
 | 
						|
  GetRelativeAddressInVtfBuffer (FitTableAddOffset, &RelativeAddress, FIRST_VTF);
 | 
						|
  FitTableAdd = *(UINTN *) RelativeAddress;
 | 
						|
 | 
						|
  //
 | 
						|
  // The FitTableAdd is the extracted Itanium based address pointing to FIT
 | 
						|
  // table. The relative address will return its actual location in VTF
 | 
						|
  // Buffer.
 | 
						|
  //
 | 
						|
  GetRelativeAddressInVtfBuffer (FitTableAdd, &RelativeAddress, FIRST_VTF);
 | 
						|
 | 
						|
  TmpFitPtr         = (FIT_TABLE *) RelativeAddress;
 | 
						|
  NumFitComponents  = TmpFitPtr->CompSize;
 | 
						|
 | 
						|
  for (Index = 0; Index < NumFitComponents; Index++) {
 | 
						|
    if ((TmpFitPtr->CvAndType & FIT_TYPE_MASK) == COMP_TYPE_FIT_UNUSED) {
 | 
						|
      *FitPtr = TmpFitPtr;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    TmpFitPtr++;
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
CompareItems (
 | 
						|
  IN const VOID  *Arg1,
 | 
						|
  IN const VOID  *Arg2
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
    This function is used by qsort to sort the FIT table based upon Component
 | 
						|
    Type in their incresing order.
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
    Arg1  -   Pointer to Arg1
 | 
						|
    Arg2  -   Pointer to Arg2
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
    None
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  if ((((FIT_TABLE *) Arg1)->CvAndType & FIT_TYPE_MASK) > (((FIT_TABLE *) Arg2)->CvAndType & FIT_TYPE_MASK)) {
 | 
						|
    return 1;
 | 
						|
  } else if ((((FIT_TABLE *) Arg1)->CvAndType & FIT_TYPE_MASK) < (((FIT_TABLE *) Arg2)->CvAndType & FIT_TYPE_MASK)) {
 | 
						|
    return -1;
 | 
						|
  } else {
 | 
						|
    return 0;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
SortFitTable (
 | 
						|
  IN  VOID
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
    This function is used by qsort to sort the FIT table based upon Component
 | 
						|
    Type in their incresing order.
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
    VOID
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
    None
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  FIT_TABLE *FitTable;
 | 
						|
  FIT_TABLE *TmpFitPtr;
 | 
						|
  UINTN     NumFitComponents;
 | 
						|
  UINTN     Index;
 | 
						|
 | 
						|
  GetFitTableStartAddress (&FitTable);
 | 
						|
  TmpFitPtr         = FitTable;
 | 
						|
  NumFitComponents  = 0;
 | 
						|
  for (Index = 0; Index < FitTable->CompSize; Index++) {
 | 
						|
    if ((TmpFitPtr->CvAndType & FIT_TYPE_MASK) != COMP_TYPE_FIT_UNUSED) {
 | 
						|
      NumFitComponents += 1;
 | 
						|
    }
 | 
						|
    TmpFitPtr++;
 | 
						|
  }
 | 
						|
  qsort ((VOID *) FitTable, NumFitComponents, sizeof (FIT_TABLE), CompareItems);
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
UpdateFitEntryForFwVolume (
 | 
						|
  IN  UINT64  Size
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  This function updates the information about Firmware Volume  in FIT TABLE.
 | 
						|
  This FIT table has to be immediately below the PAL_A Start and it contains
 | 
						|
  component type and address information. Other information can't be
 | 
						|
  created this time so we would need to fix it up..
 | 
						|
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  Size   - Firmware Volume Size
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  VOID
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  FIT_TABLE *CompFitPtr;
 | 
						|
  UINTN     RelativeAddress;
 | 
						|
 | 
						|
  //
 | 
						|
  // FV Fit table will be located at PAL_A Startaddress - 16 byte location
 | 
						|
  //
 | 
						|
  Vtf1LastStartAddress -= 0x10;
 | 
						|
  Vtf1TotalSize += 0x10;
 | 
						|
 | 
						|
  GetRelativeAddressInVtfBuffer (Vtf1LastStartAddress, &RelativeAddress, FIRST_VTF);
 | 
						|
 | 
						|
  CompFitPtr              = (FIT_TABLE *) RelativeAddress;
 | 
						|
  CompFitPtr->CompAddress = Fv1BaseAddress;
 | 
						|
 | 
						|
  //
 | 
						|
  // Since we don't have any information about its location in Firmware Volume,
 | 
						|
  // initialize address to 0. This will be updated once Firmware Volume is
 | 
						|
  // being build and its current address will be fixed in FIT table. Currently
 | 
						|
  // we haven't implemented it so far and working on architectural clarafication
 | 
						|
  //
 | 
						|
  //
 | 
						|
  // Firmware Volume Size in 16 byte block
 | 
						|
  //
 | 
						|
  CompFitPtr->CompSize = ((UINT32) Size) / 16;
 | 
						|
 | 
						|
  //
 | 
						|
  // Since Firmware Volume does not exist by the time we create this FIT info
 | 
						|
  // this should be fixedup from Firmware Volume creation tool. We haven't
 | 
						|
  // worked out a method so far.
 | 
						|
  //
 | 
						|
  CompFitPtr->CompVersion = MAKE_VERSION (0, 0);
 | 
						|
 | 
						|
  //
 | 
						|
  // Since we don't have any info about this file, we are making sure that
 | 
						|
  // checksum is not needed.
 | 
						|
  //
 | 
						|
  CompFitPtr->CvAndType = CV_N_TYPE (0, COMP_TYPE_FIT_FV_BOOT);
 | 
						|
 | 
						|
  //
 | 
						|
  // Since non VTF component will reside outside the VTF, we will not have its
 | 
						|
  // binary image while creating VTF, hence we will not perform checksum at
 | 
						|
  // this time. Once Firmware Volume is being created which will contain this
 | 
						|
  // VTF, it will fix the FIT table for all the non VTF component and hence
 | 
						|
  // checksum
 | 
						|
  //
 | 
						|
  CompFitPtr->CheckSum = 0;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
UpdateFitEntryForNonVTFComp (
 | 
						|
  IN  PARSED_VTF_INFO   *VtfInfo
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  This function updates the information about non VTF component in FIT TABLE.
 | 
						|
  Since non VTF componets binaries are not part of VTF binary, we would still
 | 
						|
  be required to update its location information in Firmware Volume, inside
 | 
						|
  FIT table.
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  VtfInfo    - Pointer to VTF Info Structure
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  EFI_ABORTED  - The function fails to update the component in FIT
 | 
						|
  EFI_SUCCESS  - The function completed successfully
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  FIT_TABLE *CompFitPtr;
 | 
						|
 | 
						|
  //
 | 
						|
  // Scan the FIT table for available space
 | 
						|
  //
 | 
						|
  GetNextAvailableFitPtr (&CompFitPtr);
 | 
						|
  if (CompFitPtr == NULL) {
 | 
						|
    Error (NULL, 0, 5003, "Invalid", "Can't update this component in FIT");
 | 
						|
    return EFI_ABORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Since we don't have any information about its location in Firmware Volume,
 | 
						|
  // initialize address to 0. This will be updated once Firmware Volume is
 | 
						|
  // being build and its current address will be fixed in FIT table
 | 
						|
  //
 | 
						|
  CompFitPtr->CompAddress = 0;
 | 
						|
  CompFitPtr->CompSize    = VtfInfo->CompSize;
 | 
						|
  CompFitPtr->CompVersion = MAKE_VERSION (VtfInfo->MajorVer, VtfInfo->MinorVer);
 | 
						|
  CompFitPtr->CvAndType   = CV_N_TYPE (VtfInfo->CheckSumRequired, VtfInfo->CompType);
 | 
						|
 | 
						|
  //
 | 
						|
  // Since non VTF component will reside outside the VTF, we will not have its
 | 
						|
  // binary image while creating VTF, hence we will not perform checksum at
 | 
						|
  // this time. Once Firmware Volume is being created which will contain this
 | 
						|
  // VTF, it will fix the FIT table for all the non VTF component and hence
 | 
						|
  // checksum
 | 
						|
  //
 | 
						|
  CompFitPtr->CheckSum = 0;
 | 
						|
 | 
						|
  //
 | 
						|
  // Fit Type is FV_BOOT which means Firmware Volume, we initialize this to base
 | 
						|
  // address of Firmware Volume in which this VTF will be attached.
 | 
						|
  //
 | 
						|
  if ((CompFitPtr->CvAndType & 0x7F) == COMP_TYPE_FIT_FV_BOOT) {
 | 
						|
    CompFitPtr->CompAddress = Fv1BaseAddress;
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
//
 | 
						|
// !!!WARNING
 | 
						|
// This function is updating the SALE_ENTRY in Itanium address space as per SAL
 | 
						|
// spec. SALE_ENTRY is being read from SYM file of PEICORE. Once the PEI
 | 
						|
// CORE moves in Firmware Volume, we would need to modify this function to be
 | 
						|
// used with a API which will detect PEICORE component while building Firmware
 | 
						|
// Volume and update its entry in FIT table as well as in Itanium address space
 | 
						|
// as per Intel?Itanium(TM) SAL address space
 | 
						|
//
 | 
						|
EFI_STATUS
 | 
						|
UpdateEntryPoint (
 | 
						|
  IN  PARSED_VTF_INFO   *VtfInfo,
 | 
						|
  IN  UINT64            *CompStartAddress
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  This function updated the architectural entry point in IPF, SALE_ENTRY.
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  VtfInfo            - Pointer to VTF Info Structure
 | 
						|
  CompStartAddress   - Pointer to Component Start Address
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  EFI_INVALID_PARAMETER  - The parameter is invalid
 | 
						|
  EFI_SUCCESS            - The function completed successfully
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  UINTN   RelativeAddress;
 | 
						|
  UINT64  SalEntryAdd;
 | 
						|
  FILE    *Fp;
 | 
						|
  UINTN   Offset;
 | 
						|
 | 
						|
  CHAR8   Buff[FILE_NAME_SIZE];
 | 
						|
  CHAR8   Buff1[10];
 | 
						|
  CHAR8   Buff2[10];
 | 
						|
  CHAR8   OffsetStr[30];
 | 
						|
  CHAR8   Buff3[10];
 | 
						|
  CHAR8   Buff4[10];
 | 
						|
  CHAR8   Buff5[10];
 | 
						|
  CHAR8   Token[50];
 | 
						|
 | 
						|
  Fp = fopen (VtfInfo->CompSymName, "rb");
 | 
						|
 | 
						|
  if (Fp == NULL) {
 | 
						|
    Error (NULL, 0, 0001, "Error opening file", VtfInfo->CompSymName);
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  while (fgets (Buff, sizeof (Buff), Fp) != NULL) {
 | 
						|
    fscanf (
 | 
						|
      Fp,
 | 
						|
      "%s %s %s %s %s %s %s",
 | 
						|
      Buff1,
 | 
						|
      Buff2,
 | 
						|
      OffsetStr,
 | 
						|
      Buff3,
 | 
						|
      Buff4,
 | 
						|
      Buff5,
 | 
						|
      Token
 | 
						|
      );
 | 
						|
    if (strnicmp (Token, "SALE_ENTRY", 10) == 0) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  Offset = strtoul (OffsetStr, NULL, 16);
 | 
						|
 | 
						|
  *CompStartAddress += Offset;
 | 
						|
  SalEntryAdd = Fv1EndAddress - (SIZE_IA32_RESET_VECT + SIZE_SALE_ENTRY_POINT);
 | 
						|
 | 
						|
  GetRelativeAddressInVtfBuffer (SalEntryAdd, &RelativeAddress, FIRST_VTF);
 | 
						|
 | 
						|
  memcpy ((VOID *) RelativeAddress, (VOID *) CompStartAddress, sizeof (UINT64));
 | 
						|
 | 
						|
  if (Fp != NULL) {
 | 
						|
    fclose (Fp);
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
CreateAndUpdateComponent (
 | 
						|
  IN  PARSED_VTF_INFO   *VtfInfo
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  This function reads the binary file for each components and update them
 | 
						|
  in VTF Buffer as well as in FIT table. If the component is located in non
 | 
						|
  VTF area, only the FIT table address will be updated
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  VtfInfo    - Pointer to Parsed Info
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  EFI_SUCCESS      - The function completed successful
 | 
						|
  EFI_ABORTED      - Aborted due to one of the many reasons like:
 | 
						|
                      (a) Component Size greater than the specified size.
 | 
						|
                      (b) Error opening files.
 | 
						|
 | 
						|
  EFI_INVALID_PARAMETER     Value returned from call to UpdateEntryPoint()
 | 
						|
  EFI_OUT_OF_RESOURCES      Memory allocation failure.
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
  UINT64      CompStartAddress;
 | 
						|
  UINT64      FileSize;
 | 
						|
  UINT64      NumByteRead;
 | 
						|
  UINT64      NumAdjustByte;
 | 
						|
  UINT8       *Buffer;
 | 
						|
  FILE        *Fp;
 | 
						|
  FIT_TABLE   *CompFitPtr;
 | 
						|
  BOOLEAN     Aligncheck;
 | 
						|
 | 
						|
  if (VtfInfo->LocationType == NONE) {
 | 
						|
    UpdateFitEntryForNonVTFComp (VtfInfo);
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  Fp = fopen (VtfInfo->CompBinName, "rb");
 | 
						|
 | 
						|
  if (Fp == NULL) {
 | 
						|
    Error (NULL, 0, 0001, "Error opening file", VtfInfo->CompBinName);
 | 
						|
    return EFI_ABORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  FileSize = _filelength (fileno (Fp));
 | 
						|
  if ((VtfInfo->CompType == COMP_TYPE_FIT_PAL_B) || (VtfInfo->CompType == COMP_TYPE_FIT_PAL_A_SPECIFIC)) {
 | 
						|
 | 
						|
    //
 | 
						|
    // BUGBUG: Satish to correct
 | 
						|
    //
 | 
						|
    FileSize -= SIZE_OF_PAL_HEADER;
 | 
						|
  }
 | 
						|
 | 
						|
  if (VtfInfo->PreferredSize) {
 | 
						|
    if (FileSize > VtfInfo->CompSize) {
 | 
						|
      Error (NULL, 0, 2000, "Invalid parameter", "The component size is more than specified size.");
 | 
						|
      return EFI_ABORTED;
 | 
						|
    }
 | 
						|
 | 
						|
    FileSize = VtfInfo->CompSize;
 | 
						|
  }
 | 
						|
 | 
						|
  Buffer = malloc ((UINTN) FileSize);
 | 
						|
  if (Buffer == NULL) {
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
  memset (Buffer, 0, (UINTN) FileSize);
 | 
						|
 | 
						|
  if ((VtfInfo->CompType == COMP_TYPE_FIT_PAL_B) || (VtfInfo->CompType == COMP_TYPE_FIT_PAL_A_SPECIFIC)) {
 | 
						|
 | 
						|
    //
 | 
						|
    // Read first 64 bytes of PAL header and use it to find version info
 | 
						|
    //
 | 
						|
    NumByteRead = fread (Buffer, sizeof (UINT8), SIZE_OF_PAL_HEADER, Fp);
 | 
						|
 | 
						|
    //
 | 
						|
    // PAL header contains the version info. Currently, we will use the header
 | 
						|
    // to read version info and then discard.
 | 
						|
    //
 | 
						|
    if (!VtfInfo->VersionPresent) {
 | 
						|
      GetComponentVersionInfo (VtfInfo, Buffer);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  NumByteRead = fread (Buffer, sizeof (UINT8), (UINTN) FileSize, Fp);
 | 
						|
  fclose (Fp);
 | 
						|
 | 
						|
  //
 | 
						|
  // If it is non PAL_B component, pass the entire buffer to get the version
 | 
						|
  // info and implement any specific case inside GetComponentVersionInfo.
 | 
						|
  //
 | 
						|
  if (VtfInfo->CompType != COMP_TYPE_FIT_PAL_B) {
 | 
						|
    if (!VtfInfo->VersionPresent) {
 | 
						|
      GetComponentVersionInfo (VtfInfo, Buffer);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (VtfInfo->LocationType == SECOND_VTF) {
 | 
						|
 | 
						|
    CompStartAddress = (Vtf2LastStartAddress - FileSize);
 | 
						|
  } else {
 | 
						|
    CompStartAddress = (Vtf1LastStartAddress - FileSize);
 | 
						|
  }
 | 
						|
 | 
						|
  if (VtfInfo->CompType == COMP_TYPE_FIT_PAL_B) {
 | 
						|
    Aligncheck = CheckAddressAlignment (CompStartAddress, 32 * 1024, &NumAdjustByte);
 | 
						|
  } else {
 | 
						|
    Aligncheck = CheckAddressAlignment (CompStartAddress, 8, &NumAdjustByte);
 | 
						|
  }
 | 
						|
 | 
						|
  if (!Aligncheck) {
 | 
						|
    CompStartAddress -= NumAdjustByte;
 | 
						|
  }
 | 
						|
 | 
						|
  if (VtfInfo->LocationType == SECOND_VTF && SecondVTF == TRUE) {
 | 
						|
    Vtf2LastStartAddress = CompStartAddress;
 | 
						|
    Vtf2TotalSize += (UINT32) (FileSize + NumAdjustByte);
 | 
						|
    Status = UpdateVtfBuffer (CompStartAddress, Buffer, FileSize, SECOND_VTF);
 | 
						|
  } else if (VtfInfo->LocationType == FIRST_VTF) {
 | 
						|
    Vtf1LastStartAddress = CompStartAddress;
 | 
						|
    Vtf1TotalSize += (UINT32) (FileSize + NumAdjustByte);
 | 
						|
    Status = UpdateVtfBuffer (CompStartAddress, Buffer, FileSize, FIRST_VTF);
 | 
						|
  } else {
 | 
						|
    Error (NULL, 0, 2000,"Invalid Parameter", "There's component in second VTF so second BaseAddress and Size must be specified!");
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return EFI_ABORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  GetNextAvailableFitPtr (&CompFitPtr);
 | 
						|
 | 
						|
  CompFitPtr->CompAddress = CompStartAddress | IPF_CACHE_BIT;
 | 
						|
  if ((FileSize % 16) != 0) {
 | 
						|
    Error (NULL, 0, 2000, "Invalid parameter", "Binary FileSize must be a multiple of 16.");
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
  //assert ((FileSize % 16) == 0);
 | 
						|
  CompFitPtr->CompSize    = (UINT32) (FileSize / 16);
 | 
						|
  CompFitPtr->CompVersion = MAKE_VERSION (VtfInfo->MajorVer, VtfInfo->MinorVer);
 | 
						|
  CompFitPtr->CvAndType   = CV_N_TYPE (VtfInfo->CheckSumRequired, VtfInfo->CompType);
 | 
						|
  if (VtfInfo->CheckSumRequired) {
 | 
						|
    CompFitPtr->CheckSum  = 0;
 | 
						|
    CompFitPtr->CheckSum  = CalculateChecksum8 (Buffer, (UINTN) FileSize);
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Free the buffer
 | 
						|
  //
 | 
						|
  if (Buffer) {
 | 
						|
    free (Buffer);
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Update the SYM file for this component based on it's start address.
 | 
						|
  //
 | 
						|
  Status = UpdateSymFile (CompStartAddress, SymFileName, VtfInfo->CompSymName, FileSize);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
 | 
						|
    //
 | 
						|
    // At this time, SYM files are not required, so continue on error.
 | 
						|
    //
 | 
						|
  }
 | 
						|
 | 
						|
  // !!!!!!!!!!!!!!!!!!!!!
 | 
						|
  // BUGBUG:
 | 
						|
  // This part of the code is a temporary line since PEICORE is going to be inside
 | 
						|
  // VTF till we work out how to determine the SALE_ENTRY through it. We will need
 | 
						|
  // to clarify so many related questions
 | 
						|
  // !!!!!!!!!!!!!!!!!!!!!!!
 | 
						|
 | 
						|
  if (VtfInfo->CompType == COMP_TYPE_FIT_PEICORE) {
 | 
						|
    Status = UpdateEntryPoint (VtfInfo, &CompStartAddress);
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
CreateAndUpdatePAL_A (
 | 
						|
  IN  PARSED_VTF_INFO   *VtfInfo
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  This function reads the binary file for each components and update them
 | 
						|
  in VTF Buffer as well as FIT table
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  VtfInfo    - Pointer to Parsed Info
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  EFI_ABORTED           - Due to one of the following reasons:
 | 
						|
                           (a)Error Opening File
 | 
						|
                           (b)The PAL_A Size is more than specified size status
 | 
						|
                              One of the values mentioned below returned from
 | 
						|
                              call to UpdateSymFile
 | 
						|
  EFI_SUCCESS           - The function completed successfully.
 | 
						|
  EFI_INVALID_PARAMETER - One of the input parameters was invalid.
 | 
						|
  EFI_ABORTED           - An error occurred.UpdateSymFile
 | 
						|
  EFI_OUT_OF_RESOURCES  - Memory allocation failed.
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
  UINT64      PalStartAddress;
 | 
						|
  UINT64      AbsAddress;
 | 
						|
  UINTN       RelativeAddress;
 | 
						|
  UINT64      FileSize;
 | 
						|
  UINT64      NumByteRead;
 | 
						|
  UINT8       *Buffer;
 | 
						|
  FILE        *Fp;
 | 
						|
  FIT_TABLE   *PalFitPtr;
 | 
						|
 | 
						|
  Fp = fopen (VtfInfo->CompBinName, "rb");
 | 
						|
 | 
						|
  if (Fp == NULL) {
 | 
						|
    Error (NULL, 0, 0001, "Error opening file", VtfInfo->CompBinName);
 | 
						|
    return EFI_ABORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  FileSize = _filelength (fileno (Fp));
 | 
						|
  if (FileSize < 64) {
 | 
						|
    Error (NULL, 0, 2000, "Invalid parameter", "PAL_A bin header is 64 bytes, so the Bin size must be larger than 64 bytes!");
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
  FileSize -= SIZE_OF_PAL_HEADER;
 | 
						|
 | 
						|
 | 
						|
  if (VtfInfo->PreferredSize) {
 | 
						|
    if (FileSize > VtfInfo->CompSize) {
 | 
						|
      Error (NULL, 0, 2000, "Invalid parameter", "The PAL_A Size is more than the specified size.");
 | 
						|
      return EFI_ABORTED;
 | 
						|
    }
 | 
						|
 | 
						|
    FileSize = VtfInfo->CompSize;
 | 
						|
  }
 | 
						|
 | 
						|
  Buffer = malloc ((UINTN) FileSize);
 | 
						|
  if (Buffer == NULL) {
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
  memset (Buffer, 0, (UINTN) FileSize);
 | 
						|
 | 
						|
  //
 | 
						|
  // Read, Get version Info and discard the PAL header.
 | 
						|
  //
 | 
						|
  NumByteRead = fread (Buffer, sizeof (UINT8), SIZE_OF_PAL_HEADER, Fp);
 | 
						|
 | 
						|
  //
 | 
						|
  // Extract the version info from header of PAL_A. Once done, discrad this buffer
 | 
						|
  //
 | 
						|
  if (!VtfInfo->VersionPresent) {
 | 
						|
    GetComponentVersionInfo (VtfInfo, Buffer);
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Read PAL_A file in a buffer
 | 
						|
  //
 | 
						|
  NumByteRead = fread (Buffer, sizeof (UINT8), (UINTN) FileSize, Fp);
 | 
						|
  fclose (Fp);
 | 
						|
 | 
						|
  PalStartAddress       = Fv1EndAddress - (SIZE_TO_OFFSET_PAL_A_END + FileSize);
 | 
						|
  Vtf1LastStartAddress  = PalStartAddress;
 | 
						|
  Vtf1TotalSize += (UINT32) FileSize;
 | 
						|
  Status      = UpdateVtfBuffer (PalStartAddress, Buffer, FileSize, FIRST_VTF);
 | 
						|
 | 
						|
  AbsAddress  = Fv1EndAddress - SIZE_TO_PAL_A_FIT;
 | 
						|
  GetRelativeAddressInVtfBuffer (AbsAddress, &RelativeAddress, FIRST_VTF);
 | 
						|
  PalFitPtr               = (FIT_TABLE *) RelativeAddress;
 | 
						|
  PalFitPtr->CompAddress  = PalStartAddress | IPF_CACHE_BIT;
 | 
						|
  //assert ((FileSize % 16) == 0);
 | 
						|
  if ((FileSize % 16) != 0) {
 | 
						|
    Error (NULL, 0, 2000, "Invalid parameter", "Binary FileSize must be a multiple of 16.");
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  PalFitPtr->CompSize     = (UINT32) (FileSize / 16);
 | 
						|
  PalFitPtr->CompVersion  = MAKE_VERSION (VtfInfo->MajorVer, VtfInfo->MinorVer);
 | 
						|
  PalFitPtr->CvAndType    = CV_N_TYPE (VtfInfo->CheckSumRequired, VtfInfo->CompType);
 | 
						|
  if (VtfInfo->CheckSumRequired) {
 | 
						|
    PalFitPtr->CheckSum = 0;
 | 
						|
    PalFitPtr->CheckSum = CalculateChecksum8 (Buffer, (UINTN) FileSize);
 | 
						|
  }
 | 
						|
 | 
						|
  if (Buffer) {
 | 
						|
    free (Buffer);
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Update the SYM file for this component based on it's start address.
 | 
						|
  //
 | 
						|
  Status = UpdateSymFile (PalStartAddress, SymFileName, VtfInfo->CompSymName, FileSize);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
 | 
						|
    //
 | 
						|
    // At this time, SYM files are not required, so continue on error.
 | 
						|
    //
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
CreateFitTableAndInitialize (
 | 
						|
  IN  PARSED_VTF_INFO   *VtfInfo
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  This function creates and intializes FIT table which would be used to
 | 
						|
  add component info inside this
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  VtfInfo    - Pointer to Parsed Info
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  EFI_ABORTED  - Aborted due to no size information
 | 
						|
  EFI_SUCCESS  - The function completed successfully
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  UINT64    PalFitTableAdd;
 | 
						|
  UINT64    FitTableAdd;
 | 
						|
  UINT64    FitTableAddressOffset;
 | 
						|
  FIT_TABLE *PalFitPtr;
 | 
						|
  FIT_TABLE *FitStartPtr;
 | 
						|
  UINTN     NumFitComp;
 | 
						|
  UINTN     RelativeAddress;
 | 
						|
  UINTN     Index;
 | 
						|
 | 
						|
  if (!VtfInfo->PreferredSize) {
 | 
						|
    Error (NULL, 0, 2000, "Invalid parameter", "FIT could not be allocated because there is no size information.");
 | 
						|
    return EFI_ABORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  if ((VtfInfo->CompSize % 16) != 0) {
 | 
						|
    Error (NULL, 0, 2000, "Invalid parameter", "Invalid FIT Table Size, it is not a multiple of 16 bytes. Please correct the size.");
 | 
						|
  }
 | 
						|
 | 
						|
  PalFitTableAdd = Fv1EndAddress - SIZE_TO_PAL_A_FIT;
 | 
						|
  GetRelativeAddressInVtfBuffer (PalFitTableAdd, &RelativeAddress, FIRST_VTF);
 | 
						|
  PalFitPtr             = (FIT_TABLE *) RelativeAddress;
 | 
						|
  PalFitTableAdd        = (PalFitPtr->CompAddress - VtfInfo->CompSize);
 | 
						|
 | 
						|
  FitTableAdd           = (PalFitPtr->CompAddress - 0x10) - VtfInfo->CompSize;
 | 
						|
  FitTableAddressOffset = Fv1EndAddress - (SIZE_IA32_RESET_VECT + SIZE_SALE_ENTRY_POINT + SIZE_FIT_TABLE_ADD);
 | 
						|
  GetRelativeAddressInVtfBuffer (FitTableAddressOffset, &RelativeAddress, FIRST_VTF);
 | 
						|
  *(UINT64 *) RelativeAddress = FitTableAdd;
 | 
						|
 | 
						|
  GetRelativeAddressInVtfBuffer (FitTableAdd, &RelativeAddress, FIRST_VTF);
 | 
						|
 | 
						|
  //
 | 
						|
  // Update Fit Table with FIT Signature and FIT info in first 16 bytes.
 | 
						|
  //
 | 
						|
  FitStartPtr = (FIT_TABLE *) RelativeAddress;
 | 
						|
 | 
						|
  strncpy ((CHAR8 *) &FitStartPtr->CompAddress, FIT_SIGNATURE, 8);  // "_FIT_   "
 | 
						|
  assert (((VtfInfo->CompSize & 0x00FFFFFF) % 16) == 0);
 | 
						|
  FitStartPtr->CompSize     = (VtfInfo->CompSize & 0x00FFFFFF) / 16;
 | 
						|
  FitStartPtr->CompVersion  = MAKE_VERSION (VtfInfo->MajorVer, VtfInfo->MinorVer);
 | 
						|
 | 
						|
  //
 | 
						|
  // BUGBUG: If a checksum is required, add code to checksum the FIT table.  Also
 | 
						|
  // determine what to do for things like the FV component that aren't easily checksummed.
 | 
						|
  // The checksum will be done once we are done with all the componet update in the FIT
 | 
						|
  // table
 | 
						|
  //
 | 
						|
  FitStartPtr->CvAndType  = CV_N_TYPE (VtfInfo->CheckSumRequired, VtfInfo->CompType);
 | 
						|
 | 
						|
  NumFitComp              = FitStartPtr->CompSize;
 | 
						|
 | 
						|
  FitStartPtr++;
 | 
						|
 | 
						|
  //
 | 
						|
  // Intialize remaining FIT table space to UNUSED fit component type
 | 
						|
  // so that when we need to create a FIT entry for a component, we can
 | 
						|
  // locate a free one and use it.
 | 
						|
  //
 | 
						|
  for (Index = 0; Index < (NumFitComp - 1); Index++) {
 | 
						|
    FitStartPtr->CvAndType = 0x7F;  // Initialize all with UNUSED
 | 
						|
    FitStartPtr++;
 | 
						|
  }
 | 
						|
 | 
						|
  Vtf1TotalSize += VtfInfo->CompSize;
 | 
						|
  Vtf1LastStartAddress -= VtfInfo->CompSize;
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
WriteVtfBinary (
 | 
						|
  IN CHAR8     *FileName,
 | 
						|
  IN UINT32    VtfSize,
 | 
						|
  IN LOC_TYPE  LocType
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  Write Firmware Volume from memory to a file.
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  FileName     - Output File Name which needed to be created/
 | 
						|
  VtfSize      - FileSize
 | 
						|
  LocType      - The type of the VTF
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  EFI_ABORTED - Returned due to one of the following resons:
 | 
						|
                 (a) Error Opening File
 | 
						|
                 (b) Failing to copy buffers
 | 
						|
  EFI_SUCCESS - The fuction completes successfully
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  FILE  *Fp;
 | 
						|
  UINTN NumByte;
 | 
						|
  VOID  *VtfBuffer;
 | 
						|
  UINTN RelativeAddress;
 | 
						|
 | 
						|
  if (LocType == FIRST_VTF) {
 | 
						|
    GetRelativeAddressInVtfBuffer (Vtf1LastStartAddress, &RelativeAddress, FIRST_VTF);
 | 
						|
    VtfBuffer = (VOID *) RelativeAddress;
 | 
						|
  } else {
 | 
						|
    GetRelativeAddressInVtfBuffer (Vtf2LastStartAddress, &RelativeAddress, SECOND_VTF);
 | 
						|
    VtfBuffer = (VOID *) RelativeAddress;
 | 
						|
  }
 | 
						|
 | 
						|
  Fp = fopen (FileName, "wb");
 | 
						|
  if (Fp == NULL) {
 | 
						|
    Error (NULL, 0, 0001, "Error opening file", FileName);
 | 
						|
    return EFI_ABORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  NumByte = fwrite (VtfBuffer, sizeof (UINT8), (UINTN) VtfSize, Fp);
 | 
						|
 | 
						|
  if (Fp) {
 | 
						|
    fclose (Fp);
 | 
						|
  }
 | 
						|
 | 
						|
  if (NumByte != (sizeof (UINT8) * VtfSize)) {
 | 
						|
    Error (NULL, 0, 0002, "Error writing file", FileName);
 | 
						|
    return EFI_ABORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
UpdateVtfBuffer (
 | 
						|
  IN  UINT64   StartAddress,
 | 
						|
  IN  UINT8    *Buffer,
 | 
						|
  IN  UINT64   DataSize,
 | 
						|
  IN LOC_TYPE  LocType
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  Update the Firmware Volume Buffer with requested buffer data
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  StartAddress   - StartAddress in buffer. This number will automatically
 | 
						|
                  point to right address in buffer where data needed
 | 
						|
                  to be updated.
 | 
						|
  Buffer         - Buffer pointer from data will be copied to memory mapped buffer.
 | 
						|
  DataSize       - Size of the data needed to be copied.
 | 
						|
  LocType        - The type of the VTF: First or Second
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  EFI_ABORTED  - The input parameter is error
 | 
						|
  EFI_SUCCESS  - The function completed successfully
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  UINT8 *LocalBufferPtrToWrite;
 | 
						|
 | 
						|
  if (LocType == FIRST_VTF) {
 | 
						|
    if ((StartAddress | IPF_CACHE_BIT) < (Vtf1LastStartAddress | IPF_CACHE_BIT)) {
 | 
						|
      Error (NULL, 0, 2000, "Invalid parameter", "Start Address is less than the VTF start address.");
 | 
						|
      return EFI_ABORTED;
 | 
						|
    }
 | 
						|
 | 
						|
    LocalBufferPtrToWrite = (UINT8 *) Vtf1EndBuffer;
 | 
						|
 | 
						|
    LocalBufferPtrToWrite -= (Fv1EndAddress - StartAddress);
 | 
						|
 | 
						|
  } else {
 | 
						|
 | 
						|
    if ((StartAddress | IPF_CACHE_BIT) < (Vtf2LastStartAddress | IPF_CACHE_BIT)) {
 | 
						|
      Error (NULL, 0, 2000, "Invalid parameter", "Error StartAddress");
 | 
						|
      return EFI_ABORTED;
 | 
						|
    }
 | 
						|
    LocalBufferPtrToWrite = (UINT8 *) Vtf2EndBuffer;
 | 
						|
    LocalBufferPtrToWrite -= (Fv2EndAddress - StartAddress);
 | 
						|
  }
 | 
						|
 | 
						|
  memcpy (LocalBufferPtrToWrite, Buffer, (UINTN) DataSize);
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
UpdateFfsHeader (
 | 
						|
  IN UINT32         TotalVtfSize,
 | 
						|
  IN LOC_TYPE       LocType
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  Update the Firmware Volume Buffer with requested buffer data
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  TotalVtfSize     - Size of the VTF
 | 
						|
  Fileoffset       - The start of the file relative to the start of the FV.
 | 
						|
  LocType          - The type of the VTF
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  EFI_SUCCESS            - The function completed successfully
 | 
						|
  EFI_INVALID_PARAMETER  - The Ffs File Header Pointer is NULL
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  EFI_FFS_FILE_HEADER *FileHeader;
 | 
						|
  UINTN               RelativeAddress;
 | 
						|
  EFI_GUID            EfiFirmwareVolumeTopFileGuid = EFI_FFS_VOLUME_TOP_FILE_GUID;
 | 
						|
 | 
						|
  //
 | 
						|
  // Find the VTF file header location
 | 
						|
  //
 | 
						|
  if (LocType == FIRST_VTF) {
 | 
						|
    GetRelativeAddressInVtfBuffer (Vtf1LastStartAddress, &RelativeAddress, FIRST_VTF);
 | 
						|
    FileHeader = (EFI_FFS_FILE_HEADER *) RelativeAddress;
 | 
						|
  } else {
 | 
						|
    GetRelativeAddressInVtfBuffer (Vtf2LastStartAddress, &RelativeAddress, SECOND_VTF);
 | 
						|
    FileHeader = (EFI_FFS_FILE_HEADER *) RelativeAddress;
 | 
						|
  }
 | 
						|
 | 
						|
  if (FileHeader == NULL) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // write header
 | 
						|
  //
 | 
						|
  memset (FileHeader, 0, sizeof (EFI_FFS_FILE_HEADER));
 | 
						|
  memcpy (&FileHeader->Name, &EfiFirmwareVolumeTopFileGuid, sizeof (EFI_GUID));
 | 
						|
  FileHeader->Type        = EFI_FV_FILETYPE_RAW;
 | 
						|
  FileHeader->Attributes  = FFS_ATTRIB_CHECKSUM;
 | 
						|
 | 
						|
  //
 | 
						|
  // Now FileSize includes the EFI_FFS_FILE_HEADER
 | 
						|
  //
 | 
						|
  FileHeader->Size[0] = (UINT8) (TotalVtfSize & 0x000000FF);
 | 
						|
  FileHeader->Size[1] = (UINT8) ((TotalVtfSize & 0x0000FF00) >> 8);
 | 
						|
  FileHeader->Size[2] = (UINT8) ((TotalVtfSize & 0x00FF0000) >> 16);
 | 
						|
 | 
						|
  //
 | 
						|
  // Fill in checksums and state, all three must be zero for the checksums.
 | 
						|
  //
 | 
						|
  FileHeader->IntegrityCheck.Checksum.Header  = 0;
 | 
						|
  FileHeader->IntegrityCheck.Checksum.File    = 0;
 | 
						|
  FileHeader->State                           = 0;
 | 
						|
  FileHeader->IntegrityCheck.Checksum.Header  = CalculateChecksum8 ((UINT8 *) FileHeader, sizeof (EFI_FFS_FILE_HEADER));
 | 
						|
  FileHeader->IntegrityCheck.Checksum.File    = CalculateChecksum8 ((UINT8 *) (FileHeader + 1), TotalVtfSize - sizeof (EFI_FFS_FILE_HEADER));
 | 
						|
  FileHeader->State                           = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID;
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
ValidateAddressAndSize (
 | 
						|
  IN  UINT64  BaseAddress,
 | 
						|
  IN  UINT64  FwVolSize
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  Update the Firmware Volume Buffer with requested buffer data
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  BaseAddress    - Base address for the Fw Volume.
 | 
						|
 | 
						|
  FwVolSize      - Total Size of the FwVolume to which VTF will be attached..
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  EFI_SUCCESS     - The function completed successfully
 | 
						|
  EFI_UNSUPPORTED - The input parameter is error
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  if ((BaseAddress >= 0) && (FwVolSize > 0x40) && ((BaseAddress + FwVolSize) % 8 == 0)) {
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_UNSUPPORTED;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
UpdateIA32ResetVector (
 | 
						|
  IN  CHAR8   *FileName,
 | 
						|
  IN  UINT64  FirstFwVSize
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  Update the 16 byte IA32 Reset vector to maintain the compatibility
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  FileName     - Binary file name which contains the IA32 Reset vector info..
 | 
						|
  FirstFwVSize - Total Size of the FwVolume to which VTF will be attached..
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  EFI_SUCCESS            - The function completed successfully
 | 
						|
  EFI_ABORTED            - Invalid File Size
 | 
						|
  EFI_INVALID_PARAMETER  - Bad File Name
 | 
						|
  EFI_OUT_OF_RESOURCES   - Memory allocation failed.
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  UINT8 *Buffer;
 | 
						|
  UINT8 *LocalVtfBuffer;
 | 
						|
  UINTN FileSize;
 | 
						|
  UINTN NumByteRead;
 | 
						|
  FILE  *Fp;
 | 
						|
 | 
						|
  if (!strcmp (FileName, "")) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  Fp = fopen (FileName, "rb");
 | 
						|
 | 
						|
  if (Fp == NULL) {
 | 
						|
    Error (NULL, 0, 0001, "Error opening file", FileName);
 | 
						|
    return EFI_ABORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  FileSize = _filelength (fileno (Fp));
 | 
						|
 | 
						|
  if (FileSize > 16) {
 | 
						|
    return EFI_ABORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  Buffer = malloc (FileSize);
 | 
						|
  if (Buffer == NULL) {
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
 | 
						|
  NumByteRead     = fread (Buffer, sizeof (UINT8), FileSize, Fp);
 | 
						|
 | 
						|
  LocalVtfBuffer  = (UINT8 *) Vtf1EndBuffer - SIZE_IA32_RESET_VECT;
 | 
						|
  memcpy (LocalVtfBuffer, Buffer, FileSize);
 | 
						|
 | 
						|
  if (Buffer) {
 | 
						|
    free (Buffer);
 | 
						|
  }
 | 
						|
 | 
						|
  if (Fp != NULL) {
 | 
						|
    fclose (Fp);
 | 
						|
  }
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
CleanUpMemory (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  This function cleans up any allocated buffer
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  NONE
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  NONE
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  PARSED_VTF_INFO *TempFileListPtr;
 | 
						|
 | 
						|
  if (Vtf1Buffer) {
 | 
						|
    free (Vtf1Buffer);
 | 
						|
  }
 | 
						|
 | 
						|
  if (Vtf2Buffer) {
 | 
						|
    free (Vtf2Buffer);
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Cleanup the buffer which was allocated to read the file names from FV.INF
 | 
						|
  //
 | 
						|
  FileListPtr = FileListHeadPtr;
 | 
						|
  while (FileListPtr != NULL) {
 | 
						|
    TempFileListPtr = FileListPtr->NextVtfInfo;
 | 
						|
    free (FileListPtr);
 | 
						|
    FileListPtr = TempFileListPtr;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
ProcessAndCreateVtf (
 | 
						|
  IN  UINT64  Size
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  This function process the link list created during INF file parsing
 | 
						|
  and create component in VTF and updates its info in FIT table
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  Size   - Size of the Firmware Volume of which, this VTF belongs to.
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  EFI_UNSUPPORTED - Unknown FIT type
 | 
						|
  EFI_SUCCESS     - The function completed successfully
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  EFI_STATUS      Status;
 | 
						|
  PARSED_VTF_INFO *ParsedInfoPtr;
 | 
						|
 | 
						|
  Status        = EFI_SUCCESS;
 | 
						|
 | 
						|
  ParsedInfoPtr = FileListHeadPtr;
 | 
						|
 | 
						|
  while (ParsedInfoPtr != NULL) {
 | 
						|
 | 
						|
    switch (ParsedInfoPtr->CompType) {
 | 
						|
    //
 | 
						|
    // COMP_TYPE_FIT_HEADER is a special case, hence handle it here
 | 
						|
    //
 | 
						|
    case COMP_TYPE_FIT_HEADER:
 | 
						|
      //COMP_TYPE_FIT_HEADER          0x00
 | 
						|
      Status = CreateFitTableAndInitialize (ParsedInfoPtr);
 | 
						|
      break;
 | 
						|
 | 
						|
    //
 | 
						|
    // COMP_TYPE_FIT_PAL_A is a special case, hence handle it here
 | 
						|
    //
 | 
						|
    case COMP_TYPE_FIT_PAL_A:
 | 
						|
      //COMP_TYPE_FIT_PAL_A           0x0F
 | 
						|
      Status = CreateAndUpdatePAL_A (ParsedInfoPtr);
 | 
						|
 | 
						|
      //
 | 
						|
      // Based on VTF specification, once the PAL_A component has been written,
 | 
						|
      // update the Firmware Volume info as FIT table. This will be utilized
 | 
						|
      // to extract the Firmware Volume Start address where this VTF will be
 | 
						|
      // of part.
 | 
						|
      //
 | 
						|
      if (Status == EFI_SUCCESS) {
 | 
						|
        UpdateFitEntryForFwVolume (Size);
 | 
						|
      }
 | 
						|
      break;
 | 
						|
 | 
						|
    case COMP_TYPE_FIT_FV_BOOT:
 | 
						|
      //COMP_TYPE_FIT_FV_BOOT         0x7E
 | 
						|
      //
 | 
						|
      // Since FIT entry for Firmware Volume has been created and it is
 | 
						|
      // located at (PAL_A start - 16 byte). So we will not process any
 | 
						|
      // Firmware Volume related entry from INF file
 | 
						|
      //
 | 
						|
      Status = EFI_SUCCESS;
 | 
						|
      break;
 | 
						|
 | 
						|
    default:
 | 
						|
      //
 | 
						|
      // Any other component type should be handled here. This will create the
 | 
						|
      // image in specified VTF and create appropriate entry about this
 | 
						|
      // component in FIT Entry.
 | 
						|
      //
 | 
						|
      Status = CreateAndUpdateComponent (ParsedInfoPtr);
 | 
						|
      if (EFI_ERROR (Status)) {
 | 
						|
        Error (NULL, 0, 0002, "Error updating component", ParsedInfoPtr->CompName);
 | 
						|
        return EFI_ABORTED;
 | 
						|
      } else {
 | 
						|
      break;}
 | 
						|
    }
 | 
						|
 | 
						|
    ParsedInfoPtr = ParsedInfoPtr->NextVtfInfo;
 | 
						|
  }
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
GenerateVtfImage (
 | 
						|
  IN  UINT64  StartAddress1,
 | 
						|
  IN  UINT64  Size1,
 | 
						|
  IN  UINT64  StartAddress2,
 | 
						|
  IN  UINT64  Size2,
 | 
						|
  IN  FILE    *fp
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  This is the main function which will be called from application.
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  StartAddress1  - The start address of the first VTF
 | 
						|
  Size1          - The size of the first VTF
 | 
						|
  StartAddress2  - The start address of the second VTF
 | 
						|
  Size2          - The size of the second VTF
 | 
						|
  fp             - The pointer to BSF inf file
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  EFI_OUT_OF_RESOURCES - Can not allocate memory
 | 
						|
  The return value can be any of the values
 | 
						|
  returned by the calls to following functions:
 | 
						|
      GetVtfRelatedInfoFromInfFile
 | 
						|
      ProcessAndCreateVtf
 | 
						|
      UpdateIA32ResetVector
 | 
						|
      UpdateFfsHeader
 | 
						|
      WriteVtfBinary
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
  FILE            *VtfFP;
 | 
						|
 | 
						|
  Status          = EFI_UNSUPPORTED;
 | 
						|
  VtfFP = fp;
 | 
						|
 | 
						|
  if (StartAddress2 == 0) {
 | 
						|
    SecondVTF = FALSE;
 | 
						|
  } else {
 | 
						|
    SecondVTF = TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  Fv1BaseAddress        = StartAddress1;
 | 
						|
  Fv1EndAddress         = Fv1BaseAddress + Size1;
 | 
						|
  if (Fv1EndAddress != 0x100000000ULL || Size1 < 0x100000) {
 | 
						|
    Error (NULL, 0, 2000, "Invalid parameter", "Error BaseAddress and Size parameters!");
 | 
						|
    if (Size1 < 0x100000) {
 | 
						|
      Error (NULL, 0, 2000, "Invalid parameter", "The FwVolumeSize must be larger than 1M!");
 | 
						|
    } else if (SecondVTF != TRUE) {
 | 
						|
      Error (NULL, 0, 2000, "Invalid parameter", "BaseAddress + FwVolumeSize must equal 0x100000000!");
 | 
						|
    }
 | 
						|
    Usage();
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // The image buffer for the First VTF
 | 
						|
  //
 | 
						|
  Vtf1Buffer = malloc ((UINTN) Size1);
 | 
						|
  if (Vtf1Buffer == NULL) {
 | 
						|
    Error (NULL, 0, 4001, "Resource", "Not enough resources available to create memory mapped file for the Boot Strap File!");
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
  memset (Vtf1Buffer, 0x00, (UINTN) Size1);
 | 
						|
  Vtf1EndBuffer         = (UINT8 *) Vtf1Buffer + Size1;
 | 
						|
  Vtf1LastStartAddress  = Fv1EndAddress | IPF_CACHE_BIT;
 | 
						|
 | 
						|
  if (SecondVTF) {
 | 
						|
    Fv2BaseAddress        = StartAddress2;
 | 
						|
    Fv2EndAddress         = Fv2BaseAddress + Size2;
 | 
						|
    if (Fv2EndAddress != StartAddress1) {
 | 
						|
      Error (NULL, 0, 2000, "Invalid parameter", "Error BaseAddress and Size parameters!");
 | 
						|
      if (SecondVTF == TRUE) {
 | 
						|
        Error (NULL, 0, 2000, "Invalid parameter", "FirstBaseAddress + FirstFwVolumeSize must equal 0x100000000!");
 | 
						|
        Error (NULL, 0, 2000, "Invalid parameter", "SecondBaseAddress + SecondFwVolumeSize must equal FirstBaseAddress!");
 | 
						|
      }
 | 
						|
      Usage();
 | 
						|
      return EFI_INVALID_PARAMETER;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // The image buffer for the second VTF
 | 
						|
    //
 | 
						|
    Vtf2Buffer = malloc ((UINTN) Size2);
 | 
						|
    if (Vtf2Buffer == NULL) {
 | 
						|
      Error (NULL, 0, 4001, "Resource", "Not enough resources available to create memory mapped file for the Boot Strap File!");
 | 
						|
      return EFI_OUT_OF_RESOURCES;
 | 
						|
    }
 | 
						|
    memset (Vtf2Buffer, 0x00, (UINTN) Size2);
 | 
						|
    Vtf2EndBuffer         = (UINT8 *) Vtf2Buffer + Size2;
 | 
						|
    Vtf2LastStartAddress  = Fv2EndAddress | IPF_CACHE_BIT;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = GetVtfRelatedInfoFromInfFile (VtfFP);
 | 
						|
 | 
						|
  if (Status != EFI_SUCCESS) {
 | 
						|
    Error (NULL, 0, 0003, "Error parsing file", "the input file.");
 | 
						|
    CleanUpMemory ();
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = ProcessAndCreateVtf (Size1);
 | 
						|
  if (Status != EFI_SUCCESS) {
 | 
						|
    CleanUpMemory ();
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  if (SectionOptionFlag) {
 | 
						|
    Status = UpdateIA32ResetVector (IA32BinFile, Vtf1TotalSize);
 | 
						|
    if (Status != EFI_SUCCESS) {
 | 
						|
      CleanUpMemory ();
 | 
						|
      return Status;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Re arrange the FIT Table for Ascending order of their FIT Type..
 | 
						|
  //
 | 
						|
  SortFitTable ();
 | 
						|
 | 
						|
  //
 | 
						|
  // All components have been updated in FIT table. Now perform the FIT table
 | 
						|
  // checksum. The following function will check if Checksum is required,
 | 
						|
  // if yes, then it will perform the checksum otherwise not.
 | 
						|
  //
 | 
						|
  CalculateFitTableChecksum ();
 | 
						|
 | 
						|
  //
 | 
						|
  // Write the FFS header
 | 
						|
  //
 | 
						|
  Vtf1TotalSize += sizeof (EFI_FFS_FILE_HEADER);
 | 
						|
  Vtf1LastStartAddress -= sizeof (EFI_FFS_FILE_HEADER);
 | 
						|
 | 
						|
  Status = UpdateFfsHeader (Vtf1TotalSize, FIRST_VTF);
 | 
						|
  if (Status != EFI_SUCCESS) {
 | 
						|
    CleanUpMemory ();
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Update the VTF buffer into specified VTF binary file
 | 
						|
  //
 | 
						|
  Status  = WriteVtfBinary (OutFileName1, Vtf1TotalSize, FIRST_VTF);
 | 
						|
 | 
						|
  if (SecondVTF) {
 | 
						|
    Vtf2TotalSize += sizeof (EFI_FFS_FILE_HEADER);
 | 
						|
    Vtf2LastStartAddress -= sizeof (EFI_FFS_FILE_HEADER);
 | 
						|
    Status = UpdateFfsHeader (Vtf2TotalSize, SECOND_VTF);
 | 
						|
    if (Status != EFI_SUCCESS) {
 | 
						|
      CleanUpMemory ();
 | 
						|
      return Status;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Update the VTF buffer into specified VTF binary file
 | 
						|
    //
 | 
						|
    Status  = WriteVtfBinary (OutFileName2, Vtf2TotalSize, SECOND_VTF);
 | 
						|
  }
 | 
						|
 | 
						|
  CleanUpMemory ();
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
PeimFixupInFitTable (
 | 
						|
  IN  UINT64  StartAddress
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  This function is an entry point to fixup SAL-E entry point.
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  StartAddress - StartAddress for PEIM.....
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  EFI_SUCCESS          - The function completed successfully
 | 
						|
  EFI_ABORTED          - Error Opening File
 | 
						|
  EFI_OUT_OF_RESOURCES - System out of resources for memory allocation.
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
  FILE        *Fp;
 | 
						|
  UINT64      *StartAddressPtr;
 | 
						|
  UINTN       FirstFwVSize;
 | 
						|
  UINTN       NumByte;
 | 
						|
 | 
						|
  StartAddressPtr   = malloc (sizeof (UINT64));
 | 
						|
  if (StartAddressPtr == NULL) {
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
  *StartAddressPtr = StartAddress;
 | 
						|
 | 
						|
  Fp = fopen (OutFileName1, "rb");
 | 
						|
 | 
						|
  if (Fp == NULL) {
 | 
						|
    Error (NULL, 0, 0001, "Error opening file", OutFileName1);
 | 
						|
    if (StartAddressPtr) {
 | 
						|
      free (StartAddressPtr);
 | 
						|
    }
 | 
						|
    return EFI_ABORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  FirstFwVSize = _filelength (fileno (Fp));
 | 
						|
  fseek (Fp, (long) (FirstFwVSize - (UINTN) (SIZE_IA32_RESET_VECT + SIZE_SALE_ENTRY_POINT)), SEEK_SET);
 | 
						|
  NumByte = fwrite ((VOID *) StartAddressPtr, sizeof (UINT64), 1, Fp);
 | 
						|
 | 
						|
  if (Fp) {
 | 
						|
    fclose (Fp);
 | 
						|
  }
 | 
						|
 | 
						|
  if (StartAddressPtr) {
 | 
						|
    free (StartAddressPtr);
 | 
						|
  }
 | 
						|
 | 
						|
  Status = EFI_SUCCESS;
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
UpdateSymFile (
 | 
						|
  IN UINT64 BaseAddress,
 | 
						|
  IN CHAR8  *DestFileName,
 | 
						|
  IN CHAR8  *SourceFileName,
 | 
						|
  IN UINT64 FileSize
 | 
						|
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  This function adds the SYM tokens in the source file to the destination file.
 | 
						|
  The SYM tokens are updated to reflect the base address.
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  BaseAddress    - The base address for the new SYM tokens.
 | 
						|
  DestFileName   - The destination file.
 | 
						|
  SourceFileName - The source file.
 | 
						|
  FileSize       - Size of bin file.
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  EFI_SUCCESS             - The function completed successfully.
 | 
						|
  EFI_INVALID_PARAMETER   - One of the input parameters was invalid.
 | 
						|
  EFI_ABORTED             - An error occurred.
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  FILE    *SourceFile;
 | 
						|
  FILE    *DestFile;
 | 
						|
  CHAR8   Buffer[_MAX_PATH];
 | 
						|
  CHAR8   Type[_MAX_PATH];
 | 
						|
  CHAR8   Address[_MAX_PATH];
 | 
						|
  CHAR8   Section[_MAX_PATH];
 | 
						|
  CHAR8   Token[_MAX_PATH];
 | 
						|
  CHAR8   BaseToken[_MAX_PATH];
 | 
						|
  UINT64  TokenAddress;
 | 
						|
  long    StartLocation;
 | 
						|
 | 
						|
  //
 | 
						|
  // Verify input parameters.
 | 
						|
  //
 | 
						|
  if (BaseAddress == 0 || DestFileName == NULL || SourceFileName == NULL) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Open the source file
 | 
						|
  //
 | 
						|
  SourceFile = fopen (SourceFileName, "r");
 | 
						|
  if (SourceFile == NULL) {
 | 
						|
 | 
						|
    //
 | 
						|
    // SYM files are not required.
 | 
						|
    //
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Use the file name minus extension as the base for tokens
 | 
						|
  //
 | 
						|
  strcpy (BaseToken, SourceFileName);
 | 
						|
  strtok (BaseToken, ". \t\n");
 | 
						|
  strcat (BaseToken, "__");
 | 
						|
 | 
						|
  //
 | 
						|
  // Open the destination file
 | 
						|
  //
 | 
						|
  DestFile = fopen (DestFileName, "a+");
 | 
						|
  if (DestFile == NULL) {
 | 
						|
    fclose (SourceFile);
 | 
						|
    Error (NULL, 0, 0001, "Error opening file", DestFileName);
 | 
						|
    return EFI_ABORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // If this is the beginning of the output file, write the symbol format info.
 | 
						|
  //
 | 
						|
  if (fseek (DestFile, 0, SEEK_END) != 0) {
 | 
						|
    fclose (SourceFile);
 | 
						|
    fclose (DestFile);
 | 
						|
    Error (NULL, 0, 2000, "Invalid parameter", "not at the beginning of the output file.");
 | 
						|
    return EFI_ABORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  StartLocation = ftell (DestFile);
 | 
						|
 | 
						|
  if (StartLocation == 0) {
 | 
						|
    fprintf (DestFile, "TEXTSYM format | V1.0\n");
 | 
						|
  } else if (StartLocation == -1) {
 | 
						|
    fclose (SourceFile);
 | 
						|
    fclose (DestFile);
 | 
						|
    Error (NULL, 0, 2000, "Invalid parameter", "StartLocation error");
 | 
						|
    return EFI_ABORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Read the first line
 | 
						|
  //
 | 
						|
  if (fgets (Buffer, _MAX_PATH, SourceFile) == NULL) {
 | 
						|
    Buffer[0] = 0;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Make sure it matches the expected sym format
 | 
						|
  //
 | 
						|
  if (strcmp (Buffer, "TEXTSYM format | V1.0\n")) {
 | 
						|
    fclose (SourceFile);
 | 
						|
    fclose (DestFile);
 | 
						|
    Error (NULL, 0, 2000, "Invalid parameter", "The symbol file does not match the expected TEXTSYM format (V1.0.)");
 | 
						|
    return EFI_ABORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Read in the file
 | 
						|
  //
 | 
						|
  while (feof (SourceFile) == 0) {
 | 
						|
 | 
						|
    //
 | 
						|
    // Read a line
 | 
						|
    //
 | 
						|
    if (fscanf (SourceFile, "%s | %s | %s | %s\n", Type, Address, Section, Token) == 4) {
 | 
						|
 | 
						|
      //
 | 
						|
      // Get the token address
 | 
						|
      //
 | 
						|
      AsciiStringToUint64 (Address, TRUE, &TokenAddress);
 | 
						|
      if (TokenAddress > FileSize) {
 | 
						|
        //
 | 
						|
        // Symbol offset larger than FileSize. This Symbol can't be in Bin file. Don't print them.
 | 
						|
        //
 | 
						|
        break;
 | 
						|
      }
 | 
						|
 | 
						|
      //
 | 
						|
      // Add the base address, the size of the FFS file header and the size of the peim header.
 | 
						|
      //
 | 
						|
      TokenAddress += BaseAddress &~IPF_CACHE_BIT;
 | 
						|
 | 
						|
      fprintf (DestFile, "%s | %016llX | ", Type, (unsigned long long) TokenAddress);
 | 
						|
      fprintf (DestFile, "%s | %s\n    %s\n", Section, Token, BaseToken); 
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  fclose (SourceFile);
 | 
						|
  fclose (DestFile);
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
CalculateFitTableChecksum (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  This function will perform byte checksum on the FIT table, if the the checksum required
 | 
						|
  field is set to CheckSum required. If the checksum is not required then checksum byte
 | 
						|
  will have value as 0;.
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  NONE
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  Status       - Value returned by call to CalculateChecksum8 ()
 | 
						|
  EFI_SUCCESS  - The function completed successfully
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  FIT_TABLE *TmpFitPtr;
 | 
						|
  UINT64    FitTableAdd;
 | 
						|
  UINT64    FitTableAddOffset;
 | 
						|
  UINTN     RelativeAddress;
 | 
						|
  UINTN     Size;
 | 
						|
 | 
						|
  //
 | 
						|
  // Read the Fit Table address from Itanium-based address map.
 | 
						|
  //
 | 
						|
  FitTableAddOffset = Fv1EndAddress - (SIZE_IA32_RESET_VECT + SIZE_SALE_ENTRY_POINT + SIZE_FIT_TABLE_ADD);
 | 
						|
 | 
						|
  //
 | 
						|
  // Translate this Itanium-based address in terms of local buffer address which
 | 
						|
  // contains the image for Boot Strapped File
 | 
						|
  //
 | 
						|
  GetRelativeAddressInVtfBuffer (FitTableAddOffset, &RelativeAddress, FIRST_VTF);
 | 
						|
  FitTableAdd = *(UINTN *) RelativeAddress;
 | 
						|
 | 
						|
  GetRelativeAddressInVtfBuffer (FitTableAdd, &RelativeAddress, FIRST_VTF);
 | 
						|
 | 
						|
  TmpFitPtr = (FIT_TABLE *) RelativeAddress;
 | 
						|
 | 
						|
  Size      = TmpFitPtr->CompSize * 16;
 | 
						|
 | 
						|
  if ((TmpFitPtr->CvAndType & CHECKSUM_BIT_MASK) >> 7) {
 | 
						|
    TmpFitPtr->CheckSum = 0;
 | 
						|
    TmpFitPtr->CheckSum = CalculateChecksum8 ((UINT8 *) TmpFitPtr, Size);
 | 
						|
  } else {
 | 
						|
    TmpFitPtr->CheckSum = 0;
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
Version (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  Displays the standard utility information to SDTOUT
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  None
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  None
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  fprintf (stdout, "%s Version %d.%d\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION);
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
Usage (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  Displays the utility usage syntax to STDOUT
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  None
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  None
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  //
 | 
						|
  // Summary usage
 | 
						|
  //
 | 
						|
  fprintf (stdout, "Usage: %s [options] <-f input_file> <-r BaseAddress> <-s FwVolumeSize>\n\n", UTILITY_NAME);
 | 
						|
 | 
						|
  //
 | 
						|
  // Copyright declaration
 | 
						|
  //
 | 
						|
  fprintf (stdout, "Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.\n\n");
 | 
						|
  //
 | 
						|
  // Details Option
 | 
						|
  //
 | 
						|
  fprintf (stdout, "Options:\n");
 | 
						|
  fprintf (stdout, "  -f Input_file,   --filename Input_file\n\
 | 
						|
                        Input_file is name of the BS Image INF file\n");
 | 
						|
  fprintf (stdout, "  -r BaseAddress,  --baseaddr BaseAddress\n\
 | 
						|
                        BaseAddress is the starting address of Firmware Volume\n\
 | 
						|
                        where Boot Strapped Image will reside.\n");
 | 
						|
  fprintf (stdout, "  -s FwVolumeSize, --size FwVolumeSize\n\
 | 
						|
                        FwVolumeSize is the size of Firmware Volume.\n");
 | 
						|
  fprintf (stdout, "  -o FileName,     --output FileName\n\
 | 
						|
                        File will be created to store the ouput content.\n");
 | 
						|
  fprintf (stdout, "  -v, --verbose         Turn on verbose output with informational messages.\n");
 | 
						|
  fprintf (stdout, "  --version             Show program's version number and exit.\n");
 | 
						|
  fprintf (stdout, "  -h, --help            Show this help message and exit.\n");
 | 
						|
  fprintf (stdout, "  -q, --quiet           Disable all messages except FATAL ERRORS.\n");
 | 
						|
  fprintf (stdout, "  -d, --debug [#, 0-9]  Enable debug messages at level #.\n");
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
main (
 | 
						|
  IN  int  argc,
 | 
						|
  IN  char  **argv
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  This utility uses GenVtf.dll to build a Boot Strap File Image which will be
 | 
						|
  part of firmware volume image.
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  argc   - The count of the parameters
 | 
						|
  argv   - The parameters
 | 
						|
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  0   - No error conditions detected.
 | 
						|
  1   - One or more of the input parameters is invalid.
 | 
						|
  2   - A resource required by the utility was unavailable.
 | 
						|
      - Most commonly this will be memory allocation or file creation.
 | 
						|
  3   - GenFvImage.dll could not be loaded.
 | 
						|
  4   - Error executing the GenFvImage dll.
 | 
						|
  5   - Now this tool does not support the IA32 platform
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  UINT8          Index;
 | 
						|
  UINT64         StartAddress1;
 | 
						|
  UINT64         StartAddress2;
 | 
						|
  UINT64         FwVolSize1;
 | 
						|
  UINT64         FwVolSize2;
 | 
						|
  BOOLEAN       FirstRoundO;
 | 
						|
  BOOLEAN       FirstRoundB;
 | 
						|
  BOOLEAN       FirstRoundS;
 | 
						|
  EFI_STATUS    Status;
 | 
						|
  FILE          *VtfFP;
 | 
						|
  CHAR8         *VtfFileName;
 | 
						|
 | 
						|
  SetUtilityName (UTILITY_NAME);
 | 
						|
 | 
						|
  //
 | 
						|
  // Initialize variables
 | 
						|
  //
 | 
						|
  StartAddress1 = 0;
 | 
						|
  StartAddress2 = 0;
 | 
						|
  FwVolSize1    = 0;
 | 
						|
  FwVolSize2    = 0;
 | 
						|
  FirstRoundB   = TRUE;
 | 
						|
  FirstRoundS   = TRUE;
 | 
						|
  FirstRoundO   = TRUE;
 | 
						|
  DebugMode     = FALSE;
 | 
						|
  OutFileName1  = NULL;
 | 
						|
  OutFileName2  = NULL;
 | 
						|
  VtfFP = NULL;
 | 
						|
  DebugLevel = 0;
 | 
						|
 | 
						|
  //
 | 
						|
  // Verify the correct number of arguments
 | 
						|
  //
 | 
						|
  if (argc == 1) {
 | 
						|
    Usage();
 | 
						|
    return 0;
 | 
						|
  }
 | 
						|
 | 
						|
  if ((strcmp(argv[1], "-h") == 0) || (strcmp(argv[1], "--help") == 0)) {
 | 
						|
    Usage();
 | 
						|
    return 0;
 | 
						|
  }
 | 
						|
 | 
						|
  if ((strcmp(argv[1], "--version") == 0)) {
 | 
						|
    Version();
 | 
						|
    return 0;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Parse the command line arguments
 | 
						|
  //
 | 
						|
  for (Index = 1; Index < argc; Index += 2) {
 | 
						|
    if ((stricmp (argv[Index], "-o") == 0) || (stricmp (argv[Index], "--output") == 0)) {
 | 
						|
      if (argv[Index + 1] == NULL || argv[Index + 1][0] == '-') {
 | 
						|
        Error (NULL, 0, 1003, "Invalid option value", "Output file is missing for -o option");
 | 
						|
        goto ERROR;
 | 
						|
      }
 | 
						|
      //
 | 
						|
      // Get the output file name
 | 
						|
      //
 | 
						|
      VTF_OUTPUT = TRUE;
 | 
						|
      if (FirstRoundO) {
 | 
						|
        //
 | 
						|
        // It's the first output file name
 | 
						|
        //
 | 
						|
        OutFileName1 = (CHAR8 *)argv[Index+1];
 | 
						|
        FirstRoundO = FALSE;
 | 
						|
      } else {
 | 
						|
        //
 | 
						|
        //It's the second output file name
 | 
						|
        //
 | 
						|
        OutFileName2 = (CHAR8 *)argv[Index+1];
 | 
						|
      }
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    if ((stricmp (argv[Index], "-f") == 0) || (stricmp (argv[Index], "--filename") == 0)) {
 | 
						|
      if (argv[Index + 1] == NULL || argv[Index + 1][0] == '-') {
 | 
						|
        Error (NULL, 0, 1003, "Invalid option value", "BS Image INF file is missing for -f option");
 | 
						|
        goto ERROR;
 | 
						|
      }
 | 
						|
      //
 | 
						|
      // Get the input VTF file name
 | 
						|
      //
 | 
						|
      VtfFileName = argv[Index+1];
 | 
						|
      VtfFP = fopen(VtfFileName, "rb");
 | 
						|
      if (VtfFP == NULL) {
 | 
						|
        Error (NULL, 0, 0001, "Error opening file", VtfFileName);
 | 
						|
        goto ERROR;
 | 
						|
      }
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
    
 | 
						|
    if ((stricmp (argv[Index], "-r") == 0) || (stricmp (argv[Index], "--baseaddr") == 0)) {
 | 
						|
      if (FirstRoundB) {
 | 
						|
        Status      = AsciiStringToUint64 (argv[Index + 1], FALSE, &StartAddress1);
 | 
						|
        FirstRoundB = FALSE;
 | 
						|
      } else {
 | 
						|
        Status = AsciiStringToUint64 (argv[Index + 1], FALSE, &StartAddress2);
 | 
						|
      }
 | 
						|
      if (Status != EFI_SUCCESS) {
 | 
						|
        Error (NULL, 0, 2000, "Invalid option value", "%s is Bad FV start address.", argv[Index + 1]);
 | 
						|
        goto ERROR;
 | 
						|
      }  
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    if ((stricmp (argv[Index], "-s") == 0) || (stricmp (argv[Index], "--size") == 0)) {
 | 
						|
      if (FirstRoundS) {
 | 
						|
        Status      = AsciiStringToUint64 (argv[Index + 1], FALSE, &FwVolSize1);
 | 
						|
        FirstRoundS = FALSE;
 | 
						|
      } else {
 | 
						|
        Status = AsciiStringToUint64 (argv[Index + 1], FALSE, &FwVolSize2);
 | 
						|
    	  SecondVTF = TRUE;
 | 
						|
      }
 | 
						|
 | 
						|
      if (Status != EFI_SUCCESS) {
 | 
						|
        Error (NULL, 0, 2000, "Invalid option value", "%s is Bad FV size.", argv[Index + 1]);
 | 
						|
        goto ERROR;
 | 
						|
      }
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    if ((stricmp (argv[Index], "-v") == 0) || (stricmp (argv[Index], "--verbose") == 0)) {
 | 
						|
	    VerboseMode = TRUE;
 | 
						|
	    Index--;
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    if ((stricmp (argv[Index], "-q") == 0) || (stricmp (argv[Index], "--quiet") == 0)) {
 | 
						|
      QuietMode = TRUE;
 | 
						|
      Index--;
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    if ((stricmp (argv[Index], "-d") == 0) || (stricmp (argv[Index], "--debug") == 0)) {
 | 
						|
      //
 | 
						|
      // debug level specified
 | 
						|
      //
 | 
						|
      Status = AsciiStringToUint64(argv[Index + 1], FALSE, &DebugLevel);
 | 
						|
      if (EFI_ERROR (Status)) {
 | 
						|
        Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[Index], argv[Index + 1]);
 | 
						|
        goto ERROR;
 | 
						|
      }
 | 
						|
      if (DebugLevel > 9)  {
 | 
						|
        Error (NULL, 0, 2000, "Invalid option value", "Unrecognized argument %s.", argv[Index + 1]);
 | 
						|
        goto ERROR;
 | 
						|
      }
 | 
						|
      if((DebugLevel <= 9) &&(DebugLevel >= 5)) {
 | 
						|
        DebugMode = TRUE;
 | 
						|
      } else {
 | 
						|
        DebugMode = FALSE;
 | 
						|
      }
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    Error (NULL, 0, 2000, "Invalid parameter", "Unrecognized argument %s.", argv[Index]);
 | 
						|
    goto ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  if (VtfFP == NULL) {
 | 
						|
    Error (NULL, 0, 2000, "Invalid parameter", "No BS Image INF file is specified");
 | 
						|
    goto ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  if (FirstRoundB) {
 | 
						|
    Error (NULL, 0, 2000, "Invalid parameter", "No FV base address is specified");
 | 
						|
    goto ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  if (FirstRoundS) {
 | 
						|
    Error (NULL, 0, 2000, "Invalid parameter", "No FV Size is specified");
 | 
						|
    goto ERROR;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // All Parameters has been parsed, now set the message print level
 | 
						|
  //
 | 
						|
  if (QuietMode) {
 | 
						|
    SetPrintLevel(40);
 | 
						|
  } else if (VerboseMode) {
 | 
						|
    SetPrintLevel(15);
 | 
						|
  } else if (DebugMode) {
 | 
						|
    SetPrintLevel(DebugLevel);
 | 
						|
  }
 | 
						|
 | 
						|
  if (VerboseMode) {
 | 
						|
    VerboseMsg("%s tool start.\n", UTILITY_NAME);
 | 
						|
  }
 | 
						|
 | 
						|
  if (VTF_OUTPUT == FALSE) {
 | 
						|
    if (SecondVTF == TRUE) {
 | 
						|
      OutFileName1 = VTF_OUTPUT_FILE1;
 | 
						|
      OutFileName2 = VTF_OUTPUT_FILE2;
 | 
						|
	  } else {
 | 
						|
      OutFileName1 = VTF_OUTPUT_FILE1;
 | 
						|
    }
 | 
						|
    SymFileName = VTF_SYM_FILE;
 | 
						|
  } else {
 | 
						|
    INTN OutFileNameLen = strlen(OutFileName1);
 | 
						|
    INTN Index;
 | 
						|
 | 
						|
    for (Index = OutFileNameLen; Index > 0; --Index) {
 | 
						|
      if (OutFileName1[Index] == '/' || OutFileName1[Index] == '\\') {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    if (Index == 0) {
 | 
						|
      SymFileName = VTF_SYM_FILE;
 | 
						|
    } else {
 | 
						|
      INTN SymFileNameLen = Index + 1 + strlen(VTF_SYM_FILE);
 | 
						|
      SymFileName = malloc(SymFileNameLen + 1);
 | 
						|
      memcpy(SymFileName, OutFileName1, Index + 1);
 | 
						|
      memcpy(SymFileName + Index + 1, VTF_SYM_FILE, strlen(VTF_SYM_FILE));
 | 
						|
      SymFileName[SymFileNameLen] = '\0';
 | 
						|
    }
 | 
						|
    if (DebugMode) {
 | 
						|
      DebugMsg(UTILITY_NAME, 0, DebugLevel, SymFileName, NULL);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Call the GenVtfImage
 | 
						|
  //
 | 
						|
  if (DebugMode) {
 | 
						|
    DebugMsg(UTILITY_NAME, 0, DebugLevel, "Start to generate the VTF image\n", NULL);
 | 
						|
  }
 | 
						|
  Status = GenerateVtfImage (StartAddress1, FwVolSize1, StartAddress2, FwVolSize2, VtfFP);
 | 
						|
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    switch (Status) {
 | 
						|
 | 
						|
    case EFI_INVALID_PARAMETER:
 | 
						|
      Error (NULL, 0, 2000, "Invalid parameter", "Invalid parameter passed to GenVtf function.");
 | 
						|
      break;
 | 
						|
 | 
						|
    case EFI_ABORTED:
 | 
						|
      Error (NULL, 0, 3000, "Invalid", "Error detected while creating the file image.");
 | 
						|
      break;
 | 
						|
 | 
						|
    case EFI_OUT_OF_RESOURCES:
 | 
						|
      Error (NULL, 0, 4002, "Resource", "GenVtfImage function could not allocate required resources.");
 | 
						|
      break;
 | 
						|
 | 
						|
    case EFI_VOLUME_CORRUPTED:
 | 
						|
      Error (NULL, 0, 3000, "Invalid", "No base address was specified.");
 | 
						|
      break;
 | 
						|
 | 
						|
    default:
 | 
						|
      Error (NULL, 0, 3000, "Invalid", "GenVtfImage function returned unknown status %x.", (int) Status );
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
ERROR:
 | 
						|
  if (VtfFP != NULL) {
 | 
						|
    fclose (VtfFP);
 | 
						|
  }
 | 
						|
 | 
						|
  if (DebugMode) {
 | 
						|
    DebugMsg(UTILITY_NAME, 0, DebugLevel, "VTF image generated successful\n", NULL);
 | 
						|
  }
 | 
						|
 | 
						|
  if (VerboseMode) {
 | 
						|
    VerboseMsg("%s tool done with return code is 0x%x.\n", UTILITY_NAME, GetUtilityStatus ());
 | 
						|
  }
 | 
						|
  return GetUtilityStatus();
 | 
						|
}
 |