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 42from Common.MultipleWorkspace import MultipleWorkspace as mws 43 44## Version and Copyright 45versionNumber = "1.0" + ' ' + gBUILD_VERSION 46__version__ = "%prog Version " + versionNumber 47__copyright__ = "Copyright (c) 2007 - 2014, Intel Corporation All rights reserved." 48 49## Tool entrance method 50# 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. 54# 55# @retval 0 Tool was successful 56# @retval 1 Tool failed 57# 58def main(): 59 global Options 60 Options = myOptionParser() 61 62 global Workspace 63 Workspace = "" 64 ArchList = None 65 ReturnCode = 0 66 67 EdkLogger.Initialize() 68 try: 69 if Options.verbose != None: 70 EdkLogger.SetLevel(EdkLogger.VERBOSE) 71 GenFdsGlobalVariable.VerboseMode = True 72 73 if Options.FixedAddress != None: 74 GenFdsGlobalVariable.FixedLoadAddress = True 75 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 81 else: 82 EdkLogger.SetLevel(EdkLogger.INFO) 83 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.") 90 else: 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']) 95 if (Options.debug): 96 GenFdsGlobalVariable.VerboseLogger("Using Workspace:" + Workspace) 97 os.chdir(GenFdsGlobalVariable.WorkSpaceDir) 98 99 # set multiple workspace 100 PackagesPath = os.getenv("PACKAGES_PATH") 101 mws.setWs(GenFdsGlobalVariable.WorkSpaceDir, PackagesPath) 102 103 if (Options.filename): 104 FdfFilename = Options.filename 105 FdfFilename = GenFdsGlobalVariable.ReplaceWorkspaceMacro(FdfFilename) 106 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) 113 114 GenFdsGlobalVariable.FdfFile = FdfFilename 115 GenFdsGlobalVariable.FdfFileTimeStamp = os.path.getmtime(FdfFilename) 116 else: 117 EdkLogger.error("GenFds", OPTION_MISSING, "Missing FDF filename") 118 119 if (Options.BuildTarget): 120 GenFdsGlobalVariable.TargetName = Options.BuildTarget 121 else: 122 EdkLogger.error("GenFds", OPTION_MISSING, "Missing build target") 123 124 if (Options.ToolChain): 125 GenFdsGlobalVariable.ToolChainTag = Options.ToolChain 126 else: 127 EdkLogger.error("GenFds", OPTION_MISSING, "Missing tool chain tag") 128 129 if (Options.activePlatform): 130 ActivePlatform = Options.activePlatform 131 ActivePlatform = GenFdsGlobalVariable.ReplaceWorkspaceMacro(ActivePlatform) 132 133 if ActivePlatform[0:2] == '..': 134 ActivePlatform = os.path.realpath(ActivePlatform) 135 136 if not os.path.isabs (ActivePlatform): 137 ActivePlatform = mws.join(GenFdsGlobalVariable.WorkSpaceDir, ActivePlatform) 138 139 if not os.path.exists(ActivePlatform) : 140 EdkLogger.error("GenFds", FILE_NOT_FOUND, "ActivePlatform doesn't exist!") 141 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:] 147 else: 148 EdkLogger.error("GenFds", FILE_NOT_FOUND, "ActivePlatform doesn't exist!") 149 else: 150 EdkLogger.error("GenFds", OPTION_MISSING, "Missing active platform") 151 152 GenFdsGlobalVariable.ActivePlatform = PathClass(NormPath(ActivePlatform), Workspace) 153 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) 165 else: 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) 172 else: 173 EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=BuildConfigurationFile) 174 175 #Set global flag for build mode 176 GlobalData.gIgnoreSource = Options.IgnoreSources 177 178 if Options.Macros: 179 for Pair in Options.Macros: 180 if Pair.startswith('"'): 181 Pair = Pair[1:] 182 if Pair.endswith('"'): 183 Pair = Pair[:-1] 184 List = Pair.split('=') 185 if len(List) == 2: 186 if List[0].strip() == "EFI_SOURCE": 187 GlobalData.gEfiSource = List[1].strip() 188 GlobalData.gGlobalDefines["EFI_SOURCE"] = GlobalData.gEfiSource 189 continue 190 elif List[0].strip() == "EDK_SOURCE": 191 GlobalData.gEdkSource = List[1].strip() 192 GlobalData.gGlobalDefines["EDK_SOURCE"] = GlobalData.gEdkSource 193 continue 194 elif List[0].strip() in ["WORKSPACE", "TARGET", "TOOLCHAIN"]: 195 GlobalData.gGlobalDefines[List[0].strip()] = List[1].strip() 196 else: 197 GlobalData.gCommandLineDefines[List[0].strip()] = List[1].strip() 198 else: 199 GlobalData.gCommandLineDefines[List[0].strip()] = "TRUE" 200 os.environ["WORKSPACE"] = Workspace 201 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() 206 207 # 208 # Get files real name in workspace dir 209 # 210 GlobalData.gAllFiles = DirCache(Workspace) 211 GlobalData.gWorkspace = Workspace 212 213 if (Options.archList) : 214 ArchList = Options.archList.split(',') 215 else: 216# EdkLogger.error("GenFds", OPTION_MISSING, "Missing build ARCH") 217 ArchList = BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'COMMON', Options.BuildTarget, Options.ToolChain].SupArchList 218 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))) 222 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 226 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 233 else: 234 for Arch in ArchList: 235 GenFdsGlobalVariable.OutputDirDict[Arch] = os.path.join(GenFdsGlobalVariable.OutputDirFromDscDict[Arch], GenFdsGlobalVariable.TargetName + '_' + GenFdsGlobalVariable.ToolChainTag) 236 237 for Key in GenFdsGlobalVariable.OutputDirDict: 238 OutputDir = GenFdsGlobalVariable.OutputDirDict[Key] 239 if OutputDir[0:2] == '..': 240 OutputDir = os.path.realpath(OutputDir) 241 242 if OutputDir[1] != ':': 243 OutputDir = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, OutputDir) 244 245 if not os.path.exists(OutputDir): 246 EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=OutputDir) 247 GenFdsGlobalVariable.OutputDirDict[Key] = OutputDir 248 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() 252 253 if FdfParserObj.CycleReferenceCheck(): 254 EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Cycle Reference Detected in FDF file") 255 256 if (Options.uiFdName) : 257 if Options.uiFdName.upper() in FdfParserObj.Profile.FdDict.keys(): 258 GenFds.OnlyGenerateThisFd = Options.uiFdName 259 else: 260 EdkLogger.error("GenFds", OPTION_VALUE_INVALID, 261 "No such an FD in FDF file: %s" % Options.uiFdName) 262 263 if (Options.uiFvName) : 264 if Options.uiFvName.upper() in FdfParserObj.Profile.FvDict.keys(): 265 GenFds.OnlyGenerateThisFv = Options.uiFvName 266 else: 267 EdkLogger.error("GenFds", OPTION_VALUE_INVALID, 268 "No such an FV in FDF file: %s" % Options.uiFvName) 269 270 if (Options.uiCapName) : 271 if Options.uiCapName.upper() in FdfParserObj.Profile.CapsuleDict.keys(): 272 GenFds.OnlyGenerateThisCap = Options.uiCapName 273 else: 274 EdkLogger.error("GenFds", OPTION_VALUE_INVALID, 275 "No such a Capsule in FDF file: %s" % Options.uiCapName) 276 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) 280 """Call GenFds""" 281 GenFds.GenFd('', FdfParserObj, BuildWorkSpace, ArchList) 282 283 """Generate GUID cross reference file""" 284 GenFds.GenerateGuidXRefFile(BuildWorkSpace, ArchList) 285 286 """Display FV space info.""" 287 GenFds.DisplayFvSpaceInfo(FdfParserObj) 288 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: 294 import traceback 295 EdkLogger.quiet(traceback.format_exc()) 296 ReturnCode = X.args[0] 297 except: 298 import traceback 299 EdkLogger.error( 300 "\nPython", 301 CODE_ERROR, 302 "Tools code failure", 303 ExtraData="Please send email to edk2-devel@lists.sourceforge.net for help, attaching following call stack trace!\n", 304 RaiseError=False 305 ) 306 EdkLogger.quiet(traceback.format_exc()) 307 ReturnCode = CODE_ERROR 308 finally: 309 ClearDuplicatedInf() 310 return ReturnCode 311 312gParamCheck = [] 313def SingleCheckCallback(option, opt_str, value, parser): 314 if option not in gParamCheck: 315 setattr(parser.values, option.dest, value) 316 gParamCheck.append(option) 317 else: 318 parser.error("Option %s only allows one instance in command line!" % option) 319 320## Parse command line options 321# 322# Using standard Python module optparse to parse command line option of this tool. 323# 324# @retval Opt A optparse.Values object containing the parsed options 325# @retval Args Target of build command 326# 327def 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") 352 353 (Options, args) = Parser.parse_args() 354 return Options 355 356## The class implementing the EDK2 flash image generation process 357# 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 362# 363class GenFds : 364 FdfParsef = None 365 # FvName, FdName, CapName in FDF, Image file name 366 ImageBinDict = {} 367 OnlyGenerateThisFd = None 368 OnlyGenerateThisFv = None 369 OnlyGenerateThisCap = None 370 371 ## GenFd() 372 # 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 377 # 378 def GenFd (OutputDir, FdfParser, WorkSpace, ArchList): 379 GenFdsGlobalVariable.SetDir ('', FdfParser, WorkSpace, ArchList) 380 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() 386 return 387 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()) 390 if FdObj != None: 391 FdObj.GenFd() 392 return 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] 396 FdObj.GenFd() 397 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()) 401 if FvObj != None: 402 Buffer = StringIO.StringIO() 403 FvObj.AddToBuffer(Buffer) 404 Buffer.close() 405 return 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) 411 Buffer.close() 412 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() 419 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) 425 426 ## GetFvBlockSize() 427 # 428 # @param FvObj Whose block size to get 429 # @retval int Block size value 430 # 431 def GetFvBlockSize(FvObj): 432 DefaultBlockSize = 0x1 433 FdObj = None 434 if GenFds.OnlyGenerateThisFd != None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys(): 435 FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[GenFds.OnlyGenerateThisFd.upper()] 436 if FdObj == None: 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] 444 else: 445 return ElementRegion.BlockSizeOfRegion(ElementFd.BlockSizeList) 446 if FvObj.BlockSizeList != []: 447 return FvObj.BlockSizeList[0][0] 448 return DefaultBlockSize 449 else: 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] 456 else: 457 return ElementRegion.BlockSizeOfRegion(ElementFd.BlockSizeList) 458 return DefaultBlockSize 459 460 ## DisplayFvSpaceInfo() 461 # 462 # @param FvObj Whose block size to get 463 # @retval None 464 # 465 def DisplayFvSpaceInfo(FdfParser): 466 467 FvSpaceInfoList = [] 468 MaxFvNameLength = 0 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) 475 TotalFound = False 476 Total = '' 477 UsedFound = False 478 Used = '' 479 FreeFound = False 480 Free = '' 481 for Line in FileLinesList: 482 NameValue = Line.split('=') 483 if len(NameValue) == 2: 484 if NameValue[0].strip() == 'EFI_FV_TOTAL_SIZE': 485 TotalFound = True 486 Total = NameValue[1].strip() 487 if NameValue[0].strip() == 'EFI_FV_TAKEN_SIZE': 488 UsedFound = True 489 Used = NameValue[1].strip() 490 if NameValue[0].strip() == 'EFI_FV_SPACE_SIZE': 491 FreeFound = True 492 Free = NameValue[1].strip() 493 494 if TotalFound and UsedFound and FreeFound: 495 FvSpaceInfoList.append((FvName, Total, Used, Free)) 496 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: 504 Percentage = '100' 505 else: 506 Percentage = str((UsedSizeValue + 0.0) / TotalSizeValue)[0:4].lstrip('0.') 507 508 GenFdsGlobalVariable.InfLogger(Name + ' ' + '[' + Percentage + '%Full] ' + str(TotalSizeValue) + ' total, ' + str(UsedSizeValue) + ' used, ' + str(FreeSizeValue) + ' free') 509 510 ## PreprocessImage() 511 # 512 # @param BuildDb Database from build meta data files 513 # @param DscFile modules from dsc file will be preprocessed 514 # @retval None 515 # 516 def PreprocessImage(BuildDb, DscFile): 517 PcdDict = BuildDb.BuildObject[DscFile, 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].Pcds 518 PcdValue = '' 519 for Key in PcdDict: 520 PcdObj = PcdDict[Key] 521 if PcdObj.TokenCName == 'PcdBsBaseAddress': 522 PcdValue = PcdObj.DefaultValue 523 break 524 525 if PcdValue == '': 526 return 527 528 Int64PcdValue = long(PcdValue, 0) 529 if Int64PcdValue == 0 or Int64PcdValue < -1: 530 return 531 532 TopAddress = 0 533 if Int64PcdValue > 0: 534 TopAddress = Int64PcdValue 535 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 540 541 def GenerateGuidXRefFile(BuildDb, ArchList): 542 GuidXRefFileName = os.path.join(GenFdsGlobalVariable.FvDir, "Guid.xref") 543 GuidXRefFile = StringIO.StringIO('') 544 GuidDict = {} 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(): 551 GuidDict[key] = item 552 for key, item in Module.Guids.items(): 553 GuidDict[key] = item 554 for key, item in Module.Ppis.items(): 555 GuidDict[key] = item 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)) 560 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) 566 GuidXRefFile.close() 567 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) 574 575if __name__ == '__main__': 576 r = 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 579 sys.exit(r) 580 581