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