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