## @file
# Global variables for GenFds
#
#  Copyright (c) 2007 - 2012, 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.
#

##
# Import Modules
#
import os
import sys
import subprocess
import struct
import array

from Common.BuildToolError import *
from Common import EdkLogger
from Common.Misc import SaveFileOnChange

from Common.TargetTxtClassObject import TargetTxtClassObject
from Common.ToolDefClassObject import ToolDefClassObject
from AutoGen.BuildEngine import BuildRule
import Common.DataType as DataType
from Common.Misc import PathClass

## Global variables
#
#
class GenFdsGlobalVariable:
    FvDir = ''
    OutputDirDict = {}
    BinDir = ''
    # will be FvDir + os.sep + 'Ffs'
    FfsDir = ''
    FdfParser = None
    LibDir = ''
    WorkSpace = None
    WorkSpaceDir = ''
    EdkSourceDir = ''
    OutputDirFromDscDict = {}
    TargetName = ''
    ToolChainTag = ''
    RuleDict = {}
    ArchList = None
    VtfDict = {}
    ActivePlatform = None
    FvAddressFileName = ''
    VerboseMode = False
    DebugLevel = -1
    SharpCounter = 0
    SharpNumberPerLine = 40
    FdfFile = ''
    FdfFileTimeStamp = 0
    FixedLoadAddress = False
    PlatformName = ''
    
    BuildRuleFamily = "MSFT"
    ToolChainFamily = "MSFT"
    __BuildRuleDatabase = None
    
    #
    # The list whose element are flags to indicate if large FFS or SECTION files exist in FV.
    # At the beginning of each generation of FV, false flag is appended to the list,
    # after the call to GenerateSection returns, check the size of the output file,
    # if it is greater than 0xFFFFFF, the tail flag in list is set to true,
    # and EFI_FIRMWARE_FILE_SYSTEM3_GUID is passed to C GenFv.
    # At the end of generation of FV, pop the flag.
    # List is used as a stack to handle nested FV generation.
    #
    LargeFileInFvFlags = []
    EFI_FIRMWARE_FILE_SYSTEM3_GUID = '5473C07A-3DCB-4dca-BD6F-1E9689E7349A'
    LARGE_FILE_SIZE = 0x1000000

    SectionHeader = struct.Struct("3B 1B")
    
    ## LoadBuildRule
    #
    @staticmethod
    def __LoadBuildRule():
        if GenFdsGlobalVariable.__BuildRuleDatabase:
            return GenFdsGlobalVariable.__BuildRuleDatabase
        BuildConfigurationFile = os.path.normpath(os.path.join(GenFdsGlobalVariable.WorkSpaceDir, "Conf/target.txt"))
        TargetTxt = TargetTxtClassObject()
        if os.path.isfile(BuildConfigurationFile) == True:
            TargetTxt.LoadTargetTxtFile(BuildConfigurationFile)
            if DataType.TAB_TAT_DEFINES_BUILD_RULE_CONF in TargetTxt.TargetTxtDictionary:
                BuildRuleFile = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_BUILD_RULE_CONF]
            if BuildRuleFile in [None, '']:
                BuildRuleFile = 'Conf/build_rule.txt'
            GenFdsGlobalVariable.__BuildRuleDatabase = BuildRule(BuildRuleFile)
            ToolDefinitionFile = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]
            if ToolDefinitionFile == '':
                ToolDefinitionFile = "Conf/tools_def.txt"
            if os.path.isfile(ToolDefinitionFile):
                ToolDef = ToolDefClassObject()
                ToolDef.LoadToolDefFile(ToolDefinitionFile)
                ToolDefinition = ToolDef.ToolsDefTxtDatabase
                if DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY in ToolDefinition \
                   and GenFdsGlobalVariable.ToolChainTag in ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY] \
                   and ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY][GenFdsGlobalVariable.ToolChainTag]:
                    GenFdsGlobalVariable.BuildRuleFamily = ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY][GenFdsGlobalVariable.ToolChainTag]
                    
                if DataType.TAB_TOD_DEFINES_FAMILY in ToolDefinition \
                   and GenFdsGlobalVariable.ToolChainTag in ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY] \
                   and ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY][GenFdsGlobalVariable.ToolChainTag]:
                    GenFdsGlobalVariable.ToolChainFamily = ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY][GenFdsGlobalVariable.ToolChainTag]
        return GenFdsGlobalVariable.__BuildRuleDatabase

    ## GetBuildRules
    #    @param Inf: object of InfBuildData
    #    @param Arch: current arch
    #
    @staticmethod
    def GetBuildRules(Inf, Arch):
        if not Arch:
            Arch = 'COMMON'

        if not Arch in GenFdsGlobalVariable.OutputDirDict:
            return {}

        BuildRuleDatabase = GenFdsGlobalVariable.__LoadBuildRule()
        if not BuildRuleDatabase:
            return {}

        PathClassObj = PathClass(Inf.MetaFile.File,
                                 GenFdsGlobalVariable.WorkSpaceDir)
        Macro = {}
        Macro["WORKSPACE"             ] = GenFdsGlobalVariable.WorkSpaceDir
        Macro["MODULE_NAME"           ] = Inf.BaseName
        Macro["MODULE_GUID"           ] = Inf.Guid
        Macro["MODULE_VERSION"        ] = Inf.Version
        Macro["MODULE_TYPE"           ] = Inf.ModuleType
        Macro["MODULE_FILE"           ] = str(PathClassObj)
        Macro["MODULE_FILE_BASE_NAME" ] = PathClassObj.BaseName
        Macro["MODULE_RELATIVE_DIR"   ] = PathClassObj.SubDir
        Macro["MODULE_DIR"            ] = PathClassObj.SubDir

        Macro["BASE_NAME"             ] = Inf.BaseName

        Macro["ARCH"                  ] = Arch
        Macro["TOOLCHAIN"             ] = GenFdsGlobalVariable.ToolChainTag
        Macro["TOOLCHAIN_TAG"         ] = GenFdsGlobalVariable.ToolChainTag
        Macro["TOOL_CHAIN_TAG"        ] = GenFdsGlobalVariable.ToolChainTag
        Macro["TARGET"                ] = GenFdsGlobalVariable.TargetName

        Macro["BUILD_DIR"             ] = GenFdsGlobalVariable.OutputDirDict[Arch]
        Macro["BIN_DIR"               ] = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch], Arch)
        Macro["LIB_DIR"               ] = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch], Arch)
        BuildDir = os.path.join(
            GenFdsGlobalVariable.OutputDirDict[Arch],
            Arch,
            PathClassObj.SubDir,
            PathClassObj.BaseName
        )
        Macro["MODULE_BUILD_DIR"      ] = BuildDir
        Macro["OUTPUT_DIR"            ] = os.path.join(BuildDir, "OUTPUT")
        Macro["DEBUG_DIR"             ] = os.path.join(BuildDir, "DEBUG")

        BuildRules = {}
        for Type in BuildRuleDatabase.FileTypeList:
            #first try getting build rule by BuildRuleFamily
            RuleObject = BuildRuleDatabase[Type, Inf.BuildType, Arch, GenFdsGlobalVariable.BuildRuleFamily]
            if not RuleObject:
                # build type is always module type, but ...
                if Inf.ModuleType != Inf.BuildType:
                    RuleObject = BuildRuleDatabase[Type, Inf.ModuleType, Arch, GenFdsGlobalVariable.BuildRuleFamily]
            #second try getting build rule by ToolChainFamily
            if not RuleObject:
                RuleObject = BuildRuleDatabase[Type, Inf.BuildType, Arch, GenFdsGlobalVariable.ToolChainFamily]
                if not RuleObject:
                    # build type is always module type, but ...
                    if Inf.ModuleType != Inf.BuildType:
                        RuleObject = BuildRuleDatabase[Type, Inf.ModuleType, Arch, GenFdsGlobalVariable.ToolChainFamily]
            if not RuleObject:
                continue
            RuleObject = RuleObject.Instantiate(Macro)
            BuildRules[Type] = RuleObject
            for Ext in RuleObject.SourceFileExtList:
                BuildRules[Ext] = RuleObject
        return BuildRules

    ## GetModuleCodaTargetList
    #
    #    @param Inf: object of InfBuildData
    #    @param Arch: current arch
    #
    @staticmethod
    def GetModuleCodaTargetList(Inf, Arch):
        BuildRules = GenFdsGlobalVariable.GetBuildRules(Inf, Arch)
        if not BuildRules:
            return []

        TargetList = set()
        FileList = []
        for File in Inf.Sources:
            if File.TagName in ("", "*", GenFdsGlobalVariable.ToolChainTag) and \
                File.ToolChainFamily in ("", "*", GenFdsGlobalVariable.ToolChainFamily):
                FileList.append((File, DataType.TAB_UNKNOWN_FILE))
        
        for File in Inf.Binaries:
            if File.Target in ['COMMON', '*', GenFdsGlobalVariable.TargetName]:
                FileList.append((File, File.Type))

        for File, FileType in FileList:
            LastTarget = None
            RuleChain = []
            SourceList = [File]
            Index = 0
            while Index < len(SourceList):
                Source = SourceList[Index]
                Index = Index + 1
    
                if File.IsBinary and File == Source and Inf.Binaries != None and File in Inf.Binaries:
                    # Skip all files that are not binary libraries
                    if not Inf.LibraryClass:
                        continue            
                    RuleObject = BuildRules[DataType.TAB_DEFAULT_BINARY_FILE]
                elif FileType in BuildRules:
                    RuleObject = BuildRules[FileType]
                elif Source.Ext in BuildRules:
                    RuleObject = BuildRules[Source.Ext]
                else:
                    # stop at no more rules
                    if LastTarget:
                        TargetList.add(str(LastTarget))
                    break
    
                FileType = RuleObject.SourceFileType
    
                # stop at STATIC_LIBRARY for library
                if Inf.LibraryClass and FileType == DataType.TAB_STATIC_LIBRARY:
                    if LastTarget:
                        TargetList.add(str(LastTarget))
                    break
    
                Target = RuleObject.Apply(Source)
                if not Target:
                    if LastTarget:
                        TargetList.add(str(LastTarget))
                    break
                elif not Target.Outputs:
                    # Only do build for target with outputs
                    TargetList.add(str(Target))
    
                # to avoid cyclic rule
                if FileType in RuleChain:
                    break
    
                RuleChain.append(FileType)
                SourceList.extend(Target.Outputs)
                LastTarget = Target
                FileType = DataType.TAB_UNKNOWN_FILE

        return list(TargetList)

    ## SetDir()
    #
    #   @param  OutputDir           Output directory
    #   @param  FdfParser           FDF contents parser
    #   @param  Workspace           The directory of workspace
    #   @param  ArchList            The Arch list of platform
    #
    def SetDir (OutputDir, FdfParser, WorkSpace, ArchList):
        GenFdsGlobalVariable.VerboseLogger( "GenFdsGlobalVariable.OutputDir :%s" %OutputDir)
