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