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