Current GenFds Tool class GuidSection() is parsing the tools_def.txt for every GUID'ed section that has a GUID defined tool, it cause a bad performance. so this patch cache the defined Guid tool to improve the performance. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Yonghong Zhu <yonghong.zhu@intel.com> Reviewed-by: Liming Gao <liming.gao@intel.com>
		
			
				
	
	
		
			731 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			731 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
## @file
 | 
						|
# Global variables for GenFds
 | 
						|
#
 | 
						|
#  Copyright (c) 2007 - 2016, 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 Common.LongFilePathOs as 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
 | 
						|
from Common.LongFilePathSupport import OpenLongFilePath as open
 | 
						|
from Common.MultipleWorkspace import MultipleWorkspace as mws
 | 
						|
 | 
						|
## Global variables
 | 
						|
#
 | 
						|
#
 | 
						|
class GenFdsGlobalVariable:
 | 
						|
    FvDir = ''
 | 
						|
    OutputDirDict = {}
 | 
						|
    BinDir = ''
 | 
						|
    # will be FvDir + os.sep + 'Ffs'
 | 
						|
    FfsDir = ''
 | 
						|
    FdfParser = None
 | 
						|
    LibDir = ''
 | 
						|
    WorkSpace = None
 | 
						|
    WorkSpaceDir = ''
 | 
						|
    ConfDir = ''
 | 
						|
    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
 | 
						|
    GuidToolDefinition = {}
 | 
						|
    
 | 
						|
    #
 | 
						|
    # 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.ConfDir, "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 = []
 | 
						|
 | 
						|
        if not Inf.IsBinaryModule:
 | 
						|
            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):
 | 
						|
        String = mws.handleWsMacro(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 = mws.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,
 | 
						|
                '$(SPACE)' : ' '
 | 
						|
               }
 | 
						|
        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)
 |