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