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