4 # Copyright (c) 2007 - 2016, 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
.Misc
import CheckPcdDatum
42 from Common
.BuildVersion
import gBUILD_VERSION
43 from Common
.MultipleWorkspace
import MultipleWorkspace
as mws
45 ## Version and Copyright
46 versionNumber
= "1.0" + ' ' + gBUILD_VERSION
47 __version__
= "%prog Version " + versionNumber
48 __copyright__
= "Copyright (c) 2007 - 2016, Intel Corporation All rights reserved."
50 ## Tool entrance method
52 # This method mainly dispatch specific methods per the command line options.
53 # If no error found, return zero value so the caller of this tool can know
54 # if it's executed successfully or not.
56 # @retval 0 Tool was successful
57 # @retval 1 Tool failed
61 Options
= myOptionParser()
68 EdkLogger
.Initialize()
70 if Options
.verbose
!= None:
71 EdkLogger
.SetLevel(EdkLogger
.VERBOSE
)
72 GenFdsGlobalVariable
.VerboseMode
= True
74 if Options
.FixedAddress
!= None:
75 GenFdsGlobalVariable
.FixedLoadAddress
= True
77 if Options
.quiet
!= None:
78 EdkLogger
.SetLevel(EdkLogger
.QUIET
)
79 if Options
.debug
!= None:
80 EdkLogger
.SetLevel(Options
.debug
+ 1)
81 GenFdsGlobalVariable
.DebugLevel
= Options
.debug
83 EdkLogger
.SetLevel(EdkLogger
.INFO
)
85 if (Options
.Workspace
== None):
86 EdkLogger
.error("GenFds", OPTION_MISSING
, "WORKSPACE not defined",
87 ExtraData
="Please use '-w' switch to pass it or set the WORKSPACE environment variable.")
88 elif not os
.path
.exists(Options
.Workspace
):
89 EdkLogger
.error("GenFds", PARAMETER_INVALID
, "WORKSPACE is invalid",
90 ExtraData
="Please use '-w' switch to pass it or set the WORKSPACE environment variable.")
92 Workspace
= os
.path
.normcase(Options
.Workspace
)
93 GenFdsGlobalVariable
.WorkSpaceDir
= Workspace
94 if 'EDK_SOURCE' in os
.environ
.keys():
95 GenFdsGlobalVariable
.EdkSourceDir
= os
.path
.normcase(os
.environ
['EDK_SOURCE'])
97 GenFdsGlobalVariable
.VerboseLogger("Using Workspace:" + Workspace
)
98 os
.chdir(GenFdsGlobalVariable
.WorkSpaceDir
)
100 # set multiple workspace
101 PackagesPath
= os
.getenv("PACKAGES_PATH")
102 mws
.setWs(GenFdsGlobalVariable
.WorkSpaceDir
, PackagesPath
)
104 if (Options
.filename
):
105 FdfFilename
= Options
.filename
106 FdfFilename
= GenFdsGlobalVariable
.ReplaceWorkspaceMacro(FdfFilename
)
108 if FdfFilename
[0:2] == '..':
109 FdfFilename
= os
.path
.realpath(FdfFilename
)
110 if not os
.path
.isabs(FdfFilename
):
111 FdfFilename
= mws
.join(GenFdsGlobalVariable
.WorkSpaceDir
, FdfFilename
)
112 if not os
.path
.exists(FdfFilename
):
113 EdkLogger
.error("GenFds", FILE_NOT_FOUND
, ExtraData
=FdfFilename
)
115 GenFdsGlobalVariable
.FdfFile
= FdfFilename
116 GenFdsGlobalVariable
.FdfFileTimeStamp
= os
.path
.getmtime(FdfFilename
)
118 EdkLogger
.error("GenFds", OPTION_MISSING
, "Missing FDF filename")
120 if (Options
.BuildTarget
):
121 GenFdsGlobalVariable
.TargetName
= Options
.BuildTarget
123 EdkLogger
.error("GenFds", OPTION_MISSING
, "Missing build target")
125 if (Options
.ToolChain
):
126 GenFdsGlobalVariable
.ToolChainTag
= Options
.ToolChain
128 EdkLogger
.error("GenFds", OPTION_MISSING
, "Missing tool chain tag")
130 if (Options
.activePlatform
):
131 ActivePlatform
= Options
.activePlatform
132 ActivePlatform
= GenFdsGlobalVariable
.ReplaceWorkspaceMacro(ActivePlatform
)
134 if ActivePlatform
[0:2] == '..':
135 ActivePlatform
= os
.path
.realpath(ActivePlatform
)
137 if not os
.path
.isabs (ActivePlatform
):
138 ActivePlatform
= mws
.join(GenFdsGlobalVariable
.WorkSpaceDir
, ActivePlatform
)
140 if not os
.path
.exists(ActivePlatform
) :
141 EdkLogger
.error("GenFds", FILE_NOT_FOUND
, "ActivePlatform doesn't exist!")
143 EdkLogger
.error("GenFds", OPTION_MISSING
, "Missing active platform")
145 GenFdsGlobalVariable
.ActivePlatform
= PathClass(NormPath(ActivePlatform
))
147 if (Options
.ConfDirectory
):
148 # Get alternate Conf location, if it is absolute, then just use the absolute directory name
149 ConfDirectoryPath
= os
.path
.normpath(Options
.ConfDirectory
)
150 if ConfDirectoryPath
.startswith('"'):
151 ConfDirectoryPath
= ConfDirectoryPath
[1:]
152 if ConfDirectoryPath
.endswith('"'):
153 ConfDirectoryPath
= ConfDirectoryPath
[:-1]
154 if not os
.path
.isabs(ConfDirectoryPath
):
155 # Since alternate directory name is not absolute, the alternate directory is located within the WORKSPACE
156 # This also handles someone specifying the Conf directory in the workspace. Using --conf=Conf
157 ConfDirectoryPath
= os
.path
.join(GenFdsGlobalVariable
.WorkSpaceDir
, ConfDirectoryPath
)
159 # Get standard WORKSPACE/Conf, use the absolute path to the WORKSPACE/Conf
160 ConfDirectoryPath
= mws
.join(GenFdsGlobalVariable
.WorkSpaceDir
, 'Conf')
161 GenFdsGlobalVariable
.ConfDir
= ConfDirectoryPath
162 BuildConfigurationFile
= os
.path
.normpath(os
.path
.join(ConfDirectoryPath
, "target.txt"))
163 if os
.path
.isfile(BuildConfigurationFile
) == True:
164 TargetTxtClassObject
.TargetTxtClassObject(BuildConfigurationFile
)
166 EdkLogger
.error("GenFds", FILE_NOT_FOUND
, ExtraData
=BuildConfigurationFile
)
168 #Set global flag for build mode
169 GlobalData
.gIgnoreSource
= Options
.IgnoreSources
172 for Pair
in Options
.Macros
:
173 if Pair
.startswith('"'):
175 if Pair
.endswith('"'):
177 List
= Pair
.split('=')
179 if List
[0].strip() == "EFI_SOURCE":
180 GlobalData
.gEfiSource
= List
[1].strip()
181 GlobalData
.gGlobalDefines
["EFI_SOURCE"] = GlobalData
.gEfiSource
183 elif List
[0].strip() == "EDK_SOURCE":
184 GlobalData
.gEdkSource
= List
[1].strip()
185 GlobalData
.gGlobalDefines
["EDK_SOURCE"] = GlobalData
.gEdkSource
187 elif List
[0].strip() in ["WORKSPACE", "TARGET", "TOOLCHAIN"]:
188 GlobalData
.gGlobalDefines
[List
[0].strip()] = List
[1].strip()
190 GlobalData
.gCommandLineDefines
[List
[0].strip()] = List
[1].strip()
192 GlobalData
.gCommandLineDefines
[List
[0].strip()] = "TRUE"
193 os
.environ
["WORKSPACE"] = Workspace
195 """call Workspace build create database"""
196 GlobalData
.gDatabasePath
= os
.path
.normpath(os
.path
.join(ConfDirectoryPath
, GlobalData
.gDatabasePath
))
197 BuildWorkSpace
= WorkspaceDatabase(GlobalData
.gDatabasePath
)
198 BuildWorkSpace
.InitDatabase()
201 # Get files real name in workspace dir
203 GlobalData
.gAllFiles
= DirCache(Workspace
)
204 GlobalData
.gWorkspace
= Workspace
206 if (Options
.archList
) :
207 ArchList
= Options
.archList
.split(',')
209 # EdkLogger.error("GenFds", OPTION_MISSING, "Missing build ARCH")
210 ArchList
= BuildWorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, 'COMMON', Options
.BuildTarget
, Options
.ToolChain
].SupArchList
212 TargetArchList
= set(BuildWorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, 'COMMON', Options
.BuildTarget
, Options
.ToolChain
].SupArchList
) & set(ArchList
)
213 if len(TargetArchList
) == 0:
214 EdkLogger
.error("GenFds", GENFDS_ERROR
, "Target ARCH %s not in platform supported ARCH %s" % (str(ArchList
), str(BuildWorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, 'COMMON'].SupArchList
)))
216 for Arch
in ArchList
:
217 GenFdsGlobalVariable
.OutputDirFromDscDict
[Arch
] = NormPath(BuildWorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
, Options
.BuildTarget
, Options
.ToolChain
].OutputDirectory
)
218 GenFdsGlobalVariable
.PlatformName
= BuildWorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
, Options
.BuildTarget
, Options
.ToolChain
].PlatformName
220 if (Options
.outputDir
):
221 OutputDirFromCommandLine
= GenFdsGlobalVariable
.ReplaceWorkspaceMacro(Options
.outputDir
)
222 if not os
.path
.isabs (OutputDirFromCommandLine
):
223 OutputDirFromCommandLine
= os
.path
.join(GenFdsGlobalVariable
.WorkSpaceDir
, OutputDirFromCommandLine
)
224 for Arch
in ArchList
:
225 GenFdsGlobalVariable
.OutputDirDict
[Arch
] = OutputDirFromCommandLine
227 for Arch
in ArchList
:
228 GenFdsGlobalVariable
.OutputDirDict
[Arch
] = os
.path
.join(GenFdsGlobalVariable
.OutputDirFromDscDict
[Arch
], GenFdsGlobalVariable
.TargetName
+ '_' + GenFdsGlobalVariable
.ToolChainTag
)
230 for Key
in GenFdsGlobalVariable
.OutputDirDict
:
231 OutputDir
= GenFdsGlobalVariable
.OutputDirDict
[Key
]
232 if OutputDir
[0:2] == '..':
233 OutputDir
= os
.path
.realpath(OutputDir
)
235 if OutputDir
[1] != ':':
236 OutputDir
= os
.path
.join (GenFdsGlobalVariable
.WorkSpaceDir
, OutputDir
)
238 if not os
.path
.exists(OutputDir
):
239 EdkLogger
.error("GenFds", FILE_NOT_FOUND
, ExtraData
=OutputDir
)
240 GenFdsGlobalVariable
.OutputDirDict
[Key
] = OutputDir
242 """ Parse Fdf file, has to place after build Workspace as FDF may contain macros from DSC file """
243 FdfParserObj
= FdfParser
.FdfParser(FdfFilename
)
244 FdfParserObj
.ParseFile()
246 if FdfParserObj
.CycleReferenceCheck():
247 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "Cycle Reference Detected in FDF file")
249 if (Options
.uiFdName
) :
250 if Options
.uiFdName
.upper() in FdfParserObj
.Profile
.FdDict
.keys():
251 GenFds
.OnlyGenerateThisFd
= Options
.uiFdName
253 EdkLogger
.error("GenFds", OPTION_VALUE_INVALID
,
254 "No such an FD in FDF file: %s" % Options
.uiFdName
)
256 if (Options
.uiFvName
) :
257 if Options
.uiFvName
.upper() in FdfParserObj
.Profile
.FvDict
.keys():
258 GenFds
.OnlyGenerateThisFv
= Options
.uiFvName
260 EdkLogger
.error("GenFds", OPTION_VALUE_INVALID
,
261 "No such an FV in FDF file: %s" % Options
.uiFvName
)
263 if (Options
.uiCapName
) :
264 if Options
.uiCapName
.upper() in FdfParserObj
.Profile
.CapsuleDict
.keys():
265 GenFds
.OnlyGenerateThisCap
= Options
.uiCapName
267 EdkLogger
.error("GenFds", OPTION_VALUE_INVALID
,
268 "No such a Capsule in FDF file: %s" % Options
.uiCapName
)
270 GenFdsGlobalVariable
.WorkSpace
= BuildWorkSpace
272 GenFdsGlobalVariable
.ArchList
= ArchList
274 if Options
.OptionPcd
:
275 GlobalData
.BuildOptionPcd
= Options
.OptionPcd
276 CheckBuildOptionPcd()
278 """Modify images from build output if the feature of loading driver at fixed address is on."""
279 if GenFdsGlobalVariable
.FixedLoadAddress
:
280 GenFds
.PreprocessImage(BuildWorkSpace
, GenFdsGlobalVariable
.ActivePlatform
)
282 GenFds
.GenFd('', FdfParserObj
, BuildWorkSpace
, ArchList
)
284 """Generate GUID cross reference file"""
285 GenFds
.GenerateGuidXRefFile(BuildWorkSpace
, ArchList
)
287 """Display FV space info."""
288 GenFds
.DisplayFvSpaceInfo(FdfParserObj
)
290 except FdfParser
.Warning, X
:
291 EdkLogger
.error(X
.ToolName
, FORMAT_INVALID
, File
=X
.FileName
, Line
=X
.LineNumber
, ExtraData
=X
.Message
, RaiseError
=False)
292 ReturnCode
= FORMAT_INVALID
293 except FatalError
, X
:
294 if Options
.debug
!= None:
296 EdkLogger
.quiet(traceback
.format_exc())
297 ReturnCode
= X
.args
[0]
303 "Tools code failure",
304 ExtraData
="Please send email to edk2-devel@lists.01.org for help, attaching following call stack trace!\n",
307 EdkLogger
.quiet(traceback
.format_exc())
308 ReturnCode
= CODE_ERROR
314 def SingleCheckCallback(option
, opt_str
, value
, parser
):
315 if option
not in gParamCheck
:
316 setattr(parser
.values
, option
.dest
, value
)
317 gParamCheck
.append(option
)
319 parser
.error("Option %s only allows one instance in command line!" % option
)
321 def CheckBuildOptionPcd():
322 for Arch
in GenFdsGlobalVariable
.ArchList
:
323 PkgList
= GenFdsGlobalVariable
.WorkSpace
.GetPackageList(GenFdsGlobalVariable
.ActivePlatform
, Arch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
)
324 for i
, pcd
in enumerate(GlobalData
.BuildOptionPcd
):
325 if type(pcd
) is tuple:
327 (pcdname
, pcdvalue
) = pcd
.split('=')
329 EdkLogger
.error('GenFds', OPTION_MISSING
, "No Value specified for the PCD %s." % (pcdname
))
331 (TokenSpaceGuidCName
, TokenCName
) = pcdname
.split('.')
335 TokenSpaceGuidCName
= ''
336 HasTokenSpace
= False
337 TokenSpaceGuidCNameList
= []
341 for package
in PkgList
:
342 for key
in package
.Pcds
:
343 PcdItem
= package
.Pcds
[key
]
345 if (PcdItem
.TokenCName
, PcdItem
.TokenSpaceGuidCName
) == (TokenCName
, TokenSpaceGuidCName
):
346 PcdDatumType
= PcdItem
.DatumType
347 NewValue
= BuildOptionPcdValueFormat(TokenSpaceGuidCName
, TokenCName
, PcdDatumType
, pcdvalue
)
350 if PcdItem
.TokenCName
== TokenCName
:
351 if not PcdItem
.TokenSpaceGuidCName
in TokenSpaceGuidCNameList
:
352 if len (TokenSpaceGuidCNameList
) < 1:
353 TokenSpaceGuidCNameList
.append(PcdItem
.TokenSpaceGuidCName
)
354 PcdDatumType
= PcdItem
.DatumType
355 TokenSpaceGuidCName
= PcdItem
.TokenSpaceGuidCName
356 NewValue
= BuildOptionPcdValueFormat(TokenSpaceGuidCName
, TokenCName
, PcdDatumType
, pcdvalue
)
361 PCD_VALIDATION_INFO_ERROR
,
362 "The Pcd %s is found under multiple different TokenSpaceGuid: %s and %s." % (TokenCName
, PcdItem
.TokenSpaceGuidCName
, TokenSpaceGuidCNameList
[0])
365 GlobalData
.BuildOptionPcd
[i
] = (TokenSpaceGuidCName
, TokenCName
, NewValue
)
367 def BuildOptionPcdValueFormat(TokenSpaceGuidCName
, TokenCName
, PcdDatumType
, Value
):
368 if PcdDatumType
== 'VOID*':
369 if Value
.startswith('L'):
371 EdkLogger
.error('GenFds', OPTION_VALUE_INVALID
, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", B"{...}"')
372 Value
= Value
[0] + '"' + Value
[1:] + '"'
373 elif Value
.startswith('B'):
375 EdkLogger
.error('GenFds', OPTION_VALUE_INVALID
, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", B"{...}"')
379 EdkLogger
.error('GenFds', OPTION_VALUE_INVALID
, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", B"{...}"')
380 Value
= '"' + Value
+ '"'
382 IsValid
, Cause
= CheckPcdDatum(PcdDatumType
, Value
)
384 EdkLogger
.error('build', FORMAT_INVALID
, Cause
, ExtraData
="%s.%s" % (TokenSpaceGuidCName
, TokenCName
))
385 if PcdDatumType
== 'BOOLEAN':
386 Value
= Value
.upper()
387 if Value
== 'TRUE' or Value
== '1':
389 elif Value
== 'FALSE' or Value
== '0':
394 ## Parse command line options
396 # Using standard Python module optparse to parse command line option of this tool.
398 # @retval Opt A optparse.Values object containing the parsed options
399 # @retval Args Target of build command
401 def myOptionParser():
402 usage
= "%prog [options] -f input_file -a arch_list -b build_target -p active_platform -t tool_chain_tag -D \"MacroName [= MacroValue]\""
403 Parser
= OptionParser(usage
=usage
, description
=__copyright__
, version
="%prog " + str(versionNumber
))
404 Parser
.add_option("-f", "--file", dest
="filename", type="string", help="Name of FDF file to convert", action
="callback", callback
=SingleCheckCallback
)
405 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")
406 Parser
.add_option("-q", "--quiet", action
="store_true", type=None, help="Disable all messages except FATAL ERRORS.")
407 Parser
.add_option("-v", "--verbose", action
="store_true", type=None, help="Turn on verbose output with informational messages printed.")
408 Parser
.add_option("-d", "--debug", action
="store", type="int", help="Enable debug messages at specified level.")
409 Parser
.add_option("-p", "--platform", type="string", dest
="activePlatform", help="Set the ACTIVE_PLATFORM, overrides target.txt ACTIVE_PLATFORM setting.",
410 action
="callback", callback
=SingleCheckCallback
)
411 Parser
.add_option("-w", "--workspace", type="string", dest
="Workspace", default
=os
.environ
.get('WORKSPACE'), help="Set the WORKSPACE",
412 action
="callback", callback
=SingleCheckCallback
)
413 Parser
.add_option("-o", "--outputDir", type="string", dest
="outputDir", help="Name of Build Output directory",
414 action
="callback", callback
=SingleCheckCallback
)
415 Parser
.add_option("-r", "--rom_image", dest
="uiFdName", help="Build the image using the [FD] section named by FdUiName.")
416 Parser
.add_option("-i", "--FvImage", dest
="uiFvName", help="Build the FV image using the [FV] section named by UiFvName")
417 Parser
.add_option("-C", "--CapsuleImage", dest
="uiCapName", help="Build the Capsule image using the [Capsule] section named by UiCapName")
418 Parser
.add_option("-b", "--buildtarget", type="string", dest
="BuildTarget", help="Set the build TARGET, overrides target.txt TARGET setting.",
419 action
="callback", callback
=SingleCheckCallback
)
420 Parser
.add_option("-t", "--tagname", type="string", dest
="ToolChain", help="Using the tools: TOOL_CHAIN_TAG name to build the platform.",
421 action
="callback", callback
=SingleCheckCallback
)
422 Parser
.add_option("-D", "--define", action
="append", type="string", dest
="Macros", help="Macro: \"Name [= Value]\".")
423 Parser
.add_option("-s", "--specifyaddress", dest
="FixedAddress", action
="store_true", type=None, help="Specify driver load address.")
424 Parser
.add_option("--conf", action
="store", type="string", dest
="ConfDirectory", help="Specify the customized Conf directory.")
425 Parser
.add_option("--ignore-sources", action
="store_true", dest
="IgnoreSources", default
=False, help="Focus to a binary build and ignore all source files")
426 Parser
.add_option("--pcd", action
="append", dest
="OptionPcd", help="Set PCD value by command line. Format: \"PcdName=Value\" ")
428 (Options
, args
) = Parser
.parse_args()
431 ## The class implementing the EDK2 flash image generation process
433 # This process includes:
434 # 1. Collect workspace information, includes platform and module information
435 # 2. Call methods of Fd class to generate FD
436 # 3. Call methods of Fv class to generate FV that not belong to FD
440 # FvName, FdName, CapName in FDF, Image file name
442 OnlyGenerateThisFd
= None
443 OnlyGenerateThisFv
= None
444 OnlyGenerateThisCap
= None
448 # @param OutputDir Output directory
449 # @param FdfParser FDF contents parser
450 # @param Workspace The directory of workspace
451 # @param ArchList The Arch list of platform
453 def GenFd (OutputDir
, FdfParser
, WorkSpace
, ArchList
):
454 GenFdsGlobalVariable
.SetDir ('', FdfParser
, WorkSpace
, ArchList
)
456 GenFdsGlobalVariable
.VerboseLogger(" Generate all Fd images and their required FV and Capsule images!")
457 if GenFds
.OnlyGenerateThisCap
!= None and GenFds
.OnlyGenerateThisCap
.upper() in GenFdsGlobalVariable
.FdfParser
.Profile
.CapsuleDict
.keys():
458 CapsuleObj
= GenFdsGlobalVariable
.FdfParser
.Profile
.CapsuleDict
.get(GenFds
.OnlyGenerateThisCap
.upper())
459 if CapsuleObj
!= None:
460 CapsuleObj
.GenCapsule()
463 if GenFds
.OnlyGenerateThisFd
!= None and GenFds
.OnlyGenerateThisFd
.upper() in GenFdsGlobalVariable
.FdfParser
.Profile
.FdDict
.keys():
464 FdObj
= GenFdsGlobalVariable
.FdfParser
.Profile
.FdDict
.get(GenFds
.OnlyGenerateThisFd
.upper())
468 elif GenFds
.OnlyGenerateThisFd
== None and GenFds
.OnlyGenerateThisFv
== None:
469 for FdName
in GenFdsGlobalVariable
.FdfParser
.Profile
.FdDict
.keys():
470 FdObj
= GenFdsGlobalVariable
.FdfParser
.Profile
.FdDict
[FdName
]
473 GenFdsGlobalVariable
.VerboseLogger("\n Generate other FV images! ")
474 if GenFds
.OnlyGenerateThisFv
!= None and GenFds
.OnlyGenerateThisFv
.upper() in GenFdsGlobalVariable
.FdfParser
.Profile
.FvDict
.keys():
475 FvObj
= GenFdsGlobalVariable
.FdfParser
.Profile
.FvDict
.get(GenFds
.OnlyGenerateThisFv
.upper())
477 Buffer
= StringIO
.StringIO()
478 FvObj
.AddToBuffer(Buffer
)
481 elif GenFds
.OnlyGenerateThisFv
== None:
482 for FvName
in GenFdsGlobalVariable
.FdfParser
.Profile
.FvDict
.keys():
483 Buffer
= StringIO
.StringIO('')
484 FvObj
= GenFdsGlobalVariable
.FdfParser
.Profile
.FvDict
[FvName
]
485 FvObj
.AddToBuffer(Buffer
)
488 if GenFds
.OnlyGenerateThisFv
== None and GenFds
.OnlyGenerateThisFd
== None and GenFds
.OnlyGenerateThisCap
== None:
489 if GenFdsGlobalVariable
.FdfParser
.Profile
.CapsuleDict
!= {}:
490 GenFdsGlobalVariable
.VerboseLogger("\n Generate other Capsule images!")
491 for CapsuleName
in GenFdsGlobalVariable
.FdfParser
.Profile
.CapsuleDict
.keys():
492 CapsuleObj
= GenFdsGlobalVariable
.FdfParser
.Profile
.CapsuleDict
[CapsuleName
]
493 CapsuleObj
.GenCapsule()
495 if GenFdsGlobalVariable
.FdfParser
.Profile
.OptRomDict
!= {}:
496 GenFdsGlobalVariable
.VerboseLogger("\n Generate all Option ROM!")
497 for DriverName
in GenFdsGlobalVariable
.FdfParser
.Profile
.OptRomDict
.keys():
498 OptRomObj
= GenFdsGlobalVariable
.FdfParser
.Profile
.OptRomDict
[DriverName
]
499 OptRomObj
.AddToBuffer(None)
503 # @param FvObj Whose block size to get
504 # @retval int Block size value
506 def GetFvBlockSize(FvObj
):
507 DefaultBlockSize
= 0x1
509 if GenFds
.OnlyGenerateThisFd
!= None and GenFds
.OnlyGenerateThisFd
.upper() in GenFdsGlobalVariable
.FdfParser
.Profile
.FdDict
.keys():
510 FdObj
= GenFdsGlobalVariable
.FdfParser
.Profile
.FdDict
[GenFds
.OnlyGenerateThisFd
.upper()]
512 for ElementFd
in GenFdsGlobalVariable
.FdfParser
.Profile
.FdDict
.values():
513 for ElementRegion
in ElementFd
.RegionList
:
514 if ElementRegion
.RegionType
== 'FV':
515 for ElementRegionData
in ElementRegion
.RegionDataList
:
516 if ElementRegionData
!= None and ElementRegionData
.upper() == FvObj
.UiFvName
:
517 if FvObj
.BlockSizeList
!= []:
518 return FvObj
.BlockSizeList
[0][0]
520 return ElementRegion
.BlockSizeOfRegion(ElementFd
.BlockSizeList
)
521 if FvObj
.BlockSizeList
!= []:
522 return FvObj
.BlockSizeList
[0][0]
523 return DefaultBlockSize
525 for ElementRegion
in FdObj
.RegionList
:
526 if ElementRegion
.RegionType
== 'FV':
527 for ElementRegionData
in ElementRegion
.RegionDataList
:
528 if ElementRegionData
!= None and ElementRegionData
.upper() == FvObj
.UiFvName
:
529 if FvObj
.BlockSizeList
!= []:
530 return FvObj
.BlockSizeList
[0][0]
532 return ElementRegion
.BlockSizeOfRegion(ElementFd
.BlockSizeList
)
533 return DefaultBlockSize
535 ## DisplayFvSpaceInfo()
537 # @param FvObj Whose block size to get
540 def DisplayFvSpaceInfo(FdfParser
):
544 for FvName
in FdfParser
.Profile
.FvDict
:
545 if len(FvName
) > MaxFvNameLength
:
546 MaxFvNameLength
= len(FvName
)
547 FvSpaceInfoFileName
= os
.path
.join(GenFdsGlobalVariable
.FvDir
, FvName
.upper() + '.Fv.map')
548 if os
.path
.exists(FvSpaceInfoFileName
):
549 FileLinesList
= linecache
.getlines(FvSpaceInfoFileName
)
556 for Line
in FileLinesList
:
557 NameValue
= Line
.split('=')
558 if len(NameValue
) == 2:
559 if NameValue
[0].strip() == 'EFI_FV_TOTAL_SIZE':
561 Total
= NameValue
[1].strip()
562 if NameValue
[0].strip() == 'EFI_FV_TAKEN_SIZE':
564 Used
= NameValue
[1].strip()
565 if NameValue
[0].strip() == 'EFI_FV_SPACE_SIZE':
567 Free
= NameValue
[1].strip()
569 if TotalFound
and UsedFound
and FreeFound
:
570 FvSpaceInfoList
.append((FvName
, Total
, Used
, Free
))
572 GenFdsGlobalVariable
.InfLogger('\nFV Space Information')
573 for FvSpaceInfo
in FvSpaceInfoList
:
574 Name
= FvSpaceInfo
[0]
575 TotalSizeValue
= long(FvSpaceInfo
[1], 0)
576 UsedSizeValue
= long(FvSpaceInfo
[2], 0)
577 FreeSizeValue
= long(FvSpaceInfo
[3], 0)
578 if UsedSizeValue
== TotalSizeValue
:
581 Percentage
= str((UsedSizeValue
+ 0.0) / TotalSizeValue
)[0:4].lstrip('0.')
583 GenFdsGlobalVariable
.InfLogger(Name
+ ' ' + '[' + Percentage
+ '%Full] ' + str(TotalSizeValue
) + ' total, ' + str(UsedSizeValue
) + ' used, ' + str(FreeSizeValue
) + ' free')
587 # @param BuildDb Database from build meta data files
588 # @param DscFile modules from dsc file will be preprocessed
591 def PreprocessImage(BuildDb
, DscFile
):
592 PcdDict
= BuildDb
.BuildObject
[DscFile
, 'COMMON', GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
].Pcds
595 PcdObj
= PcdDict
[Key
]
596 if PcdObj
.TokenCName
== 'PcdBsBaseAddress':
597 PcdValue
= PcdObj
.DefaultValue
603 Int64PcdValue
= long(PcdValue
, 0)
604 if Int64PcdValue
== 0 or Int64PcdValue
< -1:
608 if Int64PcdValue
> 0:
609 TopAddress
= Int64PcdValue
611 ModuleDict
= BuildDb
.BuildObject
[DscFile
, 'COMMON', GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
].Modules
612 for Key
in ModuleDict
:
613 ModuleObj
= BuildDb
.BuildObject
[Key
, 'COMMON', GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
614 print ModuleObj
.BaseName
+ ' ' + ModuleObj
.ModuleType
616 def GenerateGuidXRefFile(BuildDb
, ArchList
):
617 GuidXRefFileName
= os
.path
.join(GenFdsGlobalVariable
.FvDir
, "Guid.xref")
618 GuidXRefFile
= StringIO
.StringIO('')
620 for Arch
in ArchList
:
621 PlatformDataBase
= BuildDb
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
622 for ModuleFile
in PlatformDataBase
.Modules
:
623 Module
= BuildDb
.BuildObject
[ModuleFile
, Arch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
624 GuidXRefFile
.write("%s %s\n" % (Module
.Guid
, Module
.BaseName
))
625 for key
, item
in Module
.Protocols
.items():
627 for key
, item
in Module
.Guids
.items():
629 for key
, item
in Module
.Ppis
.items():
631 # Append GUIDs, Protocols, and PPIs to the Xref file
632 GuidXRefFile
.write("\n")
633 for key
, item
in GuidDict
.items():
634 GuidXRefFile
.write("%s %s\n" % (GuidStructureStringToGuidString(item
).upper(), key
))
636 if GuidXRefFile
.getvalue():
637 SaveFileOnChange(GuidXRefFileName
, GuidXRefFile
.getvalue(), False)
638 GenFdsGlobalVariable
.InfLogger("\nGUID cross reference file can be found at %s" % GuidXRefFileName
)
639 elif os
.path
.exists(GuidXRefFileName
):
640 os
.remove(GuidXRefFileName
)
643 ##Define GenFd as static function
644 GenFd
= staticmethod(GenFd
)
645 GetFvBlockSize
= staticmethod(GetFvBlockSize
)
646 DisplayFvSpaceInfo
= staticmethod(DisplayFvSpaceInfo
)
647 PreprocessImage
= staticmethod(PreprocessImage
)
648 GenerateGuidXRefFile
= staticmethod(GenerateGuidXRefFile
)
650 if __name__
== '__main__':
652 ## 0-127 is a safe return range, and 1 is a standard default error
653 if r
< 0 or r
> 127: r
= 1