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