Sync EDKII BaseTools to BaseTools project r1911.
[efi/edk2/.git] / edk2 / BaseTools / 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 (OutputDirFromCommandLine):
200                 OutputDirFromCommandLine = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, OutputDirFromCommandLine)
201             for Arch in ArchList:
202                 GenFdsGlobalVariable.OutputDirDict[Arch] = OutputDirFromCommandLine
203         else:
204             for Arch in ArchList:
205                 GenFdsGlobalVariable.OutputDirDict[Arch] = os.path.join(GenFdsGlobalVariable.OutputDirFromDscDict[Arch], GenFdsGlobalVariable.TargetName + '_' + GenFdsGlobalVariable.ToolChainTag)
206
207         for Key in GenFdsGlobalVariable.OutputDirDict:
208             OutputDir = GenFdsGlobalVariable.OutputDirDict[Key]
209             if OutputDir[0:2] == '..':
210                 OutputDir = os.path.realpath(OutputDir)
211
212             if OutputDir[1] != ':':
213                 OutputDir = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, OutputDir)
214
215             if not os.path.exists(OutputDir):
216                 EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=OutputDir)
217             GenFdsGlobalVariable.OutputDirDict[Key] = OutputDir
218
219         """ Parse Fdf file, has to place after build Workspace as FDF may contain macros from DSC file """
220         FdfParserObj = FdfParser.FdfParser(FdfFilename)
221         FdfParserObj.ParseFile()
222
223         if FdfParserObj.CycleReferenceCheck():
224             EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Cycle Reference Detected in FDF file")
225
226         if (Options.uiFdName) :
227             if Options.uiFdName.upper() in FdfParserObj.Profile.FdDict.keys():
228                 GenFds.OnlyGenerateThisFd = Options.uiFdName
229             else:
230                 EdkLogger.error("GenFds", OPTION_VALUE_INVALID,
231                                 "No such an FD in FDF file: %s" % Options.uiFdName)
232
233         if (Options.uiFvName) :
234             if Options.uiFvName.upper() in FdfParserObj.Profile.FvDict.keys():
235                 GenFds.OnlyGenerateThisFv = Options.uiFvName
236             else:
237                 EdkLogger.error("GenFds", OPTION_VALUE_INVALID,
238                                 "No such an FV in FDF file: %s" % Options.uiFvName)
239
240         """Modify images from build output if the feature of loading driver at fixed address is on."""
241         if GenFdsGlobalVariable.FixedLoadAddress:
242             GenFds.PreprocessImage(BuildWorkSpace, GenFdsGlobalVariable.ActivePlatform)
243         """Call GenFds"""
244         GenFds.GenFd('', FdfParserObj, BuildWorkSpace, ArchList)
245
246         """Generate GUID cross reference file"""
247         GenFds.GenerateGuidXRefFile(BuildWorkSpace, ArchList)
248
249         """Display FV space info."""
250         GenFds.DisplayFvSpaceInfo(FdfParserObj)
251
252     except FdfParser.Warning, X:
253         EdkLogger.error(X.ToolName, FORMAT_INVALID, File=X.FileName, Line=X.LineNumber, ExtraData=X.Message, RaiseError = False)
254         ReturnCode = FORMAT_INVALID
255     except FatalError, X:
256         if Options.debug != None:
257             import traceback
258             EdkLogger.quiet(traceback.format_exc())
259         ReturnCode = X.args[0]
260     except:
261         import traceback
262         EdkLogger.error(
263                     "\nPython",
264                     CODE_ERROR,
265                     "Tools code failure",
266                     ExtraData="Please submit bug report in www.TianoCore.org, attaching following call stack trace!\n",
267                     RaiseError=False
268                     )
269         EdkLogger.quiet(traceback.format_exc())
270         ReturnCode = CODE_ERROR
271     return ReturnCode
272
273 gParamCheck = []
274 def SingleCheckCallback(option, opt_str, value, parser):
275     if option not in gParamCheck:
276         setattr(parser.values, option.dest, value)
277         gParamCheck.append(option)
278     else:
279         parser.error("Option %s only allows one instance in command line!" % option)
280         
281 ## Parse command line options
282 #
283 # Using standard Python module optparse to parse command line option of this tool.
284 #
285 #   @retval Opt   A optparse.Values object containing the parsed options
286 #   @retval Args  Target of build command
287 #
288 def myOptionParser():
289     usage = "%prog [options] -f input_file -a arch_list -b build_target -p active_platform -t tool_chain_tag -D \"MacroName [= MacroValue]\""
290     Parser = OptionParser(usage=usage,description=__copyright__,version="%prog " + str(versionNumber))
291     Parser.add_option("-f", "--file", dest="filename", type="string", help="Name of FDF file to convert", action="callback", callback=SingleCheckCallback)
292     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")
293     Parser.add_option("-q", "--quiet", action="store_true", type=None, help="Disable all messages except FATAL ERRORS.")
294     Parser.add_option("-v", "--verbose", action="store_true", type=None, help="Turn on verbose output with informational messages printed.")
295     Parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.")
296     Parser.add_option("-p", "--platform", type="string", dest="activePlatform", help="Set the ACTIVE_PLATFORM, overrides target.txt ACTIVE_PLATFORM setting.",
297                       action="callback", callback=SingleCheckCallback)
298     Parser.add_option("-w", "--workspace", type="string", dest="Workspace", default=os.environ.get('WORKSPACE'), help="Set the WORKSPACE",
299                       action="callback", callback=SingleCheckCallback)
300     Parser.add_option("-o", "--outputDir", type="string", dest="outputDir", help="Name of Build Output directory",
301                       action="callback", callback=SingleCheckCallback)
302     Parser.add_option("-r", "--rom_image", dest="uiFdName", help="Build the image using the [FD] section named by FdUiName.")
303     Parser.add_option("-i", "--FvImage", dest="uiFvName", help="Buld the FV image using the [FV] section named by UiFvName")
304     Parser.add_option("-b", "--buildtarget", type="choice", choices=['DEBUG','RELEASE'], dest="BuildTarget", help="Build TARGET is one of list: DEBUG, RELEASE.",
305                       action="callback", callback=SingleCheckCallback)
306     Parser.add_option("-t", "--tagname", type="string", dest="ToolChain", help="Using the tools: TOOL_CHAIN_TAG name to build the platform.",
307                       action="callback", callback=SingleCheckCallback)
308     Parser.add_option("-D", "--define", action="append", type="string", dest="Macros", help="Macro: \"Name [= Value]\".")
309     Parser.add_option("-s", "--specifyaddress", dest="FixedAddress", action="store_true", type=None, help="Specify driver load address.")
310     (Options, args) = Parser.parse_args()
311     return Options
312
313 ## The class implementing the EDK2 flash image generation process
314 #
315 #   This process includes:
316 #       1. Collect workspace information, includes platform and module information
317 #       2. Call methods of Fd class to generate FD
318 #       3. Call methods of Fv class to generate FV that not belong to FD
319 #
320 class GenFds :
321     FdfParsef = None
322     # FvName, FdName, CapName in FDF, Image file name
323     ImageBinDict = {}
324     OnlyGenerateThisFd = None
325     OnlyGenerateThisFv = None
326
327     ## GenFd()
328     #
329     #   @param  OutputDir           Output directory
330     #   @param  FdfParser           FDF contents parser
331     #   @param  Workspace           The directory of workspace
332     #   @param  ArchList            The Arch list of platform
333     #
334     def GenFd (OutputDir, FdfParser, WorkSpace, ArchList):
335         GenFdsGlobalVariable.SetDir ('', FdfParser, WorkSpace, ArchList)
336
337         GenFdsGlobalVariable.VerboseLogger(" Generate all Fd images and their required FV and Capsule images!")
338         if GenFds.OnlyGenerateThisFd != None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():
339             FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict.get(GenFds.OnlyGenerateThisFd.upper())
340             if FdObj != None:
341                 FdObj.GenFd()
342         elif GenFds.OnlyGenerateThisFd == None:
343             for FdName in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():
344                 FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[FdName]
345                 FdObj.GenFd()
346
347         GenFdsGlobalVariable.VerboseLogger("\n Generate other FV images! ")
348         if GenFds.OnlyGenerateThisFv != None and GenFds.OnlyGenerateThisFv.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():
349             FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(GenFds.OnlyGenerateThisFv.upper())
350             if FvObj != None:
351                 Buffer = StringIO.StringIO()
352                 # Get FV base Address
353                 FvObj.AddToBuffer(Buffer, None, GenFds.GetFvBlockSize(FvObj))
354                 Buffer.close()
355                 return
356         elif GenFds.OnlyGenerateThisFv == None:
357             for FvName in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():
358                 Buffer = StringIO.StringIO('')
359                 FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict[FvName]
360                 # Get FV base Address
361                 FvObj.AddToBuffer(Buffer, None, GenFds.GetFvBlockSize(FvObj))
362                 Buffer.close()
363         
364         if GenFds.OnlyGenerateThisFv == None and GenFds.OnlyGenerateThisFd == None:
365             if GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict != {}:
366                 GenFdsGlobalVariable.VerboseLogger("\n Generate other Capsule images!")
367                 for CapsuleName in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.keys():
368                     CapsuleObj = GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict[CapsuleName]
369                     CapsuleObj.GenCapsule()
370
371             if GenFdsGlobalVariable.FdfParser.Profile.OptRomDict != {}:
372                 GenFdsGlobalVariable.VerboseLogger("\n Generate all Option ROM!")
373                 for DriverName in GenFdsGlobalVariable.FdfParser.Profile.OptRomDict.keys():
374                     OptRomObj = GenFdsGlobalVariable.FdfParser.Profile.OptRomDict[DriverName]
375                     OptRomObj.AddToBuffer(None)
376
377     ## GetFvBlockSize()
378     #
379     #   @param  FvObj           Whose block size to get
380     #   @retval int             Block size value
381     #
382     def GetFvBlockSize(FvObj):
383         DefaultBlockSize = 0x1
384         FdObj = None
385         if GenFds.OnlyGenerateThisFd != None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():
386             FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[GenFds.OnlyGenerateThisFd.upper()]
387         if FdObj == None:
388             for ElementFd in GenFdsGlobalVariable.FdfParser.Profile.FdDict.values():
389                 for ElementRegion in ElementFd.RegionList:
390                     if ElementRegion.RegionType == 'FV':
391                         for ElementRegionData in ElementRegion.RegionDataList:
392                             if ElementRegionData != None and ElementRegionData.upper() == FvObj.UiFvName:
393                                 if FvObj.BlockSizeList != []:
394                                     return FvObj.BlockSizeList[0][0]
395                                 else:
396                                     return ElementRegion.BlockSizeOfRegion(ElementFd.BlockSizeList)
397             if FvObj.BlockSizeList != []:
398                 return FvObj.BlockSizeList[0][0]
399             return DefaultBlockSize
400         else:
401             for ElementRegion in FdObj.RegionList:
402                     if ElementRegion.RegionType == 'FV':
403                         for ElementRegionData in ElementRegion.RegionDataList:
404                             if ElementRegionData != None and ElementRegionData.upper() == FvObj.UiFvName:
405                                 if FvObj.BlockSizeList != []:
406                                     return FvObj.BlockSizeList[0][0]
407                                 else:
408                                     return ElementRegion.BlockSizeOfRegion(ElementFd.BlockSizeList)
409             return DefaultBlockSize
410
411     ## DisplayFvSpaceInfo()
412     #
413     #   @param  FvObj           Whose block size to get
414     #   @retval None
415     #
416     def DisplayFvSpaceInfo(FdfParser):
417         
418         FvSpaceInfoList = []
419         MaxFvNameLength = 0
420         for FvName in FdfParser.Profile.FvDict:
421             if len(FvName) > MaxFvNameLength:
422                 MaxFvNameLength = len(FvName)
423             FvSpaceInfoFileName = os.path.join(GenFdsGlobalVariable.FvDir, FvName.upper() + '.Fv.map')
424             if os.path.exists(FvSpaceInfoFileName):
425                 FileLinesList = linecache.getlines(FvSpaceInfoFileName)
426                 TotalFound = False
427                 Total = ''
428                 UsedFound = False
429                 Used = ''
430                 FreeFound = False
431                 Free = ''
432                 for Line in FileLinesList:
433                     NameValue = Line.split('=')
434                     if len(NameValue) == 2:
435                         if NameValue[0].strip() == 'EFI_FV_TOTAL_SIZE':
436                             TotalFound = True
437                             Total = NameValue[1].strip()
438                         if NameValue[0].strip() == 'EFI_FV_TAKEN_SIZE':
439                             UsedFound = True
440                             Used = NameValue[1].strip()
441                         if NameValue[0].strip() == 'EFI_FV_SPACE_SIZE':
442                             FreeFound = True
443                             Free = NameValue[1].strip()
444                 
445                 if TotalFound and UsedFound and FreeFound:
446                     FvSpaceInfoList.append((FvName, Total, Used, Free))
447                 
448         GenFdsGlobalVariable.InfLogger('\nFV Space Information')
449         for FvSpaceInfo in FvSpaceInfoList:
450             Name = FvSpaceInfo[0]
451             TotalSizeValue = long(FvSpaceInfo[1], 0)
452             UsedSizeValue = long(FvSpaceInfo[2], 0)
453             FreeSizeValue = long(FvSpaceInfo[3], 0)
454             GenFdsGlobalVariable.InfLogger(Name + ' ' + '[' + str((UsedSizeValue+0.0)/TotalSizeValue)[0:4].lstrip('0.') + '%Full] ' + str(TotalSizeValue) + ' total, ' + str(UsedSizeValue) + ' used, ' + str(FreeSizeValue) + ' free')
455
456     ## PreprocessImage()
457     #
458     #   @param  BuildDb         Database from build meta data files
459     #   @param  DscFile         modules from dsc file will be preprocessed
460     #   @retval None
461     #
462     def PreprocessImage(BuildDb, DscFile):
463         PcdDict = BuildDb.BuildObject[DscFile, 'COMMON'].Pcds
464         PcdValue = ''
465         for Key in PcdDict:
466             PcdObj = PcdDict[Key]
467             if PcdObj.TokenCName == 'PcdBsBaseAddress':
468                 PcdValue = PcdObj.DefaultValue
469                 break
470         
471         if PcdValue == '':
472             return
473         
474         Int64PcdValue = long(PcdValue, 0)
475         if Int64PcdValue == 0 or Int64PcdValue < -1:    
476             return
477                 
478         TopAddress = 0
479         if Int64PcdValue > 0:
480             TopAddress = Int64PcdValue
481             
482         ModuleDict = BuildDb.BuildObject[DscFile, 'COMMON'].Modules
483         for Key in ModuleDict:
484             ModuleObj = BuildDb.BuildObject[Key, 'COMMON']
485             print ModuleObj.BaseName + ' ' + ModuleObj.ModuleType
486
487     def GenerateGuidXRefFile(BuildDb, ArchList):
488         GuidXRefFileName = os.path.join(GenFdsGlobalVariable.FvDir, "Guid.xref")
489         GuidXRefFile = open(GuidXRefFileName, "w+")
490         for Arch in ArchList:
491             PlatformDataBase = BuildDb.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch]
492             for ModuleFile in PlatformDataBase.Modules:
493                 Module = BuildDb.BuildObject[ModuleFile, Arch]
494                 GuidXRefFile.write("%s %s\n" % (Module.Guid, Module.BaseName))
495         GuidXRefFile.close()
496         GenFdsGlobalVariable.InfLogger("\nGUID cross reference file saved to %s" % GuidXRefFileName)
497         
498     ##Define GenFd as static function
499     GenFd = staticmethod(GenFd)
500     GetFvBlockSize = staticmethod(GetFvBlockSize)
501     DisplayFvSpaceInfo = staticmethod(DisplayFvSpaceInfo)
502     PreprocessImage = staticmethod(PreprocessImage)
503     GenerateGuidXRefFile = staticmethod(GenerateGuidXRefFile)
504
505 if __name__ == '__main__':
506     r = main()
507     ## 0-127 is a safe return range, and 1 is a standard default error
508     if r < 0 or r > 127: r = 1
509     sys.exit(r)
510