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