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