X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=BaseTools%2FSource%2FPython%2FGenFds%2FGenFds.py;h=810a1f86e948943372199c75c8ab5eb729621052;hp=277da357af0164b75584c347ddc570eb51f4853b;hb=066c71544ed1c0e1a703b26982f9da60d21bcc5a;hpb=db55dac77579fa2722e4457bfc4369f98b8ff52a
diff --git a/BaseTools/Source/Python/GenFds/GenFds.py b/BaseTools/Source/Python/GenFds/GenFds.py
index 277da357af..810a1f86e9 100644
--- a/BaseTools/Source/Python/GenFds/GenFds.py
+++ b/BaseTools/Source/Python/GenFds/GenFds.py
@@ -1,7 +1,7 @@
## @file
# generate flash image
#
-# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.
+# Copyright (c) 2007 - 2018, 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
@@ -24,7 +24,6 @@ import Common.BuildToolError as BuildToolError
from GenFdsGlobalVariable import GenFdsGlobalVariable
from Workspace.WorkspaceDatabase import WorkspaceDatabase
from Workspace.BuildClassObject import PcdClassObject
-from Workspace.BuildClassObject import ModuleBuildClassObject
import RuleComplexFile
from EfiSection import EfiSection
import StringIO
@@ -38,10 +37,11 @@ from Common.Misc import DirCache, PathClass
from Common.Misc import SaveFileOnChange
from Common.Misc import ClearDuplicatedInf
from Common.Misc import GuidStructureStringToGuidString
-from Common.Misc import CheckPcdDatum
-from Common.Misc import BuildOptionPcdValueFormat
from Common.BuildVersion import gBUILD_VERSION
from Common.MultipleWorkspace import MultipleWorkspace as mws
+import FfsFileStatement
+import glob
+from struct import unpack
## Version and Copyright
versionNumber = "1.0" + ' ' + gBUILD_VERSION
@@ -68,22 +68,22 @@ def main():
EdkLogger.Initialize()
try:
- if Options.verbose != None:
+ if Options.verbose is not None:
EdkLogger.SetLevel(EdkLogger.VERBOSE)
GenFdsGlobalVariable.VerboseMode = True
- if Options.FixedAddress != None:
+ if Options.FixedAddress is not None:
GenFdsGlobalVariable.FixedLoadAddress = True
- if Options.quiet != None:
+ if Options.quiet is not None:
EdkLogger.SetLevel(EdkLogger.QUIET)
- if Options.debug != None:
+ if Options.debug is not None:
EdkLogger.SetLevel(Options.debug + 1)
GenFdsGlobalVariable.DebugLevel = Options.debug
else:
EdkLogger.SetLevel(EdkLogger.INFO)
- if (Options.Workspace == None):
+ if (Options.Workspace is None):
EdkLogger.error("GenFds", OPTION_MISSING, "WORKSPACE not defined",
ExtraData="Please use '-w' switch to pass it or set the WORKSPACE environment variable.")
elif not os.path.exists(Options.Workspace):
@@ -96,6 +96,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
@@ -139,6 +141,7 @@ def main():
else:
EdkLogger.error("GenFds", OPTION_MISSING, "Missing active platform")
+ GlobalData.BuildOptionPcd = Options.OptionPcd if Options.OptionPcd else {}
GenFdsGlobalVariable.ActivePlatform = PathClass(NormPath(ActivePlatform))
if (Options.ConfDirectory):
@@ -159,6 +162,8 @@ def main():
# Get standard WORKSPACE/Conf, use the absolute path to the WORKSPACE/Conf
ConfDirectoryPath = mws.join(GenFdsGlobalVariable.WorkSpaceDir, 'Conf')
GenFdsGlobalVariable.ConfDir = ConfDirectoryPath
+ if not GlobalData.gConfDirectory:
+ GlobalData.gConfDirectory = GenFdsGlobalVariable.ConfDir
BuildConfigurationFile = os.path.normpath(os.path.join(ConfDirectoryPath, "target.txt"))
if os.path.isfile(BuildConfigurationFile) == True:
TargetTxt = TargetTxtClassObject.TargetTxtClassObject()
@@ -173,7 +178,7 @@ def main():
# if no tool chain given in command line, get it from target.txt
if not GenFdsGlobalVariable.ToolChainTag:
ToolChainList = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_TAG]
- if ToolChainList == None or len(ToolChainList) == 0:
+ if ToolChainList is None or len(ToolChainList) == 0:
EdkLogger.error("GenFds", RESOURCE_NOT_AVAILABLE, ExtraData="No toolchain given. Don't know how to build.")
if len(ToolChainList) != 1:
EdkLogger.error("GenFds", OPTION_VALUE_INVALID, ExtraData="Only allows one instance for ToolChain.")
@@ -294,12 +299,10 @@ def main():
"No such a Capsule in FDF file: %s" % Options.uiCapName)
GenFdsGlobalVariable.WorkSpace = BuildWorkSpace
- if ArchList != None:
+ if ArchList is not None:
GenFdsGlobalVariable.ArchList = ArchList
- if Options.OptionPcd:
- GlobalData.BuildOptionPcd = Options.OptionPcd
- CheckBuildOptionPcd()
+ # Dsc Build Data will handle Pcd Settings from CommandLine.
"""Modify images from build output if the feature of loading driver at fixed address is on."""
if GenFdsGlobalVariable.FixedLoadAddress:
@@ -327,7 +330,7 @@ def main():
GenFds.GenFd('', FdfParserObj, BuildWorkSpace, ArchList)
"""Generate GUID cross reference file"""
- GenFds.GenerateGuidXRefFile(BuildWorkSpace, ArchList)
+ GenFds.GenerateGuidXRefFile(BuildWorkSpace, ArchList, FdfParserObj)
"""Display FV space info."""
GenFds.DisplayFvSpaceInfo(FdfParserObj)
@@ -336,7 +339,7 @@ def main():
EdkLogger.error(X.ToolName, FORMAT_INVALID, File=X.FileName, Line=X.LineNumber, ExtraData=X.Message, RaiseError=False)
ReturnCode = FORMAT_INVALID
except FatalError, X:
- if Options.debug != None:
+ if Options.debug is not None:
import traceback
EdkLogger.quiet(traceback.format_exc())
ReturnCode = X.args[0]
@@ -363,53 +366,6 @@ def SingleCheckCallback(option, opt_str, value, parser):
else:
parser.error("Option %s only allows one instance in command line!" % option)
-def CheckBuildOptionPcd():
- for Arch in GenFdsGlobalVariable.ArchList:
- PkgList = GenFdsGlobalVariable.WorkSpace.GetPackageList(GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag)
- for i, pcd in enumerate(GlobalData.BuildOptionPcd):
- if type(pcd) is tuple:
- continue
- (pcdname, pcdvalue) = pcd.split('=')
- if not pcdvalue:
- EdkLogger.error('GenFds', OPTION_MISSING, "No Value specified for the PCD %s." % (pcdname))
- if '.' in pcdname:
- (TokenSpaceGuidCName, TokenCName) = pcdname.split('.')
- HasTokenSpace = True
- else:
- TokenCName = pcdname
- TokenSpaceGuidCName = ''
- HasTokenSpace = False
- TokenSpaceGuidCNameList = []
- FoundFlag = False
- PcdDatumType = ''
- NewValue = ''
- for package in PkgList:
- for key in package.Pcds:
- PcdItem = package.Pcds[key]
- if HasTokenSpace:
- if (PcdItem.TokenCName, PcdItem.TokenSpaceGuidCName) == (TokenCName, TokenSpaceGuidCName):
- PcdDatumType = PcdItem.DatumType
- NewValue = BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)
- FoundFlag = True
- else:
- if PcdItem.TokenCName == TokenCName:
- if not PcdItem.TokenSpaceGuidCName in TokenSpaceGuidCNameList:
- if len (TokenSpaceGuidCNameList) < 1:
- TokenSpaceGuidCNameList.append(PcdItem.TokenSpaceGuidCName)
- PcdDatumType = PcdItem.DatumType
- TokenSpaceGuidCName = PcdItem.TokenSpaceGuidCName
- NewValue = BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)
- FoundFlag = True
- else:
- EdkLogger.error(
- 'GenFds',
- PCD_VALIDATION_INFO_ERROR,
- "The Pcd %s is found under multiple different TokenSpaceGuid: %s and %s." % (TokenCName, PcdItem.TokenSpaceGuidCName, TokenSpaceGuidCNameList[0])
- )
-
- GlobalData.BuildOptionPcd[i] = (TokenSpaceGuidCName, TokenCName, NewValue)
-
-
## FindExtendTool()
#
# Find location of tools to process data
@@ -421,7 +377,7 @@ def CheckBuildOptionPcd():
def FindExtendTool(KeyStringList, CurrentArchList, NameGuid):
ToolDb = ToolDefClassObject.ToolDefDict(GenFdsGlobalVariable.ConfDir).ToolsDefTxtDatabase
# if user not specify filter, try to deduce it from global data.
- if KeyStringList == None or KeyStringList == []:
+ if KeyStringList is None or KeyStringList == []:
Target = GenFdsGlobalVariable.TargetName
ToolChain = GenFdsGlobalVariable.ToolChainTag
if ToolChain not in ToolDb['TOOL_CHAIN_TAG']:
@@ -442,7 +398,7 @@ def FindExtendTool(KeyStringList, CurrentArchList, NameGuid):
ToolOptionKey = None
KeyList = None
for ToolDef in ToolDefinition.items():
- if NameGuid == ToolDef[1]:
+ if NameGuid.lower() == ToolDef[1].lower() :
KeyList = ToolDef[0].split('_')
Key = KeyList[0] + \
'_' + \
@@ -454,7 +410,7 @@ def FindExtendTool(KeyStringList, CurrentArchList, NameGuid):
ToolOptionKey = Key + '_' + KeyList[3] + '_FLAGS'
ToolPath = ToolDefinition.get(ToolPathKey)
ToolOption = ToolDefinition.get(ToolOptionKey)
- if ToolPathTmp == None:
+ if ToolPathTmp is None:
ToolPathTmp = ToolPath
else:
if ToolPathTmp != ToolPath:
@@ -535,6 +491,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
@@ -565,38 +522,38 @@ class GenFds :
GenFdsGlobalVariable.SetDir ('', FdfParser, WorkSpace, ArchList)
GenFdsGlobalVariable.VerboseLogger(" Generate all Fd images and their required FV and Capsule images!")
- if GenFds.OnlyGenerateThisCap != None and GenFds.OnlyGenerateThisCap.upper() in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.keys():
+ if GenFds.OnlyGenerateThisCap is not None and GenFds.OnlyGenerateThisCap.upper() in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.keys():
CapsuleObj = GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.get(GenFds.OnlyGenerateThisCap.upper())
- if CapsuleObj != None:
+ if CapsuleObj is not None:
CapsuleObj.GenCapsule()
return
- if GenFds.OnlyGenerateThisFd != None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():
+ if GenFds.OnlyGenerateThisFd is not None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():
FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict.get(GenFds.OnlyGenerateThisFd.upper())
- if FdObj != None:
+ if FdObj is not None:
FdObj.GenFd()
return
- elif GenFds.OnlyGenerateThisFd == None and GenFds.OnlyGenerateThisFv == None:
+ elif GenFds.OnlyGenerateThisFd is None and GenFds.OnlyGenerateThisFv is None:
for FdName in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():
FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[FdName]
FdObj.GenFd()
GenFdsGlobalVariable.VerboseLogger("\n Generate other FV images! ")
- if GenFds.OnlyGenerateThisFv != None and GenFds.OnlyGenerateThisFv.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():
+ if GenFds.OnlyGenerateThisFv is not None and GenFds.OnlyGenerateThisFv.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():
FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(GenFds.OnlyGenerateThisFv.upper())
- if FvObj != None:
+ if FvObj is not None:
Buffer = StringIO.StringIO()
FvObj.AddToBuffer(Buffer)
Buffer.close()
return
- elif GenFds.OnlyGenerateThisFv == None:
+ elif GenFds.OnlyGenerateThisFv is None:
for FvName in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():
Buffer = StringIO.StringIO('')
FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict[FvName]
FvObj.AddToBuffer(Buffer)
Buffer.close()
- if GenFds.OnlyGenerateThisFv == None and GenFds.OnlyGenerateThisFd == None and GenFds.OnlyGenerateThisCap == None:
+ if GenFds.OnlyGenerateThisFv is None and GenFds.OnlyGenerateThisFd is None and GenFds.OnlyGenerateThisCap is None:
if GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict != {}:
GenFdsGlobalVariable.VerboseLogger("\n Generate other Capsule images!")
for CapsuleName in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.keys():
@@ -608,6 +565,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()
#
@@ -617,14 +591,14 @@ class GenFds :
def GetFvBlockSize(FvObj):
DefaultBlockSize = 0x1
FdObj = None
- if GenFds.OnlyGenerateThisFd != None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():
+ if GenFds.OnlyGenerateThisFd is not None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():
FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[GenFds.OnlyGenerateThisFd.upper()]
- if FdObj == None:
+ if FdObj is None:
for ElementFd in GenFdsGlobalVariable.FdfParser.Profile.FdDict.values():
for ElementRegion in ElementFd.RegionList:
if ElementRegion.RegionType == 'FV':
for ElementRegionData in ElementRegion.RegionDataList:
- if ElementRegionData != None and ElementRegionData.upper() == FvObj.UiFvName:
+ if ElementRegionData is not None and ElementRegionData.upper() == FvObj.UiFvName:
if FvObj.BlockSizeList != []:
return FvObj.BlockSizeList[0][0]
else:
@@ -636,7 +610,7 @@ class GenFds :
for ElementRegion in FdObj.RegionList:
if ElementRegion.RegionType == 'FV':
for ElementRegionData in ElementRegion.RegionDataList:
- if ElementRegionData != None and ElementRegionData.upper() == FvObj.UiFvName:
+ if ElementRegionData is not None and ElementRegionData.upper() == FvObj.UiFvName:
if FvObj.BlockSizeList != []:
return FvObj.BlockSizeList[0][0]
else:
@@ -724,14 +698,20 @@ class GenFds :
ModuleObj = BuildDb.BuildObject[Key, 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
print ModuleObj.BaseName + ' ' + ModuleObj.ModuleType
- def GenerateGuidXRefFile(BuildDb, ArchList):
+ def GenerateGuidXRefFile(BuildDb, ArchList, FdfParserObj):
GuidXRefFileName = os.path.join(GenFdsGlobalVariable.FvDir, "Guid.xref")
GuidXRefFile = StringIO.StringIO('')
GuidDict = {}
+ ModuleList = []
+ FileGuidList = []
for Arch in ArchList:
PlatformDataBase = BuildDb.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
for ModuleFile in PlatformDataBase.Modules:
Module = BuildDb.BuildObject[ModuleFile, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
+ if Module in ModuleList:
+ continue
+ else:
+ ModuleList.append(Module)
GuidXRefFile.write("%s %s\n" % (Module.Guid, Module.BaseName))
for key, item in Module.Protocols.items():
GuidDict[key] = item
@@ -739,6 +719,81 @@ class GenFds :
GuidDict[key] = item
for key, item in Module.Ppis.items():
GuidDict[key] = item
+ for FvName in FdfParserObj.Profile.FvDict:
+ for FfsObj in FdfParserObj.Profile.FvDict[FvName].FfsList:
+ if not isinstance(FfsObj, FfsFileStatement.FileStatement):
+ InfPath = PathClass(NormPath(mws.join(GenFdsGlobalVariable.WorkSpaceDir, FfsObj.InfFileName)))
+ FdfModule = BuildDb.BuildObject[InfPath, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
+ if FdfModule in ModuleList:
+ continue
+ else:
+ ModuleList.append(FdfModule)
+ GuidXRefFile.write("%s %s\n" % (FdfModule.Guid, FdfModule.BaseName))
+ for key, item in FdfModule.Protocols.items():
+ GuidDict[key] = item
+ for key, item in FdfModule.Guids.items():
+ GuidDict[key] = item
+ for key, item in FdfModule.Ppis.items():
+ GuidDict[key] = item
+ else:
+ FileStatementGuid = FfsObj.NameGuid
+ if FileStatementGuid in FileGuidList:
+ continue
+ else:
+ FileGuidList.append(FileStatementGuid)
+ Name = []
+ FfsPath = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs')
+ FfsPath = glob.glob(os.path.join(FfsPath, FileStatementGuid) + '*')
+ if not FfsPath:
+ continue
+ if not os.path.exists(FfsPath[0]):
+ continue
+ MatchDict = {}
+ ReFileEnds = re.compile('\S+(.ui)$|\S+(fv.sec.txt)$|\S+(.pe32.txt)$|\S+(.te.txt)$|\S+(.pic.txt)$|\S+(.raw.txt)$|\S+(.ffs.txt)$')
+ FileList = os.listdir(FfsPath[0])
+ for File in FileList:
+ Match = ReFileEnds.search(File)
+ if Match:
+ for Index in range(1, 8):
+ if Match.group(Index) and Match.group(Index) in MatchDict:
+ MatchDict[Match.group(Index)].append(File)
+ elif Match.group(Index):
+ MatchDict[Match.group(Index)] = [File]
+ if not MatchDict:
+ continue
+ if '.ui' in MatchDict:
+ for File in MatchDict['.ui']:
+ with open(os.path.join(FfsPath[0], File), 'rb') as F:
+ F.read()
+ length = F.tell()
+ F.seek(4)
+ TmpStr = unpack('%dh' % ((length - 4) / 2), F.read())
+ Name = ''.join([chr(c) for c in TmpStr[:-1]])
+ else:
+ FileList = []
+ if 'fv.sec.txt' in MatchDict:
+ FileList = MatchDict['fv.sec.txt']
+ elif '.pe32.txt' in MatchDict:
+ FileList = MatchDict['.pe32.txt']
+ elif '.te.txt' in MatchDict:
+ FileList = MatchDict['.te.txt']
+ elif '.pic.txt' in MatchDict:
+ FileList = MatchDict['.pic.txt']
+ elif '.raw.txt' in MatchDict:
+ FileList = MatchDict['.raw.txt']
+ elif '.ffs.txt' in MatchDict:
+ FileList = MatchDict['.ffs.txt']
+ else:
+ pass
+ for File in FileList:
+ with open(os.path.join(FfsPath[0], File), 'r') as F:
+ Name.append((F.read().split()[-1]))
+ if not Name:
+ continue
+
+ Name = ' '.join(Name) if type(Name) == type([]) else Name
+ GuidXRefFile.write("%s %s\n" %(FileStatementGuid, Name))
+
# Append GUIDs, Protocols, and PPIs to the Xref file
GuidXRefFile.write("\n")
for key, item in GuidDict.items():