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