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