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