]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/GenFds/GenFds.py
BaseTools: enhance error handling for DSC file
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / GenFds.py
CommitLineData
f51461c8
LG
1## @file\r
2# generate flash image\r
3#\r
3a0f8bde 4# Copyright (c) 2007 - 2016, 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
33import Common.DataType\r
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
f51461c8 41from Common.BuildVersion import gBUILD_VERSION\r
05cc51ad 42from Common.MultipleWorkspace import MultipleWorkspace as mws\r
f51461c8
LG
43\r
44## Version and Copyright\r
45versionNumber = "1.0" + ' ' + gBUILD_VERSION\r
46__version__ = "%prog Version " + versionNumber\r
1be2ed90 47__copyright__ = "Copyright (c) 2007 - 2014, Intel Corporation All rights reserved."\r
f51461c8
LG
48\r
49## Tool entrance method\r
50#\r
51# This method mainly dispatch specific methods per the command line options.\r
52# If no error found, return zero value so the caller of this tool can know\r
53# if it's executed successfully or not.\r
54#\r
55# @retval 0 Tool was successful\r
56# @retval 1 Tool failed\r
57#\r
58def main():\r
59 global Options\r
60 Options = myOptionParser()\r
61\r
62 global Workspace\r
63 Workspace = ""\r
64 ArchList = None\r
65 ReturnCode = 0\r
66\r
67 EdkLogger.Initialize()\r
68 try:\r
69 if Options.verbose != None:\r
70 EdkLogger.SetLevel(EdkLogger.VERBOSE)\r
71 GenFdsGlobalVariable.VerboseMode = True\r
72 \r
73 if Options.FixedAddress != None:\r
74 GenFdsGlobalVariable.FixedLoadAddress = True\r
75 \r
76 if Options.quiet != None:\r
77 EdkLogger.SetLevel(EdkLogger.QUIET)\r
78 if Options.debug != None:\r
79 EdkLogger.SetLevel(Options.debug + 1)\r
80 GenFdsGlobalVariable.DebugLevel = Options.debug\r
81 else:\r
82 EdkLogger.SetLevel(EdkLogger.INFO)\r
83\r
84 if (Options.Workspace == None):\r
85 EdkLogger.error("GenFds", OPTION_MISSING, "WORKSPACE not defined",\r
86 ExtraData="Please use '-w' switch to pass it or set the WORKSPACE environment variable.")\r
87 elif not os.path.exists(Options.Workspace):\r
88 EdkLogger.error("GenFds", PARAMETER_INVALID, "WORKSPACE is invalid",\r
89 ExtraData="Please use '-w' switch to pass it or set the WORKSPACE environment variable.")\r
90 else:\r
91 Workspace = os.path.normcase(Options.Workspace)\r
92 GenFdsGlobalVariable.WorkSpaceDir = Workspace\r
93 if 'EDK_SOURCE' in os.environ.keys():\r
94 GenFdsGlobalVariable.EdkSourceDir = os.path.normcase(os.environ['EDK_SOURCE'])\r
95 if (Options.debug):\r
47fea6af 96 GenFdsGlobalVariable.VerboseLogger("Using Workspace:" + Workspace)\r
f51461c8 97 os.chdir(GenFdsGlobalVariable.WorkSpaceDir)\r
05cc51ad
LY
98 \r
99 # set multiple workspace\r
100 PackagesPath = os.getenv("PACKAGES_PATH")\r
101 mws.setWs(GenFdsGlobalVariable.WorkSpaceDir, PackagesPath)\r
f51461c8
LG
102\r
103 if (Options.filename):\r
104 FdfFilename = Options.filename\r
105 FdfFilename = GenFdsGlobalVariable.ReplaceWorkspaceMacro(FdfFilename)\r
106\r
107 if FdfFilename[0:2] == '..':\r
108 FdfFilename = os.path.realpath(FdfFilename)\r
47fea6af 109 if not os.path.isabs(FdfFilename):\r
05cc51ad 110 FdfFilename = mws.join(GenFdsGlobalVariable.WorkSpaceDir, FdfFilename)\r
f51461c8
LG
111 if not os.path.exists(FdfFilename):\r
112 EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=FdfFilename)\r
f51461c8
LG
113\r
114 GenFdsGlobalVariable.FdfFile = FdfFilename\r
115 GenFdsGlobalVariable.FdfFileTimeStamp = os.path.getmtime(FdfFilename)\r
116 else:\r
117 EdkLogger.error("GenFds", OPTION_MISSING, "Missing FDF filename")\r
118\r
119 if (Options.BuildTarget):\r
120 GenFdsGlobalVariable.TargetName = Options.BuildTarget\r
121 else:\r
122 EdkLogger.error("GenFds", OPTION_MISSING, "Missing build target")\r
123\r
124 if (Options.ToolChain):\r
125 GenFdsGlobalVariable.ToolChainTag = Options.ToolChain\r
126 else:\r
127 EdkLogger.error("GenFds", OPTION_MISSING, "Missing tool chain tag")\r
128\r
129 if (Options.activePlatform):\r
130 ActivePlatform = Options.activePlatform\r
131 ActivePlatform = GenFdsGlobalVariable.ReplaceWorkspaceMacro(ActivePlatform)\r
132\r
133 if ActivePlatform[0:2] == '..':\r
134 ActivePlatform = os.path.realpath(ActivePlatform)\r
135\r
136 if not os.path.isabs (ActivePlatform):\r
05cc51ad 137 ActivePlatform = mws.join(GenFdsGlobalVariable.WorkSpaceDir, ActivePlatform)\r
f51461c8
LG
138\r
139 if not os.path.exists(ActivePlatform) :\r
140 EdkLogger.error("GenFds", FILE_NOT_FOUND, "ActivePlatform doesn't exist!")\r
141\r
9b9500a1 142 if os.path.normcase (ActivePlatform).find(Workspace) == 0:\r
05cc51ad 143 ActivePlatform = mws.relpath(ActivePlatform, Workspace)\r
f51461c8
LG
144 if len(ActivePlatform) > 0 :\r
145 if ActivePlatform[0] == '\\' or ActivePlatform[0] == '/':\r
146 ActivePlatform = ActivePlatform[1:]\r
147 else:\r
148 EdkLogger.error("GenFds", FILE_NOT_FOUND, "ActivePlatform doesn't exist!")\r
149 else:\r
150 EdkLogger.error("GenFds", OPTION_MISSING, "Missing active platform")\r
151\r
152 GenFdsGlobalVariable.ActivePlatform = PathClass(NormPath(ActivePlatform), Workspace)\r
153\r
97fa0ee9
YL
154 if (Options.ConfDirectory):\r
155 # Get alternate Conf location, if it is absolute, then just use the absolute directory name\r
156 ConfDirectoryPath = os.path.normpath(Options.ConfDirectory)\r
157 if ConfDirectoryPath.startswith('"'):\r
158 ConfDirectoryPath = ConfDirectoryPath[1:]\r
159 if ConfDirectoryPath.endswith('"'):\r
160 ConfDirectoryPath = ConfDirectoryPath[:-1]\r
161 if not os.path.isabs(ConfDirectoryPath):\r
162 # Since alternate directory name is not absolute, the alternate directory is located within the WORKSPACE\r
163 # This also handles someone specifying the Conf directory in the workspace. Using --conf=Conf\r
164 ConfDirectoryPath = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, ConfDirectoryPath)\r
165 else:\r
166 # Get standard WORKSPACE/Conf, use the absolute path to the WORKSPACE/Conf\r
05cc51ad 167 ConfDirectoryPath = mws.join(GenFdsGlobalVariable.WorkSpaceDir, 'Conf')\r
97fa0ee9
YL
168 GenFdsGlobalVariable.ConfDir = ConfDirectoryPath\r
169 BuildConfigurationFile = os.path.normpath(os.path.join(ConfDirectoryPath, "target.txt"))\r
f51461c8
LG
170 if os.path.isfile(BuildConfigurationFile) == True:\r
171 TargetTxtClassObject.TargetTxtClassObject(BuildConfigurationFile)\r
172 else:\r
173 EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=BuildConfigurationFile)\r
174\r
97fa0ee9
YL
175 #Set global flag for build mode\r
176 GlobalData.gIgnoreSource = Options.IgnoreSources\r
177\r
f51461c8
LG
178 if Options.Macros:\r
179 for Pair in Options.Macros:\r
97fa0ee9
YL
180 if Pair.startswith('"'):\r
181 Pair = Pair[1:]\r
182 if Pair.endswith('"'):\r
183 Pair = Pair[:-1]\r
f51461c8
LG
184 List = Pair.split('=')\r
185 if len(List) == 2:\r
186 if List[0].strip() == "EFI_SOURCE":\r
187 GlobalData.gEfiSource = List[1].strip()\r
188 GlobalData.gGlobalDefines["EFI_SOURCE"] = GlobalData.gEfiSource\r
189 continue\r
190 elif List[0].strip() == "EDK_SOURCE":\r
191 GlobalData.gEdkSource = List[1].strip()\r
192 GlobalData.gGlobalDefines["EDK_SOURCE"] = GlobalData.gEdkSource\r
193 continue\r
194 elif List[0].strip() in ["WORKSPACE", "TARGET", "TOOLCHAIN"]:\r
195 GlobalData.gGlobalDefines[List[0].strip()] = List[1].strip()\r
196 else:\r
197 GlobalData.gCommandLineDefines[List[0].strip()] = List[1].strip()\r
198 else:\r
199 GlobalData.gCommandLineDefines[List[0].strip()] = "TRUE"\r
200 os.environ["WORKSPACE"] = Workspace\r
201\r
202 """call Workspace build create database"""\r
97fa0ee9
YL
203 GlobalData.gDatabasePath = os.path.normpath(os.path.join(ConfDirectoryPath, GlobalData.gDatabasePath))\r
204 BuildWorkSpace = WorkspaceDatabase(GlobalData.gDatabasePath)\r
f51461c8
LG
205 BuildWorkSpace.InitDatabase()\r
206 \r
207 #\r
208 # Get files real name in workspace dir\r
209 #\r
210 GlobalData.gAllFiles = DirCache(Workspace)\r
211 GlobalData.gWorkspace = Workspace\r
212\r
213 if (Options.archList) :\r
214 ArchList = Options.archList.split(',')\r
215 else:\r
216# EdkLogger.error("GenFds", OPTION_MISSING, "Missing build ARCH")\r
217 ArchList = BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'COMMON', Options.BuildTarget, Options.ToolChain].SupArchList\r
218\r
219 TargetArchList = set(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'COMMON', Options.BuildTarget, Options.ToolChain].SupArchList) & set(ArchList)\r
220 if len(TargetArchList) == 0:\r
221 EdkLogger.error("GenFds", GENFDS_ERROR, "Target ARCH %s not in platform supported ARCH %s" % (str(ArchList), str(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'COMMON'].SupArchList)))\r
222 \r
223 for Arch in ArchList:\r
224 GenFdsGlobalVariable.OutputDirFromDscDict[Arch] = NormPath(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, Options.BuildTarget, Options.ToolChain].OutputDirectory)\r
225 GenFdsGlobalVariable.PlatformName = BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, Options.BuildTarget, Options.ToolChain].PlatformName\r
226\r
227 if (Options.outputDir):\r
228 OutputDirFromCommandLine = GenFdsGlobalVariable.ReplaceWorkspaceMacro(Options.outputDir)\r
229 if not os.path.isabs (OutputDirFromCommandLine):\r
230 OutputDirFromCommandLine = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, OutputDirFromCommandLine)\r
231 for Arch in ArchList:\r
232 GenFdsGlobalVariable.OutputDirDict[Arch] = OutputDirFromCommandLine\r
233 else:\r
234 for Arch in ArchList:\r
235 GenFdsGlobalVariable.OutputDirDict[Arch] = os.path.join(GenFdsGlobalVariable.OutputDirFromDscDict[Arch], GenFdsGlobalVariable.TargetName + '_' + GenFdsGlobalVariable.ToolChainTag)\r
236\r
237 for Key in GenFdsGlobalVariable.OutputDirDict:\r
238 OutputDir = GenFdsGlobalVariable.OutputDirDict[Key]\r
239 if OutputDir[0:2] == '..':\r
240 OutputDir = os.path.realpath(OutputDir)\r
241\r
242 if OutputDir[1] != ':':\r
243 OutputDir = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, OutputDir)\r
244\r
245 if not os.path.exists(OutputDir):\r
246 EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=OutputDir)\r
247 GenFdsGlobalVariable.OutputDirDict[Key] = OutputDir\r
248\r
249 """ Parse Fdf file, has to place after build Workspace as FDF may contain macros from DSC file """\r
250 FdfParserObj = FdfParser.FdfParser(FdfFilename)\r
251 FdfParserObj.ParseFile()\r
252\r
253 if FdfParserObj.CycleReferenceCheck():\r
254 EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Cycle Reference Detected in FDF file")\r
255\r
256 if (Options.uiFdName) :\r
257 if Options.uiFdName.upper() in FdfParserObj.Profile.FdDict.keys():\r
258 GenFds.OnlyGenerateThisFd = Options.uiFdName\r
259 else:\r
260 EdkLogger.error("GenFds", OPTION_VALUE_INVALID,\r
261 "No such an FD in FDF file: %s" % Options.uiFdName)\r
262\r
263 if (Options.uiFvName) :\r
264 if Options.uiFvName.upper() in FdfParserObj.Profile.FvDict.keys():\r
265 GenFds.OnlyGenerateThisFv = Options.uiFvName\r
266 else:\r
267 EdkLogger.error("GenFds", OPTION_VALUE_INVALID,\r
268 "No such an FV in FDF file: %s" % Options.uiFvName)\r
269\r
270 if (Options.uiCapName) :\r
271 if Options.uiCapName.upper() in FdfParserObj.Profile.CapsuleDict.keys():\r
272 GenFds.OnlyGenerateThisCap = Options.uiCapName\r
273 else:\r
274 EdkLogger.error("GenFds", OPTION_VALUE_INVALID,\r
275 "No such a Capsule in FDF file: %s" % Options.uiCapName)\r
276\r
277 """Modify images from build output if the feature of loading driver at fixed address is on."""\r
278 if GenFdsGlobalVariable.FixedLoadAddress:\r
279 GenFds.PreprocessImage(BuildWorkSpace, GenFdsGlobalVariable.ActivePlatform)\r
280 """Call GenFds"""\r
281 GenFds.GenFd('', FdfParserObj, BuildWorkSpace, ArchList)\r
282\r
283 """Generate GUID cross reference file"""\r
284 GenFds.GenerateGuidXRefFile(BuildWorkSpace, ArchList)\r
285\r
286 """Display FV space info."""\r
287 GenFds.DisplayFvSpaceInfo(FdfParserObj)\r
288\r
289 except FdfParser.Warning, X:\r
47fea6af 290 EdkLogger.error(X.ToolName, FORMAT_INVALID, File=X.FileName, Line=X.LineNumber, ExtraData=X.Message, RaiseError=False)\r
f51461c8
LG
291 ReturnCode = FORMAT_INVALID\r
292 except FatalError, X:\r
293 if Options.debug != None:\r
294 import traceback\r
295 EdkLogger.quiet(traceback.format_exc())\r
296 ReturnCode = X.args[0]\r
297 except:\r
298 import traceback\r
299 EdkLogger.error(\r
300 "\nPython",\r
301 CODE_ERROR,\r
302 "Tools code failure",\r
3a0f8bde 303 ExtraData="Please send email to edk2-devel@lists.01.org for help, attaching following call stack trace!\n",\r
f51461c8
LG
304 RaiseError=False\r
305 )\r
306 EdkLogger.quiet(traceback.format_exc())\r
307 ReturnCode = CODE_ERROR\r
97fa0ee9
YL
308 finally:\r
309 ClearDuplicatedInf()\r
f51461c8
LG
310 return ReturnCode\r
311\r
312gParamCheck = []\r
313def SingleCheckCallback(option, opt_str, value, parser):\r
314 if option not in gParamCheck:\r
315 setattr(parser.values, option.dest, value)\r
316 gParamCheck.append(option)\r
317 else:\r
318 parser.error("Option %s only allows one instance in command line!" % option)\r
319 \r
320## Parse command line options\r
321#\r
322# Using standard Python module optparse to parse command line option of this tool.\r
323#\r
324# @retval Opt A optparse.Values object containing the parsed options\r
325# @retval Args Target of build command\r
326#\r
327def myOptionParser():\r
328 usage = "%prog [options] -f input_file -a arch_list -b build_target -p active_platform -t tool_chain_tag -D \"MacroName [= MacroValue]\""\r
47fea6af 329 Parser = OptionParser(usage=usage, description=__copyright__, version="%prog " + str(versionNumber))\r
f51461c8
LG
330 Parser.add_option("-f", "--file", dest="filename", type="string", help="Name of FDF file to convert", action="callback", callback=SingleCheckCallback)\r
331 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
332 Parser.add_option("-q", "--quiet", action="store_true", type=None, help="Disable all messages except FATAL ERRORS.")\r
333 Parser.add_option("-v", "--verbose", action="store_true", type=None, help="Turn on verbose output with informational messages printed.")\r
334 Parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.")\r
335 Parser.add_option("-p", "--platform", type="string", dest="activePlatform", help="Set the ACTIVE_PLATFORM, overrides target.txt ACTIVE_PLATFORM setting.",\r
336 action="callback", callback=SingleCheckCallback)\r
337 Parser.add_option("-w", "--workspace", type="string", dest="Workspace", default=os.environ.get('WORKSPACE'), help="Set the WORKSPACE",\r
338 action="callback", callback=SingleCheckCallback)\r
339 Parser.add_option("-o", "--outputDir", type="string", dest="outputDir", help="Name of Build Output directory",\r
340 action="callback", callback=SingleCheckCallback)\r
341 Parser.add_option("-r", "--rom_image", dest="uiFdName", help="Build the image using the [FD] section named by FdUiName.")\r
342 Parser.add_option("-i", "--FvImage", dest="uiFvName", help="Build the FV image using the [FV] section named by UiFvName")\r
343 Parser.add_option("-C", "--CapsuleImage", dest="uiCapName", help="Build the Capsule image using the [Capsule] section named by UiCapName")\r
344 Parser.add_option("-b", "--buildtarget", type="string", dest="BuildTarget", help="Set the build TARGET, overrides target.txt TARGET setting.",\r
345 action="callback", callback=SingleCheckCallback)\r
346 Parser.add_option("-t", "--tagname", type="string", dest="ToolChain", help="Using the tools: TOOL_CHAIN_TAG name to build the platform.",\r
347 action="callback", callback=SingleCheckCallback)\r
348 Parser.add_option("-D", "--define", action="append", type="string", dest="Macros", help="Macro: \"Name [= Value]\".")\r
349 Parser.add_option("-s", "--specifyaddress", dest="FixedAddress", action="store_true", type=None, help="Specify driver load address.")\r
97fa0ee9
YL
350 Parser.add_option("--conf", action="store", type="string", dest="ConfDirectory", help="Specify the customized Conf directory.")\r
351 Parser.add_option("--ignore-sources", action="store_true", dest="IgnoreSources", default=False, help="Focus to a binary build and ignore all source files")\r
352\r
f51461c8
LG
353 (Options, args) = Parser.parse_args()\r
354 return Options\r
355\r
356## The class implementing the EDK2 flash image generation process\r
357#\r
358# This process includes:\r
359# 1. Collect workspace information, includes platform and module information\r
360# 2. Call methods of Fd class to generate FD\r
361# 3. Call methods of Fv class to generate FV that not belong to FD\r
362#\r
363class GenFds :\r
364 FdfParsef = None\r
365 # FvName, FdName, CapName in FDF, Image file name\r
366 ImageBinDict = {}\r
367 OnlyGenerateThisFd = None\r
368 OnlyGenerateThisFv = None\r
369 OnlyGenerateThisCap = None\r
370\r
371 ## GenFd()\r
372 #\r
373 # @param OutputDir Output directory\r
374 # @param FdfParser FDF contents parser\r
375 # @param Workspace The directory of workspace\r
376 # @param ArchList The Arch list of platform\r
377 #\r
378 def GenFd (OutputDir, FdfParser, WorkSpace, ArchList):\r
379 GenFdsGlobalVariable.SetDir ('', FdfParser, WorkSpace, ArchList)\r
380\r
381 GenFdsGlobalVariable.VerboseLogger(" Generate all Fd images and their required FV and Capsule images!")\r
382 if GenFds.OnlyGenerateThisCap != None and GenFds.OnlyGenerateThisCap.upper() in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.keys():\r
383 CapsuleObj = GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.get(GenFds.OnlyGenerateThisCap.upper())\r
384 if CapsuleObj != None:\r
385 CapsuleObj.GenCapsule()\r
386 return\r
387\r
388 if GenFds.OnlyGenerateThisFd != None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():\r
389 FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict.get(GenFds.OnlyGenerateThisFd.upper())\r
390 if FdObj != None:\r
391 FdObj.GenFd()\r
392 return\r
393 elif GenFds.OnlyGenerateThisFd == None and GenFds.OnlyGenerateThisFv == None:\r
394 for FdName in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():\r
395 FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[FdName]\r
396 FdObj.GenFd()\r
397\r
398 GenFdsGlobalVariable.VerboseLogger("\n Generate other FV images! ")\r
399 if GenFds.OnlyGenerateThisFv != None and GenFds.OnlyGenerateThisFv.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():\r
400 FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(GenFds.OnlyGenerateThisFv.upper())\r
401 if FvObj != None:\r
402 Buffer = StringIO.StringIO()\r
403 FvObj.AddToBuffer(Buffer)\r
404 Buffer.close()\r
405 return\r
406 elif GenFds.OnlyGenerateThisFv == None:\r
407 for FvName in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():\r
408 Buffer = StringIO.StringIO('')\r
409 FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict[FvName]\r
410 FvObj.AddToBuffer(Buffer)\r
411 Buffer.close()\r
412 \r
413 if GenFds.OnlyGenerateThisFv == None and GenFds.OnlyGenerateThisFd == None and GenFds.OnlyGenerateThisCap == None:\r
414 if GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict != {}:\r
415 GenFdsGlobalVariable.VerboseLogger("\n Generate other Capsule images!")\r
416 for CapsuleName in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.keys():\r
417 CapsuleObj = GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict[CapsuleName]\r
418 CapsuleObj.GenCapsule()\r
419\r
420 if GenFdsGlobalVariable.FdfParser.Profile.OptRomDict != {}:\r
421 GenFdsGlobalVariable.VerboseLogger("\n Generate all Option ROM!")\r
422 for DriverName in GenFdsGlobalVariable.FdfParser.Profile.OptRomDict.keys():\r
423 OptRomObj = GenFdsGlobalVariable.FdfParser.Profile.OptRomDict[DriverName]\r
424 OptRomObj.AddToBuffer(None)\r
425\r
426 ## GetFvBlockSize()\r
427 #\r
428 # @param FvObj Whose block size to get\r
429 # @retval int Block size value\r
430 #\r
431 def GetFvBlockSize(FvObj):\r
432 DefaultBlockSize = 0x1\r
433 FdObj = None\r
434 if GenFds.OnlyGenerateThisFd != None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():\r
435 FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[GenFds.OnlyGenerateThisFd.upper()]\r
436 if FdObj == None:\r
437 for ElementFd in GenFdsGlobalVariable.FdfParser.Profile.FdDict.values():\r
438 for ElementRegion in ElementFd.RegionList:\r
439 if ElementRegion.RegionType == 'FV':\r
440 for ElementRegionData in ElementRegion.RegionDataList:\r
441 if ElementRegionData != None and ElementRegionData.upper() == FvObj.UiFvName:\r
442 if FvObj.BlockSizeList != []:\r
443 return FvObj.BlockSizeList[0][0]\r
444 else:\r
445 return ElementRegion.BlockSizeOfRegion(ElementFd.BlockSizeList)\r
446 if FvObj.BlockSizeList != []:\r
447 return FvObj.BlockSizeList[0][0]\r
448 return DefaultBlockSize\r
449 else:\r
450 for ElementRegion in FdObj.RegionList:\r
451 if ElementRegion.RegionType == 'FV':\r
452 for ElementRegionData in ElementRegion.RegionDataList:\r
453 if ElementRegionData != None and ElementRegionData.upper() == FvObj.UiFvName:\r
454 if FvObj.BlockSizeList != []:\r
455 return FvObj.BlockSizeList[0][0]\r
456 else:\r
457 return ElementRegion.BlockSizeOfRegion(ElementFd.BlockSizeList)\r
458 return DefaultBlockSize\r
459\r
460 ## DisplayFvSpaceInfo()\r
461 #\r
462 # @param FvObj Whose block size to get\r
463 # @retval None\r
464 #\r
465 def DisplayFvSpaceInfo(FdfParser):\r
466 \r
467 FvSpaceInfoList = []\r
468 MaxFvNameLength = 0\r
469 for FvName in FdfParser.Profile.FvDict:\r
470 if len(FvName) > MaxFvNameLength:\r
471 MaxFvNameLength = len(FvName)\r
472 FvSpaceInfoFileName = os.path.join(GenFdsGlobalVariable.FvDir, FvName.upper() + '.Fv.map')\r
473 if os.path.exists(FvSpaceInfoFileName):\r
474 FileLinesList = linecache.getlines(FvSpaceInfoFileName)\r
475 TotalFound = False\r
476 Total = ''\r
477 UsedFound = False\r
478 Used = ''\r
479 FreeFound = False\r
480 Free = ''\r
481 for Line in FileLinesList:\r
482 NameValue = Line.split('=')\r
483 if len(NameValue) == 2:\r
484 if NameValue[0].strip() == 'EFI_FV_TOTAL_SIZE':\r
485 TotalFound = True\r
486 Total = NameValue[1].strip()\r
487 if NameValue[0].strip() == 'EFI_FV_TAKEN_SIZE':\r
488 UsedFound = True\r
489 Used = NameValue[1].strip()\r
490 if NameValue[0].strip() == 'EFI_FV_SPACE_SIZE':\r
491 FreeFound = True\r
492 Free = NameValue[1].strip()\r
493 \r
494 if TotalFound and UsedFound and FreeFound:\r
495 FvSpaceInfoList.append((FvName, Total, Used, Free))\r
496 \r
497 GenFdsGlobalVariable.InfLogger('\nFV Space Information')\r
498 for FvSpaceInfo in FvSpaceInfoList:\r
499 Name = FvSpaceInfo[0]\r
500 TotalSizeValue = long(FvSpaceInfo[1], 0)\r
501 UsedSizeValue = long(FvSpaceInfo[2], 0)\r
502 FreeSizeValue = long(FvSpaceInfo[3], 0)\r
503 if UsedSizeValue == TotalSizeValue:\r
504 Percentage = '100'\r
505 else:\r
47fea6af
YZ
506 Percentage = str((UsedSizeValue + 0.0) / TotalSizeValue)[0:4].lstrip('0.')\r
507\r
f51461c8
LG
508 GenFdsGlobalVariable.InfLogger(Name + ' ' + '[' + Percentage + '%Full] ' + str(TotalSizeValue) + ' total, ' + str(UsedSizeValue) + ' used, ' + str(FreeSizeValue) + ' free')\r
509\r
510 ## PreprocessImage()\r
511 #\r
512 # @param BuildDb Database from build meta data files\r
513 # @param DscFile modules from dsc file will be preprocessed\r
514 # @retval None\r
515 #\r
516 def PreprocessImage(BuildDb, DscFile):\r
517 PcdDict = BuildDb.BuildObject[DscFile, 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].Pcds\r
518 PcdValue = ''\r
519 for Key in PcdDict:\r
520 PcdObj = PcdDict[Key]\r
521 if PcdObj.TokenCName == 'PcdBsBaseAddress':\r
522 PcdValue = PcdObj.DefaultValue\r
523 break\r
524 \r
525 if PcdValue == '':\r
526 return\r
527 \r
528 Int64PcdValue = long(PcdValue, 0)\r
529 if Int64PcdValue == 0 or Int64PcdValue < -1: \r
530 return\r
531 \r
532 TopAddress = 0\r
533 if Int64PcdValue > 0:\r
534 TopAddress = Int64PcdValue\r
535 \r
536 ModuleDict = BuildDb.BuildObject[DscFile, 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].Modules\r
537 for Key in ModuleDict:\r
538 ModuleObj = BuildDb.BuildObject[Key, 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
539 print ModuleObj.BaseName + ' ' + ModuleObj.ModuleType\r
540\r
541 def GenerateGuidXRefFile(BuildDb, ArchList):\r
542 GuidXRefFileName = os.path.join(GenFdsGlobalVariable.FvDir, "Guid.xref")\r
543 GuidXRefFile = StringIO.StringIO('')\r
e4ac870f 544 GuidDict = {}\r
f51461c8
LG
545 for Arch in ArchList:\r
546 PlatformDataBase = BuildDb.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
547 for ModuleFile in PlatformDataBase.Modules:\r
548 Module = BuildDb.BuildObject[ModuleFile, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
549 GuidXRefFile.write("%s %s\n" % (Module.Guid, Module.BaseName))\r
e4ac870f
LG
550 for key, item in Module.Protocols.items():\r
551 GuidDict[key] = item\r
552 for key, item in Module.Guids.items():\r
553 GuidDict[key] = item\r
554 for key, item in Module.Ppis.items():\r
555 GuidDict[key] = item\r
556 # Append GUIDs, Protocols, and PPIs to the Xref file\r
557 GuidXRefFile.write("\n")\r
558 for key, item in GuidDict.items():\r
559 GuidXRefFile.write("%s %s\n" % (GuidStructureStringToGuidString(item).upper(), key))\r
560\r
f51461c8
LG
561 if GuidXRefFile.getvalue():\r
562 SaveFileOnChange(GuidXRefFileName, GuidXRefFile.getvalue(), False)\r
563 GenFdsGlobalVariable.InfLogger("\nGUID cross reference file can be found at %s" % GuidXRefFileName)\r
564 elif os.path.exists(GuidXRefFileName):\r
565 os.remove(GuidXRefFileName)\r
566 GuidXRefFile.close()\r
567\r
568 ##Define GenFd as static function\r
569 GenFd = staticmethod(GenFd)\r
570 GetFvBlockSize = staticmethod(GetFvBlockSize)\r
571 DisplayFvSpaceInfo = staticmethod(DisplayFvSpaceInfo)\r
572 PreprocessImage = staticmethod(PreprocessImage)\r
573 GenerateGuidXRefFile = staticmethod(GenerateGuidXRefFile)\r
574\r
575if __name__ == '__main__':\r
576 r = main()\r
577 ## 0-127 is a safe return range, and 1 is a standard default error\r
578 if r < 0 or r > 127: r = 1\r
579 sys.exit(r)\r
580\r