From 37de70b764200718cc39a21abc491c335e3da7b3 Mon Sep 17 00:00:00 2001 From: Yonghong Zhu Date: Wed, 22 Nov 2017 15:42:25 +0800 Subject: [PATCH] BaseTools: Update Makefile to support FFS file generation Update Makefile to support FFS file generation with new build option --genfds-multi-thread. Cc: Liming Gao Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Yonghong Zhu Signed-off-by: Yunhua Feng Reviewed-by: Liming Gao --- BaseTools/Source/Python/AutoGen/AutoGen.py | 23 +- BaseTools/Source/Python/AutoGen/GenMake.py | 90 +++++++- BaseTools/Source/Python/Common/GlobalData.py | 1 + .../Source/Python/GenFds/AprioriSection.py | 14 +- .../Source/Python/GenFds/CompressSection.py | 10 +- BaseTools/Source/Python/GenFds/DataSection.py | 37 ++-- .../Source/Python/GenFds/DepexSection.py | 6 +- BaseTools/Source/Python/GenFds/EfiSection.py | 78 ++++--- BaseTools/Source/Python/GenFds/Fd.py | 24 ++- .../Source/Python/GenFds/FfsFileStatement.py | 4 +- .../Source/Python/GenFds/FfsInfStatement.py | 202 ++++++++++-------- BaseTools/Source/Python/GenFds/Fv.py | 189 ++++++++-------- .../Source/Python/GenFds/FvImageSection.py | 8 +- BaseTools/Source/Python/GenFds/GenFds.py | 20 ++ .../Python/GenFds/GenFdsGlobalVariable.py | 174 ++++++++++++--- BaseTools/Source/Python/GenFds/GuidSection.py | 168 ++++++++------- .../Python/GenFds/OptRomFileStatement.py | 4 +- .../Python/GenFds/OptRomInfStatement.py | 12 +- BaseTools/Source/Python/GenFds/OptionRom.py | 25 ++- BaseTools/Source/Python/GenFds/Region.py | 49 +++-- BaseTools/Source/Python/GenFds/Section.py | 4 +- BaseTools/Source/Python/GenFds/UiSection.py | 5 +- BaseTools/Source/Python/GenFds/VerSection.py | 9 +- BaseTools/Source/Python/build/build.py | 48 ++++- 24 files changed, 793 insertions(+), 411 deletions(-) diff --git a/BaseTools/Source/Python/AutoGen/AutoGen.py b/BaseTools/Source/Python/AutoGen/AutoGen.py index 008ad8ebc3..1c4c395479 100644 --- a/BaseTools/Source/Python/AutoGen/AutoGen.py +++ b/BaseTools/Source/Python/AutoGen/AutoGen.py @@ -1307,12 +1307,15 @@ class PlatformAutoGen(AutoGen): # @param CreateModuleMakeFile Flag indicating if the makefile for # modules will be created as well # - def CreateMakeFile(self, CreateModuleMakeFile=False): + def CreateMakeFile(self, CreateModuleMakeFile=False, FfsCommand = {}): if CreateModuleMakeFile: for ModuleFile in self.Platform.Modules: Ma = ModuleAutoGen(self.Workspace, ModuleFile, self.BuildTarget, self.ToolChain, self.Arch, self.MetaFile) - Ma.CreateMakeFile(True) + if (ModuleFile.File, self.Arch) in FfsCommand: + Ma.CreateMakeFile(True, FfsCommand[ModuleFile.File, self.Arch]) + else: + Ma.CreateMakeFile(True) #Ma.CreateAsBuiltInf() # no need to create makefile for the platform more than once @@ -2760,6 +2763,7 @@ class ModuleAutoGen(AutoGen): self._BuildDir = None self._OutputDir = None + self._FfsOutputDir = None self._DebugDir = None self._MakeFileDir = None @@ -2876,6 +2880,7 @@ class ModuleAutoGen(AutoGen): self._Macro["PLATFORM_RELATIVE_DIR" ] = self.PlatformInfo.SourceDir self._Macro["PLATFORM_DIR" ] = mws.join(self.WorkspaceDir, self.PlatformInfo.SourceDir) self._Macro["PLATFORM_OUTPUT_DIR" ] = self.PlatformInfo.OutputDir + self._Macro["FFS_OUTPUT_DIR" ] = self.FfsOutputDir return self._Macro ## Return the module build data object @@ -2966,6 +2971,15 @@ class ModuleAutoGen(AutoGen): CreateDirectory(self._OutputDir) return self._OutputDir + ## Return the directory to store ffs file + def _GetFfsOutputDir(self): + if self._FfsOutputDir == None: + if GlobalData.gFdfParser != None: + self._FfsOutputDir = path.join(self.PlatformInfo.BuildDir, "FV", "Ffs", self.Guid + self.Name) + else: + self._FfsOutputDir = '' + return self._FfsOutputDir + ## Return the directory to store auto-gened source files of the mdoule def _GetDebugDir(self): if self._DebugDir == None: @@ -4222,14 +4236,14 @@ class ModuleAutoGen(AutoGen): # @param CreateLibraryMakeFile Flag indicating if or not the makefiles of # dependent libraries will be created # - def CreateMakeFile(self, CreateLibraryMakeFile=True): + def CreateMakeFile(self, CreateLibraryMakeFile=True, GenFfsList = []): # Ignore generating makefile when it is a binary module if self.IsBinaryModule: return if self.IsMakeFileCreated: return - + self.GenFfsList = GenFfsList if not self.IsLibrary and CreateLibraryMakeFile: for LibraryAutoGen in self.LibraryAutoGenList: LibraryAutoGen.CreateMakeFile() @@ -4457,6 +4471,7 @@ class ModuleAutoGen(AutoGen): IsBinaryModule = property(_IsBinaryModule) BuildDir = property(_GetBuildDir) OutputDir = property(_GetOutputDir) + FfsOutputDir = property(_GetFfsOutputDir) DebugDir = property(_GetDebugDir) MakeFileDir = property(_GetMakeFileDir) CustomMakefile = property(_GetCustomMakefile) diff --git a/BaseTools/Source/Python/AutoGen/GenMake.py b/BaseTools/Source/Python/AutoGen/GenMake.py index 942eb44cc2..2abfdb3ac4 100644 --- a/BaseTools/Source/Python/AutoGen/GenMake.py +++ b/BaseTools/Source/Python/AutoGen/GenMake.py @@ -143,6 +143,11 @@ class BuildFile(object): "nmake" : 'if exist %(dir)s $(RD) %(dir)s', "gmake" : "$(RD) %(dir)s" } + ## cp if exist + _CP_TEMPLATE_ = { + "nmake" : 'if exist %(Src)s $(CP) %(Src)s %(Dst)s', + "gmake" : "test -f %(Src)s && $(CP) %(Src)s %(Dst)s" + } _CD_TEMPLATE_ = { "nmake" : 'if exist %(dir)s cd %(dir)s', @@ -211,6 +216,8 @@ class BuildFile(object): for MacroName in MacroDefinitions: MacroValue = MacroDefinitions[MacroName] MacroValueLength = len(MacroValue) + if MacroValueLength == 0: + continue if MacroValueLength <= PathLength and Path.startswith(MacroValue): Path = "$(%s)%s" % (MacroName, Path[MacroValueLength:]) break @@ -250,6 +257,7 @@ BASE_NAME = $(MODULE_NAME) MODULE_RELATIVE_DIR = ${module_relative_directory} PACKAGE_RELATIVE_DIR = ${package_relative_directory} MODULE_DIR = ${module_dir} +FFS_OUTPUT_DIR = ${ffs_output_directory} MODULE_ENTRY_POINT = ${module_entry_point} ARCH_ENTRY_POINT = ${arch_entry_point} @@ -441,6 +449,10 @@ cleanlib: self.Macros["BIN_DIR" ] = self._AutoGenObject.Macros["BIN_DIR"] self.Macros["BUILD_DIR" ] = self._AutoGenObject.Macros["BUILD_DIR"] self.Macros["WORKSPACE" ] = self._AutoGenObject.Macros["WORKSPACE"] + self.Macros["FFS_OUTPUT_DIR" ] = self._AutoGenObject.Macros["FFS_OUTPUT_DIR"] + self.GenFfsList = ModuleAutoGen.GenFfsList + self.MacroList = ['FFS_OUTPUT_DIR', 'MODULE_GUID', 'OUTPUT_DIR'] + self.FfsOutputFileList = [] # Compose a dict object containing information used to do replacement in template def _CreateTemplateDict(self): @@ -555,6 +567,7 @@ cleanlib: ExtraData="[%s]" % str(self._AutoGenObject)) self.ProcessBuildTargetList() + self.ParserGenerateFfsCmd() # Generate macros used to represent input files FileMacroList = [] # macro name = file list @@ -627,6 +640,7 @@ cleanlib: "platform_version" : self.PlatformInfo.Version, "platform_relative_directory": self.PlatformInfo.SourceDir, "platform_output_directory" : self.PlatformInfo.OutputDir, + "ffs_output_directory" : self._AutoGenObject.Macros["FFS_OUTPUT_DIR"], "platform_dir" : self._AutoGenObject.Macros["PLATFORM_DIR"], "module_name" : self._AutoGenObject.Name, @@ -673,6 +687,79 @@ cleanlib: return MakefileTemplateDict + def ParserGenerateFfsCmd(self): + #Add Ffs cmd to self.BuildTargetList + OutputFile = '' + DepsFileList = [] + + for Cmd in self.GenFfsList: + if Cmd[2]: + for CopyCmd in Cmd[2]: + Src, Dst = CopyCmd + Src = self.ReplaceMacro(Src) + Dst = self.ReplaceMacro(Dst) + if Dst not in self.ResultFileList: + self.ResultFileList.append('%s' % Dst) + if '%s :' %(Dst) not in self.BuildTargetList: + self.BuildTargetList.append("%s :" %(Dst)) + self.BuildTargetList.append('\t' + self._CP_TEMPLATE_[self._FileType] %{'Src': Src, 'Dst': Dst}) + + FfsCmdList = Cmd[0] + for index, Str in enumerate(FfsCmdList): + if '-o' == Str: + OutputFile = FfsCmdList[index + 1] + if '-i' == Str: + if DepsFileList == []: + DepsFileList = [FfsCmdList[index + 1]] + else: + DepsFileList.append(FfsCmdList[index + 1]) + DepsFileString = ' '.join(DepsFileList).strip() + if DepsFileString == '': + continue + OutputFile = self.ReplaceMacro(OutputFile) + self.ResultFileList.append('%s' % OutputFile) + DepsFileString = self.ReplaceMacro(DepsFileString) + self.BuildTargetList.append('%s : %s' % (OutputFile, DepsFileString)) + CmdString = ' '.join(FfsCmdList).strip() + CmdString = self.ReplaceMacro(CmdString) + self.BuildTargetList.append('\t%s' % CmdString) + + self.ParseSecCmd(DepsFileList, Cmd[1]) + for SecOutputFile, SecDepsFile, SecCmd in self.FfsOutputFileList : + self.BuildTargetList.append('%s : %s' % (self.ReplaceMacro(SecOutputFile), self.ReplaceMacro(SecDepsFile))) + self.BuildTargetList.append('\t%s' % self.ReplaceMacro(SecCmd)) + self.FfsOutputFileList = [] + + def ParseSecCmd(self, OutputFileList, CmdTuple): + for OutputFile in OutputFileList: + for SecCmdStr in CmdTuple: + SecDepsFileList = [] + SecCmdList = SecCmdStr.split() + CmdName = SecCmdList[0] + for index, CmdItem in enumerate(SecCmdList): + if '-o' == CmdItem and OutputFile == SecCmdList[index + 1]: + index = index + 1 + while index + 1 < len(SecCmdList): + if not SecCmdList[index+1].startswith('-'): + SecDepsFileList.append(SecCmdList[index + 1]) + index = index + 1 + if CmdName == 'Trim': + SecDepsFileList.append(os.path.join('$(DEBUG_DIR)', os.path.basename(OutputFile).replace('offset', 'efi'))) + if OutputFile.endswith('.ui') or OutputFile.endswith('.ver'): + SecDepsFileList.append(os.path.join('$(MODULE_DIR)','$(MODULE_FILE)')) + self.FfsOutputFileList.append((OutputFile, ' '.join(SecDepsFileList), SecCmdStr)) + if len(SecDepsFileList) > 0: + self.ParseSecCmd(SecDepsFileList, CmdTuple) + break + else: + continue + + def ReplaceMacro(self, str): + for Macro in self.MacroList: + if self._AutoGenObject.Macros[Macro] and self._AutoGenObject.Macros[Macro] in str: + str = str.replace(self._AutoGenObject.Macros[Macro], '$(' + Macro + ')') + return str + def CommandExceedLimit(self): FlagDict = { 'CC' : { 'Macro' : '$(CC_FLAGS)', 'Value' : False}, @@ -1453,7 +1540,8 @@ class TopLevelMakefile(BuildFile): if GlobalData.gCaseInsensitive: ExtraOption += " -c" - + if GlobalData.gEnableGenfdsMultiThread: + ExtraOption += " --genfds-multi-thread" if GlobalData.gIgnoreSource: ExtraOption += " --ignore-sources" diff --git a/BaseTools/Source/Python/Common/GlobalData.py b/BaseTools/Source/Python/Common/GlobalData.py index e348e9af2d..8b7562daa1 100644 --- a/BaseTools/Source/Python/Common/GlobalData.py +++ b/BaseTools/Source/Python/Common/GlobalData.py @@ -95,3 +95,4 @@ gBinCacheSource = None gPlatformHash = None gPackageHash = {} gModuleHash = {} +gEnableGenfdsMultiThread = False diff --git a/BaseTools/Source/Python/GenFds/AprioriSection.py b/BaseTools/Source/Python/GenFds/AprioriSection.py index a2306d062d..70e2e5a3ba 100644 --- a/BaseTools/Source/Python/GenFds/AprioriSection.py +++ b/BaseTools/Source/Python/GenFds/AprioriSection.py @@ -1,7 +1,7 @@ ## @file # process APRIORI file data and generate PEI/DXE APRIORI file # -# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.
+# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.
# # This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License @@ -47,7 +47,7 @@ class AprioriSection (AprioriSectionClassObject): # @param Dict dictionary contains macro and its value # @retval string Generated file name # - def GenFfs (self, FvName, Dict = {}): + def GenFfs (self, FvName, Dict = {}, IsMakefile = False): DXE_GUID = "FC510EE7-FFDC-11D4-BD41-0080C73C8881" PEI_GUID = "1B45CC0A-156A-428A-AF62-49864DA0E6E6" Buffer = StringIO.StringIO('') @@ -66,6 +66,7 @@ class AprioriSection (AprioriSectionClassObject): AprioriFileGuid + FvName + '.Ffs') Dict.update(self.DefineVarDict) + InfFileName = None for FfsObj in self.FfsList : Guid = "" if isinstance(FfsObj, FfsFileStatement.FileStatement): @@ -110,9 +111,14 @@ class AprioriSection (AprioriSectionClassObject): RawSectionFileName = os.path.join( OutputAprFilePath, \ AprioriFileGuid + FvName + '.raw' ) - GenFdsGlobalVariable.GenerateSection(RawSectionFileName, [OutputAprFileName], 'EFI_SECTION_RAW') + MakefilePath = None + if IsMakefile: + if not InfFileName: + return None + MakefilePath = InfFileName, Arch + GenFdsGlobalVariable.GenerateSection(RawSectionFileName, [OutputAprFileName], 'EFI_SECTION_RAW', IsMakefile=IsMakefile) GenFdsGlobalVariable.GenerateFfs(AprFfsFileName, [RawSectionFileName], - 'EFI_FV_FILETYPE_FREEFORM', AprioriFileGuid) + 'EFI_FV_FILETYPE_FREEFORM', AprioriFileGuid, MakefilePath=MakefilePath) return AprFfsFileName diff --git a/BaseTools/Source/Python/GenFds/CompressSection.py b/BaseTools/Source/Python/GenFds/CompressSection.py index fac58d14f8..64ad275d83 100644 --- a/BaseTools/Source/Python/GenFds/CompressSection.py +++ b/BaseTools/Source/Python/GenFds/CompressSection.py @@ -1,7 +1,7 @@ ## @file # process compress section generation # -# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.
+# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.
# # This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License @@ -53,7 +53,7 @@ class CompressSection (CompressSectionClassObject) : # @param Dict dictionary contains macro and its value # @retval tuple (Generated file name, section alignment) # - def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = {}): + def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = {}, IsMakefile = False): if FfsInf != None: self.CompType = FfsInf.__ExtendMacro__(self.CompType) @@ -64,10 +64,10 @@ class CompressSection (CompressSectionClassObject) : for Sect in self.SectionList: Index = Index + 1 SecIndex = '%s.%d' %(SecNum, Index) - ReturnSectList, AlignValue = Sect.GenSection(OutputPath, ModuleName, SecIndex, KeyStringList, FfsInf, Dict) + ReturnSectList, AlignValue = Sect.GenSection(OutputPath, ModuleName, SecIndex, KeyStringList, FfsInf, Dict, IsMakefile=IsMakefile) if ReturnSectList != []: for FileData in ReturnSectList: - SectFiles += (FileData,) + SectFiles += (FileData,) OutputFile = OutputPath + \ @@ -79,7 +79,7 @@ class CompressSection (CompressSectionClassObject) : OutputFile = os.path.normpath(OutputFile) GenFdsGlobalVariable.GenerateSection(OutputFile, SectFiles, Section.Section.SectionType['COMPRESS'], - CompressionType=self.CompTypeDict[self.CompType]) + CompressionType=self.CompTypeDict[self.CompType], IsMakefile=IsMakefile) OutputFileList = [] OutputFileList.append(OutputFile) return OutputFileList, self.Alignment diff --git a/BaseTools/Source/Python/GenFds/DataSection.py b/BaseTools/Source/Python/GenFds/DataSection.py index 78c0af4db1..2d2975f75c 100644 --- a/BaseTools/Source/Python/GenFds/DataSection.py +++ b/BaseTools/Source/Python/GenFds/DataSection.py @@ -48,7 +48,7 @@ class DataSection (DataSectionClassObject): # @param Dict dictionary contains macro and its value # @retval tuple (Generated file name list, section alignment) # - def GenSection(self, OutputPath, ModuleName, SecNum, keyStringList, FfsFile = None, Dict = {}): + def GenSection(self, OutputPath, ModuleName, SecNum, keyStringList, FfsFile = None, Dict = {}, IsMakefile = False): # # Prepare the parameter of GenSection # @@ -69,10 +69,16 @@ class DataSection (DataSectionClassObject): Filename = GenFdsGlobalVariable.MacroExtend(self.SectFileName) if Filename[(len(Filename)-4):] == '.efi': MapFile = Filename.replace('.efi', '.map') - if os.path.exists(MapFile): - CopyMapFile = os.path.join(OutputPath, ModuleName + '.map') - if not os.path.exists(CopyMapFile) or (os.path.getmtime(MapFile) > os.path.getmtime(CopyMapFile)): - CopyLongFilePath(MapFile, CopyMapFile) + CopyMapFile = os.path.join(OutputPath, ModuleName + '.map') + if IsMakefile: + if GenFdsGlobalVariable.CopyList == []: + GenFdsGlobalVariable.CopyList = [(MapFile, CopyMapFile)] + else: + GenFdsGlobalVariable.CopyList.append((MapFile, CopyMapFile)) + else: + if os.path.exists(MapFile): + if not os.path.exists(CopyMapFile) or (os.path.getmtime(MapFile) > os.path.getmtime(CopyMapFile)): + CopyLongFilePath(MapFile, CopyMapFile) #Get PE Section alignment when align is set to AUTO if self.Alignment == 'Auto' and self.SecType in ('TE', 'PE32'): @@ -96,24 +102,25 @@ class DataSection (DataSectionClassObject): CopyLongFilePath(self.SectFileName, FileBeforeStrip) StrippedFile = os.path.join(OutputPath, ModuleName + '.stripped') GenFdsGlobalVariable.GenerateFirmwareImage( - StrippedFile, - [GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict)], - Strip=True - ) + StrippedFile, + [GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict)], + Strip=True, + IsMakefile = IsMakefile + ) self.SectFileName = StrippedFile if self.SecType == 'TE': TeFile = os.path.join( OutputPath, ModuleName + 'Te.raw') GenFdsGlobalVariable.GenerateFirmwareImage( - TeFile, - [GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict)], - Type='te' - ) + TeFile, + [GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict)], + Type='te', + IsMakefile = IsMakefile + ) self.SectFileName = TeFile OutputFile = os.path.join (OutputPath, ModuleName + 'SEC' + SecNum + Ffs.SectionSuffix.get(self.SecType)) OutputFile = os.path.normpath(OutputFile) - - GenFdsGlobalVariable.GenerateSection(OutputFile, [self.SectFileName], Section.Section.SectionType.get(self.SecType)) + GenFdsGlobalVariable.GenerateSection(OutputFile, [self.SectFileName], Section.Section.SectionType.get(self.SecType), IsMakefile = IsMakefile) FileList = [OutputFile] return FileList, self.Alignment diff --git a/BaseTools/Source/Python/GenFds/DepexSection.py b/BaseTools/Source/Python/GenFds/DepexSection.py index 8f78c0fad4..1992d2abd8 100644 --- a/BaseTools/Source/Python/GenFds/DepexSection.py +++ b/BaseTools/Source/Python/GenFds/DepexSection.py @@ -1,7 +1,7 @@ ## @file # process depex section generation # -# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.
+# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.
# # This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License @@ -76,7 +76,7 @@ class DepexSection (DepexSectionClassObject): # @param Dict dictionary contains macro and its value # @retval tuple (Generated file name list, section alignment) # - def GenSection(self, OutputPath, ModuleName, SecNum, keyStringList, FfsFile = None, Dict = {}): + def GenSection(self, OutputPath, ModuleName, SecNum, keyStringList, FfsFile = None, Dict = {}, IsMakefile = False): if self.ExpressionProcessed == False: self.Expression = self.Expression.replace("\n", " ").replace("\r", " ") @@ -119,6 +119,6 @@ class DepexSection (DepexSectionClassObject): OutputFile = os.path.join (OutputPath, ModuleName + 'SEC' + SecNum + '.dpx') OutputFile = os.path.normpath(OutputFile) - GenFdsGlobalVariable.GenerateSection(OutputFile, [InputFile], Section.Section.SectionType.get (SecType)) + GenFdsGlobalVariable.GenerateSection(OutputFile, [InputFile], Section.Section.SectionType.get (SecType), IsMakefile=IsMakefile) FileList = [OutputFile] return FileList, self.Alignment diff --git a/BaseTools/Source/Python/GenFds/EfiSection.py b/BaseTools/Source/Python/GenFds/EfiSection.py index 7da3c1e7b0..7b3b717191 100644 --- a/BaseTools/Source/Python/GenFds/EfiSection.py +++ b/BaseTools/Source/Python/GenFds/EfiSection.py @@ -53,7 +53,7 @@ class EfiSection (EfiSectionClassObject): # @param Dict dictionary contains macro and its value # @retval tuple (Generated file name list, section alignment) # - def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = {}) : + def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = {}, IsMakefile = False) : if self.FileName != None and self.FileName.startswith('PCD('): self.FileName = GenFdsGlobalVariable.GetPcdValue(self.FileName) @@ -91,6 +91,8 @@ class EfiSection (EfiSectionClassObject): FileList.append(Filename) elif os.path.exists(Filename): FileList.append(Filename) + elif '.depex' in FfsInf.FinalTargetSuffixMap or FfsInf.Depex: + FileList.append(Filename) else: FileList, IsSect = Section.Section.GetFileList(FfsInf, self.FileType, self.FileExtension, Dict) if IsSect : @@ -119,8 +121,9 @@ class EfiSection (EfiSectionClassObject): Num = SecNum OutputFile = os.path.join( OutputPath, ModuleName + 'SEC' + str(Num) + Ffs.SectionSuffix.get(SectionType)) GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_VERSION', - #Ui=StringData, - Ver=BuildNum) + #Ui=StringData, + Ver=BuildNum, + IsMakefile=IsMakefile) OutputFileList.append(OutputFile) elif FileList != []: @@ -135,8 +138,9 @@ class EfiSection (EfiSectionClassObject): if BuildNum != None and BuildNum != '': BuildNumTuple = ('-j', BuildNum) GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_VERSION', - #Ui=VerString, - Ver=BuildNum) + #Ui=VerString, + Ver=BuildNum, + IsMakefile=IsMakefile) OutputFileList.append(OutputFile) else: @@ -157,8 +161,9 @@ class EfiSection (EfiSectionClassObject): Num = SecNum OutputFile = os.path.join( OutputPath, ModuleName + 'SEC' + str(Num) + Ffs.SectionSuffix.get(SectionType)) GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_VERSION', - #Ui=VerString, - Ver=BuildNum) + #Ui=VerString, + Ver=BuildNum, + IsMakefile=IsMakefile) OutputFileList.append(OutputFile) # @@ -175,7 +180,7 @@ class EfiSection (EfiSectionClassObject): Num = SecNum OutputFile = os.path.join( OutputPath, ModuleName + 'SEC' + str(Num) + Ffs.SectionSuffix.get(SectionType)) GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_USER_INTERFACE', - Ui=StringData) + Ui=StringData, IsMakefile=IsMakefile) OutputFileList.append(OutputFile) elif FileList != []: @@ -187,7 +192,7 @@ class EfiSection (EfiSectionClassObject): UiString = f.read() f.close() GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_USER_INTERFACE', - Ui=UiString) + Ui=UiString, IsMakefile=IsMakefile) OutputFileList.append(OutputFile) else: if StringData != None and len(StringData) > 0: @@ -204,7 +209,7 @@ class EfiSection (EfiSectionClassObject): Num = SecNum OutputFile = os.path.join( OutputPath, ModuleName + 'SEC' + str(Num) + Ffs.SectionSuffix.get(SectionType)) GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_USER_INTERFACE', - Ui=StringData) + Ui=StringData, IsMakefile=IsMakefile) OutputFileList.append(OutputFile) @@ -238,23 +243,36 @@ class EfiSection (EfiSectionClassObject): if File[(len(File)-4):] == '.efi': MapFile = File.replace('.efi', '.map') - if os.path.exists(MapFile): - CopyMapFile = os.path.join(OutputPath, ModuleName + '.map') - if not os.path.exists(CopyMapFile) or \ - (os.path.getmtime(MapFile) > os.path.getmtime(CopyMapFile)): - CopyLongFilePath(MapFile, CopyMapFile) + CopyMapFile = os.path.join(OutputPath, ModuleName + '.map') + if IsMakefile: + if GenFdsGlobalVariable.CopyList == []: + GenFdsGlobalVariable.CopyList = [(MapFile, CopyMapFile)] + else: + GenFdsGlobalVariable.CopyList.append((MapFile, CopyMapFile)) + else: + if os.path.exists(MapFile): + if not os.path.exists(CopyMapFile) or \ + (os.path.getmtime(MapFile) > os.path.getmtime(CopyMapFile)): + CopyLongFilePath(MapFile, CopyMapFile) if not NoStrip: FileBeforeStrip = os.path.join(OutputPath, ModuleName + '.efi') - if not os.path.exists(FileBeforeStrip) or \ - (os.path.getmtime(File) > os.path.getmtime(FileBeforeStrip)): - CopyLongFilePath(File, FileBeforeStrip) + if IsMakefile: + if GenFdsGlobalVariable.CopyList == []: + GenFdsGlobalVariable.CopyList = [(File, FileBeforeStrip)] + else: + GenFdsGlobalVariable.CopyList.append((File, FileBeforeStrip)) + else: + if not os.path.exists(FileBeforeStrip) or \ + (os.path.getmtime(File) > os.path.getmtime(FileBeforeStrip)): + CopyLongFilePath(File, FileBeforeStrip) StrippedFile = os.path.join(OutputPath, ModuleName + '.stripped') GenFdsGlobalVariable.GenerateFirmwareImage( - StrippedFile, - [File], - Strip=True - ) + StrippedFile, + [File], + Strip=True, + IsMakefile = IsMakefile + ) File = StrippedFile """For TE Section call GenFw to generate TE image""" @@ -262,17 +280,19 @@ class EfiSection (EfiSectionClassObject): if SectionType == 'TE': TeFile = os.path.join( OutputPath, ModuleName + 'Te.raw') GenFdsGlobalVariable.GenerateFirmwareImage( - TeFile, - [File], - Type='te' - ) + TeFile, + [File], + Type='te', + IsMakefile = IsMakefile + ) File = TeFile """Call GenSection""" GenFdsGlobalVariable.GenerateSection(OutputFile, - [File], - Section.Section.SectionType.get (SectionType) - ) + [File], + Section.Section.SectionType.get (SectionType), + IsMakefile=IsMakefile + ) OutputFileList.append(OutputFile) return OutputFileList, Align diff --git a/BaseTools/Source/Python/GenFds/Fd.py b/BaseTools/Source/Python/GenFds/Fd.py index f330a7ed55..f735d3b5b0 100644 --- a/BaseTools/Source/Python/GenFds/Fd.py +++ b/BaseTools/Source/Python/GenFds/Fd.py @@ -45,7 +45,7 @@ class FD(FDClassObject): # # @retval string Generated FD file name # - def GenFd (self): + def GenFd (self, Flag = False): if self.FdUiName.upper() + 'fd' in GenFds.ImageBinDict.keys(): return GenFds.ImageBinDict[self.FdUiName.upper() + 'fd'] @@ -53,7 +53,8 @@ class FD(FDClassObject): # Print Information # FdFileName = os.path.join(GenFdsGlobalVariable.FvDir, self.FdUiName + '.fd') - GenFdsGlobalVariable.InfLogger("Fd File Name:%s (%s)" %(self.FdUiName, FdFileName)) + if not Flag: + GenFdsGlobalVariable.InfLogger("\nFd File Name:%s (%s)" %(self.FdUiName, FdFileName)) Offset = 0x00 for item in self.BlockSizeList: @@ -85,11 +86,13 @@ class FD(FDClassObject): elif RegionObj.Offset <= PreviousRegionStart or (RegionObj.Offset >=PreviousRegionStart and RegionObj.Offset < PreviousRegionStart + PreviousRegionSize): pass elif RegionObj.Offset > PreviousRegionStart + PreviousRegionSize: - GenFdsGlobalVariable.InfLogger('Padding region starting from offset 0x%X, with size 0x%X' %(PreviousRegionStart + PreviousRegionSize, RegionObj.Offset - (PreviousRegionStart + PreviousRegionSize))) + if not Flag: + GenFdsGlobalVariable.InfLogger('Padding region starting from offset 0x%X, with size 0x%X' %(PreviousRegionStart + PreviousRegionSize, RegionObj.Offset - (PreviousRegionStart + PreviousRegionSize))) PadRegion = Region.Region() PadRegion.Offset = PreviousRegionStart + PreviousRegionSize PadRegion.Size = RegionObj.Offset - PadRegion.Offset - PadRegion.AddToBuffer(TempFdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFds.ImageBinDict, self.vtfRawDict, self.DefineVarDict) + if not Flag: + PadRegion.AddToBuffer(TempFdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFds.ImageBinDict, self.vtfRawDict, self.DefineVarDict) PreviousRegionStart = RegionObj.Offset PreviousRegionSize = RegionObj.Size # @@ -113,11 +116,13 @@ class FD(FDClassObject): 'Region offset 0x%X overlaps with Region starting from 0x%X, size 0x%X' \ % (RegionObj.Offset, PreviousRegionStart, PreviousRegionSize)) elif RegionObj.Offset > PreviousRegionStart + PreviousRegionSize: - GenFdsGlobalVariable.InfLogger('Padding region starting from offset 0x%X, with size 0x%X' %(PreviousRegionStart + PreviousRegionSize, RegionObj.Offset - (PreviousRegionStart + PreviousRegionSize))) + if not Flag: + GenFdsGlobalVariable.InfLogger('Padding region starting from offset 0x%X, with size 0x%X' %(PreviousRegionStart + PreviousRegionSize, RegionObj.Offset - (PreviousRegionStart + PreviousRegionSize))) PadRegion = Region.Region() PadRegion.Offset = PreviousRegionStart + PreviousRegionSize PadRegion.Size = RegionObj.Offset - PadRegion.Offset - PadRegion.AddToBuffer(FdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFds.ImageBinDict, self.vtfRawDict, self.DefineVarDict) + if not Flag: + PadRegion.AddToBuffer(FdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFds.ImageBinDict, self.vtfRawDict, self.DefineVarDict) PreviousRegionStart = RegionObj.Offset PreviousRegionSize = RegionObj.Size # @@ -131,13 +136,14 @@ class FD(FDClassObject): # Call each region's AddToBuffer function # GenFdsGlobalVariable.VerboseLogger('Call each region\'s AddToBuffer function') - RegionObj.AddToBuffer (FdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFds.ImageBinDict, self.vtfRawDict, self.DefineVarDict) + RegionObj.AddToBuffer (FdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFds.ImageBinDict, self.vtfRawDict, self.DefineVarDict,Flag=Flag) # # Write the buffer contents to Fd file # GenFdsGlobalVariable.VerboseLogger('Write the buffer contents to Fd file') - SaveFileOnChange(FdFileName, FdBuffer.getvalue()) - FdBuffer.close(); + if not Flag: + SaveFileOnChange(FdFileName, FdBuffer.getvalue()) + FdBuffer.close() GenFds.ImageBinDict[self.FdUiName.upper() + 'fd'] = FdFileName return FdFileName diff --git a/BaseTools/Source/Python/GenFds/FfsFileStatement.py b/BaseTools/Source/Python/GenFds/FfsFileStatement.py index f76ddf4d95..edb131266d 100644 --- a/BaseTools/Source/Python/GenFds/FfsFileStatement.py +++ b/BaseTools/Source/Python/GenFds/FfsFileStatement.py @@ -1,7 +1,7 @@ ## @file # process FFS generation from FILE statement # -# Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.
+# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.
# # This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License @@ -57,7 +57,7 @@ class FileStatement (FileStatementClassObject) : # @param FvParentAddr Parent Fv base address # @retval string Generated FFS file name # - def GenFfs(self, Dict = {}, FvChildAddr=[], FvParentAddr=None): + def GenFfs(self, Dict = {}, FvChildAddr=[], FvParentAddr=None, IsMakefile=False): if self.NameGuid != None and self.NameGuid.startswith('PCD('): PcdValue = GenFdsGlobalVariable.GetPcdValue(self.NameGuid) diff --git a/BaseTools/Source/Python/GenFds/FfsInfStatement.py b/BaseTools/Source/Python/GenFds/FfsInfStatement.py index 958cecfad6..4b4781755d 100644 --- a/BaseTools/Source/Python/GenFds/FfsInfStatement.py +++ b/BaseTools/Source/Python/GenFds/FfsInfStatement.py @@ -44,6 +44,8 @@ from PatchPcdValue.PatchPcdValue import PatchBinaryFile from Common.LongFilePathSupport import CopyLongFilePath from Common.LongFilePathSupport import OpenLongFilePath as open import Common.GlobalData as GlobalData +from DepexSection import DepexSection +from Common.Misc import SaveFileOnChange ## generate FFS from INF # @@ -72,6 +74,7 @@ class FfsInfStatement(FfsInfStatementClassObject): self.OverrideGuid = None self.PatchedBinFile = '' self.MacroDict = {} + self.Depex = False ## GetFinalTargetSuffixMap() method # @@ -320,6 +323,11 @@ class FfsInfStatement(FfsInfStatementClassObject): self.InfModule = Inf self.PcdIsDriver = Inf.PcdIsDriver self.IsBinaryModule = Inf.IsBinaryModule + Inf._GetDepex() + Inf._GetDepexExpression() + if len(Inf._Depex.data) > 0 and len(Inf._DepexExpression.data) > 0: + self.Depex = True + GenFdsGlobalVariable.VerboseLogger("BaseName : %s" % self.BaseName) GenFdsGlobalVariable.VerboseLogger("ModuleGuid : %s" % self.ModuleGuid) GenFdsGlobalVariable.VerboseLogger("ModuleType : %s" % self.ModuleType) @@ -335,7 +343,7 @@ class FfsInfStatement(FfsInfStatementClassObject): if not os.path.exists(self.OutputPath) : os.makedirs(self.OutputPath) - self.EfiOutputPath = self.__GetEFIOutPutPath__() + self.EfiOutputPath, self.EfiDebugPath = self.__GetEFIOutPutPath__() GenFdsGlobalVariable.VerboseLogger( "ModuelEFIPath: " + self.EfiOutputPath) ## PatchEfiFile @@ -414,12 +422,13 @@ class FfsInfStatement(FfsInfStatementClassObject): # @param FvParentAddr Parent Fv base address # @retval string Generated FFS file name # - def GenFfs(self, Dict = {}, FvChildAddr = [], FvParentAddr=None): + def GenFfs(self, Dict = {}, FvChildAddr = [], FvParentAddr=None, IsMakefile=False): # # Parse Inf file get Module related information # self.__InfParse__(Dict) + Arch = self.GetCurrentArch() SrcFile = mws.join( GenFdsGlobalVariable.WorkSpaceDir , self.InfFileName); DestFile = os.path.join( self.OutputPath, self.ModuleGuid + '.ffs') @@ -451,7 +460,9 @@ class FfsInfStatement(FfsInfStatementClassObject): if len(self.BinFileList) > 0: if self.Rule == None or self.Rule == "": self.Rule = "BINARY" - + + if not IsMakefile and GenFdsGlobalVariable.EnableGenfdsMultiThread and self.Rule != 'BINARY': + IsMakefile = True # # Get the rule of how to generate Ffs file # @@ -472,17 +483,19 @@ class FfsInfStatement(FfsInfStatementClassObject): # # For the rule only has simpleFile # + MakefilePath = None + if IsMakefile: + MakefilePath = self.InfFileName, Arch if isinstance (Rule, RuleSimpleFile.RuleSimpleFile) : - SectionOutputList = self.__GenSimpleFileSection__(Rule) - FfsOutput = self.__GenSimpleFileFfs__(Rule, SectionOutputList) + SectionOutputList = self.__GenSimpleFileSection__(Rule, IsMakefile=IsMakefile) + FfsOutput = self.__GenSimpleFileFfs__(Rule, SectionOutputList, MakefilePath=MakefilePath) return FfsOutput # # For Rule has ComplexFile # elif isinstance(Rule, RuleComplexFile.RuleComplexFile): - InputSectList, InputSectAlignments = self.__GenComplexFileSection__(Rule, FvChildAddr, FvParentAddr) - FfsOutput = self.__GenComplexFileFfs__(Rule, InputSectList, InputSectAlignments) - + InputSectList, InputSectAlignments = self.__GenComplexFileSection__(Rule, FvChildAddr, FvParentAddr, IsMakefile=IsMakefile) + FfsOutput = self.__GenComplexFileFfs__(Rule, InputSectList, InputSectAlignments, MakefilePath=MakefilePath) return FfsOutput ## __ExtendMacro__() method @@ -651,6 +664,7 @@ class FfsInfStatement(FfsInfStatementClassObject): def __GetEFIOutPutPath__(self): Arch = '' OutputPath = '' + DebugPath = '' (ModulePath, FileName) = os.path.split(self.InfFileName) Index = FileName.rfind('.') FileName = FileName[0:Index] @@ -666,8 +680,15 @@ class FfsInfStatement(FfsInfStatementClassObject): FileName, 'OUTPUT' ) + DebugPath = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch], + Arch , + ModulePath, + FileName, + 'DEBUG' + ) OutputPath = os.path.realpath(OutputPath) - return OutputPath + DebugPath = os.path.realpath(DebugPath) + return OutputPath, DebugPath ## __GenSimpleFileSection__() method # @@ -677,7 +698,7 @@ class FfsInfStatement(FfsInfStatementClassObject): # @param Rule The rule object used to generate section # @retval string File name of the generated section file # - def __GenSimpleFileSection__(self, Rule): + def __GenSimpleFileSection__(self, Rule, IsMakefile = False): # # Prepare the parameter of GenSection # @@ -743,22 +764,23 @@ class FfsInfStatement(FfsInfStatementClassObject): CopyLongFilePath(File, FileBeforeStrip) StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped') GenFdsGlobalVariable.GenerateFirmwareImage( - StrippedFile, - [File], - Strip=True - ) + StrippedFile, + [File], + Strip=True, + IsMakefile=IsMakefile + ) File = StrippedFile if SectionType == 'TE': TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw') GenFdsGlobalVariable.GenerateFirmwareImage( - TeFile, - [File], - Type='te' - ) + TeFile, + [File], + Type='te', + IsMakefile=IsMakefile + ) File = TeFile - - GenFdsGlobalVariable.GenerateSection(OutputFile, [File], Section.Section.SectionType[SectionType]) + GenFdsGlobalVariable.GenerateSection(OutputFile, [File], Section.Section.SectionType[SectionType], IsMakefile=IsMakefile) OutputFileList.append(OutputFile) else: SecNum = '%d' %Index @@ -785,22 +807,23 @@ class FfsInfStatement(FfsInfStatementClassObject): StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped') GenFdsGlobalVariable.GenerateFirmwareImage( - StrippedFile, - [GenSecInputFile], - Strip=True - ) + StrippedFile, + [GenSecInputFile], + Strip=True, + IsMakefile=IsMakefile + ) GenSecInputFile = StrippedFile if SectionType == 'TE': TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw') GenFdsGlobalVariable.GenerateFirmwareImage( - TeFile, - [GenSecInputFile], - Type='te' - ) + TeFile, + [GenSecInputFile], + Type='te', + IsMakefile=IsMakefile + ) GenSecInputFile = TeFile - - GenFdsGlobalVariable.GenerateSection(OutputFile, [GenSecInputFile], Section.Section.SectionType[SectionType]) + GenFdsGlobalVariable.GenerateSection(OutputFile, [GenSecInputFile], Section.Section.SectionType[SectionType], IsMakefile=IsMakefile) OutputFileList.append(OutputFile) return OutputFileList @@ -814,7 +837,7 @@ class FfsInfStatement(FfsInfStatementClassObject): # @param InputFileList The output file list from GenSection # @retval string Generated FFS file name # - def __GenSimpleFileFfs__(self, Rule, InputFileList): + def __GenSimpleFileFfs__(self, Rule, InputFileList, MakefilePath = None): FfsOutput = self.OutputPath + \ os.sep + \ self.__ExtendMacro__(Rule.NameGuid) + \ @@ -840,12 +863,13 @@ class FfsInfStatement(FfsInfStatementClassObject): % (Rule.NameGuid)) self.ModuleGuid = RegistryGuidStr - GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputSection, - Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType], - self.ModuleGuid, Fixed=Rule.Fixed, - CheckSum=Rule.CheckSum, Align=Rule.Alignment, - SectionAlign=SectionAlignments - ) + GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputSection, + Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType], + self.ModuleGuid, Fixed=Rule.Fixed, + CheckSum=Rule.CheckSum, Align=Rule.Alignment, + SectionAlign=SectionAlignments, + MakefilePath=MakefilePath + ) return FfsOutput ## __GenComplexFileSection__() method @@ -858,14 +882,14 @@ class FfsInfStatement(FfsInfStatementClassObject): # @param FvParentAddr Parent Fv base address # @retval string File name of the generated section file # - def __GenComplexFileSection__(self, Rule, FvChildAddr, FvParentAddr): + def __GenComplexFileSection__(self, Rule, FvChildAddr, FvParentAddr, IsMakefile = False): if self.ModuleType in ('SEC', 'PEI_CORE', 'PEIM'): if Rule.KeepReloc != None: self.KeepRelocFromRule = Rule.KeepReloc SectFiles = [] SectAlignments = [] Index = 1 - HasGneratedFlag = False + HasGeneratedFlag = False if self.PcdIsDriver == 'PEI_PCD_DRIVER': if self.IsBinaryModule: PcdExDbFileName = os.path.join(GenFdsGlobalVariable.FvDir, "PEIPcdDataBase.raw") @@ -875,6 +899,7 @@ class FfsInfStatement(FfsInfStatementClassObject): GenFdsGlobalVariable.GenerateSection(PcdExDbSecName, [PcdExDbFileName], "EFI_SECTION_RAW", + IsMakefile = IsMakefile ) SectFiles.append(PcdExDbSecName) SectAlignments.append(None) @@ -885,9 +910,10 @@ class FfsInfStatement(FfsInfStatementClassObject): PcdExDbFileName = os.path.join(self.EfiOutputPath, "DXEPcdDataBase.raw") PcdExDbSecName = os.path.join(self.OutputPath, "DXEPcdDataBaseSec.raw") GenFdsGlobalVariable.GenerateSection(PcdExDbSecName, - [PcdExDbFileName], - "EFI_SECTION_RAW", - ) + [PcdExDbFileName], + "EFI_SECTION_RAW", + IsMakefile = IsMakefile + ) SectFiles.append(PcdExDbSecName) SectAlignments.append(None) for Sect in Rule.SectionList: @@ -917,11 +943,11 @@ class FfsInfStatement(FfsInfStatementClassObject): Sect.FvParentAddr = FvParentAddr if Rule.KeyStringList != []: - SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, Rule.KeyStringList, self) + SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, Rule.KeyStringList, self, IsMakefile = IsMakefile) else : - SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, self.KeyStringList, self) + SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, self.KeyStringList, self, IsMakefile = IsMakefile) - if not HasGneratedFlag: + if not HasGeneratedFlag: UniVfrOffsetFileSection = "" ModuleFileName = mws.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName) InfData = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClass(ModuleFileName), self.CurrentArch] @@ -944,27 +970,40 @@ class FfsInfStatement(FfsInfStatementClassObject): if len(VfrUniBaseName) > 0: - VfrUniOffsetList = self.__GetBuildOutputMapFileVfrUniInfo(VfrUniBaseName) - # - # Generate the Raw data of raw section - # - if VfrUniOffsetList: - os.path.join( self.OutputPath, self.BaseName + '.offset') - UniVfrOffsetFileName = os.path.join( self.OutputPath, self.BaseName + '.offset') - UniVfrOffsetFileSection = os.path.join( self.OutputPath, self.BaseName + 'Offset' + '.raw') - - self.__GenUniVfrOffsetFile (VfrUniOffsetList, UniVfrOffsetFileName) - - UniVfrOffsetFileNameList = [] - UniVfrOffsetFileNameList.append(UniVfrOffsetFileName) - """Call GenSection""" - GenFdsGlobalVariable.GenerateSection(UniVfrOffsetFileSection, - UniVfrOffsetFileNameList, - "EFI_SECTION_RAW" - ) - os.remove(UniVfrOffsetFileName) + if IsMakefile: + if InfData.BuildType != 'UEFI_HII': + UniVfrOffsetFileName = os.path.join(self.OutputPath, self.BaseName + '.offset') + UniVfrOffsetFileSection = os.path.join(self.OutputPath, self.BaseName + 'Offset' + '.raw') + UniVfrOffsetFileNameList = [] + UniVfrOffsetFileNameList.append(UniVfrOffsetFileName) + TrimCmd = "Trim --Vfr-Uni-Offset -o %s --ModuleName=%s --DebugDir=%s " % (UniVfrOffsetFileName, self.BaseName, self.EfiDebugPath) + GenFdsGlobalVariable.SecCmdList.append(TrimCmd) + GenFdsGlobalVariable.GenerateSection(UniVfrOffsetFileSection, + [UniVfrOffsetFileName], + "EFI_SECTION_RAW", + IsMakefile = True + ) + else: + VfrUniOffsetList = self.__GetBuildOutputMapFileVfrUniInfo(VfrUniBaseName) + # + # Generate the Raw data of raw section + # + if VfrUniOffsetList: + UniVfrOffsetFileName = os.path.join(self.OutputPath, self.BaseName + '.offset') + UniVfrOffsetFileSection = os.path.join(self.OutputPath, self.BaseName + 'Offset' + '.raw') + self.__GenUniVfrOffsetFile (VfrUniOffsetList, UniVfrOffsetFileName) + UniVfrOffsetFileNameList = [] + UniVfrOffsetFileNameList.append(UniVfrOffsetFileName) + """Call GenSection""" + + GenFdsGlobalVariable.GenerateSection(UniVfrOffsetFileSection, + UniVfrOffsetFileNameList, + "EFI_SECTION_RAW" + ) + #os.remove(UniVfrOffsetFileName) + if UniVfrOffsetFileSection: SectList.append(UniVfrOffsetFileSection) - HasGneratedFlag = True + HasGeneratedFlag = True for SecName in SectList : SectFiles.append(SecName) @@ -981,7 +1020,7 @@ class FfsInfStatement(FfsInfStatementClassObject): # @param InputFileList The output file list from GenSection # @retval string Generated FFS file name # - def __GenComplexFileFfs__(self, Rule, InputFile, Alignments): + def __GenComplexFileFfs__(self, Rule, InputFile, Alignments, MakefilePath = None): if Rule.NameGuid != None and Rule.NameGuid.startswith('PCD('): PcdValue = GenFdsGlobalVariable.GetPcdValue(Rule.NameGuid) @@ -998,11 +1037,12 @@ class FfsInfStatement(FfsInfStatementClassObject): FfsOutput = os.path.join( self.OutputPath, self.ModuleGuid + '.ffs') GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputFile, - Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType], - self.ModuleGuid, Fixed=Rule.Fixed, - CheckSum=Rule.CheckSum, Align=Rule.Alignment, - SectionAlign=Alignments - ) + Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType], + self.ModuleGuid, Fixed=Rule.Fixed, + CheckSum=Rule.CheckSum, Align=Rule.Alignment, + SectionAlign=Alignments, + MakefilePath=MakefilePath + ) return FfsOutput ## __GetGenFfsCmdParameter__() method @@ -1048,12 +1088,7 @@ class FfsInfStatement(FfsInfStatementClassObject): # @param UniVfrOffsetFileName The output offset file name. # def __GenUniVfrOffsetFile(self, VfrUniOffsetList, UniVfrOffsetFileName): - - try: - fInputfile = open(UniVfrOffsetFileName, "wb+", 0) - except: - EdkLogger.error("GenFds", FILE_OPEN_FAILURE, "File open failed for %s" %UniVfrOffsetFileName,None) - + # Use a instance of StringIO to cache data fStringIO = StringIO.StringIO('') @@ -1085,18 +1120,11 @@ class FfsInfStatement(FfsInfStatementClassObject): # # write data into file. # - try : - fInputfile.write (fStringIO.getvalue()) + try : + SaveFileOnChange(UniVfrOffsetFileName, fStringIO.getvalue()) except: EdkLogger.error("GenFds", FILE_WRITE_FAILURE, "Write data to file %s failed, please check whether the file been locked or using by other applications." %UniVfrOffsetFileName,None) fStringIO.close () - fInputfile.close () - - - - - - - + diff --git a/BaseTools/Source/Python/GenFds/Fv.py b/BaseTools/Source/Python/GenFds/Fv.py index 45f6696a5f..3953756e0f 100644 --- a/BaseTools/Source/Python/GenFds/Fv.py +++ b/BaseTools/Source/Python/GenFds/Fv.py @@ -22,6 +22,7 @@ from struct import * import Ffs import AprioriSection +import FfsFileStatement from GenFdsGlobalVariable import GenFdsGlobalVariable from GenFds import GenFds from CommonDataClass.FdfClass import FvClassObject @@ -67,7 +68,7 @@ class FV (FvClassObject): # @param MacroDict macro value pair # @retval string Generated FV file path # - def AddToBuffer (self, Buffer, BaseAddress=None, BlockSize= None, BlockNum=None, ErasePloarity='1', VtfDict=None, MacroDict = {}) : + def AddToBuffer (self, Buffer, BaseAddress=None, BlockSize= None, BlockNum=None, ErasePloarity='1', VtfDict=None, MacroDict = {}, Flag=False) : if BaseAddress == None and self.UiFvName.upper() + 'fv' in GenFds.ImageBinDict.keys(): return GenFds.ImageBinDict[self.UiFvName.upper() + 'fv'] @@ -88,15 +89,15 @@ class FV (FvClassObject): continue elif self.UiFvName.upper() == RegionData.upper(): GenFdsGlobalVariable.ErrorLogger("Capsule %s in FD region can't contain a FV %s in FD region." % (self.CapsuleName, self.UiFvName.upper())) - - GenFdsGlobalVariable.InfLogger( "\nGenerating %s FV" %self.UiFvName) + if not Flag: + GenFdsGlobalVariable.InfLogger( "\nGenerating %s FV" %self.UiFvName) GenFdsGlobalVariable.LargeFileInFvFlags.append(False) FFSGuid = None if self.FvBaseAddress != None: BaseAddress = self.FvBaseAddress - - self.__InitializeInf__(BaseAddress, BlockSize, BlockNum, ErasePloarity, VtfDict) + if not Flag: + self.__InitializeInf__(BaseAddress, BlockSize, BlockNum, ErasePloarity, VtfDict) # # First Process the Apriori section # @@ -105,23 +106,30 @@ class FV (FvClassObject): GenFdsGlobalVariable.VerboseLogger('First generate Apriori file !') FfsFileList = [] for AprSection in self.AprioriSectionList: - FileName = AprSection.GenFfs (self.UiFvName, MacroDict) + FileName = AprSection.GenFfs (self.UiFvName, MacroDict, IsMakefile=Flag) FfsFileList.append(FileName) # Add Apriori file name to Inf file - self.FvInfFile.writelines("EFI_FILE_NAME = " + \ - FileName + \ - T_CHAR_LF) + if not Flag: + self.FvInfFile.writelines("EFI_FILE_NAME = " + \ + FileName + \ + T_CHAR_LF) # Process Modules in FfsList for FfsFile in self.FfsList : - FileName = FfsFile.GenFfs(MacroDict, FvParentAddr=BaseAddress) + if Flag: + if isinstance(FfsFile, FfsFileStatement.FileStatement): + continue + if GenFdsGlobalVariable.EnableGenfdsMultiThread and GenFdsGlobalVariable.ModuleFile and GenFdsGlobalVariable.ModuleFile.Path.find(os.path.normpath(FfsFile.InfFileName)) == -1: + continue + FileName = FfsFile.GenFfs(MacroDict, FvParentAddr=BaseAddress, IsMakefile=Flag) FfsFileList.append(FileName) - self.FvInfFile.writelines("EFI_FILE_NAME = " + \ - FileName + \ - T_CHAR_LF) - - SaveFileOnChange(self.InfFileName, self.FvInfFile.getvalue(), False) - self.FvInfFile.close() + if not Flag: + self.FvInfFile.writelines("EFI_FILE_NAME = " + \ + FileName + \ + T_CHAR_LF) + if not Flag: + SaveFileOnChange(self.InfFileName, self.FvInfFile.getvalue(), False) + self.FvInfFile.close() # # Call GenFv tool # @@ -131,88 +139,91 @@ class FV (FvClassObject): if self.CreateFileName != None: FvOutputFile = self.CreateFileName + if Flag: + GenFds.ImageBinDict[self.UiFvName.upper() + 'fv'] = FvOutputFile + return FvOutputFile + FvInfoFileName = os.path.join(GenFdsGlobalVariable.FfsDir, self.UiFvName + '.inf') - CopyLongFilePath(GenFdsGlobalVariable.FvAddressFileName, FvInfoFileName) - OrigFvInfo = None - if os.path.exists (FvInfoFileName): - OrigFvInfo = open(FvInfoFileName, 'r').read() - if GenFdsGlobalVariable.LargeFileInFvFlags[-1]: - FFSGuid = GenFdsGlobalVariable.EFI_FIRMWARE_FILE_SYSTEM3_GUID; - GenFdsGlobalVariable.GenerateFirmwareVolume( - FvOutputFile, - [self.InfFileName], - AddressFile=FvInfoFileName, - FfsList=FfsFileList, - ForceRebase=self.FvForceRebase, - FileSystemGuid=FFSGuid - ) + if not Flag: + CopyLongFilePath(GenFdsGlobalVariable.FvAddressFileName, FvInfoFileName) + OrigFvInfo = None + if os.path.exists (FvInfoFileName): + OrigFvInfo = open(FvInfoFileName, 'r').read() + if GenFdsGlobalVariable.LargeFileInFvFlags[-1]: + FFSGuid = GenFdsGlobalVariable.EFI_FIRMWARE_FILE_SYSTEM3_GUID + GenFdsGlobalVariable.GenerateFirmwareVolume( + FvOutputFile, + [self.InfFileName], + AddressFile=FvInfoFileName, + FfsList=FfsFileList, + ForceRebase=self.FvForceRebase, + FileSystemGuid=FFSGuid + ) - NewFvInfo = None - if os.path.exists (FvInfoFileName): - NewFvInfo = open(FvInfoFileName, 'r').read() - if NewFvInfo != None and NewFvInfo != OrigFvInfo: - FvChildAddr = [] - AddFileObj = open(FvInfoFileName, 'r') - AddrStrings = AddFileObj.readlines() - AddrKeyFound = False - for AddrString in AddrStrings: - if AddrKeyFound: - #get base address for the inside FvImage - FvChildAddr.append (AddrString) - elif AddrString.find ("[FV_BASE_ADDRESS]") != -1: - AddrKeyFound = True - AddFileObj.close() + NewFvInfo = None + if os.path.exists (FvInfoFileName): + NewFvInfo = open(FvInfoFileName, 'r').read() + if NewFvInfo != None and NewFvInfo != OrigFvInfo: + FvChildAddr = [] + AddFileObj = open(FvInfoFileName, 'r') + AddrStrings = AddFileObj.readlines() + AddrKeyFound = False + for AddrString in AddrStrings: + if AddrKeyFound: + #get base address for the inside FvImage + FvChildAddr.append (AddrString) + elif AddrString.find ("[FV_BASE_ADDRESS]") != -1: + AddrKeyFound = True + AddFileObj.close() - if FvChildAddr != []: - # Update Ffs again - for FfsFile in self.FfsList : - FileName = FfsFile.GenFfs(MacroDict, FvChildAddr, BaseAddress) - - if GenFdsGlobalVariable.LargeFileInFvFlags[-1]: - FFSGuid = GenFdsGlobalVariable.EFI_FIRMWARE_FILE_SYSTEM3_GUID; - #Update GenFv again - GenFdsGlobalVariable.GenerateFirmwareVolume( - FvOutputFile, - [self.InfFileName], - AddressFile=FvInfoFileName, - FfsList=FfsFileList, - ForceRebase=self.FvForceRebase, - FileSystemGuid=FFSGuid - ) + if FvChildAddr != []: + # Update Ffs again + for FfsFile in self.FfsList : + FileName = FfsFile.GenFfs(MacroDict, FvChildAddr, BaseAddress, IsMakefile=Flag) - # - # Write the Fv contents to Buffer - # - if os.path.isfile(FvOutputFile): - FvFileObj = open ( FvOutputFile,'rb') + if GenFdsGlobalVariable.LargeFileInFvFlags[-1]: + FFSGuid = GenFdsGlobalVariable.EFI_FIRMWARE_FILE_SYSTEM3_GUID; + #Update GenFv again + GenFdsGlobalVariable.GenerateFirmwareVolume( + FvOutputFile, + [self.InfFileName], + AddressFile=FvInfoFileName, + FfsList=FfsFileList, + ForceRebase=self.FvForceRebase, + FileSystemGuid=FFSGuid + ) - GenFdsGlobalVariable.VerboseLogger( "\nGenerate %s FV Successfully" %self.UiFvName) - GenFdsGlobalVariable.SharpCounter = 0 + # + # Write the Fv contents to Buffer + # + if os.path.isfile(FvOutputFile): + FvFileObj = open(FvOutputFile, 'rb') + GenFdsGlobalVariable.VerboseLogger("\nGenerate %s FV Successfully" % self.UiFvName) + GenFdsGlobalVariable.SharpCounter = 0 - Buffer.write(FvFileObj.read()) - FvFileObj.seek(0) - # PI FvHeader is 0x48 byte - FvHeaderBuffer = FvFileObj.read(0x48) - # FV alignment position. - FvAlignmentValue = 1 << (ord (FvHeaderBuffer[0x2E]) & 0x1F) - # FvAlignmentValue is larger than or equal to 1K - if FvAlignmentValue >= 0x400: - if FvAlignmentValue >= 0x100000: - #The max alignment supported by FFS is 16M. - if FvAlignmentValue >= 0x1000000: - self.FvAlignment = "16M" + Buffer.write(FvFileObj.read()) + FvFileObj.seek(0) + # PI FvHeader is 0x48 byte + FvHeaderBuffer = FvFileObj.read(0x48) + # FV alignment position. + FvAlignmentValue = 1 << (ord(FvHeaderBuffer[0x2E]) & 0x1F) + if FvAlignmentValue >= 0x400: + if FvAlignmentValue >= 0x100000: + if FvAlignmentValue >= 0x1000000: + #The max alignment supported by FFS is 16M. + self.FvAlignment = "16M" + else: + self.FvAlignment = str(FvAlignmentValue / 0x100000) + "M" else: - self.FvAlignment = str(FvAlignmentValue / 0x100000) + "M" + self.FvAlignment = str(FvAlignmentValue / 0x400) + "K" else: - self.FvAlignment = str (FvAlignmentValue / 0x400) + "K" + # FvAlignmentValue is less than 1K + self.FvAlignment = str (FvAlignmentValue) + FvFileObj.close() + GenFds.ImageBinDict[self.UiFvName.upper() + 'fv'] = FvOutputFile + GenFdsGlobalVariable.LargeFileInFvFlags.pop() else: - # FvAlignmentValue is less than 1K - self.FvAlignment = str (FvAlignmentValue) - FvFileObj.close() - GenFds.ImageBinDict[self.UiFvName.upper() + 'fv'] = FvOutputFile - GenFdsGlobalVariable.LargeFileInFvFlags.pop() - else: - GenFdsGlobalVariable.ErrorLogger("Failed to generate %s FV file." %self.UiFvName) + GenFdsGlobalVariable.ErrorLogger("Failed to generate %s FV file." %self.UiFvName) return FvOutputFile ## _GetBlockSize() diff --git a/BaseTools/Source/Python/GenFds/FvImageSection.py b/BaseTools/Source/Python/GenFds/FvImageSection.py index 68f17c31e8..916ff91917 100644 --- a/BaseTools/Source/Python/GenFds/FvImageSection.py +++ b/BaseTools/Source/Python/GenFds/FvImageSection.py @@ -50,7 +50,7 @@ class FvImageSection(FvImageSectionClassObject): # @param Dict dictionary contains macro and its value # @retval tuple (Generated file name, section alignment) # - def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = {}): + def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = {}, IsMakefile = False): OutputFileList = [] if self.FvFileType != None: @@ -75,7 +75,7 @@ class FvImageSection(FvImageSectionClassObject): MaxFvAlignment = FvAlignmentValue OutputFile = os.path.join(OutputPath, ModuleName + 'SEC' + Num + Ffs.SectionSuffix.get("FV_IMAGE")) - GenFdsGlobalVariable.GenerateSection(OutputFile, [FvFileName], 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE') + GenFdsGlobalVariable.GenerateSection(OutputFile, [FvFileName], 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE', IsMakefile=IsMakefile) OutputFileList.append(OutputFile) # MaxFvAlignment is larger than or equal to 1K @@ -101,7 +101,7 @@ class FvImageSection(FvImageSectionClassObject): Fv = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(self.FvName) if Fv != None: self.Fv = Fv - FvFileName = Fv.AddToBuffer(Buffer, self.FvAddr, MacroDict = Dict) + FvFileName = Fv.AddToBuffer(Buffer, self.FvAddr, MacroDict = Dict, Flag=IsMakefile) if Fv.FvAlignment != None: if self.Alignment == None: self.Alignment = Fv.FvAlignment @@ -139,7 +139,7 @@ class FvImageSection(FvImageSectionClassObject): # Prepare the parameter of GenSection # OutputFile = os.path.join(OutputPath, ModuleName + 'SEC' + SecNum + Ffs.SectionSuffix.get("FV_IMAGE")) - GenFdsGlobalVariable.GenerateSection(OutputFile, [FvFileName], 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE') + GenFdsGlobalVariable.GenerateSection(OutputFile, [FvFileName], 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE', IsMakefile=IsMakefile) OutputFileList.append(OutputFile) return OutputFileList, self.Alignment diff --git a/BaseTools/Source/Python/GenFds/GenFds.py b/BaseTools/Source/Python/GenFds/GenFds.py index c19dc40757..4a5d6f476a 100644 --- a/BaseTools/Source/Python/GenFds/GenFds.py +++ b/BaseTools/Source/Python/GenFds/GenFds.py @@ -99,6 +99,8 @@ def main(): GenFdsGlobalVariable.EdkSourceDir = os.path.normcase(os.environ['EDK_SOURCE']) if (Options.debug): GenFdsGlobalVariable.VerboseLogger("Using Workspace:" + Workspace) + if Options.GenfdsMultiThread: + GenFdsGlobalVariable.EnableGenfdsMultiThread = True os.chdir(GenFdsGlobalVariable.WorkSpaceDir) # set multiple workspace @@ -538,6 +540,7 @@ def myOptionParser(): Parser.add_option("--conf", action="store", type="string", dest="ConfDirectory", help="Specify the customized Conf directory.") Parser.add_option("--ignore-sources", action="store_true", dest="IgnoreSources", default=False, help="Focus to a binary build and ignore all source files") Parser.add_option("--pcd", action="append", dest="OptionPcd", help="Set PCD value by command line. Format: \"PcdName=Value\" ") + Parser.add_option("--genfds-multi-thread", action="store_true", dest="GenfdsMultiThread", default=False, help="Enable GenFds multi thread to generate ffs file.") (Options, args) = Parser.parse_args() return Options @@ -611,6 +614,23 @@ class GenFds : for DriverName in GenFdsGlobalVariable.FdfParser.Profile.OptRomDict.keys(): OptRomObj = GenFdsGlobalVariable.FdfParser.Profile.OptRomDict[DriverName] OptRomObj.AddToBuffer(None) + @staticmethod + def GenFfsMakefile(OutputDir, FdfParser, WorkSpace, ArchList, GlobalData): + GenFdsGlobalVariable.SetEnv(FdfParser, WorkSpace, ArchList, GlobalData) + for FdName in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys(): + FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[FdName] + FdObj.GenFd(Flag=True) + + for FvName in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys(): + FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict[FvName] + FvObj.AddToBuffer(Buffer=None, Flag=True) + + if GenFdsGlobalVariable.FdfParser.Profile.OptRomDict != {}: + for DriverName in GenFdsGlobalVariable.FdfParser.Profile.OptRomDict.keys(): + OptRomObj = GenFdsGlobalVariable.FdfParser.Profile.OptRomDict[DriverName] + OptRomObj.AddToBuffer(Buffer=None, Flag=True) + + return GenFdsGlobalVariable.FfsCmdDict ## GetFvBlockSize() # diff --git a/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py b/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py index 83996beeea..371d5a8217 100644 --- a/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py +++ b/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py @@ -69,6 +69,11 @@ class GenFdsGlobalVariable: ToolChainFamily = "MSFT" __BuildRuleDatabase = None GuidToolDefinition = {} + FfsCmdDict = {} + SecCmdList = [] + CopyList = [] + ModuleFile = '' + EnableGenfdsMultiThread = False # # The list whose element are flags to indicate if large FFS or SECTION files exist in FV. @@ -264,6 +269,10 @@ class GenFdsGlobalVariable: SourceList.extend(Target.Outputs) LastTarget = Target FileType = DataType.TAB_UNKNOWN_FILE + for Cmd in Target.Commands: + if "$(CP)" == Cmd.split()[0]: + CpTarget = Cmd.split()[2] + TargetList.add(CpTarget) return list(TargetList) @@ -317,6 +326,73 @@ class GenFdsGlobalVariable: FvAddressFile.close() + def SetEnv(FdfParser, WorkSpace, ArchList, GlobalData): + GenFdsGlobalVariable.ModuleFile = WorkSpace.ModuleFile + GenFdsGlobalVariable.FdfParser = FdfParser + GenFdsGlobalVariable.WorkSpace = WorkSpace.Db + GenFdsGlobalVariable.ArchList = ArchList + GenFdsGlobalVariable.ToolChainTag = GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"] + GenFdsGlobalVariable.TargetName = GlobalData.gGlobalDefines["TARGET"] + GenFdsGlobalVariable.ActivePlatform = GlobalData.gActivePlatform + GenFdsGlobalVariable.EdkSourceDir = GlobalData.gGlobalDefines["EDK_SOURCE"] + GenFdsGlobalVariable.ConfDir = GlobalData.gConfDirectory + GenFdsGlobalVariable.EnableGenfdsMultiThread = GlobalData.gEnableGenfdsMultiThread + for Arch in ArchList: + GenFdsGlobalVariable.OutputDirDict[Arch] = os.path.normpath( + os.path.join(GlobalData.gWorkspace, + WorkSpace.Db.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch,GlobalData.gGlobalDefines['TARGET'], + GlobalData.gGlobalDefines['TOOLCHAIN']].OutputDirectory, + GlobalData.gGlobalDefines['TARGET'] +'_' + GlobalData.gGlobalDefines['TOOLCHAIN'])) + GenFdsGlobalVariable.OutputDirFromDscDict[Arch] = os.path.normpath( + WorkSpace.Db.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, + GlobalData.gGlobalDefines['TARGET'], GlobalData.gGlobalDefines['TOOLCHAIN']].OutputDirectory) + GenFdsGlobalVariable.PlatformName = WorkSpace.Db.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, + GlobalData.gGlobalDefines['TARGET'], + GlobalData.gGlobalDefines['TOOLCHAIN']].PlatformName + 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) + + 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: + BsAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, + GlobalData.gGlobalDefines['TARGET'], + GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]].BsBaseAddress + if BsAddress: + 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, GlobalData.gGlobalDefines['TARGET'], + GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]].RtBaseAddress: + RtAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[ + GenFdsGlobalVariable.ActivePlatform, Arch, GlobalData.gGlobalDefines['TARGET'], + GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]].RtBaseAddress + + FvAddressFile.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \ + RtAddress + \ + T_CHAR_LF) + + FvAddressFile.close() + ## ReplaceWorkspaceMacro() # # @param String String that may contain macro @@ -363,7 +439,7 @@ class GenFdsGlobalVariable: @staticmethod def GenerateSection(Output, Input, Type=None, CompressionType=None, Guid=None, - GuidHdrLen=None, GuidAttr=[], Ui=None, Ver=None, InputAlign=None, BuildNumber=None): + GuidHdrLen=None, GuidAttr=[], Ui=None, Ver=None, InputAlign=None, BuildNumber=None, DummyFile=None, IsMakefile=False): Cmd = ["GenSec"] if Type not in [None, '']: Cmd += ["-s", Type] @@ -371,6 +447,8 @@ class GenFdsGlobalVariable: Cmd += ["-c", CompressionType] if Guid != None: Cmd += ["-g", Guid] + if DummyFile != None: + Cmd += ["--dummy", DummyFile] if GuidHdrLen not in [None, '']: Cmd += ["-l", GuidHdrLen] if len(GuidAttr) != 0: @@ -385,13 +463,21 @@ class GenFdsGlobalVariable: 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()) + if IsMakefile: + Cmd += ["-n", "$(MODULE_NAME)"] + Cmd += ["-o", Output] + #SaveFileOnChange(CommandFile, ' '.join(Cmd), False) + if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList: + GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip()) + else: + 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: @@ -399,22 +485,27 @@ class GenFdsGlobalVariable: Cmd += ["-o", Output] SaveFileOnChange(CommandFile, ' '.join(Cmd), False) - if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]): - return - - GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section") + if IsMakefile: + if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList: + GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip()) + else: + 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]): + if IsMakefile: + if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList: + GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip()) + elif GenFdsGlobalVariable.NeedsUpdate(Output, list(Input)): 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 + if (os.path.getsize(Output) >= GenFdsGlobalVariable.LARGE_FILE_SIZE and + GenFdsGlobalVariable.LargeFileInFvFlags): + GenFdsGlobalVariable.LargeFileInFvFlags[-1] = True @staticmethod def GetAlignment (AlignString): @@ -429,7 +520,7 @@ class GenFdsGlobalVariable: @staticmethod def GenerateFfs(Output, Input, Type, Guid, Fixed=False, CheckSum=False, Align=None, - SectionAlign=None): + SectionAlign=None, MakefilePath=None): Cmd = ["GenFfs", "-t", Type, "-g", Guid] mFfsValidAlign = ["0", "8", "16", "128", "512", "1K", "4K", "32K", "64K", "128K", "256K", "512K", "1M", "2M", "4M", "8M", "16M"] if Fixed == True: @@ -453,11 +544,17 @@ class GenFdsGlobalVariable: 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") + GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) + if MakefilePath: + if (tuple(Cmd),tuple(GenFdsGlobalVariable.SecCmdList),tuple(GenFdsGlobalVariable.CopyList)) not in GenFdsGlobalVariable.FfsCmdDict.keys(): + GenFdsGlobalVariable.FfsCmdDict[tuple(Cmd), tuple(GenFdsGlobalVariable.SecCmdList), tuple(GenFdsGlobalVariable.CopyList)] = MakefilePath + GenFdsGlobalVariable.SecCmdList = [] + GenFdsGlobalVariable.CopyList = [] + else: + if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input)): + return + GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FFS") @staticmethod def GenerateFirmwareVolume(Output, Input, BaseAddress=None, ForceRebase=None, Capsule=False, Dump=False, @@ -511,8 +608,8 @@ class GenFdsGlobalVariable: @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): + Align=None, Padding=None, Convert=False, IsMakefile=False): + if not GenFdsGlobalVariable.NeedsUpdate(Output, Input) and not IsMakefile: return GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) @@ -539,12 +636,15 @@ class GenFdsGlobalVariable: Cmd += ["-m"] Cmd += ["-o", Output] Cmd += Input - - GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate firmware image") + if IsMakefile: + if " ".join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList: + GenFdsGlobalVariable.SecCmdList.append(" ".join(Cmd).strip()) + else: + GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate firmware image") @staticmethod def GenerateOptionRom(Output, EfiInput, BinaryInput, Compress=False, ClassCode=None, - Revision=None, DeviceId=None, VendorId=None): + Revision=None, DeviceId=None, VendorId=None, IsMakefile=False): InputList = [] Cmd = ["EfiRom"] if len(EfiInput) > 0: @@ -565,7 +665,7 @@ class GenFdsGlobalVariable: InputList.append (BinFile) # Check List - if not GenFdsGlobalVariable.NeedsUpdate(Output, InputList): + if not GenFdsGlobalVariable.NeedsUpdate(Output, InputList) and not IsMakefile: return GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, InputList)) @@ -579,11 +679,15 @@ class GenFdsGlobalVariable: Cmd += ["-f", VendorId] Cmd += ["-o", Output] - GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate option rom") + if IsMakefile: + if " ".join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList: + GenFdsGlobalVariable.SecCmdList.append(" ".join(Cmd).strip()) + else: + GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate option rom") @staticmethod - def GuidTool(Output, Input, ToolPath, Options='', returnValue=[]): - if not GenFdsGlobalVariable.NeedsUpdate(Output, Input): + def GuidTool(Output, Input, ToolPath, Options='', returnValue=[], IsMakefile=False): + if not GenFdsGlobalVariable.NeedsUpdate(Output, Input) and not IsMakefile: return GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) @@ -591,8 +695,11 @@ class GenFdsGlobalVariable: Cmd += Options.split(' ') Cmd += ["-o", Output] Cmd += Input - - GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to call " + ToolPath, returnValue) + if IsMakefile: + if " ".join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList: + GenFdsGlobalVariable.SecCmdList.append(" ".join(Cmd).strip()) + else: + GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to call " + ToolPath, returnValue) def CallExternalTool (cmd, errorMess, returnValue=[]): @@ -727,6 +834,7 @@ class GenFdsGlobalVariable: return PcdValue SetDir = staticmethod(SetDir) + SetEnv = staticmethod(SetEnv) ReplaceWorkspaceMacro = staticmethod(ReplaceWorkspaceMacro) CallExternalTool = staticmethod(CallExternalTool) VerboseLogger = staticmethod(VerboseLogger) diff --git a/BaseTools/Source/Python/GenFds/GuidSection.py b/BaseTools/Source/Python/GenFds/GuidSection.py index f199dcd2cc..ea737bb9a7 100644 --- a/BaseTools/Source/Python/GenFds/GuidSection.py +++ b/BaseTools/Source/Python/GenFds/GuidSection.py @@ -1,7 +1,7 @@ ## @file # process GUIDed section generation # -# Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.
+# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.
# # This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License @@ -54,7 +54,7 @@ class GuidSection(GuidSectionClassObject) : # @param Dict dictionary contains macro and its value # @retval tuple (Generated file name, section alignment) # - def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf=None, Dict={}): + def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf=None, Dict={}, IsMakefile=False): # # Generate all section # @@ -94,7 +94,7 @@ class GuidSection(GuidSectionClassObject) : elif isinstance(Sect, GuidSection): Sect.FvAddr = self.FvAddr Sect.FvParentAddr = self.FvParentAddr - ReturnSectList, align = Sect.GenSection(OutputPath, ModuleName, SecIndex, KeyStringList, FfsInf, Dict) + ReturnSectList, align = Sect.GenSection(OutputPath, ModuleName, SecIndex, KeyStringList, FfsInf, Dict, IsMakefile=IsMakefile) if isinstance(Sect, GuidSection): if Sect.IncludeFvSection: self.IncludeFvSection = Sect.IncludeFvSection @@ -137,7 +137,7 @@ class GuidSection(GuidSectionClassObject) : # if self.NameGuid == None : GenFdsGlobalVariable.VerboseLogger("Use GenSection function Generate CRC32 Section") - GenFdsGlobalVariable.GenerateSection(OutputFile, SectFile, Section.Section.SectionType[self.SectionType], InputAlign=SectAlign) + GenFdsGlobalVariable.GenerateSection(OutputFile, SectFile, Section.Section.SectionType[self.SectionType], InputAlign=SectAlign, IsMakefile=IsMakefile) OutputFileList = [] OutputFileList.append(OutputFile) return OutputFileList, self.Alignment @@ -149,7 +149,7 @@ class GuidSection(GuidSectionClassObject) : # # Call GenSection with DUMMY section type. # - GenFdsGlobalVariable.GenerateSection(DummyFile, SectFile, InputAlign=SectAlign) + GenFdsGlobalVariable.GenerateSection(DummyFile, SectFile, InputAlign=SectAlign, IsMakefile=IsMakefile) # # Use external tool process the Output # @@ -172,75 +172,99 @@ class GuidSection(GuidSectionClassObject) : CmdOption = '-e' if ExternalOption != None: CmdOption = CmdOption + ' ' + ExternalOption - if self.ProcessRequired not in ("TRUE", "1") and self.IncludeFvSection and not FvAddrIsSet and self.FvParentAddr != None: - #FirstCall is only set for the encapsulated flash FV image without process required attribute. - FirstCall = True - # - # Call external tool - # - ReturnValue = [1] - if FirstCall: - #first try to call the guided tool with -z option and CmdOption for the no process required guided tool. - GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, '-z' + ' ' + CmdOption, ReturnValue) + if not GenFdsGlobalVariable.EnableGenfdsMultiThread: + if self.ProcessRequired not in ("TRUE", "1") and self.IncludeFvSection and not FvAddrIsSet and self.FvParentAddr != None: + #FirstCall is only set for the encapsulated flash FV image without process required attribute. + FirstCall = True + # + # Call external tool + # + ReturnValue = [1] + if FirstCall: + #first try to call the guided tool with -z option and CmdOption for the no process required guided tool. + GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, '-z' + ' ' + CmdOption, ReturnValue) - # - # when no call or first call failed, ReturnValue are not 1. - # Call the guided tool with CmdOption - # - if ReturnValue[0] != 0: - FirstCall = False - ReturnValue[0] = 0 - GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, CmdOption) - # - # There is external tool which does not follow standard rule which return nonzero if tool fails - # The output file has to be checked - # - if not os.path.exists(TempFile): - EdkLogger.error("GenFds", COMMAND_FAILURE, 'Fail to call %s, no output file was generated' % ExternalTool) - - FileHandleIn = open(DummyFile, 'rb') - FileHandleIn.seek(0, 2) - InputFileSize = FileHandleIn.tell() - - FileHandleOut = open(TempFile, 'rb') - FileHandleOut.seek(0, 2) - TempFileSize = FileHandleOut.tell() - - Attribute = [] - HeaderLength = None - if self.ExtraHeaderSize != -1: - HeaderLength = str(self.ExtraHeaderSize) - - if self.ProcessRequired == "NONE" and HeaderLength == None: - if TempFileSize > InputFileSize: - FileHandleIn.seek(0) - BufferIn = FileHandleIn.read() - FileHandleOut.seek(0) - BufferOut = FileHandleOut.read() - if BufferIn == BufferOut[TempFileSize - InputFileSize:]: - HeaderLength = str(TempFileSize - InputFileSize) - #auto sec guided attribute with process required - if HeaderLength == None: - Attribute.append('PROCESSING_REQUIRED') - - FileHandleIn.close() - FileHandleOut.close() - - if FirstCall and 'PROCESSING_REQUIRED' in Attribute: - # Guided data by -z option on first call is the process required data. Call the guided tool with the real option. - GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, CmdOption) + # + # when no call or first call failed, ReturnValue are not 1. + # Call the guided tool with CmdOption + # + if ReturnValue[0] != 0: + FirstCall = False + ReturnValue[0] = 0 + GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, CmdOption) + # + # There is external tool which does not follow standard rule which return nonzero if tool fails + # The output file has to be checked + # + + if not os.path.exists(TempFile) : + EdkLogger.error("GenFds", COMMAND_FAILURE, 'Fail to call %s, no output file was generated' % ExternalTool) + + FileHandleIn = open(DummyFile, 'rb') + FileHandleIn.seek(0, 2) + InputFileSize = FileHandleIn.tell() + + FileHandleOut = open(TempFile, 'rb') + FileHandleOut.seek(0, 2) + TempFileSize = FileHandleOut.tell() + + Attribute = [] + HeaderLength = None + if self.ExtraHeaderSize != -1: + HeaderLength = str(self.ExtraHeaderSize) + + if self.ProcessRequired == "NONE" and HeaderLength == None: + if TempFileSize > InputFileSize: + FileHandleIn.seek(0) + BufferIn = FileHandleIn.read() + FileHandleOut.seek(0) + BufferOut = FileHandleOut.read() + if BufferIn == BufferOut[TempFileSize - InputFileSize:]: + HeaderLength = str(TempFileSize - InputFileSize) + #auto sec guided attribute with process required + if HeaderLength == None: + Attribute.append('PROCESSING_REQUIRED') + + FileHandleIn.close() + FileHandleOut.close() + + if FirstCall and 'PROCESSING_REQUIRED' in Attribute: + # Guided data by -z option on first call is the process required data. Call the guided tool with the real option. + GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, CmdOption) + + # + # Call Gensection Add Section Header + # + if self.ProcessRequired in ("TRUE", "1"): + if 'PROCESSING_REQUIRED' not in Attribute: + Attribute.append('PROCESSING_REQUIRED') + + if self.AuthStatusValid in ("TRUE", "1"): + Attribute.append('AUTH_STATUS_VALID') + GenFdsGlobalVariable.GenerateSection(OutputFile, [TempFile], Section.Section.SectionType['GUIDED'], + Guid=self.NameGuid, GuidAttr=Attribute, GuidHdrLen=HeaderLength) + + else: + #add input file for GenSec get PROCESSING_REQUIRED + GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, CmdOption, IsMakefile=IsMakefile) + Attribute = [] + HeaderLength = None + if self.ExtraHeaderSize != -1: + HeaderLength = str(self.ExtraHeaderSize) + if self.AuthStatusValid in ("TRUE", "1"): + Attribute.append('AUTH_STATUS_VALID') + if self.ProcessRequired == "NONE" and HeaderLength == None: + GenFdsGlobalVariable.GenerateSection(OutputFile, [TempFile], Section.Section.SectionType['GUIDED'], + Guid=self.NameGuid, GuidAttr=Attribute, + GuidHdrLen=HeaderLength, DummyFile=DummyFile, IsMakefile=IsMakefile) + else: + if self.ProcessRequired in ("TRUE", "1"): + if 'PROCESSING_REQUIRED' not in Attribute: + Attribute.append('PROCESSING_REQUIRED') + GenFdsGlobalVariable.GenerateSection(OutputFile, [TempFile], Section.Section.SectionType['GUIDED'], + Guid=self.NameGuid, GuidAttr=Attribute, + GuidHdrLen=HeaderLength, IsMakefile=IsMakefile) - # - # Call Gensection Add Section Header - # - if self.ProcessRequired in ("TRUE", "1"): - if 'PROCESSING_REQUIRED' not in Attribute: - Attribute.append('PROCESSING_REQUIRED') - - if self.AuthStatusValid in ("TRUE", "1"): - Attribute.append('AUTH_STATUS_VALID') - GenFdsGlobalVariable.GenerateSection(OutputFile, [TempFile], Section.Section.SectionType['GUIDED'], - Guid=self.NameGuid, GuidAttr=Attribute, GuidHdrLen=HeaderLength) OutputFileList = [] OutputFileList.append(OutputFile) if 'PROCESSING_REQUIRED' in Attribute: diff --git a/BaseTools/Source/Python/GenFds/OptRomFileStatement.py b/BaseTools/Source/Python/GenFds/OptRomFileStatement.py index 5e3273d0f8..ab4fae611e 100644 --- a/BaseTools/Source/Python/GenFds/OptRomFileStatement.py +++ b/BaseTools/Source/Python/GenFds/OptRomFileStatement.py @@ -1,7 +1,7 @@ ## @file # process OptionROM generation from FILE statement # -# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.
+# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.
# # This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License @@ -39,7 +39,7 @@ class OptRomFileStatement: # @param Dict dictionary contains macro and value pair # @retval string Generated FFS file name # - def GenFfs(self, Dict = {}): + def GenFfs(self, Dict = {}, IsMakefile=False): if self.FileName != None: self.FileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FileName) diff --git a/BaseTools/Source/Python/GenFds/OptRomInfStatement.py b/BaseTools/Source/Python/GenFds/OptRomInfStatement.py index 069414df5b..80c4bbab6e 100644 --- a/BaseTools/Source/Python/GenFds/OptRomInfStatement.py +++ b/BaseTools/Source/Python/GenFds/OptRomInfStatement.py @@ -1,7 +1,7 @@ ## @file # process OptionROM generation from INF statement # -# Copyright (c) 2007, Intel Corporation. All rights reserved.
+# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.
# # This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License @@ -81,7 +81,7 @@ class OptRomInfStatement (FfsInfStatement): # @param self The object pointer # @retval string Generated .efi file name # - def GenFfs(self): + def GenFfs(self, IsMakefile=False): # # Parse Inf file get Module related information # @@ -98,13 +98,13 @@ class OptRomInfStatement (FfsInfStatement): # For the rule only has simpleFile # if isinstance (Rule, RuleSimpleFile.RuleSimpleFile) : - EfiOutputList = self.__GenSimpleFileSection__(Rule) + EfiOutputList = self.__GenSimpleFileSection__(Rule, IsMakefile=IsMakefile) return EfiOutputList # # For Rule has ComplexFile # elif isinstance(Rule, RuleComplexFile.RuleComplexFile): - EfiOutputList = self.__GenComplexFileSection__(Rule) + EfiOutputList = self.__GenComplexFileSection__(Rule, IsMakefile=IsMakefile) return EfiOutputList ## __GenSimpleFileSection__() method @@ -115,7 +115,7 @@ class OptRomInfStatement (FfsInfStatement): # @param Rule The rule object used to generate section # @retval string File name of the generated section file # - def __GenSimpleFileSection__(self, Rule): + def __GenSimpleFileSection__(self, Rule, IsMakefile = False): # # Prepare the parameter of GenSection # @@ -138,7 +138,7 @@ class OptRomInfStatement (FfsInfStatement): # @param Rule The rule object used to generate section # @retval string File name of the generated section file # - def __GenComplexFileSection__(self, Rule): + def __GenComplexFileSection__(self, Rule, IsMakefile=False): OutputFileList = [] for Sect in Rule.SectionList: diff --git a/BaseTools/Source/Python/GenFds/OptionRom.py b/BaseTools/Source/Python/GenFds/OptionRom.py index 7886a7cfe7..2e61a38c1d 100644 --- a/BaseTools/Source/Python/GenFds/OptionRom.py +++ b/BaseTools/Source/Python/GenFds/OptionRom.py @@ -1,7 +1,7 @@ ## @file # process OptionROM generation # -# Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.
+# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.
# # This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License @@ -49,9 +49,9 @@ class OPTIONROM (OptionRomClassObject): # @param Buffer The buffer generated OptROM data will be put # @retval string Generated OptROM file path # - def AddToBuffer (self, Buffer) : - - GenFdsGlobalVariable.InfLogger( "\nGenerating %s Option ROM ..." %self.DriverName) + def AddToBuffer (self, Buffer, Flag=False) : + if not Flag: + GenFdsGlobalVariable.InfLogger( "\nGenerating %s Option ROM ..." %self.DriverName) EfiFileList = [] BinFileList = [] @@ -60,7 +60,7 @@ class OPTIONROM (OptionRomClassObject): for FfsFile in self.FfsList : if isinstance(FfsFile, OptRomInfStatement.OptRomInfStatement): - FilePathNameList = FfsFile.GenFfs() + FilePathNameList = FfsFile.GenFfs(IsMakefile=Flag) if len(FilePathNameList) == 0: EdkLogger.error("GenFds", GENFDS_ERROR, "Module %s not produce .efi files, so NO file could be put into option ROM." % (FfsFile.InfFileName)) if FfsFile.OverrideAttribs == None: @@ -79,10 +79,11 @@ class OPTIONROM (OptionRomClassObject): FfsFile.OverrideAttribs.PciClassCode, FfsFile.OverrideAttribs.PciRevision, FfsFile.OverrideAttribs.PciDeviceId, - FfsFile.OverrideAttribs.PciVendorId) + FfsFile.OverrideAttribs.PciVendorId, + IsMakefile = Flag) BinFileList.append(TmpOutputFile) else: - FilePathName = FfsFile.GenFfs() + FilePathName = FfsFile.GenFfs(IsMakefile=Flag) if FfsFile.OverrideAttribs != None: FileName = os.path.basename(FilePathName) TmpOutputDir = os.path.join(GenFdsGlobalVariable.FvDir, self.DriverName, FfsFile.CurrentArch) @@ -97,7 +98,8 @@ class OPTIONROM (OptionRomClassObject): FfsFile.OverrideAttribs.PciClassCode, FfsFile.OverrideAttribs.PciRevision, FfsFile.OverrideAttribs.PciDeviceId, - FfsFile.OverrideAttribs.PciVendorId) + FfsFile.OverrideAttribs.PciVendorId, + IsMakefile=Flag) BinFileList.append(TmpOutputFile) else: if FfsFile.FileType == 'EFI': @@ -114,10 +116,11 @@ class OPTIONROM (OptionRomClassObject): GenFdsGlobalVariable.GenerateOptionRom( OutputFile, EfiFileList, - BinFileList - ) + BinFileList, + IsMakefile=Flag) - GenFdsGlobalVariable.InfLogger( "\nGenerate %s Option ROM Successfully" %self.DriverName) + if not Flag: + GenFdsGlobalVariable.InfLogger( "\nGenerate %s Option ROM Successfully" %self.DriverName) GenFdsGlobalVariable.SharpCounter = 0 return OutputFile diff --git a/BaseTools/Source/Python/GenFds/Region.py b/BaseTools/Source/Python/GenFds/Region.py index 945c5489fd..c946758cf5 100644 --- a/BaseTools/Source/Python/GenFds/Region.py +++ b/BaseTools/Source/Python/GenFds/Region.py @@ -1,7 +1,7 @@ ## @file # process FD Region generation # -# Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.
+# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.
# # This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License @@ -74,11 +74,14 @@ class Region(RegionClassObject): # @retval string Generated FV file path # - def AddToBuffer(self, Buffer, BaseAddress, BlockSizeList, ErasePolarity, ImageBinDict, vtfDict=None, MacroDict={}): + def AddToBuffer(self, Buffer, BaseAddress, BlockSizeList, ErasePolarity, ImageBinDict, vtfDict=None, MacroDict={}, Flag=False): Size = self.Size - GenFdsGlobalVariable.InfLogger('\nGenerate Region at Offset 0x%X' % self.Offset) - GenFdsGlobalVariable.InfLogger(" Region Size = 0x%X" % Size) + if not Flag: + GenFdsGlobalVariable.InfLogger('\nGenerate Region at Offset 0x%X' % self.Offset) + GenFdsGlobalVariable.InfLogger(" Region Size = 0x%X" % Size) GenFdsGlobalVariable.SharpCounter = 0 + if Flag and (self.RegionType != 'FV'): + return if self.RegionType == 'FV': # @@ -91,7 +94,8 @@ class Region(RegionClassObject): FileName = None if RegionData.endswith(".fv"): RegionData = GenFdsGlobalVariable.MacroExtend(RegionData, MacroDict) - GenFdsGlobalVariable.InfLogger(' Region FV File Name = .fv : %s' % RegionData) + if not Flag: + GenFdsGlobalVariable.InfLogger(' Region FV File Name = .fv : %s' % RegionData) if RegionData[1] != ':' : RegionData = mws.join (GenFdsGlobalVariable.WorkSpaceDir, RegionData) if not os.path.exists(RegionData): @@ -99,7 +103,8 @@ class Region(RegionClassObject): FileName = RegionData elif RegionData.upper() + 'fv' in ImageBinDict.keys(): - GenFdsGlobalVariable.InfLogger(' Region Name = FV') + if not Flag: + GenFdsGlobalVariable.InfLogger(' Region Name = FV') FileName = ImageBinDict[RegionData.upper() + 'fv'] else: # @@ -110,7 +115,8 @@ class Region(RegionClassObject): FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(RegionData.upper()) if FvObj != None : - GenFdsGlobalVariable.InfLogger(' Region Name = FV') + if not Flag: + GenFdsGlobalVariable.InfLogger(' Region Name = FV') # # Call GenFv tool # @@ -124,7 +130,10 @@ class Region(RegionClassObject): FvBaseAddress = '0x%X' % self.FvAddress BlockSize = None BlockNum = None - FvObj.AddToBuffer(FvBuffer, FvBaseAddress, BlockSize, BlockNum, ErasePolarity, vtfDict) + FvObj.AddToBuffer(FvBuffer, FvBaseAddress, BlockSize, BlockNum, ErasePolarity, vtfDict, Flag=Flag) + if Flag: + continue + if FvBuffer.len > Size: FvBuffer.close() EdkLogger.error("GenFds", GENFDS_ERROR, @@ -142,20 +151,22 @@ class Region(RegionClassObject): # # Add the exist Fv image into FD buffer # - if FileName != None: - FileLength = os.stat(FileName)[ST_SIZE] - if FileLength > Size: - EdkLogger.error("GenFds", GENFDS_ERROR, - "Size of FV File (%s) is larger than Region Size 0x%X specified." \ - % (RegionData, Size)) - BinFile = open(FileName, 'rb') - Buffer.write(BinFile.read()) - BinFile.close() - Size = Size - FileLength + if not Flag: + if FileName != None: + FileLength = os.stat(FileName)[ST_SIZE] + if FileLength > Size: + EdkLogger.error("GenFds", GENFDS_ERROR, + "Size of FV File (%s) is larger than Region Size 0x%X specified." \ + % (RegionData, Size)) + BinFile = open(FileName, 'rb') + Buffer.write(BinFile.read()) + BinFile.close() + Size = Size - FileLength # # Pad the left buffer # - self.PadBuffer(Buffer, ErasePolarity, Size) + if not Flag: + self.PadBuffer(Buffer, ErasePolarity, Size) if self.RegionType == 'CAPSULE': # diff --git a/BaseTools/Source/Python/GenFds/Section.py b/BaseTools/Source/Python/GenFds/Section.py index 942dd5cd3a..4c1aaacd68 100644 --- a/BaseTools/Source/Python/GenFds/Section.py +++ b/BaseTools/Source/Python/GenFds/Section.py @@ -1,7 +1,7 @@ ## @file # section base class # -# Copyright (c) 2007-2015, Intel Corporation. All rights reserved.
+# Copyright (c) 2007-2017, Intel Corporation. All rights reserved.
# # This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License @@ -141,7 +141,7 @@ class Section (SectionClassObject): else: GenFdsGlobalVariable.InfLogger ("\nCurrent ARCH \'%s\' of File %s is not in the Support Arch Scope of %s specified by INF %s in FDF" %(FfsInf.CurrentArch, File.File, File.Arch, FfsInf.InfFileName)) - if Suffix != None and os.path.exists(FfsInf.EfiOutputPath): + if Suffix != None: # # Get Makefile path and time stamp # diff --git a/BaseTools/Source/Python/GenFds/UiSection.py b/BaseTools/Source/Python/GenFds/UiSection.py index 419e1ee358..4f6926f7ca 100644 --- a/BaseTools/Source/Python/GenFds/UiSection.py +++ b/BaseTools/Source/Python/GenFds/UiSection.py @@ -48,7 +48,7 @@ class UiSection (UiSectionClassObject): # @param Dict dictionary contains macro and its value # @retval tuple (Generated file name, section alignment) # - def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf=None, Dict={}): + def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf=None, Dict={}, IsMakefile = False): # # Prepare the parameter of GenSection # @@ -69,8 +69,7 @@ class UiSection (UiSectionClassObject): FileObj.close() else: NameString = '' - - GenFdsGlobalVariable.GenerateSection(OutputFile, None, 'EFI_SECTION_USER_INTERFACE', Ui=NameString) + GenFdsGlobalVariable.GenerateSection(OutputFile, None, 'EFI_SECTION_USER_INTERFACE', Ui=NameString, IsMakefile=IsMakefile) OutputFileList = [] OutputFileList.append(OutputFile) diff --git a/BaseTools/Source/Python/GenFds/VerSection.py b/BaseTools/Source/Python/GenFds/VerSection.py index ad995d314b..e29029980f 100644 --- a/BaseTools/Source/Python/GenFds/VerSection.py +++ b/BaseTools/Source/Python/GenFds/VerSection.py @@ -1,7 +1,7 @@ ## @file # process Version section generation # -# Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.
+# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.
# # This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License @@ -48,7 +48,7 @@ class VerSection (VerSectionClassObject): # @param Dict dictionary contains macro and its value # @retval tuple (Generated file name, section alignment) # - def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf=None, Dict={}): + def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf=None, Dict={}, IsMakefile = False): # # Prepare the parameter of GenSection # @@ -65,7 +65,7 @@ class VerSection (VerSectionClassObject): # Get String Data StringData = '' if self.StringData != None: - StringData = self.StringData + StringData = self.StringData elif self.FileName != None: FileNameStr = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FileName) FileNameStr = GenFdsGlobalVariable.MacroExtend(FileNameStr, Dict) @@ -75,9 +75,8 @@ class VerSection (VerSectionClassObject): FileObj.close() else: StringData = '' - GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_VERSION', - Ver=StringData, BuildNumber=self.BuildNum) + Ver=StringData, BuildNumber=self.BuildNum, IsMakefile=IsMakefile) OutputFileList = [] OutputFileList.append(OutputFile) return OutputFileList, self.Alignment diff --git a/BaseTools/Source/Python/build/build.py b/BaseTools/Source/Python/build/build.py index 53f12457f8..f94285a964 100644 --- a/BaseTools/Source/Python/build/build.py +++ b/BaseTools/Source/Python/build/build.py @@ -50,6 +50,7 @@ from PatchPcdValue.PatchPcdValue import * import Common.EdkLogger import Common.GlobalData as GlobalData +from GenFds.GenFds import GenFds # Version and Copyright VersionNumber = "0.60" + ' ' + gBUILD_VERSION @@ -774,6 +775,7 @@ class Build(): GlobalData.gUseHashCache = BuildOptions.UseHashCache GlobalData.gBinCacheDest = BuildOptions.BinCacheDest GlobalData.gBinCacheSource = BuildOptions.BinCacheSource + GlobalData.gEnableGenfdsMultiThread = BuildOptions.GenfdsMultiThread if GlobalData.gBinCacheDest and not GlobalData.gUseHashCache: EdkLogger.error("build", OPTION_NOT_SUPPORTED, ExtraData="--binary-destination must be used together with --hash.") @@ -1208,7 +1210,7 @@ class Build(): # @param CreateDepModuleMakeFile Flag used to indicate creating makefile # for dependent modules/Libraries # - def _BuildPa(self, Target, AutoGenObject, CreateDepsCodeFile=True, CreateDepsMakeFile=True, BuildModule=False): + def _BuildPa(self, Target, AutoGenObject, CreateDepsCodeFile=True, CreateDepsMakeFile=True, BuildModule=False, FfsCommand={}): if AutoGenObject == None: return False @@ -1224,7 +1226,7 @@ class Build(): if not self.SkipAutoGen or Target == 'genmake': self.Progress.Start("Generating makefile") - AutoGenObject.CreateMakeFile(CreateDepsMakeFile) + AutoGenObject.CreateMakeFile(CreateDepsMakeFile, FfsCommand) self.Progress.Stop("done!") if Target == "genmake": return True @@ -1731,6 +1733,12 @@ class Build(): self.LoadFixAddress = Wa.Platform.LoadFixAddress self.BuildReport.AddPlatformReport(Wa) self.Progress.Stop("done!") + + # Add ffs build to makefile + CmdListDict = {} + if GlobalData.gEnableGenfdsMultiThread and self.Fdf: + CmdListDict = self._GenFfsCmd() + for Arch in Wa.ArchList: GlobalData.gGlobalDefines['ARCH'] = Arch Pa = PlatformAutoGen(Wa, self.PlatformFile, BuildTarget, ToolChain, Arch) @@ -1740,7 +1748,7 @@ class Build(): if Ma == None: continue self.BuildModules.append(Ma) - self._BuildPa(self.Target, Pa) + self._BuildPa(self.Target, Pa, FfsCommand=CmdListDict) # Create MAP file when Load Fix Address is enabled. if self.Target in ["", "all", "fds"]: @@ -1819,6 +1827,10 @@ class Build(): self.Fdf = Wa.FdfFile self.LoadFixAddress = Wa.Platform.LoadFixAddress Wa.CreateMakeFile(False) + # Add ffs build to makefile + CmdListDict = None + if GlobalData.gEnableGenfdsMultiThread and self.Fdf: + CmdListDict = self._GenFfsCmd() self.Progress.Stop("done!") MaList = [] ExitFlag = threading.Event() @@ -1838,7 +1850,11 @@ class Build(): if not self.SkipAutoGen or self.Target == 'genc': Ma.CreateCodeFile(True) if not self.SkipAutoGen or self.Target == 'genmake': - Ma.CreateMakeFile(True) + if CmdListDict and self.Fdf and (Module.File, Arch) in CmdListDict: + Ma.CreateMakeFile(True, CmdListDict[Module.File, Arch]) + del CmdListDict[Module.File, Arch] + else: + Ma.CreateMakeFile(True) MaList.append(Ma) self.BuildModules.append(Ma) self.AutoGenTime += int(round((time.time() - AutoGenStart))) @@ -1922,6 +1938,17 @@ class Build(): # self._SaveMapFile (MapBuffer, Wa) + def _GenFfsCmd(self): + CmdListDict = {} + GenFfsDict = GenFds.GenFfsMakefile('', GlobalData.gFdfParser, self, self.ArchList, GlobalData) + for Cmd in GenFfsDict: + tmpInf, tmpArch = GenFfsDict[Cmd] + if (tmpInf, tmpArch) not in CmdListDict.keys(): + CmdListDict[tmpInf, tmpArch] = [Cmd] + else: + CmdListDict[tmpInf, tmpArch].append(Cmd) + return CmdListDict + ## Build a platform in multi-thread mode # def _MultiThreadBuildPlatform(self): @@ -1957,6 +1984,11 @@ class Build(): self.BuildReport.AddPlatformReport(Wa) Wa.CreateMakeFile(False) + # Add ffs build to makefile + CmdListDict = None + if GlobalData.gEnableGenfdsMultiThread and self.Fdf: + CmdListDict = self._GenFfsCmd() + # multi-thread exit flag ExitFlag = threading.Event() ExitFlag.clear() @@ -1995,7 +2027,11 @@ class Build(): continue if not self.SkipAutoGen or self.Target == 'genmake': - Ma.CreateMakeFile(True) + if CmdListDict and self.Fdf and (Module.File, Arch) in CmdListDict: + Ma.CreateMakeFile(True, CmdListDict[Module.File, Arch]) + del CmdListDict[Module.File, Arch] + else: + Ma.CreateMakeFile(True) if self.Target == "genmake": continue self.BuildModules.append(Ma) @@ -2311,7 +2347,7 @@ def MyOptionParser(): Parser.add_option("--hash", action="store_true", dest="UseHashCache", default=False, help="Enable hash-based caching during build process.") Parser.add_option("--binary-destination", action="store", type="string", dest="BinCacheDest", help="Generate a cache of binary files in the specified directory.") Parser.add_option("--binary-source", action="store", type="string", dest="BinCacheSource", help="Consume a cache of binary files from the specified directory.") - + Parser.add_option("--genfds-multi-thread", action="store_true", dest="GenfdsMultiThread", default=False, help="Enable GenFds multi thread to generate ffs file.") (Opt, Args) = Parser.parse_args() return (Opt, Args) -- 2.39.2