1## @file 2# process FFS generation from INF statement 3# 4# Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR> 5# Copyright (c) 2014-2016 Hewlett-Packard Development Company, L.P.<BR> 6# 7# This program and the accompanying materials 8# are licensed and made available under the terms and conditions of the BSD License 9# which accompanies this distribution. The full text of the license may be found at 10# http://opensource.org/licenses/bsd-license.php 11# 12# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 13# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 14# 15 16## 17# Import Modules 18# 19import Rule 20import Common.LongFilePathOs as os 21import StringIO 22from struct import * 23from GenFdsGlobalVariable import GenFdsGlobalVariable 24import Ffs 25import subprocess 26import sys 27import Section 28import RuleSimpleFile 29import RuleComplexFile 30from CommonDataClass.FdfClass import FfsInfStatementClassObject 31from Common.MultipleWorkspace import MultipleWorkspace as mws 32from Common.String import * 33from Common.Misc import PathClass 34from Common.Misc import GuidStructureByteArrayToGuidString 35from Common.Misc import ProcessDuplicatedInf 36from Common.Misc import GetVariableOffset 37from Common import EdkLogger 38from Common.BuildToolError import * 39from GuidSection import GuidSection 40from FvImageSection import FvImageSection 41from Common.Misc import PeImageClass 42from AutoGen.GenDepex import DependencyExpression 43from PatchPcdValue.PatchPcdValue import PatchBinaryFile 44from Common.LongFilePathSupport import CopyLongFilePath 45from Common.LongFilePathSupport import OpenLongFilePath as open 46import Common.GlobalData as GlobalData 47 48## generate FFS from INF 49# 50# 51class FfsInfStatement(FfsInfStatementClassObject): 52 ## The mapping dictionary from datum type to its maximum number. 53 _MAX_SIZE_TYPE = {"BOOLEAN":0x01, "UINT8":0xFF, "UINT16":0xFFFF, "UINT32":0xFFFFFFFF, "UINT64":0xFFFFFFFFFFFFFFFF} 54 ## The constructor 55 # 56 # @param self The object pointer 57 # 58 def __init__(self): 59 FfsInfStatementClassObject.__init__(self) 60 self.TargetOverrideList = [] 61 self.ShadowFromInfFile = None 62 self.KeepRelocFromRule = None 63 self.InDsc = True 64 self.OptRomDefs = {} 65 self.PiSpecVersion = '0x00000000' 66 self.InfModule = None 67 self.FinalTargetSuffixMap = {} 68 self.CurrentLineNum = None 69 self.CurrentLineContent = None 70 self.FileName = None 71 self.InfFileName = None 72 self.OverrideGuid = None 73 self.PatchedBinFile = '' 74 self.MacroDict = {} 75 76 ## GetFinalTargetSuffixMap() method 77 # 78 # Get final build target list 79 def GetFinalTargetSuffixMap(self): 80 if not self.InfModule or not self.CurrentArch: 81 return [] 82 if not self.FinalTargetSuffixMap: 83 FinalBuildTargetList = GenFdsGlobalVariable.GetModuleCodaTargetList(self.InfModule, self.CurrentArch) 84 for File in FinalBuildTargetList: 85 self.FinalTargetSuffixMap.setdefault(os.path.splitext(File)[1], []).append(File) 86 87 # Check if current INF module has DEPEX 88 if '.depex' not in self.FinalTargetSuffixMap and self.InfModule.ModuleType != "USER_DEFINED" \ 89 and not self.InfModule.DxsFile and not self.InfModule.LibraryClass: 90 ModuleType = self.InfModule.ModuleType 91 PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag] 92 93 if ModuleType != DataType.SUP_MODULE_USER_DEFINED: 94 for LibraryClass in PlatformDataBase.LibraryClasses.GetKeys(): 95 if LibraryClass.startswith("NULL") and PlatformDataBase.LibraryClasses[LibraryClass, ModuleType]: 96 self.InfModule.LibraryClasses[LibraryClass] = PlatformDataBase.LibraryClasses[LibraryClass, ModuleType] 97 98 StrModule = str(self.InfModule) 99 PlatformModule = None 100 if StrModule in PlatformDataBase.Modules: 101 PlatformModule = PlatformDataBase.Modules[StrModule] 102 for LibraryClass in PlatformModule.LibraryClasses: 103 if LibraryClass.startswith("NULL"): 104 self.InfModule.LibraryClasses[LibraryClass] = PlatformModule.LibraryClasses[LibraryClass] 105 106 DependencyList = [self.InfModule] 107 LibraryInstance = {} 108 DepexList = [] 109 while len(DependencyList) > 0: 110 Module = DependencyList.pop(0) 111 if not Module: 112 continue 113 for Dep in Module.Depex[self.CurrentArch, ModuleType]: 114 if DepexList != []: 115 DepexList.append('AND') 116 DepexList.append('(') 117 DepexList.extend(Dep) 118 if DepexList[-1] == 'END': # no need of a END at this time 119 DepexList.pop() 120 DepexList.append(')') 121 if 'BEFORE' in DepexList or 'AFTER' in DepexList: 122 break 123 for LibName in Module.LibraryClasses: 124 if LibName in LibraryInstance: 125 continue 126 if PlatformModule and LibName in PlatformModule.LibraryClasses: 127 LibraryPath = PlatformModule.LibraryClasses[LibName] 128 else: 129 LibraryPath = PlatformDataBase.LibraryClasses[LibName, ModuleType] 130 if not LibraryPath: 131 LibraryPath = Module.LibraryClasses[LibName] 132 if not LibraryPath: 133 continue 134 LibraryModule = GenFdsGlobalVariable.WorkSpace.BuildObject[LibraryPath, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag] 135 LibraryInstance[LibName] = LibraryModule 136 DependencyList.append(LibraryModule) 137 if DepexList: 138 Dpx = DependencyExpression(DepexList, ModuleType, True) 139 if len(Dpx.PostfixNotation) != 0: 140 # It means this module has DEPEX 141 self.FinalTargetSuffixMap['.depex'] = [os.path.join(self.EfiOutputPath, self.BaseName) + '.depex'] 142 return self.FinalTargetSuffixMap 143 144 ## __InfParse() method 145 # 146 # Parse inf file to get module information 147 # 148 # @param self The object pointer 149 # @param Dict dictionary contains macro and value pair 150 # 151 def __InfParse__(self, Dict = {}): 152 153 GenFdsGlobalVariable.VerboseLogger( " Begine parsing INf file : %s" %self.InfFileName) 154 155 self.InfFileName = self.InfFileName.replace('$(WORKSPACE)', '') 156 if len(self.InfFileName) > 1 and self.InfFileName[0] == '\\' and self.InfFileName[1] == '\\': 157 pass 158 elif self.InfFileName[0] == '\\' or self.InfFileName[0] == '/' : 159 self.InfFileName = self.InfFileName[1:] 160 161 if self.InfFileName.find('$') == -1: 162 InfPath = NormPath(self.InfFileName) 163 if not os.path.exists(InfPath): 164 InfPath = GenFdsGlobalVariable.ReplaceWorkspaceMacro(InfPath) 165 if not os.path.exists(InfPath): 166 EdkLogger.error("GenFds", GENFDS_ERROR, "Non-existant Module %s !" % (self.InfFileName)) 167 168 self.CurrentArch = self.GetCurrentArch() 169 # 170 # Get the InfClass object 171 # 172 173 PathClassObj = PathClass(self.InfFileName, GenFdsGlobalVariable.WorkSpaceDir) 174 ErrorCode, ErrorInfo = PathClassObj.Validate(".inf") 175 if ErrorCode != 0: 176 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo) 177 178 # 179 # Cache lower case version of INF path before processing FILE_GUID override 180 # 181 InfLowerPath = str(PathClassObj).lower() 182 if self.OverrideGuid: 183 PathClassObj = ProcessDuplicatedInf(PathClassObj, self.OverrideGuid, GenFdsGlobalVariable.WorkSpaceDir) 184 if self.CurrentArch != None: 185 186 Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag] 187 # 188 # Set Ffs BaseName, MdouleGuid, ModuleType, Version, OutputPath 189 # 190 self.BaseName = Inf.BaseName 191 self.ModuleGuid = Inf.Guid 192 self.ModuleType = Inf.ModuleType 193 if Inf.Specification != None and 'PI_SPECIFICATION_VERSION' in Inf.Specification: 194 self.PiSpecVersion = Inf.Specification['PI_SPECIFICATION_VERSION'] 195 if Inf.AutoGenVersion < 0x00010005: 196 self.ModuleType = Inf.ComponentType 197 self.VersionString = Inf.Version 198 self.BinFileList = Inf.Binaries 199 self.SourceFileList = Inf.Sources 200 if self.KeepReloc == None and Inf.Shadow: 201 self.ShadowFromInfFile = Inf.Shadow 202 203 else: 204 Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag] 205 self.BaseName = Inf.BaseName 206 self.ModuleGuid = Inf.Guid 207 self.ModuleType = Inf.ModuleType 208 if Inf.Specification != None and 'PI_SPECIFICATION_VERSION' in Inf.Specification: 209 self.PiSpecVersion = Inf.Specification['PI_SPECIFICATION_VERSION'] 210 self.VersionString = Inf.Version 211 self.BinFileList = Inf.Binaries 212 self.SourceFileList = Inf.Sources 213 if self.BinFileList == []: 214 EdkLogger.error("GenFds", GENFDS_ERROR, 215 "INF %s specified in FDF could not be found in build ARCH %s!" \ 216 % (self.InfFileName, GenFdsGlobalVariable.ArchList)) 217 218 if self.OverrideGuid: 219 self.ModuleGuid = self.OverrideGuid 220 221 if len(self.SourceFileList) != 0 and not self.InDsc: 222 EdkLogger.warn("GenFds", GENFDS_ERROR, "Module %s NOT found in DSC file; Is it really a binary module?" % (self.InfFileName)) 223 224 if self.ModuleType == 'SMM_CORE' and int(self.PiSpecVersion, 16) < 0x0001000A: 225 EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "SMM_CORE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x0001000A", File=self.InfFileName) 226 227 if Inf._Defs != None and len(Inf._Defs) > 0: 228 self.OptRomDefs.update(Inf._Defs) 229 230 self.PatchPcds = [] 231 InfPcds = Inf.Pcds 232 Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag] 233 FdfPcdDict = GenFdsGlobalVariable.FdfParser.Profile.PcdDict 234 235 # Workaround here: both build and GenFds tool convert the workspace path to lower case 236 # But INF file path in FDF and DSC file may have real case characters. 237 # Try to convert the path to lower case to see if PCDs value are override by DSC. 238 DscModules = {} 239 for DscModule in Platform.Modules: 240 DscModules[str(DscModule).lower()] = Platform.Modules[DscModule] 241 for PcdKey in InfPcds: 242 Pcd = InfPcds[PcdKey] 243 if not hasattr(Pcd, 'Offset'): 244 continue 245 if Pcd.Type != 'PatchableInModule': 246 continue 247 # Override Patchable PCD value by the value from DSC 248 PatchPcd = None 249 if InfLowerPath in DscModules and PcdKey in DscModules[InfLowerPath].Pcds: 250 PatchPcd = DscModules[InfLowerPath].Pcds[PcdKey] 251 elif PcdKey in Platform.Pcds: 252 PatchPcd = Platform.Pcds[PcdKey] 253 DscOverride = False 254 if PatchPcd and Pcd.Type == PatchPcd.Type: 255 DefaultValue = PatchPcd.DefaultValue 256 DscOverride = True 257 258 # Override Patchable PCD value by the value from FDF 259 FdfOverride = False 260 if PcdKey in FdfPcdDict: 261 DefaultValue = FdfPcdDict[PcdKey] 262 FdfOverride = True 263 264 # Override Patchable PCD value by the value from Build Option 265 BuildOptionOverride = False 266 if GlobalData.BuildOptionPcd: 267 for pcd in GlobalData.BuildOptionPcd: 268 if PcdKey == (pcd[1], pcd[0]): 269 DefaultValue = pcd[2] 270 BuildOptionOverride = True 271 break 272 273 if not DscOverride and not FdfOverride and not BuildOptionOverride: 274 continue 275 # Check value, if value are equal, no need to patch 276 if Pcd.DatumType == "VOID*": 277 if Pcd.DefaultValue == DefaultValue or DefaultValue in [None, '']: 278 continue 279 # Get the string size from FDF or DSC 280 if DefaultValue[0] == 'L': 281 # Remove L"", but the '\0' must be appended 282 MaxDatumSize = str((len(DefaultValue) - 2) * 2) 283 elif DefaultValue[0] == '{': 284 MaxDatumSize = str(len(DefaultValue.split(','))) 285 else: 286 MaxDatumSize = str(len(DefaultValue) - 1) 287 if DscOverride: 288 Pcd.MaxDatumSize = PatchPcd.MaxDatumSize 289 # If no defined the maximum size in DSC, try to get current size from INF 290 if Pcd.MaxDatumSize in ['', None]: 291 Pcd.MaxDatumSize = str(len(Pcd.DefaultValue.split(','))) 292 else: 293 Base1 = Base2 = 10 294 if Pcd.DefaultValue.upper().startswith('0X'): 295 Base1 = 16 296 if DefaultValue.upper().startswith('0X'): 297 Base2 = 16 298 try: 299 PcdValueInImg = int(Pcd.DefaultValue, Base1) 300 PcdValueInDscOrFdf = int(DefaultValue, Base2) 301 if PcdValueInImg == PcdValueInDscOrFdf: 302 continue 303 except: 304 continue 305 # Check the Pcd size and data type 306 if Pcd.DatumType == "VOID*": 307 if int(MaxDatumSize) > int(Pcd.MaxDatumSize): 308 EdkLogger.error("GenFds", GENFDS_ERROR, "The size of VOID* type PCD '%s.%s' exceeds its maximum size %d bytes." \ 309 % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, int(MaxDatumSize) - int(Pcd.MaxDatumSize))) 310 else: 311 if PcdValueInDscOrFdf > FfsInfStatement._MAX_SIZE_TYPE[Pcd.DatumType] \ 312 or PcdValueInImg > FfsInfStatement._MAX_SIZE_TYPE[Pcd.DatumType]: 313 EdkLogger.error("GenFds", GENFDS_ERROR, "The size of %s type PCD '%s.%s' doesn't match its data type." \ 314 % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)) 315 self.PatchPcds.append((Pcd, DefaultValue)) 316 317 self.InfModule = Inf 318 self.PcdIsDriver = Inf.PcdIsDriver 319 self.IsBinaryModule = Inf.IsBinaryModule 320 GenFdsGlobalVariable.VerboseLogger("BaseName : %s" % self.BaseName) 321 GenFdsGlobalVariable.VerboseLogger("ModuleGuid : %s" % self.ModuleGuid) 322 GenFdsGlobalVariable.VerboseLogger("ModuleType : %s" % self.ModuleType) 323 GenFdsGlobalVariable.VerboseLogger("VersionString : %s" % self.VersionString) 324 GenFdsGlobalVariable.VerboseLogger("InfFileName :%s" % self.InfFileName) 325 326 # 327 # Set OutputPath = ${WorkSpace}\Build\Fv\Ffs\${ModuleGuid}+ ${MdouleName}\ 328 # 329 330 self.OutputPath = os.path.join(GenFdsGlobalVariable.FfsDir, \ 331 self.ModuleGuid + self.BaseName) 332 if not os.path.exists(self.OutputPath) : 333 os.makedirs(self.OutputPath) 334 335 self.EfiOutputPath = self.__GetEFIOutPutPath__() 336 GenFdsGlobalVariable.VerboseLogger( "ModuelEFIPath: " + self.EfiOutputPath) 337 338 ## PatchEfiFile 339 # 340 # Patch EFI file with patch PCD 341 # 342 # @param EfiFile: EFI file needs to be patched. 343 # @retval: Full path of patched EFI file: self.OutputPath + EfiFile base name 344 # If passed in file does not end with efi, return as is 345 # 346 def PatchEfiFile(self, EfiFile, FileType): 347 # 348 # If the module does not have any patches, then return path to input file 349 # 350 if not self.PatchPcds: 351 return EfiFile 352 353 # 354 # Only patch file if FileType is PE32 or ModuleType is USER_DEFINED 355 # 356 if FileType != 'PE32' and self.ModuleType != "USER_DEFINED": 357 return EfiFile 358 359 # 360 # Generate path to patched output file 361 # 362 Basename = os.path.basename(EfiFile) 363 Output = os.path.normpath (os.path.join(self.OutputPath, Basename)) 364 365 # 366 # If this file has already been patched, then return the path to the patched file 367 # 368 if self.PatchedBinFile == Output: 369 return Output 370 371 # 372 # If a different file from the same module has already been patched, then generate an error 373 # 374 if self.PatchedBinFile: 375 EdkLogger.error("GenFds", GENFDS_ERROR, 376 'Only one binary file can be patched:\n' 377 ' a binary file has been patched: %s\n' 378 ' current file: %s' % (self.PatchedBinFile, EfiFile), 379 File=self.InfFileName) 380 381 # 382 # Copy unpatched file contents to output file location to perform patching 383 # 384 CopyLongFilePath(EfiFile, Output) 385 386 # 387 # Apply patches to patched output file 388 # 389 for Pcd, Value in self.PatchPcds: 390 RetVal, RetStr = PatchBinaryFile(Output, int(Pcd.Offset, 0), Pcd.DatumType, Value, Pcd.MaxDatumSize) 391 if RetVal: 392 EdkLogger.error("GenFds", GENFDS_ERROR, RetStr, File=self.InfFileName) 393 394 # 395 # Save the path of the patched output file 396 # 397 self.PatchedBinFile = Output 398 399 # 400 # Return path to patched output file 401 # 402 return Output 403 404 ## GenFfs() method 405 # 406 # Generate FFS 407 # 408 # @param self The object pointer 409 # @param Dict dictionary contains macro and value pair 410 # @param FvChildAddr Array of the inside FvImage base address 411 # @param FvParentAddr Parent Fv base address 412 # @retval string Generated FFS file name 413 # 414 def GenFfs(self, Dict = {}, FvChildAddr = [], FvParentAddr=None): 415 # 416 # Parse Inf file get Module related information 417 # 418 419 self.__InfParse__(Dict) 420 SrcFile = mws.join( GenFdsGlobalVariable.WorkSpaceDir , self.InfFileName); 421 DestFile = os.path.join( self.OutputPath, self.ModuleGuid + '.ffs') 422 423 SrcFileDir = "." 424 SrcPath = os.path.dirname(SrcFile) 425 SrcFileName = os.path.basename(SrcFile) 426 SrcFileBase, SrcFileExt = os.path.splitext(SrcFileName) 427 DestPath = os.path.dirname(DestFile) 428 DestFileName = os.path.basename(DestFile) 429 DestFileBase, DestFileExt = os.path.splitext(DestFileName) 430 self.MacroDict = { 431 # source file 432 "${src}" : SrcFile, 433 "${s_path}" : SrcPath, 434 "${s_dir}" : SrcFileDir, 435 "${s_name}" : SrcFileName, 436 "${s_base}" : SrcFileBase, 437 "${s_ext}" : SrcFileExt, 438 # destination file 439 "${dst}" : DestFile, 440 "${d_path}" : DestPath, 441 "${d_name}" : DestFileName, 442 "${d_base}" : DestFileBase, 443 "${d_ext}" : DestFileExt 444 } 445 # 446 # Allow binary type module not specify override rule in FDF file. 447 # 448 if len(self.BinFileList) > 0: 449 if self.Rule == None or self.Rule == "": 450 self.Rule = "BINARY" 451 452 # 453 # Get the rule of how to generate Ffs file 454 # 455 Rule = self.__GetRule__() 456 GenFdsGlobalVariable.VerboseLogger( "Packing binaries from inf file : %s" %self.InfFileName) 457 # 458 # Convert Fv File Type for PI1.1 SMM driver. 459 # 460 if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) >= 0x0001000A: 461 if Rule.FvFileType == 'DRIVER': 462 Rule.FvFileType = 'SMM' 463 # 464 # Framework SMM Driver has no SMM FV file type 465 # 466 if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) < 0x0001000A: 467 if Rule.FvFileType == 'SMM' or Rule.FvFileType == 'SMM_CORE': 468 EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM or SMM_CORE FV file type", File=self.InfFileName) 469 # 470 # For the rule only has simpleFile 471 # 472 if isinstance (Rule, RuleSimpleFile.RuleSimpleFile) : 473 SectionOutputList = self.__GenSimpleFileSection__(Rule) 474 FfsOutput = self.__GenSimpleFileFfs__(Rule, SectionOutputList) 475 return FfsOutput 476 # 477 # For Rule has ComplexFile 478 # 479 elif isinstance(Rule, RuleComplexFile.RuleComplexFile): 480 InputSectList, InputSectAlignments = self.__GenComplexFileSection__(Rule, FvChildAddr, FvParentAddr) 481 FfsOutput = self.__GenComplexFileFfs__(Rule, InputSectList, InputSectAlignments) 482 483 return FfsOutput 484 485 ## __ExtendMacro__() method 486 # 487 # Replace macro with its value 488 # 489 # @param self The object pointer 490 # @param String The string to be replaced 491 # @retval string Macro replaced string 492 # 493 def __ExtendMacro__ (self, String): 494 MacroDict = { 495 '$(INF_OUTPUT)' : self.EfiOutputPath, 496 '$(MODULE_NAME)' : self.BaseName, 497 '$(BUILD_NUMBER)': self.BuildNum, 498 '$(INF_VERSION)' : self.VersionString, 499 '$(NAMED_GUID)' : self.ModuleGuid 500 } 501 String = GenFdsGlobalVariable.MacroExtend(String, MacroDict) 502 String = GenFdsGlobalVariable.MacroExtend(String, self.MacroDict) 503 return String 504 505 ## __GetRule__() method 506 # 507 # Get correct rule for generating FFS for this INF 508 # 509 # @param self The object pointer 510 # @retval Rule Rule object 511 # 512 def __GetRule__ (self) : 513 CurrentArchList = [] 514 if self.CurrentArch == None: 515 CurrentArchList = ['common'] 516 else: 517 CurrentArchList.append(self.CurrentArch) 518 519 for CurrentArch in CurrentArchList: 520 RuleName = 'RULE' + \ 521 '.' + \ 522 CurrentArch.upper() + \ 523 '.' + \ 524 self.ModuleType.upper() 525 if self.Rule != None: 526 RuleName = RuleName + \ 527 '.' + \ 528 self.Rule.upper() 529 530 Rule = GenFdsGlobalVariable.FdfParser.Profile.RuleDict.get(RuleName) 531 if Rule != None: 532 GenFdsGlobalVariable.VerboseLogger ("Want To Find Rule Name is : " + RuleName) 533 return Rule 534 535 RuleName = 'RULE' + \ 536 '.' + \ 537 'COMMON' + \ 538 '.' + \ 539 self.ModuleType.upper() 540 541 if self.Rule != None: 542 RuleName = RuleName + \ 543 '.' + \ 544 self.Rule.upper() 545 546 GenFdsGlobalVariable.VerboseLogger ('Trying to apply common rule %s for INF %s' % (RuleName, self.InfFileName)) 547 548 Rule = GenFdsGlobalVariable.FdfParser.Profile.RuleDict.get(RuleName) 549 if Rule != None: 550 GenFdsGlobalVariable.VerboseLogger ("Want To Find Rule Name is : " + RuleName) 551 return Rule 552 553 if Rule == None : 554 EdkLogger.error("GenFds", GENFDS_ERROR, 'Don\'t Find common rule %s for INF %s' \ 555 % (RuleName, self.InfFileName)) 556 557 ## __GetPlatformArchList__() method 558 # 559 # Get Arch list this INF built under 560 # 561 # @param self The object pointer 562 # @retval list Arch list 563 # 564 def __GetPlatformArchList__(self): 565 566 InfFileKey = os.path.normpath(mws.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName)) 567 DscArchList = [] 568 for Arch in GenFdsGlobalVariable.ArchList : 569 PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag] 570 if PlatformDataBase != None: 571 if InfFileKey in PlatformDataBase.Modules: 572 DscArchList.append (Arch) 573 else: 574 # 575 # BaseTools support build same module more than once, the module path with FILE_GUID overridden has 576 # the file name FILE_GUIDmodule.inf, then PlatformDataBase.Modules use FILE_GUIDmodule.inf as key, 577 # but the path (self.MetaFile.Path) is the real path 578 # 579 for key in PlatformDataBase.Modules.keys(): 580 if InfFileKey == str((PlatformDataBase.Modules[key]).MetaFile.Path): 581 DscArchList.append (Arch) 582 break 583 584 return DscArchList 585 586 ## GetCurrentArch() method 587 # 588 # Get Arch list of the module from this INF is to be placed into flash 589 # 590 # @param self The object pointer 591 # @retval list Arch list 592 # 593 def GetCurrentArch(self) : 594 595 TargetArchList = GenFdsGlobalVariable.ArchList 596 597 PlatformArchList = self.__GetPlatformArchList__() 598 599 CurArchList = TargetArchList 600 if PlatformArchList != []: 601 CurArchList = list(set (TargetArchList) & set (PlatformArchList)) 602 GenFdsGlobalVariable.VerboseLogger ("Valid target architecture(s) is : " + " ".join(CurArchList)) 603 604 ArchList = [] 605 if self.KeyStringList != []: 606 for Key in self.KeyStringList: 607 Key = GenFdsGlobalVariable.MacroExtend(Key) 608 Target, Tag, Arch = Key.split('_') 609 if Arch in CurArchList: 610 ArchList.append(Arch) 611 if Target not in self.TargetOverrideList: 612 self.TargetOverrideList.append(Target) 613 else: 614 ArchList = CurArchList 615 616 UseArchList = TargetArchList 617 if self.UseArch != None: 618 UseArchList = [] 619 UseArchList.append(self.UseArch) 620 ArchList = list(set (UseArchList) & set (ArchList)) 621 622 self.InfFileName = NormPath(self.InfFileName) 623 if len(PlatformArchList) == 0: 624 self.InDsc = False 625 PathClassObj = PathClass(self.InfFileName, GenFdsGlobalVariable.WorkSpaceDir) 626 ErrorCode, ErrorInfo = PathClassObj.Validate(".inf") 627 if ErrorCode != 0: 628 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo) 629 if len(ArchList) == 1: 630 Arch = ArchList[0] 631 return Arch 632 elif len(ArchList) > 1: 633 if len(PlatformArchList) == 0: 634 EdkLogger.error("GenFds", GENFDS_ERROR, "GenFds command line option has multiple ARCHs %s. Not able to determine which ARCH is valid for Module %s !" % (str(ArchList), self.InfFileName)) 635 else: 636 EdkLogger.error("GenFds", GENFDS_ERROR, "Module built under multiple ARCHs %s. Not able to determine which output to put into flash for Module %s !" % (str(ArchList), self.InfFileName)) 637 else: 638 EdkLogger.error("GenFds", GENFDS_ERROR, "Module %s appears under ARCH %s in platform %s, but current deduced ARCH is %s, so NO build output could be put into flash." \ 639 % (self.InfFileName, str(PlatformArchList), GenFdsGlobalVariable.ActivePlatform, str(set (UseArchList) & set (TargetArchList)))) 640 641 ## __GetEFIOutPutPath__() method 642 # 643 # Get the output path for generated files 644 # 645 # @param self The object pointer 646 # @retval string Path that output files from this INF go to 647 # 648 def __GetEFIOutPutPath__(self): 649 Arch = '' 650 OutputPath = '' 651 (ModulePath, FileName) = os.path.split(self.InfFileName) 652 Index = FileName.rfind('.') 653 FileName = FileName[0:Index] 654 if self.OverrideGuid: 655 FileName = self.OverrideGuid 656 Arch = "NoneArch" 657 if self.CurrentArch != None: 658 Arch = self.CurrentArch 659 660 OutputPath = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch], 661 Arch , 662 ModulePath, 663 FileName, 664 'OUTPUT' 665 ) 666 OutputPath = os.path.realpath(OutputPath) 667 return OutputPath 668 669 ## __GenSimpleFileSection__() method 670 # 671 # Generate section by specified file name or a list of files with file extension 672 # 673 # @param self The object pointer 674 # @param Rule The rule object used to generate section 675 # @retval string File name of the generated section file 676 # 677 def __GenSimpleFileSection__(self, Rule): 678 # 679 # Prepare the parameter of GenSection 680 # 681 FileList = [] 682 OutputFileList = [] 683 GenSecInputFile = None 684 if Rule.FileName != None: 685 GenSecInputFile = self.__ExtendMacro__(Rule.FileName) 686 if os.path.isabs(GenSecInputFile): 687 GenSecInputFile = os.path.normpath(GenSecInputFile) 688 else: 689 GenSecInputFile = os.path.normpath(os.path.join(self.EfiOutputPath, GenSecInputFile)) 690 else: 691 FileList, IsSect = Section.Section.GetFileList(self, '', Rule.FileExtension) 692 693 Index = 1 694 SectionType = Rule.SectionType 695 # 696 # Convert Fv Section Type for PI1.1 SMM driver. 697 # 698 if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) >= 0x0001000A: 699 if SectionType == 'DXE_DEPEX': 700 SectionType = 'SMM_DEPEX' 701 # 702 # Framework SMM Driver has no SMM_DEPEX section type 703 # 704 if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) < 0x0001000A: 705 if SectionType == 'SMM_DEPEX': 706 EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM_DEPEX section type", File=self.InfFileName) 707 NoStrip = True 708 if self.ModuleType in ('SEC', 'PEI_CORE', 'PEIM'): 709 if self.KeepReloc != None: 710 NoStrip = self.KeepReloc 711 elif Rule.KeepReloc != None: 712 NoStrip = Rule.KeepReloc 713 elif self.ShadowFromInfFile != None: 714 NoStrip = self.ShadowFromInfFile 715 716 if FileList != [] : 717 for File in FileList: 718 719 SecNum = '%d' %Index 720 GenSecOutputFile= self.__ExtendMacro__(Rule.NameGuid) + \ 721 Ffs.Ffs.SectionSuffix[SectionType] + 'SEC' + SecNum 722 Index = Index + 1 723 OutputFile = os.path.join(self.OutputPath, GenSecOutputFile) 724 File = GenFdsGlobalVariable.MacroExtend(File, Dict, self.CurrentArch) 725 726 #Get PE Section alignment when align is set to AUTO 727 if self.Alignment == 'Auto' and (SectionType == 'PE32' or SectionType == 'TE'): 728 ImageObj = PeImageClass (File) 729 if ImageObj.SectionAlignment < 0x400: 730 self.Alignment = str (ImageObj.SectionAlignment) 731 else: 732 self.Alignment = str (ImageObj.SectionAlignment / 0x400) + 'K' 733 734 if not NoStrip: 735 FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc') 736 if not os.path.exists(FileBeforeStrip) or \ 737 (os.path.getmtime(File) > os.path.getmtime(FileBeforeStrip)): 738 CopyLongFilePath(File, FileBeforeStrip) 739 StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped') 740 GenFdsGlobalVariable.GenerateFirmwareImage( 741 StrippedFile, 742 [File], 743 Strip=True 744 ) 745 File = StrippedFile 746 747 if SectionType == 'TE': 748 TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw') 749 GenFdsGlobalVariable.GenerateFirmwareImage( 750 TeFile, 751 [File], 752 Type='te' 753 ) 754 File = TeFile 755 756 GenFdsGlobalVariable.GenerateSection(OutputFile, [File], Section.Section.SectionType[SectionType]) 757 OutputFileList.append(OutputFile) 758 else: 759 SecNum = '%d' %Index 760 GenSecOutputFile= self.__ExtendMacro__(Rule.NameGuid) + \ 761 Ffs.Ffs.SectionSuffix[SectionType] + 'SEC' + SecNum 762 OutputFile = os.path.join(self.OutputPath, GenSecOutputFile) 763 GenSecInputFile = GenFdsGlobalVariable.MacroExtend(GenSecInputFile, Dict, self.CurrentArch) 764 765 #Get PE Section alignment when align is set to AUTO 766 if self.Alignment == 'Auto' and (SectionType == 'PE32' or SectionType == 'TE'): 767 ImageObj = PeImageClass (GenSecInputFile) 768 if ImageObj.SectionAlignment < 0x400: 769 self.Alignment = str (ImageObj.SectionAlignment) 770 else: 771 self.Alignment = str (ImageObj.SectionAlignment / 0x400) + 'K' 772 773 if not NoStrip: 774 FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc') 775 if not os.path.exists(FileBeforeStrip) or \ 776 (os.path.getmtime(GenSecInputFile) > os.path.getmtime(FileBeforeStrip)): 777 CopyLongFilePath(GenSecInputFile, FileBeforeStrip) 778 779 StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped') 780 GenFdsGlobalVariable.GenerateFirmwareImage( 781 StrippedFile, 782 [GenSecInputFile], 783 Strip=True 784 ) 785 GenSecInputFile = StrippedFile 786 787 if SectionType == 'TE': 788 TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw') 789 GenFdsGlobalVariable.GenerateFirmwareImage( 790 TeFile, 791 [GenSecInputFile], 792 Type='te' 793 ) 794 GenSecInputFile = TeFile 795 796 GenFdsGlobalVariable.GenerateSection(OutputFile, [GenSecInputFile], Section.Section.SectionType[SectionType]) 797 OutputFileList.append(OutputFile) 798 799 return OutputFileList 800 801 ## __GenSimpleFileFfs__() method 802 # 803 # Generate FFS 804 # 805 # @param self The object pointer 806 # @param Rule The rule object used to generate section 807 # @param InputFileList The output file list from GenSection 808 # @retval string Generated FFS file name 809 # 810 def __GenSimpleFileFfs__(self, Rule, InputFileList): 811 FfsOutput = self.OutputPath + \ 812 os.sep + \ 813 self.__ExtendMacro__(Rule.NameGuid) + \ 814 '.ffs' 815 816 GenFdsGlobalVariable.VerboseLogger(self.__ExtendMacro__(Rule.NameGuid)) 817 InputSection = [] 818 SectionAlignments = [] 819 for InputFile in InputFileList: 820 InputSection.append(InputFile) 821 SectionAlignments.append(Rule.SectAlignment) 822 823 if Rule.NameGuid != None and Rule.NameGuid.startswith('PCD('): 824 PcdValue = GenFdsGlobalVariable.GetPcdValue(Rule.NameGuid) 825 if len(PcdValue) == 0: 826 EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \ 827 % (Rule.NameGuid)) 828 if PcdValue.startswith('{'): 829 PcdValue = GuidStructureByteArrayToGuidString(PcdValue) 830 RegistryGuidStr = PcdValue 831 if len(RegistryGuidStr) == 0: 832 EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \ 833 % (Rule.NameGuid)) 834 self.ModuleGuid = RegistryGuidStr 835 836 GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputSection, 837 Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType], 838 self.ModuleGuid, Fixed=Rule.Fixed, 839 CheckSum=Rule.CheckSum, Align=Rule.Alignment, 840 SectionAlign=SectionAlignments 841 ) 842 return FfsOutput 843 844 ## __GenComplexFileSection__() method 845 # 846 # Generate section by sections in Rule 847 # 848 # @param self The object pointer 849 # @param Rule The rule object used to generate section 850 # @param FvChildAddr Array of the inside FvImage base address 851 # @param FvParentAddr Parent Fv base address 852 # @retval string File name of the generated section file 853 # 854 def __GenComplexFileSection__(self, Rule, FvChildAddr, FvParentAddr): 855 if self.ModuleType in ('SEC', 'PEI_CORE', 'PEIM'): 856 if Rule.KeepReloc != None: 857 self.KeepRelocFromRule = Rule.KeepReloc 858 SectFiles = [] 859 SectAlignments = [] 860 Index = 1 861 HasGneratedFlag = False 862 if self.PcdIsDriver == 'PEI_PCD_DRIVER': 863 if self.IsBinaryModule: 864 PcdExDbFileName = os.path.join(GenFdsGlobalVariable.FvDir, "PEIPcdDataBase.raw") 865 else: 866 PcdExDbFileName = os.path.join(self.EfiOutputPath, "PEIPcdDataBase.raw") 867 PcdExDbSecName = os.path.join(self.OutputPath, "PEIPcdDataBaseSec.raw") 868 GenFdsGlobalVariable.GenerateSection(PcdExDbSecName, 869 [PcdExDbFileName], 870 "EFI_SECTION_RAW", 871 ) 872 SectFiles.append(PcdExDbSecName) 873 SectAlignments.append(None) 874 elif self.PcdIsDriver == 'DXE_PCD_DRIVER': 875 if self.IsBinaryModule: 876 PcdExDbFileName = os.path.join(GenFdsGlobalVariable.FvDir, "DXEPcdDataBase.raw") 877 else: 878 PcdExDbFileName = os.path.join(self.EfiOutputPath, "DXEPcdDataBase.raw") 879 PcdExDbSecName = os.path.join(self.OutputPath, "DXEPcdDataBaseSec.raw") 880 GenFdsGlobalVariable.GenerateSection(PcdExDbSecName, 881 [PcdExDbFileName], 882 "EFI_SECTION_RAW", 883 ) 884 SectFiles.append(PcdExDbSecName) 885 SectAlignments.append(None) 886 for Sect in Rule.SectionList: 887 SecIndex = '%d' %Index 888 SectList = [] 889 # 890 # Convert Fv Section Type for PI1.1 SMM driver. 891 # 892 if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) >= 0x0001000A: 893 if Sect.SectionType == 'DXE_DEPEX': 894 Sect.SectionType = 'SMM_DEPEX' 895 # 896 # Framework SMM Driver has no SMM_DEPEX section type 897 # 898 if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) < 0x0001000A: 899 if Sect.SectionType == 'SMM_DEPEX': 900 EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM_DEPEX section type", File=self.InfFileName) 901 # 902 # process the inside FvImage from FvSection or GuidSection 903 # 904 if FvChildAddr != []: 905 if isinstance(Sect, FvImageSection): 906 Sect.FvAddr = FvChildAddr.pop(0) 907 elif isinstance(Sect, GuidSection): 908 Sect.FvAddr = FvChildAddr 909 if FvParentAddr != None and isinstance(Sect, GuidSection): 910 Sect.FvParentAddr = FvParentAddr 911 912 if Rule.KeyStringList != []: 913 SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, Rule.KeyStringList, self) 914 else : 915 SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, self.KeyStringList, self) 916 917 if not HasGneratedFlag: 918 UniVfrOffsetFileSection = "" 919 ModuleFileName = mws.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName) 920 InfData = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClass(ModuleFileName), self.CurrentArch] 921 # 922 # Search the source list in InfData to find if there are .vfr file exist. 923 # 924 VfrUniBaseName = {} 925 VfrUniOffsetList = [] 926 for SourceFile in InfData.Sources: 927 if SourceFile.Type.upper() == ".VFR" : 928 # 929 # search the .map file to find the offset of vfr binary in the PE32+/TE file. 930 # 931 VfrUniBaseName[SourceFile.BaseName] = (SourceFile.BaseName + "Bin") 932 if SourceFile.Type.upper() == ".UNI" : 933 # 934 # search the .map file to find the offset of Uni strings binary in the PE32+/TE file. 935 # 936 VfrUniBaseName["UniOffsetName"] = (self.BaseName + "Strings") 937 938 939 if len(VfrUniBaseName) > 0: 940 VfrUniOffsetList = self.__GetBuildOutputMapFileVfrUniInfo(VfrUniBaseName) 941 # 942 # Generate the Raw data of raw section 943 # 944 if VfrUniOffsetList: 945 os.path.join( self.OutputPath, self.BaseName + '.offset') 946 UniVfrOffsetFileName = os.path.join( self.OutputPath, self.BaseName + '.offset') 947 UniVfrOffsetFileSection = os.path.join( self.OutputPath, self.BaseName + 'Offset' + '.raw') 948 949 self.__GenUniVfrOffsetFile (VfrUniOffsetList, UniVfrOffsetFileName) 950 951 UniVfrOffsetFileNameList = [] 952 UniVfrOffsetFileNameList.append(UniVfrOffsetFileName) 953 """Call GenSection""" 954 GenFdsGlobalVariable.GenerateSection(UniVfrOffsetFileSection, 955 UniVfrOffsetFileNameList, 956 "EFI_SECTION_RAW" 957 ) 958 os.remove(UniVfrOffsetFileName) 959 SectList.append(UniVfrOffsetFileSection) 960 HasGneratedFlag = True 961 962 for SecName in SectList : 963 SectFiles.append(SecName) 964 SectAlignments.append(Align) 965 Index = Index + 1 966 return SectFiles, SectAlignments 967 968 ## __GenComplexFileFfs__() method 969 # 970 # Generate FFS 971 # 972 # @param self The object pointer 973 # @param Rule The rule object used to generate section 974 # @param InputFileList The output file list from GenSection 975 # @retval string Generated FFS file name 976 # 977 def __GenComplexFileFfs__(self, Rule, InputFile, Alignments): 978 979 if Rule.NameGuid != None and Rule.NameGuid.startswith('PCD('): 980 PcdValue = GenFdsGlobalVariable.GetPcdValue(Rule.NameGuid) 981 if len(PcdValue) == 0: 982 EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \ 983 % (Rule.NameGuid)) 984 if PcdValue.startswith('{'): 985 PcdValue = GuidStructureByteArrayToGuidString(PcdValue) 986 RegistryGuidStr = PcdValue 987 if len(RegistryGuidStr) == 0: 988 EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \ 989 % (Rule.NameGuid)) 990 self.ModuleGuid = RegistryGuidStr 991 992 FfsOutput = os.path.join( self.OutputPath, self.ModuleGuid + '.ffs') 993 GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputFile, 994 Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType], 995 self.ModuleGuid, Fixed=Rule.Fixed, 996 CheckSum=Rule.CheckSum, Align=Rule.Alignment, 997 SectionAlign=Alignments 998 ) 999 return FfsOutput 1000 1001 ## __GetGenFfsCmdParameter__() method 1002 # 1003 # Create parameter string for GenFfs 1004 # 1005 # @param self The object pointer 1006 # @param Rule The rule object used to generate section 1007 # @retval tuple (FileType, Fixed, CheckSum, Alignment) 1008 # 1009 def __GetGenFfsCmdParameter__(self, Rule): 1010 result = tuple() 1011 result += ('-t', Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType]) 1012 if Rule.Fixed != False: 1013 result += ('-x',) 1014 if Rule.CheckSum != False: 1015 result += ('-s',) 1016 1017 if Rule.Alignment != None and Rule.Alignment != '': 1018 result += ('-a', Rule.Alignment) 1019 1020 return result 1021 1022 ## __GetBuildOutputMapFileVfrUniInfo() method 1023 # 1024 # Find the offset of UNI/INF object offset in the EFI image file. 1025 # 1026 # @param self The object pointer 1027 # @param VfrUniBaseName A name list contain the UNI/INF object name. 1028 # @retval RetValue A list contain offset of UNI/INF object. 1029 # 1030 def __GetBuildOutputMapFileVfrUniInfo(self, VfrUniBaseName): 1031 MapFileName = os.path.join(self.EfiOutputPath, self.BaseName + ".map") 1032 EfiFileName = os.path.join(self.EfiOutputPath, self.BaseName + ".efi") 1033 return GetVariableOffset(MapFileName, EfiFileName, VfrUniBaseName.values()) 1034 1035 ## __GenUniVfrOffsetFile() method 1036 # 1037 # Generate the offset file for the module which contain VFR or UNI file. 1038 # 1039 # @param self The object pointer 1040 # @param VfrUniOffsetList A list contain the VFR/UNI offsets in the EFI image file. 1041 # @param UniVfrOffsetFileName The output offset file name. 1042 # 1043 def __GenUniVfrOffsetFile(self, VfrUniOffsetList, UniVfrOffsetFileName): 1044 1045 try: 1046 fInputfile = open(UniVfrOffsetFileName, "wb+", 0) 1047 except: 1048 EdkLogger.error("GenFds", FILE_OPEN_FAILURE, "File open failed for %s" %UniVfrOffsetFileName,None) 1049 1050 # Use a instance of StringIO to cache data 1051 fStringIO = StringIO.StringIO('') 1052 1053 for Item in VfrUniOffsetList: 1054 if (Item[0].find("Strings") != -1): 1055 # 1056 # UNI offset in image. 1057 # GUID + Offset 1058 # { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } } 1059 # 1060 UniGuid = [0xe0, 0xc5, 0x13, 0x89, 0xf6, 0x33, 0x86, 0x4d, 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66] 1061 UniGuid = [chr(ItemGuid) for ItemGuid in UniGuid] 1062 fStringIO.write(''.join(UniGuid)) 1063 UniValue = pack ('Q', int (Item[1], 16)) 1064 fStringIO.write (UniValue) 1065 else: 1066 # 1067 # VFR binary offset in image. 1068 # GUID + Offset 1069 # { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } }; 1070 # 1071 VfrGuid = [0xb4, 0x7c, 0xbc, 0xd0, 0x47, 0x6a, 0x5f, 0x49, 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2] 1072 VfrGuid = [chr(ItemGuid) for ItemGuid in VfrGuid] 1073 fStringIO.write(''.join(VfrGuid)) 1074 type (Item[1]) 1075 VfrValue = pack ('Q', int (Item[1], 16)) 1076 fStringIO.write (VfrValue) 1077 1078 # 1079 # write data into file. 1080 # 1081 try : 1082 fInputfile.write (fStringIO.getvalue()) 1083 except: 1084 EdkLogger.error("GenFds", FILE_WRITE_FAILURE, "Write data to file %s failed, please check whether the file been locked or using by other applications." %UniVfrOffsetFileName,None) 1085 1086 fStringIO.close () 1087 fInputfile.close () 1088 1089 1090 1091 1092 1093 1094 1095 1096