]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/GenFds/GenFds.py
BaseTools: Structure Pcd in CommandLine.
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / GenFds.py
CommitLineData
f51461c8
LG
1## @file\r
2# generate flash image\r
3#\r
95816356 4# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>\r
f51461c8
LG
5#\r
6# This program and the accompanying materials\r
7# are licensed and made available under the terms and conditions of the BSD License\r
8# which accompanies this distribution. The full text of the license may be found at\r
9# http://opensource.org/licenses/bsd-license.php\r
10#\r
11# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13#\r
14\r
15##\r
16# Import Modules\r
17#\r
18from optparse import OptionParser\r
19import sys\r
1be2ed90 20import Common.LongFilePathOs as os\r
f51461c8
LG
21import linecache\r
22import FdfParser\r
23import Common.BuildToolError as BuildToolError\r
24from GenFdsGlobalVariable import GenFdsGlobalVariable\r
25from Workspace.WorkspaceDatabase import WorkspaceDatabase\r
26from Workspace.BuildClassObject import PcdClassObject\r
27from Workspace.BuildClassObject import ModuleBuildClassObject\r
28import RuleComplexFile\r
29from EfiSection import EfiSection\r
30import StringIO\r
31import Common.TargetTxtClassObject as TargetTxtClassObject\r
32import Common.ToolDefClassObject as ToolDefClassObject\r
95816356 33from Common.DataType import *\r
f51461c8
LG
34import Common.GlobalData as GlobalData\r
35from Common import EdkLogger\r
36from Common.String import *\r
47fea6af 37from Common.Misc import DirCache, PathClass\r
f51461c8 38from Common.Misc import SaveFileOnChange\r
97fa0ee9 39from Common.Misc import ClearDuplicatedInf\r
e4ac870f 40from Common.Misc import GuidStructureStringToGuidString\r
6b17c11b 41from Common.Misc import CheckPcdDatum\r
db55dac7 42from Common.Misc import BuildOptionPcdValueFormat\r
f51461c8 43from Common.BuildVersion import gBUILD_VERSION\r
05cc51ad 44from Common.MultipleWorkspace import MultipleWorkspace as mws\r
5e9256cd
YZ
45import FfsFileStatement\r
46import glob\r
47from struct import unpack\r
f51461c8
LG
48\r
49## Version and Copyright\r
50versionNumber = "1.0" + ' ' + gBUILD_VERSION\r
51__version__ = "%prog Version " + versionNumber\r
95816356 52__copyright__ = "Copyright (c) 2007 - 2017, Intel Corporation All rights reserved."\r
f51461c8
LG
53\r
54## Tool entrance method\r
55#\r
56# This method mainly dispatch specific methods per the command line options.\r
57# If no error found, return zero value so the caller of this tool can know\r
58# if it's executed successfully or not.\r
59#\r
60# @retval 0 Tool was successful\r
61# @retval 1 Tool failed\r
62#\r
63def main():\r
64 global Options\r
65 Options = myOptionParser()\r
66\r
67 global Workspace\r
68 Workspace = ""\r
69 ArchList = None\r
70 ReturnCode = 0\r
71\r
72 EdkLogger.Initialize()\r
73 try:\r
74 if Options.verbose != None:\r
75 EdkLogger.SetLevel(EdkLogger.VERBOSE)\r
76 GenFdsGlobalVariable.VerboseMode = True\r
77 \r
78 if Options.FixedAddress != None:\r
79 GenFdsGlobalVariable.FixedLoadAddress = True\r
80 \r
81 if Options.quiet != None:\r
82 EdkLogger.SetLevel(EdkLogger.QUIET)\r
83 if Options.debug != None:\r
84 EdkLogger.SetLevel(Options.debug + 1)\r
85 GenFdsGlobalVariable.DebugLevel = Options.debug\r
86 else:\r
87 EdkLogger.SetLevel(EdkLogger.INFO)\r
88\r
89 if (Options.Workspace == None):\r
90 EdkLogger.error("GenFds", OPTION_MISSING, "WORKSPACE not defined",\r
91 ExtraData="Please use '-w' switch to pass it or set the WORKSPACE environment variable.")\r
92 elif not os.path.exists(Options.Workspace):\r
93 EdkLogger.error("GenFds", PARAMETER_INVALID, "WORKSPACE is invalid",\r
94 ExtraData="Please use '-w' switch to pass it or set the WORKSPACE environment variable.")\r
95 else:\r
96 Workspace = os.path.normcase(Options.Workspace)\r
97 GenFdsGlobalVariable.WorkSpaceDir = Workspace\r
98 if 'EDK_SOURCE' in os.environ.keys():\r
99 GenFdsGlobalVariable.EdkSourceDir = os.path.normcase(os.environ['EDK_SOURCE'])\r
100 if (Options.debug):\r
47fea6af 101 GenFdsGlobalVariable.VerboseLogger("Using Workspace:" + Workspace)\r
37de70b7
YZ
102 if Options.GenfdsMultiThread:\r
103 GenFdsGlobalVariable.EnableGenfdsMultiThread = True\r
f51461c8 104 os.chdir(GenFdsGlobalVariable.WorkSpaceDir)\r
05cc51ad
LY
105 \r
106 # set multiple workspace\r
107 PackagesPath = os.getenv("PACKAGES_PATH")\r
108 mws.setWs(GenFdsGlobalVariable.WorkSpaceDir, PackagesPath)\r
f51461c8
LG
109\r
110 if (Options.filename):\r
111 FdfFilename = Options.filename\r
112 FdfFilename = GenFdsGlobalVariable.ReplaceWorkspaceMacro(FdfFilename)\r
113\r
114 if FdfFilename[0:2] == '..':\r
115 FdfFilename = os.path.realpath(FdfFilename)\r
47fea6af 116 if not os.path.isabs(FdfFilename):\r
05cc51ad 117 FdfFilename = mws.join(GenFdsGlobalVariable.WorkSpaceDir, FdfFilename)\r
f51461c8
LG
118 if not os.path.exists(FdfFilename):\r
119 EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=FdfFilename)\r
f51461c8
LG
120\r
121 GenFdsGlobalVariable.FdfFile = FdfFilename\r
122 GenFdsGlobalVariable.FdfFileTimeStamp = os.path.getmtime(FdfFilename)\r
123 else:\r
124 EdkLogger.error("GenFds", OPTION_MISSING, "Missing FDF filename")\r
125\r
126 if (Options.BuildTarget):\r
127 GenFdsGlobalVariable.TargetName = Options.BuildTarget\r
f51461c8
LG
128\r
129 if (Options.ToolChain):\r
130 GenFdsGlobalVariable.ToolChainTag = Options.ToolChain\r
f51461c8
LG
131\r
132 if (Options.activePlatform):\r
133 ActivePlatform = Options.activePlatform\r
134 ActivePlatform = GenFdsGlobalVariable.ReplaceWorkspaceMacro(ActivePlatform)\r
135\r
136 if ActivePlatform[0:2] == '..':\r
137 ActivePlatform = os.path.realpath(ActivePlatform)\r
138\r
139 if not os.path.isabs (ActivePlatform):\r
05cc51ad 140 ActivePlatform = mws.join(GenFdsGlobalVariable.WorkSpaceDir, ActivePlatform)\r
f51461c8
LG
141\r
142 if not os.path.exists(ActivePlatform) :\r
143 EdkLogger.error("GenFds", FILE_NOT_FOUND, "ActivePlatform doesn't exist!")\r
f51461c8
LG
144 else:\r
145 EdkLogger.error("GenFds", OPTION_MISSING, "Missing active platform")\r
146\r
e642ceb8 147 GenFdsGlobalVariable.ActivePlatform = PathClass(NormPath(ActivePlatform))\r
f51461c8 148\r
97fa0ee9
YL
149 if (Options.ConfDirectory):\r
150 # Get alternate Conf location, if it is absolute, then just use the absolute directory name\r
151 ConfDirectoryPath = os.path.normpath(Options.ConfDirectory)\r
152 if ConfDirectoryPath.startswith('"'):\r
153 ConfDirectoryPath = ConfDirectoryPath[1:]\r
154 if ConfDirectoryPath.endswith('"'):\r
155 ConfDirectoryPath = ConfDirectoryPath[:-1]\r
156 if not os.path.isabs(ConfDirectoryPath):\r
157 # Since alternate directory name is not absolute, the alternate directory is located within the WORKSPACE\r
158 # This also handles someone specifying the Conf directory in the workspace. Using --conf=Conf\r
159 ConfDirectoryPath = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, ConfDirectoryPath)\r
160 else:\r
00bcb5c2
YZ
161 if "CONF_PATH" in os.environ.keys():\r
162 ConfDirectoryPath = os.path.normcase(os.environ["CONF_PATH"])\r
163 else:\r
164 # Get standard WORKSPACE/Conf, use the absolute path to the WORKSPACE/Conf\r
165 ConfDirectoryPath = mws.join(GenFdsGlobalVariable.WorkSpaceDir, 'Conf')\r
97fa0ee9
YL
166 GenFdsGlobalVariable.ConfDir = ConfDirectoryPath\r
167 BuildConfigurationFile = os.path.normpath(os.path.join(ConfDirectoryPath, "target.txt"))\r
f51461c8 168 if os.path.isfile(BuildConfigurationFile) == True:\r
e4979bee
YZ
169 TargetTxt = TargetTxtClassObject.TargetTxtClassObject()\r
170 TargetTxt.LoadTargetTxtFile(BuildConfigurationFile)\r
171 # if no build target given in command line, get it from target.txt\r
172 if not GenFdsGlobalVariable.TargetName:\r
173 BuildTargetList = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TARGET]\r
174 if len(BuildTargetList) != 1:\r
175 EdkLogger.error("GenFds", OPTION_VALUE_INVALID, ExtraData="Only allows one instance for Target.")\r
176 GenFdsGlobalVariable.TargetName = BuildTargetList[0]\r
177\r
178 # if no tool chain given in command line, get it from target.txt\r
179 if not GenFdsGlobalVariable.ToolChainTag:\r
180 ToolChainList = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_TAG]\r
181 if ToolChainList == None or len(ToolChainList) == 0:\r
182 EdkLogger.error("GenFds", RESOURCE_NOT_AVAILABLE, ExtraData="No toolchain given. Don't know how to build.")\r
183 if len(ToolChainList) != 1:\r
184 EdkLogger.error("GenFds", OPTION_VALUE_INVALID, ExtraData="Only allows one instance for ToolChain.")\r
185 GenFdsGlobalVariable.ToolChainTag = ToolChainList[0]\r
f51461c8
LG
186 else:\r
187 EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=BuildConfigurationFile)\r
188\r
97fa0ee9
YL
189 #Set global flag for build mode\r
190 GlobalData.gIgnoreSource = Options.IgnoreSources\r
191\r
f51461c8
LG
192 if Options.Macros:\r
193 for Pair in Options.Macros:\r
97fa0ee9
YL
194 if Pair.startswith('"'):\r
195 Pair = Pair[1:]\r
196 if Pair.endswith('"'):\r
197 Pair = Pair[:-1]\r
f51461c8
LG
198 List = Pair.split('=')\r
199 if len(List) == 2:\r
e4979bee
YZ
200 if not List[1].strip():\r
201 EdkLogger.error("GenFds", OPTION_VALUE_INVALID, ExtraData="No Value given for Macro %s" %List[0])\r
f51461c8
LG
202 if List[0].strip() == "EFI_SOURCE":\r
203 GlobalData.gEfiSource = List[1].strip()\r
204 GlobalData.gGlobalDefines["EFI_SOURCE"] = GlobalData.gEfiSource\r
205 continue\r
206 elif List[0].strip() == "EDK_SOURCE":\r
207 GlobalData.gEdkSource = List[1].strip()\r
208 GlobalData.gGlobalDefines["EDK_SOURCE"] = GlobalData.gEdkSource\r
209 continue\r
210 elif List[0].strip() in ["WORKSPACE", "TARGET", "TOOLCHAIN"]:\r
211 GlobalData.gGlobalDefines[List[0].strip()] = List[1].strip()\r
212 else:\r
213 GlobalData.gCommandLineDefines[List[0].strip()] = List[1].strip()\r
214 else:\r
215 GlobalData.gCommandLineDefines[List[0].strip()] = "TRUE"\r
216 os.environ["WORKSPACE"] = Workspace\r
217\r
e4979bee
YZ
218 # Use the -t and -b option as gGlobalDefines's TOOLCHAIN and TARGET if they are not defined\r
219 if "TARGET" not in GlobalData.gGlobalDefines.keys():\r
220 GlobalData.gGlobalDefines["TARGET"] = GenFdsGlobalVariable.TargetName\r
221 if "TOOLCHAIN" not in GlobalData.gGlobalDefines.keys():\r
222 GlobalData.gGlobalDefines["TOOLCHAIN"] = GenFdsGlobalVariable.ToolChainTag\r
223 if "TOOL_CHAIN_TAG" not in GlobalData.gGlobalDefines.keys():\r
224 GlobalData.gGlobalDefines['TOOL_CHAIN_TAG'] = GenFdsGlobalVariable.ToolChainTag\r
225\r
f51461c8 226 """call Workspace build create database"""\r
97fa0ee9
YL
227 GlobalData.gDatabasePath = os.path.normpath(os.path.join(ConfDirectoryPath, GlobalData.gDatabasePath))\r
228 BuildWorkSpace = WorkspaceDatabase(GlobalData.gDatabasePath)\r
f51461c8
LG
229 BuildWorkSpace.InitDatabase()\r
230 \r
231 #\r
232 # Get files real name in workspace dir\r
233 #\r
234 GlobalData.gAllFiles = DirCache(Workspace)\r
235 GlobalData.gWorkspace = Workspace\r
236\r
237 if (Options.archList) :\r
238 ArchList = Options.archList.split(',')\r
239 else:\r
240# EdkLogger.error("GenFds", OPTION_MISSING, "Missing build ARCH")\r
241 ArchList = BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'COMMON', Options.BuildTarget, Options.ToolChain].SupArchList\r
242\r
243 TargetArchList = set(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'COMMON', Options.BuildTarget, Options.ToolChain].SupArchList) & set(ArchList)\r
244 if len(TargetArchList) == 0:\r
245 EdkLogger.error("GenFds", GENFDS_ERROR, "Target ARCH %s not in platform supported ARCH %s" % (str(ArchList), str(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'COMMON'].SupArchList)))\r
246 \r
247 for Arch in ArchList:\r
248 GenFdsGlobalVariable.OutputDirFromDscDict[Arch] = NormPath(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, Options.BuildTarget, Options.ToolChain].OutputDirectory)\r
249 GenFdsGlobalVariable.PlatformName = BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, Options.BuildTarget, Options.ToolChain].PlatformName\r
250\r
251 if (Options.outputDir):\r
252 OutputDirFromCommandLine = GenFdsGlobalVariable.ReplaceWorkspaceMacro(Options.outputDir)\r
253 if not os.path.isabs (OutputDirFromCommandLine):\r
254 OutputDirFromCommandLine = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, OutputDirFromCommandLine)\r
255 for Arch in ArchList:\r
256 GenFdsGlobalVariable.OutputDirDict[Arch] = OutputDirFromCommandLine\r
257 else:\r
258 for Arch in ArchList:\r
259 GenFdsGlobalVariable.OutputDirDict[Arch] = os.path.join(GenFdsGlobalVariable.OutputDirFromDscDict[Arch], GenFdsGlobalVariable.TargetName + '_' + GenFdsGlobalVariable.ToolChainTag)\r
260\r
261 for Key in GenFdsGlobalVariable.OutputDirDict:\r
262 OutputDir = GenFdsGlobalVariable.OutputDirDict[Key]\r
263 if OutputDir[0:2] == '..':\r
264 OutputDir = os.path.realpath(OutputDir)\r
265\r
266 if OutputDir[1] != ':':\r
267 OutputDir = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, OutputDir)\r
268\r
269 if not os.path.exists(OutputDir):\r
270 EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=OutputDir)\r
271 GenFdsGlobalVariable.OutputDirDict[Key] = OutputDir\r
272\r
273 """ Parse Fdf file, has to place after build Workspace as FDF may contain macros from DSC file """\r
274 FdfParserObj = FdfParser.FdfParser(FdfFilename)\r
275 FdfParserObj.ParseFile()\r
276\r
277 if FdfParserObj.CycleReferenceCheck():\r
278 EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Cycle Reference Detected in FDF file")\r
279\r
280 if (Options.uiFdName) :\r
281 if Options.uiFdName.upper() in FdfParserObj.Profile.FdDict.keys():\r
282 GenFds.OnlyGenerateThisFd = Options.uiFdName\r
283 else:\r
284 EdkLogger.error("GenFds", OPTION_VALUE_INVALID,\r
285 "No such an FD in FDF file: %s" % Options.uiFdName)\r
286\r
287 if (Options.uiFvName) :\r
288 if Options.uiFvName.upper() in FdfParserObj.Profile.FvDict.keys():\r
289 GenFds.OnlyGenerateThisFv = Options.uiFvName\r
290 else:\r
291 EdkLogger.error("GenFds", OPTION_VALUE_INVALID,\r
292 "No such an FV in FDF file: %s" % Options.uiFvName)\r
293\r
294 if (Options.uiCapName) :\r
295 if Options.uiCapName.upper() in FdfParserObj.Profile.CapsuleDict.keys():\r
296 GenFds.OnlyGenerateThisCap = Options.uiCapName\r
297 else:\r
298 EdkLogger.error("GenFds", OPTION_VALUE_INVALID,\r
299 "No such a Capsule in FDF file: %s" % Options.uiCapName)\r
300\r
6b17c11b
YZ
301 GenFdsGlobalVariable.WorkSpace = BuildWorkSpace\r
302 if ArchList != None:\r
303 GenFdsGlobalVariable.ArchList = ArchList\r
304\r
6f49996c 305 # Dsc Build Data will handle Pcd Settings from CommandLine.\r
6b17c11b 306\r
f51461c8
LG
307 """Modify images from build output if the feature of loading driver at fixed address is on."""\r
308 if GenFdsGlobalVariable.FixedLoadAddress:\r
309 GenFds.PreprocessImage(BuildWorkSpace, GenFdsGlobalVariable.ActivePlatform)\r
135ae8c8
YZ
310\r
311 # Record the FV Region info that may specific in the FD\r
312 if FdfParserObj.Profile.FvDict and FdfParserObj.Profile.FdDict:\r
313 for Fv in FdfParserObj.Profile.FvDict:\r
314 FvObj = FdfParserObj.Profile.FvDict[Fv]\r
315 for Fd in FdfParserObj.Profile.FdDict:\r
316 FdObj = FdfParserObj.Profile.FdDict[Fd]\r
317 for RegionObj in FdObj.RegionList:\r
318 if RegionObj.RegionType != 'FV':\r
319 continue\r
320 for RegionData in RegionObj.RegionDataList:\r
321 if FvObj.UiFvName.upper() == RegionData.upper():\r
322 if FvObj.FvRegionInFD:\r
323 if FvObj.FvRegionInFD != RegionObj.Size:\r
324 EdkLogger.error("GenFds", FORMAT_INVALID, "The FV %s's region is specified in multiple FD with different value." %FvObj.UiFvName)\r
325 else:\r
326 FvObj.FvRegionInFD = RegionObj.Size\r
327 RegionObj.BlockInfoOfRegion(FdObj.BlockSizeList, FvObj)\r
328\r
f51461c8
LG
329 """Call GenFds"""\r
330 GenFds.GenFd('', FdfParserObj, BuildWorkSpace, ArchList)\r
331\r
332 """Generate GUID cross reference file"""\r
5e9256cd 333 GenFds.GenerateGuidXRefFile(BuildWorkSpace, ArchList, FdfParserObj)\r
f51461c8
LG
334\r
335 """Display FV space info."""\r
336 GenFds.DisplayFvSpaceInfo(FdfParserObj)\r
337\r
338 except FdfParser.Warning, X:\r
47fea6af 339 EdkLogger.error(X.ToolName, FORMAT_INVALID, File=X.FileName, Line=X.LineNumber, ExtraData=X.Message, RaiseError=False)\r
f51461c8
LG
340 ReturnCode = FORMAT_INVALID\r
341 except FatalError, X:\r
342 if Options.debug != None:\r
343 import traceback\r
344 EdkLogger.quiet(traceback.format_exc())\r
345 ReturnCode = X.args[0]\r
346 except:\r
347 import traceback\r
348 EdkLogger.error(\r
349 "\nPython",\r
350 CODE_ERROR,\r
351 "Tools code failure",\r
3a0f8bde 352 ExtraData="Please send email to edk2-devel@lists.01.org for help, attaching following call stack trace!\n",\r
f51461c8
LG
353 RaiseError=False\r
354 )\r
355 EdkLogger.quiet(traceback.format_exc())\r
356 ReturnCode = CODE_ERROR\r
97fa0ee9
YL
357 finally:\r
358 ClearDuplicatedInf()\r
f51461c8
LG
359 return ReturnCode\r
360\r
361gParamCheck = []\r
362def SingleCheckCallback(option, opt_str, value, parser):\r
363 if option not in gParamCheck:\r
364 setattr(parser.values, option.dest, value)\r
365 gParamCheck.append(option)\r
366 else:\r
367 parser.error("Option %s only allows one instance in command line!" % option)\r
6b17c11b
YZ
368\r
369def CheckBuildOptionPcd():\r
370 for Arch in GenFdsGlobalVariable.ArchList:\r
371 PkgList = GenFdsGlobalVariable.WorkSpace.GetPackageList(GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag)\r
372 for i, pcd in enumerate(GlobalData.BuildOptionPcd):\r
373 if type(pcd) is tuple:\r
374 continue\r
375 (pcdname, pcdvalue) = pcd.split('=')\r
376 if not pcdvalue:\r
377 EdkLogger.error('GenFds', OPTION_MISSING, "No Value specified for the PCD %s." % (pcdname))\r
378 if '.' in pcdname:\r
379 (TokenSpaceGuidCName, TokenCName) = pcdname.split('.')\r
380 HasTokenSpace = True\r
381 else:\r
382 TokenCName = pcdname\r
383 TokenSpaceGuidCName = ''\r
384 HasTokenSpace = False\r
385 TokenSpaceGuidCNameList = []\r
386 FoundFlag = False\r
387 PcdDatumType = ''\r
388 NewValue = ''\r
389 for package in PkgList:\r
390 for key in package.Pcds:\r
391 PcdItem = package.Pcds[key]\r
392 if HasTokenSpace:\r
393 if (PcdItem.TokenCName, PcdItem.TokenSpaceGuidCName) == (TokenCName, TokenSpaceGuidCName):\r
394 PcdDatumType = PcdItem.DatumType\r
395 NewValue = BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)\r
396 FoundFlag = True\r
397 else:\r
398 if PcdItem.TokenCName == TokenCName:\r
399 if not PcdItem.TokenSpaceGuidCName in TokenSpaceGuidCNameList:\r
400 if len (TokenSpaceGuidCNameList) < 1:\r
401 TokenSpaceGuidCNameList.append(PcdItem.TokenSpaceGuidCName)\r
402 PcdDatumType = PcdItem.DatumType\r
403 TokenSpaceGuidCName = PcdItem.TokenSpaceGuidCName\r
404 NewValue = BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)\r
405 FoundFlag = True\r
406 else:\r
407 EdkLogger.error(\r
408 'GenFds',\r
409 PCD_VALIDATION_INFO_ERROR,\r
410 "The Pcd %s is found under multiple different TokenSpaceGuid: %s and %s." % (TokenCName, PcdItem.TokenSpaceGuidCName, TokenSpaceGuidCNameList[0])\r
411 )\r
412\r
413 GlobalData.BuildOptionPcd[i] = (TokenSpaceGuidCName, TokenCName, NewValue)\r
414\r
6b17c11b 415\r
91ae2988
YZ
416## FindExtendTool()\r
417#\r
418# Find location of tools to process data\r
419#\r
420# @param KeyStringList Filter for inputs of section generation\r
421# @param CurrentArchList Arch list\r
422# @param NameGuid The Guid name\r
423#\r
424def FindExtendTool(KeyStringList, CurrentArchList, NameGuid):\r
95816356 425 ToolDb = ToolDefClassObject.ToolDefDict(GenFdsGlobalVariable.ConfDir).ToolsDefTxtDatabase\r
91ae2988
YZ
426 # if user not specify filter, try to deduce it from global data.\r
427 if KeyStringList == None or KeyStringList == []:\r
428 Target = GenFdsGlobalVariable.TargetName\r
429 ToolChain = GenFdsGlobalVariable.ToolChainTag\r
91ae2988
YZ
430 if ToolChain not in ToolDb['TOOL_CHAIN_TAG']:\r
431 EdkLogger.error("GenFds", GENFDS_ERROR, "Can not find external tool because tool tag %s is not defined in tools_def.txt!" % ToolChain)\r
432 KeyStringList = [Target + '_' + ToolChain + '_' + CurrentArchList[0]]\r
433 for Arch in CurrentArchList:\r
434 if Target + '_' + ToolChain + '_' + Arch not in KeyStringList:\r
435 KeyStringList.append(Target + '_' + ToolChain + '_' + Arch)\r
436\r
437 if GenFdsGlobalVariable.GuidToolDefinition:\r
438 if NameGuid in GenFdsGlobalVariable.GuidToolDefinition.keys():\r
439 return GenFdsGlobalVariable.GuidToolDefinition[NameGuid]\r
440\r
441 ToolDefinition = ToolDefClassObject.ToolDefDict(GenFdsGlobalVariable.ConfDir).ToolsDefTxtDictionary\r
442 ToolPathTmp = None\r
443 ToolOption = None\r
95816356
YZ
444 ToolPathKey = None\r
445 ToolOptionKey = None\r
446 KeyList = None\r
91ae2988
YZ
447 for ToolDef in ToolDefinition.items():\r
448 if NameGuid == ToolDef[1]:\r
449 KeyList = ToolDef[0].split('_')\r
450 Key = KeyList[0] + \\r
451 '_' + \\r
452 KeyList[1] + \\r
453 '_' + \\r
454 KeyList[2]\r
455 if Key in KeyStringList and KeyList[4] == 'GUID':\r
95816356
YZ
456 ToolPathKey = Key + '_' + KeyList[3] + '_PATH'\r
457 ToolOptionKey = Key + '_' + KeyList[3] + '_FLAGS'\r
458 ToolPath = ToolDefinition.get(ToolPathKey)\r
459 ToolOption = ToolDefinition.get(ToolOptionKey)\r
91ae2988
YZ
460 if ToolPathTmp == None:\r
461 ToolPathTmp = ToolPath\r
462 else:\r
463 if ToolPathTmp != ToolPath:\r
464 EdkLogger.error("GenFds", GENFDS_ERROR, "Don't know which tool to use, %s or %s ?" % (ToolPathTmp, ToolPath))\r
465\r
95816356
YZ
466 BuildOption = {}\r
467 for Arch in CurrentArchList:\r
468 Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
469 # key is (ToolChainFamily, ToolChain, CodeBase)\r
470 for item in Platform.BuildOptions:\r
471 if '_PATH' in item[1] or '_FLAGS' in item[1] or '_GUID' in item[1]:\r
472 if not item[0] or (item[0] and GenFdsGlobalVariable.ToolChainFamily== item[0]):\r
473 if item[1] not in BuildOption:\r
474 BuildOption[item[1]] = Platform.BuildOptions[item]\r
475 if BuildOption:\r
476 ToolList = [TAB_TOD_DEFINES_TARGET, TAB_TOD_DEFINES_TOOL_CHAIN_TAG, TAB_TOD_DEFINES_TARGET_ARCH]\r
477 for Index in range(2, -1, -1):\r
478 for Key in dict(BuildOption):\r
479 List = Key.split('_')\r
480 if List[Index] == '*':\r
481 for String in ToolDb[ToolList[Index]]:\r
482 if String in [Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]:\r
483 List[Index] = String\r
484 NewKey = '%s_%s_%s_%s_%s' % tuple(List)\r
485 if NewKey not in BuildOption:\r
486 BuildOption[NewKey] = BuildOption[Key]\r
487 continue\r
488 del BuildOption[Key]\r
489 elif List[Index] not in ToolDb[ToolList[Index]]:\r
490 del BuildOption[Key]\r
491 if BuildOption:\r
492 if not KeyList:\r
493 for Op in BuildOption:\r
494 if NameGuid == BuildOption[Op]:\r
495 KeyList = Op.split('_')\r
496 Key = KeyList[0] + '_' + KeyList[1] +'_' + KeyList[2]\r
497 if Key in KeyStringList and KeyList[4] == 'GUID':\r
498 ToolPathKey = Key + '_' + KeyList[3] + '_PATH'\r
499 ToolOptionKey = Key + '_' + KeyList[3] + '_FLAGS'\r
500 if ToolPathKey in BuildOption.keys():\r
501 ToolPathTmp = BuildOption.get(ToolPathKey)\r
502 if ToolOptionKey in BuildOption.keys():\r
503 ToolOption = BuildOption.get(ToolOptionKey)\r
504\r
91ae2988
YZ
505 GenFdsGlobalVariable.GuidToolDefinition[NameGuid] = (ToolPathTmp, ToolOption)\r
506 return ToolPathTmp, ToolOption\r
507\r
f51461c8
LG
508## Parse command line options\r
509#\r
510# Using standard Python module optparse to parse command line option of this tool.\r
511#\r
512# @retval Opt A optparse.Values object containing the parsed options\r
513# @retval Args Target of build command\r
514#\r
515def myOptionParser():\r
516 usage = "%prog [options] -f input_file -a arch_list -b build_target -p active_platform -t tool_chain_tag -D \"MacroName [= MacroValue]\""\r
47fea6af 517 Parser = OptionParser(usage=usage, description=__copyright__, version="%prog " + str(versionNumber))\r
f51461c8
LG
518 Parser.add_option("-f", "--file", dest="filename", type="string", help="Name of FDF file to convert", action="callback", callback=SingleCheckCallback)\r
519 Parser.add_option("-a", "--arch", dest="archList", help="comma separated list containing one or more of: IA32, X64, IPF, ARM, AARCH64 or EBC which should be built, overrides target.txt?s TARGET_ARCH")\r
520 Parser.add_option("-q", "--quiet", action="store_true", type=None, help="Disable all messages except FATAL ERRORS.")\r
521 Parser.add_option("-v", "--verbose", action="store_true", type=None, help="Turn on verbose output with informational messages printed.")\r
522 Parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.")\r
523 Parser.add_option("-p", "--platform", type="string", dest="activePlatform", help="Set the ACTIVE_PLATFORM, overrides target.txt ACTIVE_PLATFORM setting.",\r
524 action="callback", callback=SingleCheckCallback)\r
525 Parser.add_option("-w", "--workspace", type="string", dest="Workspace", default=os.environ.get('WORKSPACE'), help="Set the WORKSPACE",\r
526 action="callback", callback=SingleCheckCallback)\r
527 Parser.add_option("-o", "--outputDir", type="string", dest="outputDir", help="Name of Build Output directory",\r
528 action="callback", callback=SingleCheckCallback)\r
529 Parser.add_option("-r", "--rom_image", dest="uiFdName", help="Build the image using the [FD] section named by FdUiName.")\r
530 Parser.add_option("-i", "--FvImage", dest="uiFvName", help="Build the FV image using the [FV] section named by UiFvName")\r
531 Parser.add_option("-C", "--CapsuleImage", dest="uiCapName", help="Build the Capsule image using the [Capsule] section named by UiCapName")\r
532 Parser.add_option("-b", "--buildtarget", type="string", dest="BuildTarget", help="Set the build TARGET, overrides target.txt TARGET setting.",\r
533 action="callback", callback=SingleCheckCallback)\r
534 Parser.add_option("-t", "--tagname", type="string", dest="ToolChain", help="Using the tools: TOOL_CHAIN_TAG name to build the platform.",\r
535 action="callback", callback=SingleCheckCallback)\r
536 Parser.add_option("-D", "--define", action="append", type="string", dest="Macros", help="Macro: \"Name [= Value]\".")\r
537 Parser.add_option("-s", "--specifyaddress", dest="FixedAddress", action="store_true", type=None, help="Specify driver load address.")\r
97fa0ee9
YL
538 Parser.add_option("--conf", action="store", type="string", dest="ConfDirectory", help="Specify the customized Conf directory.")\r
539 Parser.add_option("--ignore-sources", action="store_true", dest="IgnoreSources", default=False, help="Focus to a binary build and ignore all source files")\r
6b17c11b 540 Parser.add_option("--pcd", action="append", dest="OptionPcd", help="Set PCD value by command line. Format: \"PcdName=Value\" ")\r
37de70b7 541 Parser.add_option("--genfds-multi-thread", action="store_true", dest="GenfdsMultiThread", default=False, help="Enable GenFds multi thread to generate ffs file.")\r
97fa0ee9 542\r
f51461c8
LG
543 (Options, args) = Parser.parse_args()\r
544 return Options\r
545\r
546## The class implementing the EDK2 flash image generation process\r
547#\r
548# This process includes:\r
549# 1. Collect workspace information, includes platform and module information\r
550# 2. Call methods of Fd class to generate FD\r
551# 3. Call methods of Fv class to generate FV that not belong to FD\r
552#\r
553class GenFds :\r
554 FdfParsef = None\r
555 # FvName, FdName, CapName in FDF, Image file name\r
556 ImageBinDict = {}\r
557 OnlyGenerateThisFd = None\r
558 OnlyGenerateThisFv = None\r
559 OnlyGenerateThisCap = None\r
560\r
561 ## GenFd()\r
562 #\r
563 # @param OutputDir Output directory\r
564 # @param FdfParser FDF contents parser\r
565 # @param Workspace The directory of workspace\r
566 # @param ArchList The Arch list of platform\r
567 #\r
568 def GenFd (OutputDir, FdfParser, WorkSpace, ArchList):\r
569 GenFdsGlobalVariable.SetDir ('', FdfParser, WorkSpace, ArchList)\r
570\r
571 GenFdsGlobalVariable.VerboseLogger(" Generate all Fd images and their required FV and Capsule images!")\r
572 if GenFds.OnlyGenerateThisCap != None and GenFds.OnlyGenerateThisCap.upper() in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.keys():\r
573 CapsuleObj = GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.get(GenFds.OnlyGenerateThisCap.upper())\r
574 if CapsuleObj != None:\r
575 CapsuleObj.GenCapsule()\r
576 return\r
577\r
578 if GenFds.OnlyGenerateThisFd != None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():\r
579 FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict.get(GenFds.OnlyGenerateThisFd.upper())\r
580 if FdObj != None:\r
581 FdObj.GenFd()\r
582 return\r
583 elif GenFds.OnlyGenerateThisFd == None and GenFds.OnlyGenerateThisFv == None:\r
584 for FdName in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():\r
585 FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[FdName]\r
586 FdObj.GenFd()\r
587\r
588 GenFdsGlobalVariable.VerboseLogger("\n Generate other FV images! ")\r
589 if GenFds.OnlyGenerateThisFv != None and GenFds.OnlyGenerateThisFv.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():\r
590 FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(GenFds.OnlyGenerateThisFv.upper())\r
591 if FvObj != None:\r
592 Buffer = StringIO.StringIO()\r
593 FvObj.AddToBuffer(Buffer)\r
594 Buffer.close()\r
595 return\r
596 elif GenFds.OnlyGenerateThisFv == None:\r
597 for FvName in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():\r
598 Buffer = StringIO.StringIO('')\r
599 FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict[FvName]\r
600 FvObj.AddToBuffer(Buffer)\r
601 Buffer.close()\r
602 \r
603 if GenFds.OnlyGenerateThisFv == None and GenFds.OnlyGenerateThisFd == None and GenFds.OnlyGenerateThisCap == None:\r
604 if GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict != {}:\r
605 GenFdsGlobalVariable.VerboseLogger("\n Generate other Capsule images!")\r
606 for CapsuleName in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.keys():\r
607 CapsuleObj = GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict[CapsuleName]\r
608 CapsuleObj.GenCapsule()\r
609\r
610 if GenFdsGlobalVariable.FdfParser.Profile.OptRomDict != {}:\r
611 GenFdsGlobalVariable.VerboseLogger("\n Generate all Option ROM!")\r
612 for DriverName in GenFdsGlobalVariable.FdfParser.Profile.OptRomDict.keys():\r
613 OptRomObj = GenFdsGlobalVariable.FdfParser.Profile.OptRomDict[DriverName]\r
614 OptRomObj.AddToBuffer(None)\r
37de70b7
YZ
615 @staticmethod\r
616 def GenFfsMakefile(OutputDir, FdfParser, WorkSpace, ArchList, GlobalData):\r
617 GenFdsGlobalVariable.SetEnv(FdfParser, WorkSpace, ArchList, GlobalData)\r
618 for FdName in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():\r
619 FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[FdName]\r
620 FdObj.GenFd(Flag=True)\r
621\r
622 for FvName in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():\r
623 FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict[FvName]\r
624 FvObj.AddToBuffer(Buffer=None, Flag=True)\r
625\r
626 if GenFdsGlobalVariable.FdfParser.Profile.OptRomDict != {}:\r
627 for DriverName in GenFdsGlobalVariable.FdfParser.Profile.OptRomDict.keys():\r
628 OptRomObj = GenFdsGlobalVariable.FdfParser.Profile.OptRomDict[DriverName]\r
629 OptRomObj.AddToBuffer(Buffer=None, Flag=True)\r
630\r
631 return GenFdsGlobalVariable.FfsCmdDict\r
f51461c8
LG
632\r
633 ## GetFvBlockSize()\r
634 #\r
635 # @param FvObj Whose block size to get\r
636 # @retval int Block size value\r
637 #\r
638 def GetFvBlockSize(FvObj):\r
639 DefaultBlockSize = 0x1\r
640 FdObj = None\r
641 if GenFds.OnlyGenerateThisFd != None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():\r
642 FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[GenFds.OnlyGenerateThisFd.upper()]\r
643 if FdObj == None:\r
644 for ElementFd in GenFdsGlobalVariable.FdfParser.Profile.FdDict.values():\r
645 for ElementRegion in ElementFd.RegionList:\r
646 if ElementRegion.RegionType == 'FV':\r
647 for ElementRegionData in ElementRegion.RegionDataList:\r
648 if ElementRegionData != None and ElementRegionData.upper() == FvObj.UiFvName:\r
649 if FvObj.BlockSizeList != []:\r
650 return FvObj.BlockSizeList[0][0]\r
651 else:\r
652 return ElementRegion.BlockSizeOfRegion(ElementFd.BlockSizeList)\r
653 if FvObj.BlockSizeList != []:\r
654 return FvObj.BlockSizeList[0][0]\r
655 return DefaultBlockSize\r
656 else:\r
657 for ElementRegion in FdObj.RegionList:\r
658 if ElementRegion.RegionType == 'FV':\r
659 for ElementRegionData in ElementRegion.RegionDataList:\r
660 if ElementRegionData != None and ElementRegionData.upper() == FvObj.UiFvName:\r
661 if FvObj.BlockSizeList != []:\r
662 return FvObj.BlockSizeList[0][0]\r
663 else:\r
664 return ElementRegion.BlockSizeOfRegion(ElementFd.BlockSizeList)\r
665 return DefaultBlockSize\r
666\r
667 ## DisplayFvSpaceInfo()\r
668 #\r
669 # @param FvObj Whose block size to get\r
670 # @retval None\r
671 #\r
672 def DisplayFvSpaceInfo(FdfParser):\r
673 \r
674 FvSpaceInfoList = []\r
675 MaxFvNameLength = 0\r
676 for FvName in FdfParser.Profile.FvDict:\r
677 if len(FvName) > MaxFvNameLength:\r
678 MaxFvNameLength = len(FvName)\r
679 FvSpaceInfoFileName = os.path.join(GenFdsGlobalVariable.FvDir, FvName.upper() + '.Fv.map')\r
680 if os.path.exists(FvSpaceInfoFileName):\r
681 FileLinesList = linecache.getlines(FvSpaceInfoFileName)\r
682 TotalFound = False\r
683 Total = ''\r
684 UsedFound = False\r
685 Used = ''\r
686 FreeFound = False\r
687 Free = ''\r
688 for Line in FileLinesList:\r
689 NameValue = Line.split('=')\r
690 if len(NameValue) == 2:\r
691 if NameValue[0].strip() == 'EFI_FV_TOTAL_SIZE':\r
692 TotalFound = True\r
693 Total = NameValue[1].strip()\r
694 if NameValue[0].strip() == 'EFI_FV_TAKEN_SIZE':\r
695 UsedFound = True\r
696 Used = NameValue[1].strip()\r
697 if NameValue[0].strip() == 'EFI_FV_SPACE_SIZE':\r
698 FreeFound = True\r
699 Free = NameValue[1].strip()\r
700 \r
701 if TotalFound and UsedFound and FreeFound:\r
702 FvSpaceInfoList.append((FvName, Total, Used, Free))\r
703 \r
704 GenFdsGlobalVariable.InfLogger('\nFV Space Information')\r
705 for FvSpaceInfo in FvSpaceInfoList:\r
706 Name = FvSpaceInfo[0]\r
707 TotalSizeValue = long(FvSpaceInfo[1], 0)\r
708 UsedSizeValue = long(FvSpaceInfo[2], 0)\r
709 FreeSizeValue = long(FvSpaceInfo[3], 0)\r
710 if UsedSizeValue == TotalSizeValue:\r
711 Percentage = '100'\r
712 else:\r
47fea6af
YZ
713 Percentage = str((UsedSizeValue + 0.0) / TotalSizeValue)[0:4].lstrip('0.')\r
714\r
f51461c8
LG
715 GenFdsGlobalVariable.InfLogger(Name + ' ' + '[' + Percentage + '%Full] ' + str(TotalSizeValue) + ' total, ' + str(UsedSizeValue) + ' used, ' + str(FreeSizeValue) + ' free')\r
716\r
717 ## PreprocessImage()\r
718 #\r
719 # @param BuildDb Database from build meta data files\r
720 # @param DscFile modules from dsc file will be preprocessed\r
721 # @retval None\r
722 #\r
723 def PreprocessImage(BuildDb, DscFile):\r
724 PcdDict = BuildDb.BuildObject[DscFile, 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].Pcds\r
725 PcdValue = ''\r
726 for Key in PcdDict:\r
727 PcdObj = PcdDict[Key]\r
728 if PcdObj.TokenCName == 'PcdBsBaseAddress':\r
729 PcdValue = PcdObj.DefaultValue\r
730 break\r
731 \r
732 if PcdValue == '':\r
733 return\r
734 \r
735 Int64PcdValue = long(PcdValue, 0)\r
736 if Int64PcdValue == 0 or Int64PcdValue < -1: \r
737 return\r
738 \r
739 TopAddress = 0\r
740 if Int64PcdValue > 0:\r
741 TopAddress = Int64PcdValue\r
742 \r
743 ModuleDict = BuildDb.BuildObject[DscFile, 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].Modules\r
744 for Key in ModuleDict:\r
745 ModuleObj = BuildDb.BuildObject[Key, 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
746 print ModuleObj.BaseName + ' ' + ModuleObj.ModuleType\r
747\r
5e9256cd 748 def GenerateGuidXRefFile(BuildDb, ArchList, FdfParserObj):\r
f51461c8
LG
749 GuidXRefFileName = os.path.join(GenFdsGlobalVariable.FvDir, "Guid.xref")\r
750 GuidXRefFile = StringIO.StringIO('')\r
e4ac870f 751 GuidDict = {}\r
5e9256cd
YZ
752 ModuleList = []\r
753 FileGuidList = []\r
f51461c8
LG
754 for Arch in ArchList:\r
755 PlatformDataBase = BuildDb.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
756 for ModuleFile in PlatformDataBase.Modules:\r
757 Module = BuildDb.BuildObject[ModuleFile, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
5e9256cd
YZ
758 if Module in ModuleList:\r
759 continue\r
760 else:\r
761 ModuleList.append(Module)\r
f51461c8 762 GuidXRefFile.write("%s %s\n" % (Module.Guid, Module.BaseName))\r
e4ac870f
LG
763 for key, item in Module.Protocols.items():\r
764 GuidDict[key] = item\r
765 for key, item in Module.Guids.items():\r
766 GuidDict[key] = item\r
767 for key, item in Module.Ppis.items():\r
768 GuidDict[key] = item\r
5e9256cd
YZ
769 for FvName in FdfParserObj.Profile.FvDict:\r
770 for FfsObj in FdfParserObj.Profile.FvDict[FvName].FfsList:\r
771 if not isinstance(FfsObj, FfsFileStatement.FileStatement):\r
772 InfPath = PathClass(NormPath(mws.join(GenFdsGlobalVariable.WorkSpaceDir, FfsObj.InfFileName)))\r
773 FdfModule = BuildDb.BuildObject[InfPath, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
774 if FdfModule in ModuleList:\r
775 continue\r
776 else:\r
777 ModuleList.append(FdfModule)\r
778 GuidXRefFile.write("%s %s\n" % (FdfModule.Guid, FdfModule.BaseName))\r
779 for key, item in FdfModule.Protocols.items():\r
780 GuidDict[key] = item\r
781 for key, item in FdfModule.Guids.items():\r
782 GuidDict[key] = item\r
783 for key, item in FdfModule.Ppis.items():\r
784 GuidDict[key] = item\r
785 else:\r
786 FileStatementGuid = FfsObj.NameGuid\r
787 if FileStatementGuid in FileGuidList:\r
788 continue\r
789 else:\r
790 FileGuidList.append(FileStatementGuid)\r
791 Name = []\r
792 FfsPath = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs')\r
793 FfsPath = glob.glob(os.path.join(FfsPath, FileStatementGuid) + '*')\r
794 if not FfsPath:\r
795 continue\r
796 if not os.path.exists(FfsPath[0]):\r
797 continue\r
798 MatchDict = {}\r
799 ReFileEnds = re.compile('\S+(.ui)$|\S+(fv.sec.txt)$|\S+(.pe32.txt)$|\S+(.te.txt)$|\S+(.pic.txt)$|\S+(.raw.txt)$|\S+(.ffs.txt)$')\r
800 FileList = os.listdir(FfsPath[0])\r
801 for File in FileList:\r
802 Match = ReFileEnds.search(File)\r
803 if Match:\r
804 for Index in range(1, 8):\r
805 if Match.group(Index) and Match.group(Index) in MatchDict:\r
806 MatchDict[Match.group(Index)].append(File)\r
807 elif Match.group(Index):\r
808 MatchDict[Match.group(Index)] = [File]\r
809 if not MatchDict:\r
810 continue\r
811 if '.ui' in MatchDict:\r
812 for File in MatchDict['.ui']:\r
813 with open(os.path.join(FfsPath[0], File), 'rb') as F:\r
814 F.read()\r
815 length = F.tell()\r
816 F.seek(4)\r
817 TmpStr = unpack('%dh' % ((length - 4) / 2), F.read())\r
818 Name = ''.join([chr(c) for c in TmpStr[:-1]])\r
819 else:\r
820 FileList = []\r
821 if 'fv.sec.txt' in MatchDict:\r
822 FileList = MatchDict['fv.sec.txt']\r
823 elif '.pe32.txt' in MatchDict:\r
824 FileList = MatchDict['.pe32.txt']\r
825 elif '.te.txt' in MatchDict:\r
826 FileList = MatchDict['.te.txt']\r
827 elif '.pic.txt' in MatchDict:\r
828 FileList = MatchDict['.pic.txt']\r
829 elif '.raw.txt' in MatchDict:\r
830 FileList = MatchDict['.raw.txt']\r
831 elif '.ffs.txt' in MatchDict:\r
832 FileList = MatchDict['.ffs.txt']\r
833 else:\r
834 pass\r
835 for File in FileList:\r
836 with open(os.path.join(FfsPath[0], File), 'r') as F:\r
837 Name.append((F.read().split()[-1]))\r
838 if not Name:\r
839 continue\r
840\r
841 Name = ' '.join(Name) if type(Name) == type([]) else Name\r
842 GuidXRefFile.write("%s %s\n" %(FileStatementGuid, Name))\r
843\r
e4ac870f
LG
844 # Append GUIDs, Protocols, and PPIs to the Xref file\r
845 GuidXRefFile.write("\n")\r
846 for key, item in GuidDict.items():\r
847 GuidXRefFile.write("%s %s\n" % (GuidStructureStringToGuidString(item).upper(), key))\r
848\r
f51461c8
LG
849 if GuidXRefFile.getvalue():\r
850 SaveFileOnChange(GuidXRefFileName, GuidXRefFile.getvalue(), False)\r
851 GenFdsGlobalVariable.InfLogger("\nGUID cross reference file can be found at %s" % GuidXRefFileName)\r
852 elif os.path.exists(GuidXRefFileName):\r
853 os.remove(GuidXRefFileName)\r
854 GuidXRefFile.close()\r
855\r
856 ##Define GenFd as static function\r
857 GenFd = staticmethod(GenFd)\r
858 GetFvBlockSize = staticmethod(GetFvBlockSize)\r
859 DisplayFvSpaceInfo = staticmethod(DisplayFvSpaceInfo)\r
860 PreprocessImage = staticmethod(PreprocessImage)\r
861 GenerateGuidXRefFile = staticmethod(GenerateGuidXRefFile)\r
862\r
863if __name__ == '__main__':\r
864 r = main()\r
865 ## 0-127 is a safe return range, and 1 is a standard default error\r
866 if r < 0 or r > 127: r = 1\r
867 sys.exit(r)\r
868\r