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