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