#        GenFdsGlobalVariable.OutputDirDict = OutputDir
        GenFdsGlobalVariable.FdfParser = FdfParser
        GenFdsGlobalVariable.WorkSpace = WorkSpace
        GenFdsGlobalVariable.FvDir = os.path.join(GenFdsGlobalVariable.OutputDirDict[ArchList[0]], 'FV')
        if not os.path.exists(GenFdsGlobalVariable.FvDir) :
            os.makedirs(GenFdsGlobalVariable.FvDir)
        GenFdsGlobalVariable.FfsDir = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs')
        if not os.path.exists(GenFdsGlobalVariable.FfsDir) :
            os.makedirs(GenFdsGlobalVariable.FfsDir)
        if ArchList != None:
            GenFdsGlobalVariable.ArchList = ArchList

        T_CHAR_LF = '\n'
        #
        # Create FV Address inf file
        #
        GenFdsGlobalVariable.FvAddressFileName = os.path.join(GenFdsGlobalVariable.FfsDir, 'FvAddress.inf')
        FvAddressFile = open (GenFdsGlobalVariable.FvAddressFileName, 'w')
        #
        # Add [Options]
        #
        FvAddressFile.writelines("[options]" + T_CHAR_LF)
        BsAddress = '0'
        for Arch in ArchList:
            if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].BsBaseAddress:
                BsAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].BsBaseAddress
                break

        FvAddressFile.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \
                                       BsAddress          + \
                                       T_CHAR_LF)

        RtAddress = '0'
        for Arch in ArchList:
            if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].RtBaseAddress:
                RtAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].RtBaseAddress

        FvAddressFile.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \
                                       RtAddress          + \
                                       T_CHAR_LF)

        FvAddressFile.close()

    ## ReplaceWorkspaceMacro()
    #
    #   @param  String           String that may contain macro
    #
    def ReplaceWorkspaceMacro(String):
        Str = String.replace('$(WORKSPACE)', GenFdsGlobalVariable.WorkSpaceDir)
        if os.path.exists(Str):
            if not os.path.isabs(Str):
                Str = os.path.abspath(Str)
        else:
            Str = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, String)
        return os.path.normpath(Str)

    ## Check if the input files are newer than output files
    #
    #   @param  Output          Path of output file
    #   @param  Input           Path list of input files
    #
    #   @retval True            if Output doesn't exist, or any Input is newer
    #   @retval False           if all Input is older than Output
    #
    @staticmethod
    def NeedsUpdate(Output, Input):
        if not os.path.exists(Output):
            return True
        # always update "Output" if no "Input" given
        if Input == None or len(Input) == 0:
            return True

        # if fdf file is changed after the 'Output" is generated, update the 'Output'
        OutputTime = os.path.getmtime(Output)
        if GenFdsGlobalVariable.FdfFileTimeStamp > OutputTime:
            return True

        for F in Input:
            # always update "Output" if any "Input" doesn't exist
            if not os.path.exists(F):
                return True
            # always update "Output" if any "Input" is newer than "Output"
            if os.path.getmtime(F) > OutputTime:
                return True
        return False

    @staticmethod
    def GenerateSection(Output, Input, Type=None, CompressionType=None, Guid=None,
                        GuidHdrLen=None, GuidAttr=[], Ui=None, Ver=None, InputAlign=None, BuildNumber=None):
        Cmd = ["GenSec"]
        if Type not in [None, '']:
            Cmd += ["-s", Type]
        if CompressionType not in [None, '']:
            Cmd += ["-c", CompressionType]
        if Guid != None:
            Cmd += ["-g", Guid]
        if GuidHdrLen not in [None, '']:
            Cmd += ["-l", GuidHdrLen]
        if len(GuidAttr) != 0:
            #Add each guided attribute
            for Attr in GuidAttr:
                Cmd += ["-r", Attr]
        if InputAlign != None:
            #Section Align is only for dummy section without section type
            for SecAlign in InputAlign:
                Cmd += ["--sectionalign", SecAlign]

        CommandFile = Output + '.txt'
        if Ui not in [None, '']:
            #Cmd += ["-n", '"' + Ui + '"']
            SectionData = array.array('B', [0,0,0,0])
            SectionData.fromstring(Ui.encode("utf_16_le"))
            SectionData.append(0)
            SectionData.append(0)
            Len = len(SectionData)
            GenFdsGlobalVariable.SectionHeader.pack_into(SectionData, 0, Len & 0xff, (Len >> 8) & 0xff, (Len >> 16) & 0xff, 0x15)
            SaveFileOnChange(Output,  SectionData.tostring())
        elif Ver not in [None, '']:
            Cmd += ["-n", Ver]
            if BuildNumber:
                Cmd += ["-j", BuildNumber]
            Cmd += ["-o", Output]

            SaveFileOnChange(CommandFile, ' '.join(Cmd), False)
            if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):
                return

            GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section")
        else:
            Cmd += ["-o", Output]
            Cmd += Input

            SaveFileOnChange(CommandFile, ' '.join(Cmd), False)
            if GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):
                GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
                GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section")

            if (os.path.getsize(Output) >= GenFdsGlobalVariable.LARGE_FILE_SIZE and
                GenFdsGlobalVariable.LargeFileInFvFlags):
                GenFdsGlobalVariable.LargeFileInFvFlags[-1] = True 

    @staticmethod
    def GetAlignment (AlignString):
        if AlignString == None:
            return 0
        if AlignString in ("1K", "2K", "4K", "8K", "16K", "32K", "64K"):
            return int (AlignString.rstrip('K')) * 1024
        else:
            return int (AlignString)

    @staticmethod
    def GenerateFfs(Output, Input, Type, Guid, Fixed=False, CheckSum=False, Align=None,
                    SectionAlign=None):
        Cmd = ["GenFfs", "-t", Type, "-g", Guid]
        if Fixed == True:
            Cmd += ["-x"]
        if CheckSum:
            Cmd += ["-s"]
        if Align not in [None, '']:
            Cmd += ["-a", Align]

        Cmd += ["-o", Output]
        for I in range(0, len(Input)):
            Cmd += ("-i", Input[I])
            if SectionAlign not in [None, '', []] and SectionAlign[I] not in [None, '']:
                Cmd += ("-n", SectionAlign[I])

        CommandFile = Output + '.txt'
        SaveFileOnChange(CommandFile, ' '.join(Cmd), False)
        if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):
            return
        GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))

        GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FFS")

    @staticmethod
    def GenerateFirmwareVolume(Output, Input, BaseAddress=None, ForceRebase=None, Capsule=False, Dump=False,
                               AddressFile=None, MapFile=None, FfsList=[], FileSystemGuid=None):
        if not GenFdsGlobalVariable.NeedsUpdate(Output, Input+FfsList):
            return
        GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))

        Cmd = ["GenFv"]
        if BaseAddress not in [None, '']:
            Cmd += ["-r", BaseAddress]
        
        if ForceRebase == False:
            Cmd +=["-F", "FALSE"]
        elif ForceRebase == True:
            Cmd +=["-F", "TRUE"]
            
        if Capsule:
            Cmd += ["-c"]
        if Dump:
            Cmd += ["-p"]
        if AddressFile not in [None, '']:
            Cmd += ["-a", AddressFile]
        if MapFile not in [None, '']:
            Cmd += ["-m", MapFile]
        if FileSystemGuid:
            Cmd += ["-g", FileSystemGuid]
        Cmd += ["-o", Output]
        for I in Input:
            Cmd += ["-i", I]

        GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FV")

    @staticmethod
    def GenerateVtf(Output, Input, BaseAddress=None, FvSize=None):
        if not GenFdsGlobalVariable.NeedsUpdate(Output, Input):
            return
        GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))

        Cmd = ["GenVtf"]
        if BaseAddress not in [None, ''] and FvSize not in [None, ''] \
            and len(BaseAddress) == len(FvSize):
            for I in range(0, len(BaseAddress)):
                Cmd += ["-r", BaseAddress[I], "-s", FvSize[I]]
        Cmd += ["-o", Output]
        for F in Input:
            Cmd += ["-f", F]

        GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate VTF")

    @staticmethod
    def GenerateFirmwareImage(Output, Input, Type="efi", SubType=None, Zero=False,
                              Strip=False, Replace=False, TimeStamp=None, Join=False,
                              Align=None, Padding=None, Convert=False):
        if not GenFdsGlobalVariable.NeedsUpdate(Output, Input):
            return
        GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))

        Cmd = ["GenFw"]
        if Type.lower() == "te":
            Cmd += ["-t"]
        if SubType not in [None, '']:
            Cmd += ["-e", SubType]
        if TimeStamp not in [None, '']:
            Cmd += ["-s", TimeStamp]
        if Align not in [None, '']:
            Cmd += ["-a", Align]
        if Padding not in [None, '']:
            Cmd += ["-p", Padding]
        if Zero:
            Cmd += ["-z"]
        if Strip:
            Cmd += ["-l"]
        if Replace:
            Cmd += ["-r"]
        if Join:
            Cmd += ["-j"]
        if Convert:
            Cmd += ["-m"]
        Cmd += ["-o", Output]
        Cmd += Input

        GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate firmware image")

    @staticmethod
    def GenerateOptionRom(Output, EfiInput, BinaryInput, Compress=False, ClassCode=None,
                        Revision=None, DeviceId=None, VendorId=None):
        InputList = []   
        Cmd = ["EfiRom"]
        if len(EfiInput) > 0:
            
            if Compress:
                Cmd += ["-ec"]
            else:
                Cmd += ["-e"]
                
            for EfiFile in EfiInput:
                Cmd += [EfiFile]
                InputList.append (EfiFile)
        
        if len(BinaryInput) > 0:
            Cmd += ["-b"]
            for BinFile in BinaryInput:
                Cmd += [BinFile]
                InputList.append (BinFile)

        # Check List
        if not GenFdsGlobalVariable.NeedsUpdate(Output, InputList):
            return
        GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, InputList))
                        
        if ClassCode != None:
            Cmd += ["-l", ClassCode]
        if Revision != None:
            Cmd += ["-r", Revision]
        if DeviceId != None:
            Cmd += ["-i", DeviceId]
        if VendorId != None:
            Cmd += ["-f", VendorId]

        Cmd += ["-o", Output]    
        GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate option rom")

    @staticmethod
    def GuidTool(Output, Input, ToolPath, Options='', returnValue=[]):
        if not GenFdsGlobalVariable.NeedsUpdate(Output, Input):
            return
        GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))

        Cmd = [ToolPath, ]
        Cmd += Options.split(' ')
        Cmd += ["-o", Output]
        Cmd += Input

        GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to call " + ToolPath, returnValue)

    def CallExternalTool (cmd, errorMess, returnValue=[]):

        if type(cmd) not in (tuple, list):
            GenFdsGlobalVariable.ErrorLogger("ToolError!  Invalid parameter type in call to CallExternalTool")

        if GenFdsGlobalVariable.DebugLevel != -1:
            cmd += ('--debug', str(GenFdsGlobalVariable.DebugLevel))
            GenFdsGlobalVariable.InfLogger (cmd)

        if GenFdsGlobalVariable.VerboseMode:
            cmd += ('-v',)
            GenFdsGlobalVariable.InfLogger (cmd)
        else:
            sys.stdout.write ('#')
            sys.stdout.flush()
            GenFdsGlobalVariable.SharpCounter = GenFdsGlobalVariable.SharpCounter + 1
            if GenFdsGlobalVariable.SharpCounter % GenFdsGlobalVariable.SharpNumberPerLine == 0:
                sys.stdout.write('\n')

        try:
            PopenObject = subprocess.Popen(' '.join(cmd), stdout=subprocess.PIPE, stderr= subprocess.PIPE, shell=True)
        except Exception, X:
            EdkLogger.error("GenFds", COMMAND_FAILURE, ExtraData="%s: %s" % (str(X), cmd[0]))
        (out, error) = PopenObject.communicate()

        while PopenObject.returncode == None :
            PopenObject.wait()
        if returnValue != [] and returnValue[0] != 0:
            #get command return value
            returnValue[0] = PopenObject.returncode
            return
        if PopenObject.returncode != 0 or GenFdsGlobalVariable.VerboseMode or GenFdsGlobalVariable.DebugLevel != -1:
            GenFdsGlobalVariable.InfLogger ("Return Value = %d" %PopenObject.returncode)
            GenFdsGlobalVariable.InfLogger (out)
            GenFdsGlobalVariable.InfLogger (error)
            if PopenObject.returncode != 0:
                print "###", cmd
                EdkLogger.error("GenFds", COMMAND_FAILURE, errorMess)

    def VerboseLogger (msg):
        EdkLogger.verbose(msg)

    def InfLogger (msg):
        EdkLogger.info(msg)

    def ErrorLogger (msg, File = None, Line = None, ExtraData = None):
        EdkLogger.error('GenFds', GENFDS_ERROR, msg, File, Line, ExtraData)

    def DebugLogger (Level, msg):
        EdkLogger.debug(Level, msg)

    ## ReplaceWorkspaceMacro()
    #
    #   @param  Str           String that may contain macro
    #   @param  MacroDict     Dictionary that contains macro value pair
    #
    def MacroExtend (Str, MacroDict = {}, Arch = 'COMMON'):
        if Str == None :
            return None

        Dict = {'$(WORKSPACE)'   : GenFdsGlobalVariable.WorkSpaceDir,
                '$(EDK_SOURCE)'  : GenFdsGlobalVariable.EdkSourceDir,
#                '$(OUTPUT_DIRECTORY)': GenFdsGlobalVariable.OutputDirFromDsc,
                '$(TARGET)' : GenFdsGlobalVariable.TargetName,
                '$(TOOL_CHAIN_TAG)' : GenFdsGlobalVariable.ToolChainTag
               }
        OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[GenFdsGlobalVariable.ArchList[0]]
        if Arch != 'COMMON' and Arch in GenFdsGlobalVariable.ArchList:
            OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[Arch]

        Dict['$(OUTPUT_DIRECTORY)'] = OutputDir

        if MacroDict != None  and len (MacroDict) != 0:
            Dict.update(MacroDict)

        for key in Dict.keys():
            if Str.find(key) >= 0 :
                Str = Str.replace (key, Dict[key])

        if Str.find('$(ARCH)') >= 0:
            if len(GenFdsGlobalVariable.ArchList) == 1:
                Str = Str.replace('$(ARCH)', GenFdsGlobalVariable.ArchList[0])
            else:
                EdkLogger.error("GenFds", GENFDS_ERROR, "No way to determine $(ARCH) for %s" % Str)

        return Str

    ## GetPcdValue()
    #
    #   @param  PcdPattern           pattern that labels a PCD.
    #
    def GetPcdValue (PcdPattern):
        if PcdPattern == None :
            return None
        PcdPair = PcdPattern.lstrip('PCD(').rstrip(')').strip().split('.')
        TokenSpace = PcdPair[0]
        TokenCName = PcdPair[1]

        PcdValue = ''
        for Arch in GenFdsGlobalVariable.ArchList:
            Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
            PcdDict = Platform.Pcds
            for Key in PcdDict:
                PcdObj = PcdDict[Key]
                if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace):
                    if PcdObj.Type != 'FixedAtBuild':
                        EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern)
                    if PcdObj.DatumType != 'VOID*':
                        EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern)
                        
                    PcdValue = PcdObj.DefaultValue
                    return PcdValue
                
            for Package in GenFdsGlobalVariable.WorkSpace.GetPackageList(GenFdsGlobalVariable.ActivePlatform, 
                                                                         Arch, 
                                                                         GenFdsGlobalVariable.TargetName, 
                                                                         GenFdsGlobalVariable.ToolChainTag):
                PcdDict = Package.Pcds
                for Key in PcdDict:
                    PcdObj = PcdDict[Key]
                    if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace):
                        if PcdObj.Type != 'FixedAtBuild':
                            EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern)
                        if PcdObj.DatumType != 'VOID*':
                            EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern)
                            
                        PcdValue = PcdObj.DefaultValue
                        return PcdValue

        return PcdValue

    SetDir = staticmethod(SetDir)
    ReplaceWorkspaceMacro = staticmethod(ReplaceWorkspaceMacro)
    CallExternalTool = staticmethod(CallExternalTool)
    VerboseLogger = staticmethod(VerboseLogger)
    InfLogger = staticmethod(InfLogger)
    ErrorLogger = staticmethod(ErrorLogger)
    DebugLogger = staticmethod(DebugLogger)
    MacroExtend = staticmethod (MacroExtend)
    GetPcdValue = staticmethod(GetPcdValue)
