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