4 # Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
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
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.
18 from optparse
import OptionParser
20 import Common
.LongFilePathOs
as os
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
31 import Common
.TargetTxtClassObject
as TargetTxtClassObject
32 import Common
.ToolDefClassObject
as ToolDefClassObject
33 import Common
.DataType
34 import Common
.GlobalData
as GlobalData
35 from Common
import EdkLogger
36 from Common
.String
import *
37 from Common
.Misc
import DirCache
, PathClass
38 from Common
.Misc
import SaveFileOnChange
39 from Common
.Misc
import ClearDuplicatedInf
40 from Common
.Misc
import GuidStructureStringToGuidString
41 from Common
.BuildVersion
import gBUILD_VERSION
42 from Common
.MultipleWorkspace
import MultipleWorkspace
as mws
44 ## Version and Copyright
45 versionNumber
= "1.0" + ' ' + gBUILD_VERSION
46 __version__
= "%prog Version " + versionNumber
47 __copyright__
= "Copyright (c) 2007 - 2014, Intel Corporation All rights reserved."
49 ## Tool entrance method
51 # This method mainly dispatch specific methods per the command line options.
52 # If no error found, return zero value so the caller of this tool can know
53 # if it's executed successfully or not.
55 # @retval 0 Tool was successful
56 # @retval 1 Tool failed
60 Options
= myOptionParser()
67 EdkLogger
.Initialize()
69 if Options
.verbose
!= None:
70 EdkLogger
.SetLevel(EdkLogger
.VERBOSE
)
71 GenFdsGlobalVariable
.VerboseMode
= True
73 if Options
.FixedAddress
!= None:
74 GenFdsGlobalVariable
.FixedLoadAddress
= True
76 if Options
.quiet
!= None:
77 EdkLogger
.SetLevel(EdkLogger
.QUIET
)
78 if Options
.debug
!= None:
79 EdkLogger
.SetLevel(Options
.debug
+ 1)
80 GenFdsGlobalVariable
.DebugLevel
= Options
.debug
82 EdkLogger
.SetLevel(EdkLogger
.INFO
)
84 if (Options
.Workspace
== None):
85 EdkLogger
.error("GenFds", OPTION_MISSING
, "WORKSPACE not defined",
86 ExtraData
="Please use '-w' switch to pass it or set the WORKSPACE environment variable.")
87 elif not os
.path
.exists(Options
.Workspace
):
88 EdkLogger
.error("GenFds", PARAMETER_INVALID
, "WORKSPACE is invalid",
89 ExtraData
="Please use '-w' switch to pass it or set the WORKSPACE environment variable.")
91 Workspace
= os
.path
.normcase(Options
.Workspace
)
92 GenFdsGlobalVariable
.WorkSpaceDir
= Workspace
93 if 'EDK_SOURCE' in os
.environ
.keys():
94 GenFdsGlobalVariable
.EdkSourceDir
= os
.path
.normcase(os
.environ
['EDK_SOURCE'])
96 GenFdsGlobalVariable
.VerboseLogger("Using Workspace:" + Workspace
)
97 os
.chdir(GenFdsGlobalVariable
.WorkSpaceDir
)
99 # set multiple workspace
100 PackagesPath
= os
.getenv("PACKAGES_PATH")
101 mws
.setWs(GenFdsGlobalVariable
.WorkSpaceDir
, PackagesPath
)
103 if (Options
.filename
):
104 FdfFilename
= Options
.filename
105 FdfFilename
= GenFdsGlobalVariable
.ReplaceWorkspaceMacro(FdfFilename
)
107 if FdfFilename
[0:2] == '..':
108 FdfFilename
= os
.path
.realpath(FdfFilename
)
109 if not os
.path
.isabs(FdfFilename
):
110 FdfFilename
= mws
.join(GenFdsGlobalVariable
.WorkSpaceDir
, FdfFilename
)
111 if not os
.path
.exists(FdfFilename
):
112 EdkLogger
.error("GenFds", FILE_NOT_FOUND
, ExtraData
=FdfFilename
)
114 GenFdsGlobalVariable
.FdfFile
= FdfFilename
115 GenFdsGlobalVariable
.FdfFileTimeStamp
= os
.path
.getmtime(FdfFilename
)
117 EdkLogger
.error("GenFds", OPTION_MISSING
, "Missing FDF filename")
119 if (Options
.BuildTarget
):
120 GenFdsGlobalVariable
.TargetName
= Options
.BuildTarget
122 EdkLogger
.error("GenFds", OPTION_MISSING
, "Missing build target")
124 if (Options
.ToolChain
):
125 GenFdsGlobalVariable
.ToolChainTag
= Options
.ToolChain
127 EdkLogger
.error("GenFds", OPTION_MISSING
, "Missing tool chain tag")
129 if (Options
.activePlatform
):
130 ActivePlatform
= Options
.activePlatform
131 ActivePlatform
= GenFdsGlobalVariable
.ReplaceWorkspaceMacro(ActivePlatform
)
133 if ActivePlatform
[0:2] == '..':
134 ActivePlatform
= os
.path
.realpath(ActivePlatform
)
136 if not os
.path
.isabs (ActivePlatform
):
137 ActivePlatform
= mws
.join(GenFdsGlobalVariable
.WorkSpaceDir
, ActivePlatform
)
139 if not os
.path
.exists(ActivePlatform
) :
140 EdkLogger
.error("GenFds", FILE_NOT_FOUND
, "ActivePlatform doesn't exist!")
142 if os
.path
.normcase (ActivePlatform
).find(Workspace
) == 0:
143 ActivePlatform
= mws
.relpath(ActivePlatform
, Workspace
)
144 if len(ActivePlatform
) > 0 :
145 if ActivePlatform
[0] == '\\' or ActivePlatform
[0] == '/':
146 ActivePlatform
= ActivePlatform
[1:]
148 EdkLogger
.error("GenFds", FILE_NOT_FOUND
, "ActivePlatform doesn't exist!")
150 EdkLogger
.error("GenFds", OPTION_MISSING
, "Missing active platform")
152 GenFdsGlobalVariable
.ActivePlatform
= PathClass(NormPath(ActivePlatform
), Workspace
)
154 if (Options
.ConfDirectory
):
155 # Get alternate Conf location, if it is absolute, then just use the absolute directory name
156 ConfDirectoryPath
= os
.path
.normpath(Options
.ConfDirectory
)
157 if ConfDirectoryPath
.startswith('"'):
158 ConfDirectoryPath
= ConfDirectoryPath
[1:]
159 if ConfDirectoryPath
.endswith('"'):
160 ConfDirectoryPath
= ConfDirectoryPath
[:-1]
161 if not os
.path
.isabs(ConfDirectoryPath
):
162 # Since alternate directory name is not absolute, the alternate directory is located within the WORKSPACE
163 # This also handles someone specifying the Conf directory in the workspace. Using --conf=Conf
164 ConfDirectoryPath
= os
.path
.join(GenFdsGlobalVariable
.WorkSpaceDir
, ConfDirectoryPath
)
166 # Get standard WORKSPACE/Conf, use the absolute path to the WORKSPACE/Conf
167 ConfDirectoryPath
= mws
.join(GenFdsGlobalVariable
.WorkSpaceDir
, 'Conf')
168 GenFdsGlobalVariable
.ConfDir
= ConfDirectoryPath
169 BuildConfigurationFile
= os
.path
.normpath(os
.path
.join(ConfDirectoryPath
, "target.txt"))
170 if os
.path
.isfile(BuildConfigurationFile
) == True:
171 TargetTxtClassObject
.TargetTxtClassObject(BuildConfigurationFile
)
173 EdkLogger
.error("GenFds", FILE_NOT_FOUND
, ExtraData
=BuildConfigurationFile
)
175 #Set global flag for build mode
176 GlobalData
.gIgnoreSource
= Options
.IgnoreSources
179 for Pair
in Options
.Macros
:
180 if Pair
.startswith('"'):
182 if Pair
.endswith('"'):
184 List
= Pair
.split('=')
186 if List
[0].strip() == "EFI_SOURCE":
187 GlobalData
.gEfiSource
= List
[1].strip()
188 GlobalData
.gGlobalDefines
["EFI_SOURCE"] = GlobalData
.gEfiSource
190 elif List
[0].strip() == "EDK_SOURCE":
191 GlobalData
.gEdkSource
= List
[1].strip()
192 GlobalData
.gGlobalDefines
["EDK_SOURCE"] = GlobalData
.gEdkSource
194 elif List
[0].strip() in ["WORKSPACE", "TARGET", "TOOLCHAIN"]:
195 GlobalData
.gGlobalDefines
[List
[0].strip()] = List
[1].strip()
197 GlobalData
.gCommandLineDefines
[List
[0].strip()] = List
[1].strip()
199 GlobalData
.gCommandLineDefines
[List
[0].strip()] = "TRUE"
200 os
.environ
["WORKSPACE"] = Workspace
202 """call Workspace build create database"""
203 GlobalData
.gDatabasePath
= os
.path
.normpath(os
.path
.join(ConfDirectoryPath
, GlobalData
.gDatabasePath
))
204 BuildWorkSpace
= WorkspaceDatabase(GlobalData
.gDatabasePath
)
205 BuildWorkSpace
.InitDatabase()
208 # Get files real name in workspace dir
210 GlobalData
.gAllFiles
= DirCache(Workspace
)
211 GlobalData
.gWorkspace
= Workspace
213 if (Options
.archList
) :
214 ArchList
= Options
.archList
.split(',')
216 # EdkLogger.error("GenFds", OPTION_MISSING, "Missing build ARCH")
217 ArchList
= BuildWorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, 'COMMON', Options
.BuildTarget
, Options
.ToolChain
].SupArchList
219 TargetArchList
= set(BuildWorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, 'COMMON', Options
.BuildTarget
, Options
.ToolChain
].SupArchList
) & set(ArchList
)
220 if len(TargetArchList
) == 0:
221 EdkLogger
.error("GenFds", GENFDS_ERROR
, "Target ARCH %s not in platform supported ARCH %s" % (str(ArchList
), str(BuildWorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, 'COMMON'].SupArchList
)))
223 for Arch
in ArchList
:
224 GenFdsGlobalVariable
.OutputDirFromDscDict
[Arch
] = NormPath(BuildWorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
, Options
.BuildTarget
, Options
.ToolChain
].OutputDirectory
)
225 GenFdsGlobalVariable
.PlatformName
= BuildWorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
, Options
.BuildTarget
, Options
.ToolChain
].PlatformName
227 if (Options
.outputDir
):
228 OutputDirFromCommandLine
= GenFdsGlobalVariable
.ReplaceWorkspaceMacro(Options
.outputDir
)
229 if not os
.path
.isabs (OutputDirFromCommandLine
):
230 OutputDirFromCommandLine
= os
.path
.join(GenFdsGlobalVariable
.WorkSpaceDir
, OutputDirFromCommandLine
)
231 for Arch
in ArchList
:
232 GenFdsGlobalVariable
.OutputDirDict
[Arch
] = OutputDirFromCommandLine
234 for Arch
in ArchList
:
235 GenFdsGlobalVariable
.OutputDirDict
[Arch
] = os
.path
.join(GenFdsGlobalVariable
.OutputDirFromDscDict
[Arch
], GenFdsGlobalVariable
.TargetName
+ '_' + GenFdsGlobalVariable
.ToolChainTag
)
237 for Key
in GenFdsGlobalVariable
.OutputDirDict
:
238 OutputDir
= GenFdsGlobalVariable
.OutputDirDict
[Key
]
239 if OutputDir
[0:2] == '..':
240 OutputDir
= os
.path
.realpath(OutputDir
)
242 if OutputDir
[1] != ':':
243 OutputDir
= os
.path
.join (GenFdsGlobalVariable
.WorkSpaceDir
, OutputDir
)
245 if not os
.path
.exists(OutputDir
):
246 EdkLogger
.error("GenFds", FILE_NOT_FOUND
, ExtraData
=OutputDir
)
247 GenFdsGlobalVariable
.OutputDirDict
[Key
] = OutputDir
249 """ Parse Fdf file, has to place after build Workspace as FDF may contain macros from DSC file """
250 FdfParserObj
= FdfParser
.FdfParser(FdfFilename
)
251 FdfParserObj
.ParseFile()
253 if FdfParserObj
.CycleReferenceCheck():
254 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "Cycle Reference Detected in FDF file")
256 if (Options
.uiFdName
) :
257 if Options
.uiFdName
.upper() in FdfParserObj
.Profile
.FdDict
.keys():
258 GenFds
.OnlyGenerateThisFd
= Options
.uiFdName
260 EdkLogger
.error("GenFds", OPTION_VALUE_INVALID
,
261 "No such an FD in FDF file: %s" % Options
.uiFdName
)
263 if (Options
.uiFvName
) :
264 if Options
.uiFvName
.upper() in FdfParserObj
.Profile
.FvDict
.keys():
265 GenFds
.OnlyGenerateThisFv
= Options
.uiFvName
267 EdkLogger
.error("GenFds", OPTION_VALUE_INVALID
,
268 "No such an FV in FDF file: %s" % Options
.uiFvName
)
270 if (Options
.uiCapName
) :
271 if Options
.uiCapName
.upper() in FdfParserObj
.Profile
.CapsuleDict
.keys():
272 GenFds
.OnlyGenerateThisCap
= Options
.uiCapName
274 EdkLogger
.error("GenFds", OPTION_VALUE_INVALID
,
275 "No such a Capsule in FDF file: %s" % Options
.uiCapName
)
277 """Modify images from build output if the feature of loading driver at fixed address is on."""
278 if GenFdsGlobalVariable
.FixedLoadAddress
:
279 GenFds
.PreprocessImage(BuildWorkSpace
, GenFdsGlobalVariable
.ActivePlatform
)
281 GenFds
.GenFd('', FdfParserObj
, BuildWorkSpace
, ArchList
)
283 """Generate GUID cross reference file"""
284 GenFds
.GenerateGuidXRefFile(BuildWorkSpace
, ArchList
)
286 """Display FV space info."""
287 GenFds
.DisplayFvSpaceInfo(FdfParserObj
)
289 except FdfParser
.Warning, X
:
290 EdkLogger
.error(X
.ToolName
, FORMAT_INVALID
, File
=X
.FileName
, Line
=X
.LineNumber
, ExtraData
=X
.Message
, RaiseError
=False)
291 ReturnCode
= FORMAT_INVALID
292 except FatalError
, X
:
293 if Options
.debug
!= None:
295 EdkLogger
.quiet(traceback
.format_exc())
296 ReturnCode
= X
.args
[0]
302 "Tools code failure",
303 ExtraData
="Please send email to edk2-devel@lists.sourceforge.net for help, attaching following call stack trace!\n",
306 EdkLogger
.quiet(traceback
.format_exc())
307 ReturnCode
= CODE_ERROR
313 def SingleCheckCallback(option
, opt_str
, value
, parser
):
314 if option
not in gParamCheck
:
315 setattr(parser
.values
, option
.dest
, value
)
316 gParamCheck
.append(option
)
318 parser
.error("Option %s only allows one instance in command line!" % option
)
320 ## Parse command line options
322 # Using standard Python module optparse to parse command line option of this tool.
324 # @retval Opt A optparse.Values object containing the parsed options
325 # @retval Args Target of build command
327 def myOptionParser():
328 usage
= "%prog [options] -f input_file -a arch_list -b build_target -p active_platform -t tool_chain_tag -D \"MacroName [= MacroValue]\""
329 Parser
= OptionParser(usage
=usage
, description
=__copyright__
, version
="%prog " + str(versionNumber
))
330 Parser
.add_option("-f", "--file", dest
="filename", type="string", help="Name of FDF file to convert", action
="callback", callback
=SingleCheckCallback
)
331 Parser
.add_option("-a", "--arch", dest
="archList", help="comma separated list containing one or more of: IA32, X64, IPF, ARM, AARCH64 or EBC which should be built, overrides target.txt?s TARGET_ARCH")
332 Parser
.add_option("-q", "--quiet", action
="store_true", type=None, help="Disable all messages except FATAL ERRORS.")
333 Parser
.add_option("-v", "--verbose", action
="store_true", type=None, help="Turn on verbose output with informational messages printed.")
334 Parser
.add_option("-d", "--debug", action
="store", type="int", help="Enable debug messages at specified level.")
335 Parser
.add_option("-p", "--platform", type="string", dest
="activePlatform", help="Set the ACTIVE_PLATFORM, overrides target.txt ACTIVE_PLATFORM setting.",
336 action
="callback", callback
=SingleCheckCallback
)
337 Parser
.add_option("-w", "--workspace", type="string", dest
="Workspace", default
=os
.environ
.get('WORKSPACE'), help="Set the WORKSPACE",
338 action
="callback", callback
=SingleCheckCallback
)
339 Parser
.add_option("-o", "--outputDir", type="string", dest
="outputDir", help="Name of Build Output directory",
340 action
="callback", callback
=SingleCheckCallback
)
341 Parser
.add_option("-r", "--rom_image", dest
="uiFdName", help="Build the image using the [FD] section named by FdUiName.")
342 Parser
.add_option("-i", "--FvImage", dest
="uiFvName", help="Build the FV image using the [FV] section named by UiFvName")
343 Parser
.add_option("-C", "--CapsuleImage", dest
="uiCapName", help="Build the Capsule image using the [Capsule] section named by UiCapName")
344 Parser
.add_option("-b", "--buildtarget", type="string", dest
="BuildTarget", help="Set the build TARGET, overrides target.txt TARGET setting.",
345 action
="callback", callback
=SingleCheckCallback
)
346 Parser
.add_option("-t", "--tagname", type="string", dest
="ToolChain", help="Using the tools: TOOL_CHAIN_TAG name to build the platform.",
347 action
="callback", callback
=SingleCheckCallback
)
348 Parser
.add_option("-D", "--define", action
="append", type="string", dest
="Macros", help="Macro: \"Name [= Value]\".")
349 Parser
.add_option("-s", "--specifyaddress", dest
="FixedAddress", action
="store_true", type=None, help="Specify driver load address.")
350 Parser
.add_option("--conf", action
="store", type="string", dest
="ConfDirectory", help="Specify the customized Conf directory.")
351 Parser
.add_option("--ignore-sources", action
="store_true", dest
="IgnoreSources", default
=False, help="Focus to a binary build and ignore all source files")
353 (Options
, args
) = Parser
.parse_args()
356 ## The class implementing the EDK2 flash image generation process
358 # This process includes:
359 # 1. Collect workspace information, includes platform and module information
360 # 2. Call methods of Fd class to generate FD
361 # 3. Call methods of Fv class to generate FV that not belong to FD
365 # FvName, FdName, CapName in FDF, Image file name
367 OnlyGenerateThisFd
= None
368 OnlyGenerateThisFv
= None
369 OnlyGenerateThisCap
= None
373 # @param OutputDir Output directory
374 # @param FdfParser FDF contents parser
375 # @param Workspace The directory of workspace
376 # @param ArchList The Arch list of platform
378 def GenFd (OutputDir
, FdfParser
, WorkSpace
, ArchList
):
379 GenFdsGlobalVariable
.SetDir ('', FdfParser
, WorkSpace
, ArchList
)
381 GenFdsGlobalVariable
.VerboseLogger(" Generate all Fd images and their required FV and Capsule images!")
382 if GenFds
.OnlyGenerateThisCap
!= None and GenFds
.OnlyGenerateThisCap
.upper() in GenFdsGlobalVariable
.FdfParser
.Profile
.CapsuleDict
.keys():
383 CapsuleObj
= GenFdsGlobalVariable
.FdfParser
.Profile
.CapsuleDict
.get(GenFds
.OnlyGenerateThisCap
.upper())
384 if CapsuleObj
!= None:
385 CapsuleObj
.GenCapsule()
388 if GenFds
.OnlyGenerateThisFd
!= None and GenFds
.OnlyGenerateThisFd
.upper() in GenFdsGlobalVariable
.FdfParser
.Profile
.FdDict
.keys():
389 FdObj
= GenFdsGlobalVariable
.FdfParser
.Profile
.FdDict
.get(GenFds
.OnlyGenerateThisFd
.upper())
393 elif GenFds
.OnlyGenerateThisFd
== None and GenFds
.OnlyGenerateThisFv
== None:
394 for FdName
in GenFdsGlobalVariable
.FdfParser
.Profile
.FdDict
.keys():
395 FdObj
= GenFdsGlobalVariable
.FdfParser
.Profile
.FdDict
[FdName
]
398 GenFdsGlobalVariable
.VerboseLogger("\n Generate other FV images! ")
399 if GenFds
.OnlyGenerateThisFv
!= None and GenFds
.OnlyGenerateThisFv
.upper() in GenFdsGlobalVariable
.FdfParser
.Profile
.FvDict
.keys():
400 FvObj
= GenFdsGlobalVariable
.FdfParser
.Profile
.FvDict
.get(GenFds
.OnlyGenerateThisFv
.upper())
402 Buffer
= StringIO
.StringIO()
403 FvObj
.AddToBuffer(Buffer
)
406 elif GenFds
.OnlyGenerateThisFv
== None:
407 for FvName
in GenFdsGlobalVariable
.FdfParser
.Profile
.FvDict
.keys():
408 Buffer
= StringIO
.StringIO('')
409 FvObj
= GenFdsGlobalVariable
.FdfParser
.Profile
.FvDict
[FvName
]
410 FvObj
.AddToBuffer(Buffer
)
413 if GenFds
.OnlyGenerateThisFv
== None and GenFds
.OnlyGenerateThisFd
== None and GenFds
.OnlyGenerateThisCap
== None:
414 if GenFdsGlobalVariable
.FdfParser
.Profile
.CapsuleDict
!= {}:
415 GenFdsGlobalVariable
.VerboseLogger("\n Generate other Capsule images!")
416 for CapsuleName
in GenFdsGlobalVariable
.FdfParser
.Profile
.CapsuleDict
.keys():
417 CapsuleObj
= GenFdsGlobalVariable
.FdfParser
.Profile
.CapsuleDict
[CapsuleName
]
418 CapsuleObj
.GenCapsule()
420 if GenFdsGlobalVariable
.FdfParser
.Profile
.OptRomDict
!= {}:
421 GenFdsGlobalVariable
.VerboseLogger("\n Generate all Option ROM!")
422 for DriverName
in GenFdsGlobalVariable
.FdfParser
.Profile
.OptRomDict
.keys():
423 OptRomObj
= GenFdsGlobalVariable
.FdfParser
.Profile
.OptRomDict
[DriverName
]
424 OptRomObj
.AddToBuffer(None)
428 # @param FvObj Whose block size to get
429 # @retval int Block size value
431 def GetFvBlockSize(FvObj
):
432 DefaultBlockSize
= 0x1
434 if GenFds
.OnlyGenerateThisFd
!= None and GenFds
.OnlyGenerateThisFd
.upper() in GenFdsGlobalVariable
.FdfParser
.Profile
.FdDict
.keys():
435 FdObj
= GenFdsGlobalVariable
.FdfParser
.Profile
.FdDict
[GenFds
.OnlyGenerateThisFd
.upper()]
437 for ElementFd
in GenFdsGlobalVariable
.FdfParser
.Profile
.FdDict
.values():
438 for ElementRegion
in ElementFd
.RegionList
:
439 if ElementRegion
.RegionType
== 'FV':
440 for ElementRegionData
in ElementRegion
.RegionDataList
:
441 if ElementRegionData
!= None and ElementRegionData
.upper() == FvObj
.UiFvName
:
442 if FvObj
.BlockSizeList
!= []:
443 return FvObj
.BlockSizeList
[0][0]
445 return ElementRegion
.BlockSizeOfRegion(ElementFd
.BlockSizeList
)
446 if FvObj
.BlockSizeList
!= []:
447 return FvObj
.BlockSizeList
[0][0]
448 return DefaultBlockSize
450 for ElementRegion
in FdObj
.RegionList
:
451 if ElementRegion
.RegionType
== 'FV':
452 for ElementRegionData
in ElementRegion
.RegionDataList
:
453 if ElementRegionData
!= None and ElementRegionData
.upper() == FvObj
.UiFvName
:
454 if FvObj
.BlockSizeList
!= []:
455 return FvObj
.BlockSizeList
[0][0]
457 return ElementRegion
.BlockSizeOfRegion(ElementFd
.BlockSizeList
)
458 return DefaultBlockSize
460 ## DisplayFvSpaceInfo()
462 # @param FvObj Whose block size to get
465 def DisplayFvSpaceInfo(FdfParser
):
469 for FvName
in FdfParser
.Profile
.FvDict
:
470 if len(FvName
) > MaxFvNameLength
:
471 MaxFvNameLength
= len(FvName
)
472 FvSpaceInfoFileName
= os
.path
.join(GenFdsGlobalVariable
.FvDir
, FvName
.upper() + '.Fv.map')
473 if os
.path
.exists(FvSpaceInfoFileName
):
474 FileLinesList
= linecache
.getlines(FvSpaceInfoFileName
)
481 for Line
in FileLinesList
:
482 NameValue
= Line
.split('=')
483 if len(NameValue
) == 2:
484 if NameValue
[0].strip() == 'EFI_FV_TOTAL_SIZE':
486 Total
= NameValue
[1].strip()
487 if NameValue
[0].strip() == 'EFI_FV_TAKEN_SIZE':
489 Used
= NameValue
[1].strip()
490 if NameValue
[0].strip() == 'EFI_FV_SPACE_SIZE':
492 Free
= NameValue
[1].strip()
494 if TotalFound
and UsedFound
and FreeFound
:
495 FvSpaceInfoList
.append((FvName
, Total
, Used
, Free
))
497 GenFdsGlobalVariable
.InfLogger('\nFV Space Information')
498 for FvSpaceInfo
in FvSpaceInfoList
:
499 Name
= FvSpaceInfo
[0]
500 TotalSizeValue
= long(FvSpaceInfo
[1], 0)
501 UsedSizeValue
= long(FvSpaceInfo
[2], 0)
502 FreeSizeValue
= long(FvSpaceInfo
[3], 0)
503 if UsedSizeValue
== TotalSizeValue
:
506 Percentage
= str((UsedSizeValue
+ 0.0) / TotalSizeValue
)[0:4].lstrip('0.')
508 GenFdsGlobalVariable
.InfLogger(Name
+ ' ' + '[' + Percentage
+ '%Full] ' + str(TotalSizeValue
) + ' total, ' + str(UsedSizeValue
) + ' used, ' + str(FreeSizeValue
) + ' free')
512 # @param BuildDb Database from build meta data files
513 # @param DscFile modules from dsc file will be preprocessed
516 def PreprocessImage(BuildDb
, DscFile
):
517 PcdDict
= BuildDb
.BuildObject
[DscFile
, 'COMMON', GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
].Pcds
520 PcdObj
= PcdDict
[Key
]
521 if PcdObj
.TokenCName
== 'PcdBsBaseAddress':
522 PcdValue
= PcdObj
.DefaultValue
528 Int64PcdValue
= long(PcdValue
, 0)
529 if Int64PcdValue
== 0 or Int64PcdValue
< -1:
533 if Int64PcdValue
> 0:
534 TopAddress
= Int64PcdValue
536 ModuleDict
= BuildDb
.BuildObject
[DscFile
, 'COMMON', GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
].Modules
537 for Key
in ModuleDict
:
538 ModuleObj
= BuildDb
.BuildObject
[Key
, 'COMMON', GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
539 print ModuleObj
.BaseName
+ ' ' + ModuleObj
.ModuleType
541 def GenerateGuidXRefFile(BuildDb
, ArchList
):
542 GuidXRefFileName
= os
.path
.join(GenFdsGlobalVariable
.FvDir
, "Guid.xref")
543 GuidXRefFile
= StringIO
.StringIO('')
545 for Arch
in ArchList
:
546 PlatformDataBase
= BuildDb
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
547 for ModuleFile
in PlatformDataBase
.Modules
:
548 Module
= BuildDb
.BuildObject
[ModuleFile
, Arch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
549 GuidXRefFile
.write("%s %s\n" % (Module
.Guid
, Module
.BaseName
))
550 for key
, item
in Module
.Protocols
.items():
552 for key
, item
in Module
.Guids
.items():
554 for key
, item
in Module
.Ppis
.items():
556 # Append GUIDs, Protocols, and PPIs to the Xref file
557 GuidXRefFile
.write("\n")
558 for key
, item
in GuidDict
.items():
559 GuidXRefFile
.write("%s %s\n" % (GuidStructureStringToGuidString(item
).upper(), key
))
561 if GuidXRefFile
.getvalue():
562 SaveFileOnChange(GuidXRefFileName
, GuidXRefFile
.getvalue(), False)
563 GenFdsGlobalVariable
.InfLogger("\nGUID cross reference file can be found at %s" % GuidXRefFileName
)
564 elif os
.path
.exists(GuidXRefFileName
):
565 os
.remove(GuidXRefFileName
)
568 ##Define GenFd as static function
569 GenFd
= staticmethod(GenFd
)
570 GetFvBlockSize
= staticmethod(GetFvBlockSize
)
571 DisplayFvSpaceInfo
= staticmethod(DisplayFvSpaceInfo
)
572 PreprocessImage
= staticmethod(PreprocessImage
)
573 GenerateGuidXRefFile
= staticmethod(GenerateGuidXRefFile
)
575 if __name__
== '__main__':
577 ## 0-127 is a safe return range, and 1 is a standard default error
578 if r
< 0 or r
> 127: r
= 1