]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/GenFds/GenFds.py
BaseTools: Support multiple .h file
[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
305 if Options.OptionPcd:\r
306 GlobalData.BuildOptionPcd = Options.OptionPcd\r
307 CheckBuildOptionPcd()\r
308\r
f51461c8
LG
309 """Modify images from build output if the feature of loading driver at fixed address is on."""\r
310 if GenFdsGlobalVariable.FixedLoadAddress:\r
311 GenFds.PreprocessImage(BuildWorkSpace, GenFdsGlobalVariable.ActivePlatform)\r
135ae8c8
YZ
312\r
313 # Record the FV Region info that may specific in the FD\r
314 if FdfParserObj.Profile.FvDict and FdfParserObj.Profile.FdDict:\r
315 for Fv in FdfParserObj.Profile.FvDict:\r
316 FvObj = FdfParserObj.Profile.FvDict[Fv]\r
317 for Fd in FdfParserObj.Profile.FdDict:\r
318 FdObj = FdfParserObj.Profile.FdDict[Fd]\r
319 for RegionObj in FdObj.RegionList:\r
320 if RegionObj.RegionType != 'FV':\r
321 continue\r
322 for RegionData in RegionObj.RegionDataList:\r
323 if FvObj.UiFvName.upper() == RegionData.upper():\r
324 if FvObj.FvRegionInFD:\r
325 if FvObj.FvRegionInFD != RegionObj.Size:\r
326 EdkLogger.error("GenFds", FORMAT_INVALID, "The FV %s's region is specified in multiple FD with different value." %FvObj.UiFvName)\r
327 else:\r
328 FvObj.FvRegionInFD = RegionObj.Size\r
329 RegionObj.BlockInfoOfRegion(FdObj.BlockSizeList, FvObj)\r
330\r
f51461c8
LG
331 """Call GenFds"""\r
332 GenFds.GenFd('', FdfParserObj, BuildWorkSpace, ArchList)\r
333\r
334 """Generate GUID cross reference file"""\r
5e9256cd 335 GenFds.GenerateGuidXRefFile(BuildWorkSpace, ArchList, FdfParserObj)\r
f51461c8
LG
336\r
337 """Display FV space info."""\r
338 GenFds.DisplayFvSpaceInfo(FdfParserObj)\r
339\r
340 except FdfParser.Warning, X:\r
47fea6af 341 EdkLogger.error(X.ToolName, FORMAT_INVALID, File=X.FileName, Line=X.LineNumber, ExtraData=X.Message, RaiseError=False)\r
f51461c8
LG
342 ReturnCode = FORMAT_INVALID\r
343 except FatalError, X:\r
344 if Options.debug != None:\r
345 import traceback\r
346 EdkLogger.quiet(traceback.format_exc())\r
347 ReturnCode = X.args[0]\r
348 except:\r
349 import traceback\r
350 EdkLogger.error(\r
351 "\nPython",\r
352 CODE_ERROR,\r
353 "Tools code failure",\r
3a0f8bde 354 ExtraData="Please send email to edk2-devel@lists.01.org for help, attaching following call stack trace!\n",\r
f51461c8
LG
355 RaiseError=False\r
356 )\r
357 EdkLogger.quiet(traceback.format_exc())\r
358 ReturnCode = CODE_ERROR\r
97fa0ee9
YL
359 finally:\r
360 ClearDuplicatedInf()\r
f51461c8
LG
361 return ReturnCode\r
362\r
363gParamCheck = []\r
364def SingleCheckCallback(option, opt_str, value, parser):\r
365 if option not in gParamCheck:\r
366 setattr(parser.values, option.dest, value)\r
367 gParamCheck.append(option)\r
368 else:\r
369 parser.error("Option %s only allows one instance in command line!" % option)\r
6b17c11b
YZ
370\r
371def CheckBuildOptionPcd():\r
372 for Arch in GenFdsGlobalVariable.ArchList:\r
373 PkgList = GenFdsGlobalVariable.WorkSpace.GetPackageList(GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag)\r
374 for i, pcd in enumerate(GlobalData.BuildOptionPcd):\r
375 if type(pcd) is tuple:\r
376 continue\r
377 (pcdname, pcdvalue) = pcd.split('=')\r
378 if not pcdvalue:\r
379 EdkLogger.error('GenFds', OPTION_MISSING, "No Value specified for the PCD %s." % (pcdname))\r
380 if '.' in pcdname:\r
381 (TokenSpaceGuidCName, TokenCName) = pcdname.split('.')\r
382 HasTokenSpace = True\r
383 else:\r
384 TokenCName = pcdname\r
385 TokenSpaceGuidCName = ''\r
386 HasTokenSpace = False\r
387 TokenSpaceGuidCNameList = []\r
388 FoundFlag = False\r
389 PcdDatumType = ''\r
390 NewValue = ''\r
391 for package in PkgList:\r
392 for key in package.Pcds:\r
393 PcdItem = package.Pcds[key]\r
394 if HasTokenSpace:\r
395 if (PcdItem.TokenCName, PcdItem.TokenSpaceGuidCName) == (TokenCName, TokenSpaceGuidCName):\r
396 PcdDatumType = PcdItem.DatumType\r
397 NewValue = BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)\r
398 FoundFlag = True\r
399 else:\r
400 if PcdItem.TokenCName == TokenCName:\r
401 if not PcdItem.TokenSpaceGuidCName in TokenSpaceGuidCNameList:\r
402 if len (TokenSpaceGuidCNameList) < 1:\r
403 TokenSpaceGuidCNameList.append(PcdItem.TokenSpaceGuidCName)\r
404 PcdDatumType = PcdItem.DatumType\r
405 TokenSpaceGuidCName = PcdItem.TokenSpaceGuidCName\r
406 NewValue = BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)\r
407 FoundFlag = True\r
408 else:\r
409 EdkLogger.error(\r
410 'GenFds',\r
411 PCD_VALIDATION_INFO_ERROR,\r
412 "The Pcd %s is found under multiple different TokenSpaceGuid: %s and %s." % (TokenCName, PcdItem.TokenSpaceGuidCName, TokenSpaceGuidCNameList[0])\r
413 )\r
414\r
415 GlobalData.BuildOptionPcd[i] = (TokenSpaceGuidCName, TokenCName, NewValue)\r
416\r
6b17c11b 417\r
91ae2988
YZ
418## FindExtendTool()\r
419#\r
420# Find location of tools to process data\r
421#\r
422# @param KeyStringList Filter for inputs of section generation\r
423# @param CurrentArchList Arch list\r
424# @param NameGuid The Guid name\r
425#\r
426def FindExtendTool(KeyStringList, CurrentArchList, NameGuid):\r
95816356 427 ToolDb = ToolDefClassObject.ToolDefDict(GenFdsGlobalVariable.ConfDir).ToolsDefTxtDatabase\r
91ae2988
YZ
428 # if user not specify filter, try to deduce it from global data.\r
429 if KeyStringList == None or KeyStringList == []:\r
430 Target = GenFdsGlobalVariable.TargetName\r
431 ToolChain = GenFdsGlobalVariable.ToolChainTag\r
91ae2988
YZ
432 if ToolChain not in ToolDb['TOOL_CHAIN_TAG']:\r
433 EdkLogger.error("GenFds", GENFDS_ERROR, "Can not find external tool because tool tag %s is not defined in tools_def.txt!" % ToolChain)\r
434 KeyStringList = [Target + '_' + ToolChain + '_' + CurrentArchList[0]]\r
435 for Arch in CurrentArchList:\r
436 if Target + '_' + ToolChain + '_' + Arch not in KeyStringList:\r
437 KeyStringList.append(Target + '_' + ToolChain + '_' + Arch)\r
438\r
439 if GenFdsGlobalVariable.GuidToolDefinition:\r
440 if NameGuid in GenFdsGlobalVariable.GuidToolDefinition.keys():\r
441 return GenFdsGlobalVariable.GuidToolDefinition[NameGuid]\r
442\r
443 ToolDefinition = ToolDefClassObject.ToolDefDict(GenFdsGlobalVariable.ConfDir).ToolsDefTxtDictionary\r
444 ToolPathTmp = None\r
445 ToolOption = None\r
95816356
YZ
446 ToolPathKey = None\r
447 ToolOptionKey = None\r
448 KeyList = None\r
91ae2988
YZ
449 for ToolDef in ToolDefinition.items():\r
450 if NameGuid == ToolDef[1]:\r
451 KeyList = ToolDef[0].split('_')\r
452 Key = KeyList[0] + \\r
453 '_' + \\r
454 KeyList[1] + \\r
455 '_' + \\r
456 KeyList[2]\r
457 if Key in KeyStringList and KeyList[4] == 'GUID':\r
95816356
YZ
458 ToolPathKey = Key + '_' + KeyList[3] + '_PATH'\r
459 ToolOptionKey = Key + '_' + KeyList[3] + '_FLAGS'\r
460 ToolPath = ToolDefinition.get(ToolPathKey)\r
461 ToolOption = ToolDefinition.get(ToolOptionKey)\r
91ae2988
YZ
462 if ToolPathTmp == None:\r
463 ToolPathTmp = ToolPath\r
464 else:\r
465 if ToolPathTmp != ToolPath:\r
466 EdkLogger.error("GenFds", GENFDS_ERROR, "Don't know which tool to use, %s or %s ?" % (ToolPathTmp, ToolPath))\r
467\r
95816356
YZ
468 BuildOption = {}\r
469 for Arch in CurrentArchList:\r
470 Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
471 # key is (ToolChainFamily, ToolChain, CodeBase)\r
472 for item in Platform.BuildOptions:\r
473 if '_PATH' in item[1] or '_FLAGS' in item[1] or '_GUID' in item[1]:\r
474 if not item[0] or (item[0] and GenFdsGlobalVariable.ToolChainFamily== item[0]):\r
475 if item[1] not in BuildOption:\r
476 BuildOption[item[1]] = Platform.BuildOptions[item]\r
477 if BuildOption:\r
478 ToolList = [TAB_TOD_DEFINES_TARGET, TAB_TOD_DEFINES_TOOL_CHAIN_TAG, TAB_TOD_DEFINES_TARGET_ARCH]\r
479 for Index in range(2, -1, -1):\r
480 for Key in dict(BuildOption):\r
481 List = Key.split('_')\r
482 if List[Index] == '*':\r
483 for String in ToolDb[ToolList[Index]]:\r
484 if String in [Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]:\r
485 List[Index] = String\r
486 NewKey = '%s_%s_%s_%s_%s' % tuple(List)\r
487 if NewKey not in BuildOption:\r
488 BuildOption[NewKey] = BuildOption[Key]\r
489 continue\r
490 del BuildOption[Key]\r
491 elif List[Index] not in ToolDb[ToolList[Index]]:\r
492 del BuildOption[Key]\r
493 if BuildOption:\r
494 if not KeyList:\r
495 for Op in BuildOption:\r
496 if NameGuid == BuildOption[Op]:\r
497 KeyList = Op.split('_')\r
498 Key = KeyList[0] + '_' + KeyList[1] +'_' + KeyList[2]\r
499 if Key in KeyStringList and KeyList[4] == 'GUID':\r
500 ToolPathKey = Key + '_' + KeyList[3] + '_PATH'\r
501 ToolOptionKey = Key + '_' + KeyList[3] + '_FLAGS'\r
502 if ToolPathKey in BuildOption.keys():\r
503 ToolPathTmp = BuildOption.get(ToolPathKey)\r
504 if ToolOptionKey in BuildOption.keys():\r
505 ToolOption = BuildOption.get(ToolOptionKey)\r
506\r
91ae2988
YZ
507 GenFdsGlobalVariable.GuidToolDefinition[NameGuid] = (ToolPathTmp, ToolOption)\r
508 return ToolPathTmp, ToolOption\r
509\r
f51461c8
LG
510## Parse command line options\r
511#\r
512# Using standard Python module optparse to parse command line option of this tool.\r
513#\r
514# @retval Opt A optparse.Values object containing the parsed options\r
515# @retval Args Target of build command\r
516#\r
517def myOptionParser():\r
518 usage = "%prog [options] -f input_file -a arch_list -b build_target -p active_platform -t tool_chain_tag -D \"MacroName [= MacroValue]\""\r
47fea6af 519 Parser = OptionParser(usage=usage, description=__copyright__, version="%prog " + str(versionNumber))\r
f51461c8
LG
520 Parser.add_option("-f", "--file", dest="filename", type="string", help="Name of FDF file to convert", action="callback", callback=SingleCheckCallback)\r
521 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
522 Parser.add_option("-q", "--quiet", action="store_true", type=None, help="Disable all messages except FATAL ERRORS.")\r
523 Parser.add_option("-v", "--verbose", action="store_true", type=None, help="Turn on verbose output with informational messages printed.")\r
524 Parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.")\r
525 Parser.add_option("-p", "--platform", type="string", dest="activePlatform", help="Set the ACTIVE_PLATFORM, overrides target.txt ACTIVE_PLATFORM setting.",\r
526 action="callback", callback=SingleCheckCallback)\r
527 Parser.add_option("-w", "--workspace", type="string", dest="Workspace", default=os.environ.get('WORKSPACE'), help="Set the WORKSPACE",\r
528 action="callback", callback=SingleCheckCallback)\r
529 Parser.add_option("-o", "--outputDir", type="string", dest="outputDir", help="Name of Build Output directory",\r
530 action="callback", callback=SingleCheckCallback)\r
531 Parser.add_option("-r", "--rom_image", dest="uiFdName", help="Build the image using the [FD] section named by FdUiName.")\r
532 Parser.add_option("-i", "--FvImage", dest="uiFvName", help="Build the FV image using the [FV] section named by UiFvName")\r
533 Parser.add_option("-C", "--CapsuleImage", dest="uiCapName", help="Build the Capsule image using the [Capsule] section named by UiCapName")\r
534 Parser.add_option("-b", "--buildtarget", type="string", dest="BuildTarget", help="Set the build TARGET, overrides target.txt TARGET setting.",\r
535 action="callback", callback=SingleCheckCallback)\r
536 Parser.add_option("-t", "--tagname", type="string", dest="ToolChain", help="Using the tools: TOOL_CHAIN_TAG name to build the platform.",\r
537 action="callback", callback=SingleCheckCallback)\r
538 Parser.add_option("-D", "--define", action="append", type="string", dest="Macros", help="Macro: \"Name [= Value]\".")\r
539 Parser.add_option("-s", "--specifyaddress", dest="FixedAddress", action="store_true", type=None, help="Specify driver load address.")\r
97fa0ee9
YL
540 Parser.add_option("--conf", action="store", type="string", dest="ConfDirectory", help="Specify the customized Conf directory.")\r
541 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 542 Parser.add_option("--pcd", action="append", dest="OptionPcd", help="Set PCD value by command line. Format: \"PcdName=Value\" ")\r
37de70b7 543 Parser.add_option("--genfds-multi-thread", action="store_true", dest="GenfdsMultiThread", default=False, help="Enable GenFds multi thread to generate ffs file.")\r
97fa0ee9 544\r
f51461c8
LG
545 (Options, args) = Parser.parse_args()\r
546 return Options\r
547\r
548## The class implementing the EDK2 flash image generation process\r
549#\r
550# This process includes:\r
551# 1. Collect workspace information, includes platform and module information\r
552# 2. Call methods of Fd class to generate FD\r
553# 3. Call methods of Fv class to generate FV that not belong to FD\r
554#\r
555class GenFds :\r
556 FdfParsef = None\r
557 # FvName, FdName, CapName in FDF, Image file name\r
558 ImageBinDict = {}\r
559 OnlyGenerateThisFd = None\r
560 OnlyGenerateThisFv = None\r
561 OnlyGenerateThisCap = None\r
562\r
563 ## GenFd()\r
564 #\r
565 # @param OutputDir Output directory\r
566 # @param FdfParser FDF contents parser\r
567 # @param Workspace The directory of workspace\r
568 # @param ArchList The Arch list of platform\r
569 #\r
570 def GenFd (OutputDir, FdfParser, WorkSpace, ArchList):\r
571 GenFdsGlobalVariable.SetDir ('', FdfParser, WorkSpace, ArchList)\r
572\r
573 GenFdsGlobalVariable.VerboseLogger(" Generate all Fd images and their required FV and Capsule images!")\r
574 if GenFds.OnlyGenerateThisCap != None and GenFds.OnlyGenerateThisCap.upper() in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.keys():\r
575 CapsuleObj = GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.get(GenFds.OnlyGenerateThisCap.upper())\r
576 if CapsuleObj != None:\r
577 CapsuleObj.GenCapsule()\r
578 return\r
579\r
580 if GenFds.OnlyGenerateThisFd != None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():\r
581 FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict.get(GenFds.OnlyGenerateThisFd.upper())\r
582 if FdObj != None:\r
583 FdObj.GenFd()\r
584 return\r
585 elif GenFds.OnlyGenerateThisFd == None and GenFds.OnlyGenerateThisFv == None:\r
586 for FdName in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():\r
587 FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[FdName]\r
588 FdObj.GenFd()\r
589\r
590 GenFdsGlobalVariable.VerboseLogger("\n Generate other FV images! ")\r
591 if GenFds.OnlyGenerateThisFv != None and GenFds.OnlyGenerateThisFv.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():\r
592 FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(GenFds.OnlyGenerateThisFv.upper())\r
593 if FvObj != None:\r
594 Buffer = StringIO.StringIO()\r
595 FvObj.AddToBuffer(Buffer)\r
596 Buffer.close()\r
597 return\r
598 elif GenFds.OnlyGenerateThisFv == None:\r
599 for FvName in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():\r
600 Buffer = StringIO.StringIO('')\r
601 FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict[FvName]\r
602 FvObj.AddToBuffer(Buffer)\r
603 Buffer.close()\r
604 \r
605 if GenFds.OnlyGenerateThisFv == None and GenFds.OnlyGenerateThisFd == None and GenFds.OnlyGenerateThisCap == None:\r
606 if GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict != {}:\r
607 GenFdsGlobalVariable.VerboseLogger("\n Generate other Capsule images!")\r
608 for CapsuleName in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.keys():\r
609 CapsuleObj = GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict[CapsuleName]\r
610 CapsuleObj.GenCapsule()\r
611\r
612 if GenFdsGlobalVariable.FdfParser.Profile.OptRomDict != {}:\r
613 GenFdsGlobalVariable.VerboseLogger("\n Generate all Option ROM!")\r
614 for DriverName in GenFdsGlobalVariable.FdfParser.Profile.OptRomDict.keys():\r
615 OptRomObj = GenFdsGlobalVariable.FdfParser.Profile.OptRomDict[DriverName]\r
616 OptRomObj.AddToBuffer(None)\r
37de70b7
YZ
617 @staticmethod\r
618 def GenFfsMakefile(OutputDir, FdfParser, WorkSpace, ArchList, GlobalData):\r
619 GenFdsGlobalVariable.SetEnv(FdfParser, WorkSpace, ArchList, GlobalData)\r
620 for FdName in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():\r
621 FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[FdName]\r
622 FdObj.GenFd(Flag=True)\r
623\r
624 for FvName in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():\r
625 FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict[FvName]\r
626 FvObj.AddToBuffer(Buffer=None, Flag=True)\r
627\r
628 if GenFdsGlobalVariable.FdfParser.Profile.OptRomDict != {}:\r
629 for DriverName in GenFdsGlobalVariable.FdfParser.Profile.OptRomDict.keys():\r
630 OptRomObj = GenFdsGlobalVariable.FdfParser.Profile.OptRomDict[DriverName]\r
631 OptRomObj.AddToBuffer(Buffer=None, Flag=True)\r
632\r
633 return GenFdsGlobalVariable.FfsCmdDict\r
f51461c8
LG
634\r
635 ## GetFvBlockSize()\r
636 #\r
637 # @param FvObj Whose block size to get\r
638 # @retval int Block size value\r
639 #\r
640 def GetFvBlockSize(FvObj):\r
641 DefaultBlockSize = 0x1\r
642 FdObj = None\r
643 if GenFds.OnlyGenerateThisFd != None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():\r
644 FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[GenFds.OnlyGenerateThisFd.upper()]\r
645 if FdObj == None:\r
646 for ElementFd in GenFdsGlobalVariable.FdfParser.Profile.FdDict.values():\r
647 for ElementRegion in ElementFd.RegionList:\r
648 if ElementRegion.RegionType == 'FV':\r
649 for ElementRegionData in ElementRegion.RegionDataList:\r
650 if ElementRegionData != None and ElementRegionData.upper() == FvObj.UiFvName:\r
651 if FvObj.BlockSizeList != []:\r
652 return FvObj.BlockSizeList[0][0]\r
653 else:\r
654 return ElementRegion.BlockSizeOfRegion(ElementFd.BlockSizeList)\r
655 if FvObj.BlockSizeList != []:\r
656 return FvObj.BlockSizeList[0][0]\r
657 return DefaultBlockSize\r
658 else:\r
659 for ElementRegion in FdObj.RegionList:\r
660 if ElementRegion.RegionType == 'FV':\r
661 for ElementRegionData in ElementRegion.RegionDataList:\r
662 if ElementRegionData != None and ElementRegionData.upper() == FvObj.UiFvName:\r
663 if FvObj.BlockSizeList != []:\r
664 return FvObj.BlockSizeList[0][0]\r
665 else:\r
666 return ElementRegion.BlockSizeOfRegion(ElementFd.BlockSizeList)\r
667 return DefaultBlockSize\r
668\r
669 ## DisplayFvSpaceInfo()\r
670 #\r
671 # @param FvObj Whose block size to get\r
672 # @retval None\r
673 #\r
674 def DisplayFvSpaceInfo(FdfParser):\r
675 \r
676 FvSpaceInfoList = []\r
677 MaxFvNameLength = 0\r
678 for FvName in FdfParser.Profile.FvDict:\r
679 if len(FvName) > MaxFvNameLength:\r
680 MaxFvNameLength = len(FvName)\r
681 FvSpaceInfoFileName = os.path.join(GenFdsGlobalVariable.FvDir, FvName.upper() + '.Fv.map')\r
682 if os.path.exists(FvSpaceInfoFileName):\r
683 FileLinesList = linecache.getlines(FvSpaceInfoFileName)\r
684 TotalFound = False\r
685 Total = ''\r
686 UsedFound = False\r
687 Used = ''\r
688 FreeFound = False\r
689 Free = ''\r
690 for Line in FileLinesList:\r
691 NameValue = Line.split('=')\r
692 if len(NameValue) == 2:\r
693 if NameValue[0].strip() == 'EFI_FV_TOTAL_SIZE':\r
694 TotalFound = True\r
695 Total = NameValue[1].strip()\r
696 if NameValue[0].strip() == 'EFI_FV_TAKEN_SIZE':\r
697 UsedFound = True\r
698 Used = NameValue[1].strip()\r
699 if NameValue[0].strip() == 'EFI_FV_SPACE_SIZE':\r
700 FreeFound = True\r
701 Free = NameValue[1].strip()\r
702 \r
703 if TotalFound and UsedFound and FreeFound:\r
704 FvSpaceInfoList.append((FvName, Total, Used, Free))\r
705 \r
706 GenFdsGlobalVariable.InfLogger('\nFV Space Information')\r
707 for FvSpaceInfo in FvSpaceInfoList:\r
708 Name = FvSpaceInfo[0]\r
709 TotalSizeValue = long(FvSpaceInfo[1], 0)\r
710 UsedSizeValue = long(FvSpaceInfo[2], 0)\r
711 FreeSizeValue = long(FvSpaceInfo[3], 0)\r
712 if UsedSizeValue == TotalSizeValue:\r
713 Percentage = '100'\r
714 else:\r
47fea6af
YZ
715 Percentage = str((UsedSizeValue + 0.0) / TotalSizeValue)[0:4].lstrip('0.')\r
716\r
f51461c8
LG
717 GenFdsGlobalVariable.InfLogger(Name + ' ' + '[' + Percentage + '%Full] ' + str(TotalSizeValue) + ' total, ' + str(UsedSizeValue) + ' used, ' + str(FreeSizeValue) + ' free')\r
718\r
719 ## PreprocessImage()\r
720 #\r
721 # @param BuildDb Database from build meta data files\r
722 # @param DscFile modules from dsc file will be preprocessed\r
723 # @retval None\r
724 #\r
725 def PreprocessImage(BuildDb, DscFile):\r
726 PcdDict = BuildDb.BuildObject[DscFile, 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].Pcds\r
727 PcdValue = ''\r
728 for Key in PcdDict:\r
729 PcdObj = PcdDict[Key]\r
730 if PcdObj.TokenCName == 'PcdBsBaseAddress':\r
731 PcdValue = PcdObj.DefaultValue\r
732 break\r
733 \r
734 if PcdValue == '':\r
735 return\r
736 \r
737 Int64PcdValue = long(PcdValue, 0)\r
738 if Int64PcdValue == 0 or Int64PcdValue < -1: \r
739 return\r
740 \r
741 TopAddress = 0\r
742 if Int64PcdValue > 0:\r
743 TopAddress = Int64PcdValue\r
744 \r
745 ModuleDict = BuildDb.BuildObject[DscFile, 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].Modules\r
746 for Key in ModuleDict:\r
747 ModuleObj = BuildDb.BuildObject[Key, 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
748 print ModuleObj.BaseName + ' ' + ModuleObj.ModuleType\r
749\r
5e9256cd 750 def GenerateGuidXRefFile(BuildDb, ArchList, FdfParserObj):\r
f51461c8
LG
751 GuidXRefFileName = os.path.join(GenFdsGlobalVariable.FvDir, "Guid.xref")\r
752 GuidXRefFile = StringIO.StringIO('')\r
e4ac870f 753 GuidDict = {}\r
5e9256cd
YZ
754 ModuleList = []\r
755 FileGuidList = []\r
f51461c8
LG
756 for Arch in ArchList:\r
757 PlatformDataBase = BuildDb.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
758 for ModuleFile in PlatformDataBase.Modules:\r
759 Module = BuildDb.BuildObject[ModuleFile, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
5e9256cd
YZ
760 if Module in ModuleList:\r
761 continue\r
762 else:\r
763 ModuleList.append(Module)\r
f51461c8 764 GuidXRefFile.write("%s %s\n" % (Module.Guid, Module.BaseName))\r
e4ac870f
LG
765 for key, item in Module.Protocols.items():\r
766 GuidDict[key] = item\r
767 for key, item in Module.Guids.items():\r
768 GuidDict[key] = item\r
769 for key, item in Module.Ppis.items():\r
770 GuidDict[key] = item\r
5e9256cd
YZ
771 for FvName in FdfParserObj.Profile.FvDict:\r
772 for FfsObj in FdfParserObj.Profile.FvDict[FvName].FfsList:\r
773 if not isinstance(FfsObj, FfsFileStatement.FileStatement):\r
774 InfPath = PathClass(NormPath(mws.join(GenFdsGlobalVariable.WorkSpaceDir, FfsObj.InfFileName)))\r
775 FdfModule = BuildDb.BuildObject[InfPath, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
776 if FdfModule in ModuleList:\r
777 continue\r
778 else:\r
779 ModuleList.append(FdfModule)\r
780 GuidXRefFile.write("%s %s\n" % (FdfModule.Guid, FdfModule.BaseName))\r
781 for key, item in FdfModule.Protocols.items():\r
782 GuidDict[key] = item\r
783 for key, item in FdfModule.Guids.items():\r
784 GuidDict[key] = item\r
785 for key, item in FdfModule.Ppis.items():\r
786 GuidDict[key] = item\r
787 else:\r
788 FileStatementGuid = FfsObj.NameGuid\r
789 if FileStatementGuid in FileGuidList:\r
790 continue\r
791 else:\r
792 FileGuidList.append(FileStatementGuid)\r
793 Name = []\r
794 FfsPath = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs')\r
795 FfsPath = glob.glob(os.path.join(FfsPath, FileStatementGuid) + '*')\r
796 if not FfsPath:\r
797 continue\r
798 if not os.path.exists(FfsPath[0]):\r
799 continue\r
800 MatchDict = {}\r
801 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
802 FileList = os.listdir(FfsPath[0])\r
803 for File in FileList:\r
804 Match = ReFileEnds.search(File)\r
805 if Match:\r
806 for Index in range(1, 8):\r
807 if Match.group(Index) and Match.group(Index) in MatchDict:\r
808 MatchDict[Match.group(Index)].append(File)\r
809 elif Match.group(Index):\r
810 MatchDict[Match.group(Index)] = [File]\r
811 if not MatchDict:\r
812 continue\r
813 if '.ui' in MatchDict:\r
814 for File in MatchDict['.ui']:\r
815 with open(os.path.join(FfsPath[0], File), 'rb') as F:\r
816 F.read()\r
817 length = F.tell()\r
818 F.seek(4)\r
819 TmpStr = unpack('%dh' % ((length - 4) / 2), F.read())\r
820 Name = ''.join([chr(c) for c in TmpStr[:-1]])\r
821 else:\r
822 FileList = []\r
823 if 'fv.sec.txt' in MatchDict:\r
824 FileList = MatchDict['fv.sec.txt']\r
825 elif '.pe32.txt' in MatchDict:\r
826 FileList = MatchDict['.pe32.txt']\r
827 elif '.te.txt' in MatchDict:\r
828 FileList = MatchDict['.te.txt']\r
829 elif '.pic.txt' in MatchDict:\r
830 FileList = MatchDict['.pic.txt']\r
831 elif '.raw.txt' in MatchDict:\r
832 FileList = MatchDict['.raw.txt']\r
833 elif '.ffs.txt' in MatchDict:\r
834 FileList = MatchDict['.ffs.txt']\r
835 else:\r
836 pass\r
837 for File in FileList:\r
838 with open(os.path.join(FfsPath[0], File), 'r') as F:\r
839 Name.append((F.read().split()[-1]))\r
840 if not Name:\r
841 continue\r
842\r
843 Name = ' '.join(Name) if type(Name) == type([]) else Name\r
844 GuidXRefFile.write("%s %s\n" %(FileStatementGuid, Name))\r
845\r
e4ac870f
LG
846 # Append GUIDs, Protocols, and PPIs to the Xref file\r
847 GuidXRefFile.write("\n")\r
848 for key, item in GuidDict.items():\r
849 GuidXRefFile.write("%s %s\n" % (GuidStructureStringToGuidString(item).upper(), key))\r
850\r
f51461c8
LG
851 if GuidXRefFile.getvalue():\r
852 SaveFileOnChange(GuidXRefFileName, GuidXRefFile.getvalue(), False)\r
853 GenFdsGlobalVariable.InfLogger("\nGUID cross reference file can be found at %s" % GuidXRefFileName)\r
854 elif os.path.exists(GuidXRefFileName):\r
855 os.remove(GuidXRefFileName)\r
856 GuidXRefFile.close()\r
857\r
858 ##Define GenFd as static function\r
859 GenFd = staticmethod(GenFd)\r
860 GetFvBlockSize = staticmethod(GetFvBlockSize)\r
861 DisplayFvSpaceInfo = staticmethod(DisplayFvSpaceInfo)\r
862 PreprocessImage = staticmethod(PreprocessImage)\r
863 GenerateGuidXRefFile = staticmethod(GenerateGuidXRefFile)\r
864\r
865if __name__ == '__main__':\r
866 r = main()\r
867 ## 0-127 is a safe return range, and 1 is a standard default error\r
868 if r < 0 or r > 127: r = 1\r
869 sys.exit(r)\r
870\r