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# 18from optparse import OptionParser 19import sys 20import Common.LongFilePathOs as os 21import linecache 22import FdfParser 23import Common.BuildToolError as BuildToolError 24from GenFdsGlobalVariable import GenFdsGlobalVariable 25from Workspace.WorkspaceDatabase import WorkspaceDatabase 26from Workspace.BuildClassObject import PcdClassObject 27from Workspace.BuildClassObject import ModuleBuildClassObject 28import RuleComplexFile 29from EfiSection import EfiSection 30import StringIO 31import Common.TargetTxtClassObject as TargetTxtClassObject 32import Common.ToolDefClassObject as ToolDefClassObject 33import Common.DataType 34import Common.GlobalData as GlobalData 35from Common import EdkLogger 36from Common.String import * 37from Common.Misc import DirCache,PathClass 38from Common.Misc import SaveFileOnChange 39from Common.Misc import ClearDuplicatedInf 40from Common.Misc import GuidStructureStringToGuidString 41from Common.BuildVersion import gBUILD_VERSION 42 43## Version and Copyright 44versionNumber = "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# 57def 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 307gParamCheck = [] 308def 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# 322def 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# 358class 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 570if __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 576