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