1## @file 2# Global variables for GenFds 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# 18import Common.LongFilePathOs as os 19import sys 20import subprocess 21import struct 22import array 23 24from Common.BuildToolError import * 25from Common import EdkLogger 26from Common.Misc import SaveFileOnChange 27 28from Common.TargetTxtClassObject import TargetTxtClassObject 29from Common.ToolDefClassObject import ToolDefClassObject 30from AutoGen.BuildEngine import BuildRule 31import Common.DataType as DataType 32from Common.Misc import PathClass 33from Common.LongFilePathSupport import OpenLongFilePath as open 34from Common.MultipleWorkspace import MultipleWorkspace as mws 35 36## Global variables 37# 38# 39class GenFdsGlobalVariable: 40 FvDir = '' 41 OutputDirDict = {} 42 BinDir = '' 43 # will be FvDir + os.sep + 'Ffs' 44 FfsDir = '' 45 FdfParser = None 46 LibDir = '' 47 WorkSpace = None 48 WorkSpaceDir = '' 49 ConfDir = '' 50 EdkSourceDir = '' 51 OutputDirFromDscDict = {} 52 TargetName = '' 53 ToolChainTag = '' 54 RuleDict = {} 55 ArchList = None 56 VtfDict = {} 57 ActivePlatform = None 58 FvAddressFileName = '' 59 VerboseMode = False 60 DebugLevel = -1 61 SharpCounter = 0 62 SharpNumberPerLine = 40 63 FdfFile = '' 64 FdfFileTimeStamp = 0 65 FixedLoadAddress = False 66 PlatformName = '' 67 68 BuildRuleFamily = "MSFT" 69 ToolChainFamily = "MSFT" 70 __BuildRuleDatabase = None 71 72 # 73 # The list whose element are flags to indicate if large FFS or SECTION files exist in FV. 74 # At the beginning of each generation of FV, false flag is appended to the list, 75 # after the call to GenerateSection returns, check the size of the output file, 76 # if it is greater than 0xFFFFFF, the tail flag in list is set to true, 77 # and EFI_FIRMWARE_FILE_SYSTEM3_GUID is passed to C GenFv. 78 # At the end of generation of FV, pop the flag. 79 # List is used as a stack to handle nested FV generation. 80 # 81 LargeFileInFvFlags = [] 82 EFI_FIRMWARE_FILE_SYSTEM3_GUID = '5473C07A-3DCB-4dca-BD6F-1E9689E7349A' 83 LARGE_FILE_SIZE = 0x1000000 84 85 SectionHeader = struct.Struct("3B 1B") 86 87 ## LoadBuildRule 88 # 89 @staticmethod 90 def __LoadBuildRule(): 91 if GenFdsGlobalVariable.__BuildRuleDatabase: 92 return GenFdsGlobalVariable.__BuildRuleDatabase 93 BuildConfigurationFile = os.path.normpath(os.path.join(GenFdsGlobalVariable.ConfDir, "target.txt")) 94 TargetTxt = TargetTxtClassObject() 95 if os.path.isfile(BuildConfigurationFile) == True: 96 TargetTxt.LoadTargetTxtFile(BuildConfigurationFile) 97 if DataType.TAB_TAT_DEFINES_BUILD_RULE_CONF in TargetTxt.TargetTxtDictionary: 98 BuildRuleFile = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_BUILD_RULE_CONF] 99 if BuildRuleFile in [None, '']: 100 BuildRuleFile = 'Conf/build_rule.txt' 101 GenFdsGlobalVariable.__BuildRuleDatabase = BuildRule(BuildRuleFile) 102 ToolDefinitionFile = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF] 103 if ToolDefinitionFile == '': 104 ToolDefinitionFile = "Conf/tools_def.txt" 105 if os.path.isfile(ToolDefinitionFile): 106 ToolDef = ToolDefClassObject() 107 ToolDef.LoadToolDefFile(ToolDefinitionFile) 108 ToolDefinition = ToolDef.ToolsDefTxtDatabase 109 if DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY in ToolDefinition \ 110 and GenFdsGlobalVariable.ToolChainTag in ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY] \ 111 and ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY][GenFdsGlobalVariable.ToolChainTag]: 112 GenFdsGlobalVariable.BuildRuleFamily = ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY][GenFdsGlobalVariable.ToolChainTag] 113 114 if DataType.TAB_TOD_DEFINES_FAMILY in ToolDefinition \ 115 and GenFdsGlobalVariable.ToolChainTag in ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY] \ 116 and ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY][GenFdsGlobalVariable.ToolChainTag]: 117 GenFdsGlobalVariable.ToolChainFamily = ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY][GenFdsGlobalVariable.ToolChainTag] 118 return GenFdsGlobalVariable.__BuildRuleDatabase 119 120 ## GetBuildRules 121 # @param Inf: object of InfBuildData 122 # @param Arch: current arch 123 # 124 @staticmethod 125 def GetBuildRules(Inf, Arch): 126 if not Arch: 127 Arch = 'COMMON' 128 129 if not Arch in GenFdsGlobalVariable.OutputDirDict: 130 return {} 131 132 BuildRuleDatabase = GenFdsGlobalVariable.__LoadBuildRule() 133 if not BuildRuleDatabase: 134 return {} 135 136 PathClassObj = PathClass(Inf.MetaFile.File, 137 GenFdsGlobalVariable.WorkSpaceDir) 138 Macro = {} 139 Macro["WORKSPACE" ] = GenFdsGlobalVariable.WorkSpaceDir 140 Macro["MODULE_NAME" ] = Inf.BaseName 141 Macro["MODULE_GUID" ] = Inf.Guid 142 Macro["MODULE_VERSION" ] = Inf.Version 143 Macro["MODULE_TYPE" ] = Inf.ModuleType 144 Macro["MODULE_FILE" ] = str(PathClassObj) 145 Macro["MODULE_FILE_BASE_NAME" ] = PathClassObj.BaseName 146 Macro["MODULE_RELATIVE_DIR" ] = PathClassObj.SubDir 147 Macro["MODULE_DIR" ] = PathClassObj.SubDir 148 149 Macro["BASE_NAME" ] = Inf.BaseName 150 151 Macro["ARCH" ] = Arch 152 Macro["TOOLCHAIN" ] = GenFdsGlobalVariable.ToolChainTag 153 Macro["TOOLCHAIN_TAG" ] = GenFdsGlobalVariable.ToolChainTag 154 Macro["TOOL_CHAIN_TAG" ] = GenFdsGlobalVariable.ToolChainTag 155 Macro["TARGET" ] = GenFdsGlobalVariable.TargetName 156 157 Macro["BUILD_DIR" ] = GenFdsGlobalVariable.OutputDirDict[Arch] 158 Macro["BIN_DIR" ] = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch], Arch) 159 Macro["LIB_DIR" ] = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch], Arch) 160 BuildDir = os.path.join( 161 GenFdsGlobalVariable.OutputDirDict[Arch], 162 Arch, 163 PathClassObj.SubDir, 164 PathClassObj.BaseName 165 ) 166 Macro["MODULE_BUILD_DIR" ] = BuildDir 167 Macro["OUTPUT_DIR" ] = os.path.join(BuildDir, "OUTPUT") 168 Macro["DEBUG_DIR" ] = os.path.join(BuildDir, "DEBUG") 169 170 BuildRules = {} 171 for Type in BuildRuleDatabase.FileTypeList: 172 #first try getting build rule by BuildRuleFamily 173 RuleObject = BuildRuleDatabase[Type, Inf.BuildType, Arch, GenFdsGlobalVariable.BuildRuleFamily] 174 if not RuleObject: 175 # build type is always module type, but ... 176 if Inf.ModuleType != Inf.BuildType: 177 RuleObject = BuildRuleDatabase[Type, Inf.ModuleType, Arch, GenFdsGlobalVariable.BuildRuleFamily] 178 #second try getting build rule by ToolChainFamily 179 if not RuleObject: 180 RuleObject = BuildRuleDatabase[Type, Inf.BuildType, Arch, GenFdsGlobalVariable.ToolChainFamily] 181 if not RuleObject: 182 # build type is always module type, but ... 183 if Inf.ModuleType != Inf.BuildType: 184 RuleObject = BuildRuleDatabase[Type, Inf.ModuleType, Arch, GenFdsGlobalVariable.ToolChainFamily] 185 if not RuleObject: 186 continue 187 RuleObject = RuleObject.Instantiate(Macro) 188 BuildRules[Type] = RuleObject 189 for Ext in RuleObject.SourceFileExtList: 190 BuildRules[Ext] = RuleObject 191 return BuildRules 192 193 ## GetModuleCodaTargetList 194 # 195 # @param Inf: object of InfBuildData 196 # @param Arch: current arch 197 # 198 @staticmethod 199 def GetModuleCodaTargetList(Inf, Arch): 200 BuildRules = GenFdsGlobalVariable.GetBuildRules(Inf, Arch) 201 if not BuildRules: 202 return [] 203 204 TargetList = set() 205 FileList = [] 206 207 if not Inf.IsBinaryModule: 208 for File in Inf.Sources: 209 if File.TagName in ("", "*", GenFdsGlobalVariable.ToolChainTag) and \ 210 File.ToolChainFamily in ("", "*", GenFdsGlobalVariable.ToolChainFamily): 211 FileList.append((File, DataType.TAB_UNKNOWN_FILE)) 212 213 for File in Inf.Binaries: 214 if File.Target in ['COMMON', '*', GenFdsGlobalVariable.TargetName]: 215 FileList.append((File, File.Type)) 216 217 for File, FileType in FileList: 218 LastTarget = None 219 RuleChain = [] 220 SourceList = [File] 221 Index = 0 222 while Index < len(SourceList): 223 Source = SourceList[Index] 224 Index = Index + 1 225 226 if File.IsBinary and File == Source and Inf.Binaries != None and File in Inf.Binaries: 227 # Skip all files that are not binary libraries 228 if not Inf.LibraryClass: 229 continue 230 RuleObject = BuildRules[DataType.TAB_DEFAULT_BINARY_FILE] 231 elif FileType in BuildRules: 232 RuleObject = BuildRules[FileType] 233 elif Source.Ext in BuildRules: 234 RuleObject = BuildRules[Source.Ext] 235 else: 236 # stop at no more rules 237 if LastTarget: 238 TargetList.add(str(LastTarget)) 239 break 240 241 FileType = RuleObject.SourceFileType 242 243 # stop at STATIC_LIBRARY for library 244 if Inf.LibraryClass and FileType == DataType.TAB_STATIC_LIBRARY: 245 if LastTarget: 246 TargetList.add(str(LastTarget)) 247 break 248 249 Target = RuleObject.Apply(Source) 250 if not Target: 251 if LastTarget: 252 TargetList.add(str(LastTarget)) 253 break 254 elif not Target.Outputs: 255 # Only do build for target with outputs 256 TargetList.add(str(Target)) 257 258 # to avoid cyclic rule 259 if FileType in RuleChain: 260 break 261 262 RuleChain.append(FileType) 263 SourceList.extend(Target.Outputs) 264 LastTarget = Target 265 FileType = DataType.TAB_UNKNOWN_FILE 266 267 return list(TargetList) 268 269 ## SetDir() 270 # 271 # @param OutputDir Output directory 272 # @param FdfParser FDF contents parser 273 # @param Workspace The directory of workspace 274 # @param ArchList The Arch list of platform 275 # 276 def SetDir (OutputDir, FdfParser, WorkSpace, ArchList): 277 GenFdsGlobalVariable.VerboseLogger("GenFdsGlobalVariable.OutputDir :%s" % OutputDir) 278# GenFdsGlobalVariable.OutputDirDict = OutputDir 279 GenFdsGlobalVariable.FdfParser = FdfParser 280 GenFdsGlobalVariable.WorkSpace = WorkSpace 281 GenFdsGlobalVariable.FvDir = os.path.join(GenFdsGlobalVariable.OutputDirDict[ArchList[0]], 'FV') 282 if not os.path.exists(GenFdsGlobalVariable.FvDir) : 283 os.makedirs(GenFdsGlobalVariable.FvDir) 284 GenFdsGlobalVariable.FfsDir = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs') 285 if not os.path.exists(GenFdsGlobalVariable.FfsDir) : 286 os.makedirs(GenFdsGlobalVariable.FfsDir) 287 if ArchList != None: 288 GenFdsGlobalVariable.ArchList = ArchList 289 290 T_CHAR_LF = '\n' 291 # 292 # Create FV Address inf file 293 # 294 GenFdsGlobalVariable.FvAddressFileName = os.path.join(GenFdsGlobalVariable.FfsDir, 'FvAddress.inf') 295 FvAddressFile = open(GenFdsGlobalVariable.FvAddressFileName, 'w') 296 # 297 # Add [Options] 298 # 299 FvAddressFile.writelines("[options]" + T_CHAR_LF) 300 BsAddress = '0' 301 for Arch in ArchList: 302 if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].BsBaseAddress: 303 BsAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].BsBaseAddress 304 break 305 306 FvAddressFile.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \ 307 BsAddress + \ 308 T_CHAR_LF) 309 310 RtAddress = '0' 311 for Arch in ArchList: 312 if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].RtBaseAddress: 313 RtAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].RtBaseAddress 314 315 FvAddressFile.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \ 316 RtAddress + \ 317 T_CHAR_LF) 318 319 FvAddressFile.close() 320 321 ## ReplaceWorkspaceMacro() 322 # 323 # @param String String that may contain macro 324 # 325 def ReplaceWorkspaceMacro(String): 326 String = mws.handleWsMacro(String) 327 Str = String.replace('$(WORKSPACE)', GenFdsGlobalVariable.WorkSpaceDir) 328 if os.path.exists(Str): 329 if not os.path.isabs(Str): 330 Str = os.path.abspath(Str) 331 else: 332 Str = mws.join(GenFdsGlobalVariable.WorkSpaceDir, String) 333 return os.path.normpath(Str) 334 335 ## Check if the input files are newer than output files 336 # 337 # @param Output Path of output file 338 # @param Input Path list of input files 339 # 340 # @retval True if Output doesn't exist, or any Input is newer 341 # @retval False if all Input is older than Output 342 # 343 @staticmethod 344 def NeedsUpdate(Output, Input): 345 if not os.path.exists(Output): 346 return True 347 # always update "Output" if no "Input" given 348 if Input == None or len(Input) == 0: 349 return True 350 351 # if fdf file is changed after the 'Output" is generated, update the 'Output' 352 OutputTime = os.path.getmtime(Output) 353 if GenFdsGlobalVariable.FdfFileTimeStamp > OutputTime: 354 return True 355 356 for F in Input: 357 # always update "Output" if any "Input" doesn't exist 358 if not os.path.exists(F): 359 return True 360 # always update "Output" if any "Input" is newer than "Output" 361 if os.path.getmtime(F) > OutputTime: 362 return True 363 return False 364 365 @staticmethod 366 def GenerateSection(Output, Input, Type=None, CompressionType=None, Guid=None, 367 GuidHdrLen=None, GuidAttr=[], Ui=None, Ver=None, InputAlign=None, BuildNumber=None): 368 Cmd = ["GenSec"] 369 if Type not in [None, '']: 370 Cmd += ["-s", Type] 371 if CompressionType not in [None, '']: 372 Cmd += ["-c", CompressionType] 373 if Guid != None: 374 Cmd += ["-g", Guid] 375 if GuidHdrLen not in [None, '']: 376 Cmd += ["-l", GuidHdrLen] 377 if len(GuidAttr) != 0: 378 #Add each guided attribute 379 for Attr in GuidAttr: 380 Cmd += ["-r", Attr] 381 if InputAlign != None: 382 #Section Align is only for dummy section without section type 383 for SecAlign in InputAlign: 384 Cmd += ["--sectionalign", SecAlign] 385 386 CommandFile = Output + '.txt' 387 if Ui not in [None, '']: 388 #Cmd += ["-n", '"' + Ui + '"'] 389 SectionData = array.array('B', [0, 0, 0, 0]) 390 SectionData.fromstring(Ui.encode("utf_16_le")) 391 SectionData.append(0) 392 SectionData.append(0) 393 Len = len(SectionData) 394 GenFdsGlobalVariable.SectionHeader.pack_into(SectionData, 0, Len & 0xff, (Len >> 8) & 0xff, (Len >> 16) & 0xff, 0x15) 395 SaveFileOnChange(Output, SectionData.tostring()) 396 elif Ver not in [None, '']: 397 Cmd += ["-n", Ver] 398 if BuildNumber: 399 Cmd += ["-j", BuildNumber] 400 Cmd += ["-o", Output] 401 402 SaveFileOnChange(CommandFile, ' '.join(Cmd), False) 403 if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]): 404 return 405 406 GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section") 407 else: 408 Cmd += ["-o", Output] 409 Cmd += Input 410 411 SaveFileOnChange(CommandFile, ' '.join(Cmd), False) 412 if GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]): 413 GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) 414 GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section") 415 416 if (os.path.getsize(Output) >= GenFdsGlobalVariable.LARGE_FILE_SIZE and 417 GenFdsGlobalVariable.LargeFileInFvFlags): 418 GenFdsGlobalVariable.LargeFileInFvFlags[-1] = True 419 420 @staticmethod 421 def GetAlignment (AlignString): 422 if AlignString == None: 423 return 0 424 if AlignString in ("1K", "2K", "4K", "8K", "16K", "32K", "64K"): 425 return int (AlignString.rstrip('K')) * 1024 426 else: 427 return int (AlignString) 428 429 @staticmethod 430 def GenerateFfs(Output, Input, Type, Guid, Fixed=False, CheckSum=False, Align=None, 431 SectionAlign=None): 432 Cmd = ["GenFfs", "-t", Type, "-g", Guid] 433 if Fixed == True: 434 Cmd += ["-x"] 435 if CheckSum: 436 Cmd += ["-s"] 437 if Align not in [None, '']: 438 Cmd += ["-a", Align] 439 440 Cmd += ["-o", Output] 441 for I in range(0, len(Input)): 442 Cmd += ("-i", Input[I]) 443 if SectionAlign not in [None, '', []] and SectionAlign[I] not in [None, '']: 444 Cmd += ("-n", SectionAlign[I]) 445 446 CommandFile = Output + '.txt' 447 SaveFileOnChange(CommandFile, ' '.join(Cmd), False) 448 if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]): 449 return 450 GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) 451 452 GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FFS") 453 454 @staticmethod 455 def GenerateFirmwareVolume(Output, Input, BaseAddress=None, ForceRebase=None, Capsule=False, Dump=False, 456 AddressFile=None, MapFile=None, FfsList=[], FileSystemGuid=None): 457 if not GenFdsGlobalVariable.NeedsUpdate(Output, Input+FfsList): 458 return 459 GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) 460 461 Cmd = ["GenFv"] 462 if BaseAddress not in [None, '']: 463 Cmd += ["-r", BaseAddress] 464 465 if ForceRebase == False: 466 Cmd += ["-F", "FALSE"] 467 elif ForceRebase == True: 468 Cmd += ["-F", "TRUE"] 469 470 if Capsule: 471 Cmd += ["-c"] 472 if Dump: 473 Cmd += ["-p"] 474 if AddressFile not in [None, '']: 475 Cmd += ["-a", AddressFile] 476 if MapFile not in [None, '']: 477 Cmd += ["-m", MapFile] 478 if FileSystemGuid: 479 Cmd += ["-g", FileSystemGuid] 480 Cmd += ["-o", Output] 481 for I in Input: 482 Cmd += ["-i", I] 483 484 GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FV") 485 486 @staticmethod 487 def GenerateVtf(Output, Input, BaseAddress=None, FvSize=None): 488 if not GenFdsGlobalVariable.NeedsUpdate(Output, Input): 489 return 490 GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) 491 492 Cmd = ["GenVtf"] 493 if BaseAddress not in [None, ''] and FvSize not in [None, ''] \ 494 and len(BaseAddress) == len(FvSize): 495 for I in range(0, len(BaseAddress)): 496 Cmd += ["-r", BaseAddress[I], "-s", FvSize[I]] 497 Cmd += ["-o", Output] 498 for F in Input: 499 Cmd += ["-f", F] 500 501 GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate VTF") 502 503 @staticmethod 504 def GenerateFirmwareImage(Output, Input, Type="efi", SubType=None, Zero=False, 505 Strip=False, Replace=False, TimeStamp=None, Join=False, 506 Align=None, Padding=None, Convert=False): 507 if not GenFdsGlobalVariable.NeedsUpdate(Output, Input): 508 return 509 GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) 510 511 Cmd = ["GenFw"] 512 if Type.lower() == "te": 513 Cmd += ["-t"] 514 if SubType not in [None, '']: 515 Cmd += ["-e", SubType] 516 if TimeStamp not in [None, '']: 517 Cmd += ["-s", TimeStamp] 518 if Align not in [None, '']: 519 Cmd += ["-a", Align] 520 if Padding not in [None, '']: 521 Cmd += ["-p", Padding] 522 if Zero: 523 Cmd += ["-z"] 524 if Strip: 525 Cmd += ["-l"] 526 if Replace: 527 Cmd += ["-r"] 528 if Join: 529 Cmd += ["-j"] 530 if Convert: 531 Cmd += ["-m"] 532 Cmd += ["-o", Output] 533 Cmd += Input 534 535 GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate firmware image") 536 537 @staticmethod 538 def GenerateOptionRom(Output, EfiInput, BinaryInput, Compress=False, ClassCode=None, 539 Revision=None, DeviceId=None, VendorId=None): 540 InputList = [] 541 Cmd = ["EfiRom"] 542 if len(EfiInput) > 0: 543 544 if Compress: 545 Cmd += ["-ec"] 546 else: 547 Cmd += ["-e"] 548 549 for EfiFile in EfiInput: 550 Cmd += [EfiFile] 551 InputList.append (EfiFile) 552 553 if len(BinaryInput) > 0: 554 Cmd += ["-b"] 555 for BinFile in BinaryInput: 556 Cmd += [BinFile] 557 InputList.append (BinFile) 558 559 # Check List 560 if not GenFdsGlobalVariable.NeedsUpdate(Output, InputList): 561 return 562 GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, InputList)) 563 564 if ClassCode != None: 565 Cmd += ["-l", ClassCode] 566 if Revision != None: 567 Cmd += ["-r", Revision] 568 if DeviceId != None: 569 Cmd += ["-i", DeviceId] 570 if VendorId != None: 571 Cmd += ["-f", VendorId] 572 573 Cmd += ["-o", Output] 574 GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate option rom") 575 576 @staticmethod 577 def GuidTool(Output, Input, ToolPath, Options='', returnValue=[]): 578 if not GenFdsGlobalVariable.NeedsUpdate(Output, Input): 579 return 580 GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) 581 582 Cmd = [ToolPath, ] 583 Cmd += Options.split(' ') 584 Cmd += ["-o", Output] 585 Cmd += Input 586 587 GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to call " + ToolPath, returnValue) 588 589 def CallExternalTool (cmd, errorMess, returnValue=[]): 590 591 if type(cmd) not in (tuple, list): 592 GenFdsGlobalVariable.ErrorLogger("ToolError! Invalid parameter type in call to CallExternalTool") 593 594 if GenFdsGlobalVariable.DebugLevel != -1: 595 cmd += ('--debug', str(GenFdsGlobalVariable.DebugLevel)) 596 GenFdsGlobalVariable.InfLogger (cmd) 597 598 if GenFdsGlobalVariable.VerboseMode: 599 cmd += ('-v',) 600 GenFdsGlobalVariable.InfLogger (cmd) 601 else: 602 sys.stdout.write ('#') 603 sys.stdout.flush() 604 GenFdsGlobalVariable.SharpCounter = GenFdsGlobalVariable.SharpCounter + 1 605 if GenFdsGlobalVariable.SharpCounter % GenFdsGlobalVariable.SharpNumberPerLine == 0: 606 sys.stdout.write('\n') 607 608 try: 609 PopenObject = subprocess.Popen(' '.join(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) 610 except Exception, X: 611 EdkLogger.error("GenFds", COMMAND_FAILURE, ExtraData="%s: %s" % (str(X), cmd[0])) 612 (out, error) = PopenObject.communicate() 613 614 while PopenObject.returncode == None : 615 PopenObject.wait() 616 if returnValue != [] and returnValue[0] != 0: 617 #get command return value 618 returnValue[0] = PopenObject.returncode 619 return 620 if PopenObject.returncode != 0 or GenFdsGlobalVariable.VerboseMode or GenFdsGlobalVariable.DebugLevel != -1: 621 GenFdsGlobalVariable.InfLogger ("Return Value = %d" % PopenObject.returncode) 622 GenFdsGlobalVariable.InfLogger (out) 623 GenFdsGlobalVariable.InfLogger (error) 624 if PopenObject.returncode != 0: 625 print "###", cmd 626 EdkLogger.error("GenFds", COMMAND_FAILURE, errorMess) 627 628 def VerboseLogger (msg): 629 EdkLogger.verbose(msg) 630 631 def InfLogger (msg): 632 EdkLogger.info(msg) 633 634 def ErrorLogger (msg, File=None, Line=None, ExtraData=None): 635 EdkLogger.error('GenFds', GENFDS_ERROR, msg, File, Line, ExtraData) 636 637 def DebugLogger (Level, msg): 638 EdkLogger.debug(Level, msg) 639 640 ## ReplaceWorkspaceMacro() 641 # 642 # @param Str String that may contain macro 643 # @param MacroDict Dictionary that contains macro value pair 644 # 645 def MacroExtend (Str, MacroDict={}, Arch='COMMON'): 646 if Str == None : 647 return None 648 649 Dict = {'$(WORKSPACE)' : GenFdsGlobalVariable.WorkSpaceDir, 650 '$(EDK_SOURCE)' : GenFdsGlobalVariable.EdkSourceDir, 651# '$(OUTPUT_DIRECTORY)': GenFdsGlobalVariable.OutputDirFromDsc, 652 '$(TARGET)' : GenFdsGlobalVariable.TargetName, 653 '$(TOOL_CHAIN_TAG)' : GenFdsGlobalVariable.ToolChainTag, 654 '$(SPACE)' : ' ' 655 } 656 OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[GenFdsGlobalVariable.ArchList[0]] 657 if Arch != 'COMMON' and Arch in GenFdsGlobalVariable.ArchList: 658 OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[Arch] 659 660 Dict['$(OUTPUT_DIRECTORY)'] = OutputDir 661 662 if MacroDict != None and len (MacroDict) != 0: 663 Dict.update(MacroDict) 664 665 for key in Dict.keys(): 666 if Str.find(key) >= 0 : 667 Str = Str.replace (key, Dict[key]) 668 669 if Str.find('$(ARCH)') >= 0: 670 if len(GenFdsGlobalVariable.ArchList) == 1: 671 Str = Str.replace('$(ARCH)', GenFdsGlobalVariable.ArchList[0]) 672 else: 673 EdkLogger.error("GenFds", GENFDS_ERROR, "No way to determine $(ARCH) for %s" % Str) 674 675 return Str 676 677 ## GetPcdValue() 678 # 679 # @param PcdPattern pattern that labels a PCD. 680 # 681 def GetPcdValue (PcdPattern): 682 if PcdPattern == None : 683 return None 684 PcdPair = PcdPattern.lstrip('PCD(').rstrip(')').strip().split('.') 685 TokenSpace = PcdPair[0] 686 TokenCName = PcdPair[1] 687 688 PcdValue = '' 689 for Arch in GenFdsGlobalVariable.ArchList: 690 Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag] 691 PcdDict = Platform.Pcds 692 for Key in PcdDict: 693 PcdObj = PcdDict[Key] 694 if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace): 695 if PcdObj.Type != 'FixedAtBuild': 696 EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern) 697 if PcdObj.DatumType != 'VOID*': 698 EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern) 699 700 PcdValue = PcdObj.DefaultValue 701 return PcdValue 702 703 for Package in GenFdsGlobalVariable.WorkSpace.GetPackageList(GenFdsGlobalVariable.ActivePlatform, 704 Arch, 705 GenFdsGlobalVariable.TargetName, 706 GenFdsGlobalVariable.ToolChainTag): 707 PcdDict = Package.Pcds 708 for Key in PcdDict: 709 PcdObj = PcdDict[Key] 710 if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace): 711 if PcdObj.Type != 'FixedAtBuild': 712 EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern) 713 if PcdObj.DatumType != 'VOID*': 714 EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern) 715 716 PcdValue = PcdObj.DefaultValue 717 return PcdValue 718 719 return PcdValue 720 721 SetDir = staticmethod(SetDir) 722 ReplaceWorkspaceMacro = staticmethod(ReplaceWorkspaceMacro) 723 CallExternalTool = staticmethod(CallExternalTool) 724 VerboseLogger = staticmethod(VerboseLogger) 725 InfLogger = staticmethod(InfLogger) 726 ErrorLogger = staticmethod(ErrorLogger) 727 DebugLogger = staticmethod(DebugLogger) 728 MacroExtend = staticmethod (MacroExtend) 729 GetPcdValue = staticmethod(GetPcdValue) 730