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