]>
Commit | Line | Data |
---|---|---|
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 | 18 | import Common.LongFilePathOs as os\r |
f51461c8 LG |
19 | import sys\r |
20 | import subprocess\r | |
21 | import struct\r | |
22 | import array\r | |
23 | \r | |
24 | from Common.BuildToolError import *\r | |
25 | from Common import EdkLogger\r | |
26 | from Common.Misc import SaveFileOnChange\r | |
27 | \r | |
28 | from Common.TargetTxtClassObject import TargetTxtClassObject\r | |
29 | from Common.ToolDefClassObject import ToolDefClassObject\r | |
30 | from AutoGen.BuildEngine import BuildRule\r | |
31 | import Common.DataType as DataType\r | |
32 | from Common.Misc import PathClass\r | |
1be2ed90 | 33 | from Common.LongFilePathSupport import OpenLongFilePath as open\r |
05cc51ad | 34 | from Common.MultipleWorkspace import MultipleWorkspace as mws\r |
f51461c8 LG |
35 | \r |
36 | ## Global variables\r | |
37 | #\r | |
38 | #\r | |
39 | class 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 | |
f51461c8 LG |
288 | \r |
289 | T_CHAR_LF = '\n'\r | |
290 | #\r | |
291 | # Create FV Address inf file\r | |
292 | #\r | |
293 | GenFdsGlobalVariable.FvAddressFileName = os.path.join(GenFdsGlobalVariable.FfsDir, 'FvAddress.inf')\r | |
47fea6af | 294 | FvAddressFile = open(GenFdsGlobalVariable.FvAddressFileName, 'w')\r |
f51461c8 LG |
295 | #\r |
296 | # Add [Options]\r | |
297 | #\r | |
298 | FvAddressFile.writelines("[options]" + T_CHAR_LF)\r | |
299 | BsAddress = '0'\r | |
300 | for Arch in ArchList:\r | |
301 | if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].BsBaseAddress:\r | |
302 | BsAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].BsBaseAddress\r | |
303 | break\r | |
304 | \r | |
305 | FvAddressFile.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \\r | |
47fea6af | 306 | BsAddress + \\r |
f51461c8 LG |
307 | T_CHAR_LF)\r |
308 | \r | |
309 | RtAddress = '0'\r | |
310 | for Arch in ArchList:\r | |
311 | if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].RtBaseAddress:\r | |
312 | RtAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].RtBaseAddress\r | |
313 | \r | |
314 | FvAddressFile.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \\r | |
47fea6af | 315 | RtAddress + \\r |
f51461c8 LG |
316 | T_CHAR_LF)\r |
317 | \r | |
318 | FvAddressFile.close()\r | |
319 | \r | |
320 | ## ReplaceWorkspaceMacro()\r | |
321 | #\r | |
322 | # @param String String that may contain macro\r | |
323 | #\r | |
324 | def ReplaceWorkspaceMacro(String):\r | |
05cc51ad | 325 | String = mws.handleWsMacro(String)\r |
f51461c8 LG |
326 | Str = String.replace('$(WORKSPACE)', GenFdsGlobalVariable.WorkSpaceDir)\r |
327 | if os.path.exists(Str):\r | |
328 | if not os.path.isabs(Str):\r | |
329 | Str = os.path.abspath(Str)\r | |
330 | else:\r | |
05cc51ad | 331 | Str = mws.join(GenFdsGlobalVariable.WorkSpaceDir, String)\r |
f51461c8 LG |
332 | return os.path.normpath(Str)\r |
333 | \r | |
334 | ## Check if the input files are newer than output files\r | |
335 | #\r | |
336 | # @param Output Path of output file\r | |
337 | # @param Input Path list of input files\r | |
338 | #\r | |
339 | # @retval True if Output doesn't exist, or any Input is newer\r | |
340 | # @retval False if all Input is older than Output\r | |
341 | #\r | |
342 | @staticmethod\r | |
343 | def NeedsUpdate(Output, Input):\r | |
344 | if not os.path.exists(Output):\r | |
345 | return True\r | |
346 | # always update "Output" if no "Input" given\r | |
347 | if Input == None or len(Input) == 0:\r | |
348 | return True\r | |
349 | \r | |
350 | # if fdf file is changed after the 'Output" is generated, update the 'Output'\r | |
351 | OutputTime = os.path.getmtime(Output)\r | |
352 | if GenFdsGlobalVariable.FdfFileTimeStamp > OutputTime:\r | |
353 | return True\r | |
354 | \r | |
355 | for F in Input:\r | |
356 | # always update "Output" if any "Input" doesn't exist\r | |
357 | if not os.path.exists(F):\r | |
358 | return True\r | |
359 | # always update "Output" if any "Input" is newer than "Output"\r | |
360 | if os.path.getmtime(F) > OutputTime:\r | |
361 | return True\r | |
362 | return False\r | |
363 | \r | |
364 | @staticmethod\r | |
365 | def GenerateSection(Output, Input, Type=None, CompressionType=None, Guid=None,\r | |
366 | GuidHdrLen=None, GuidAttr=[], Ui=None, Ver=None, InputAlign=None, BuildNumber=None):\r | |
367 | Cmd = ["GenSec"]\r | |
368 | if Type not in [None, '']:\r | |
369 | Cmd += ["-s", Type]\r | |
370 | if CompressionType not in [None, '']:\r | |
371 | Cmd += ["-c", CompressionType]\r | |
372 | if Guid != None:\r | |
373 | Cmd += ["-g", Guid]\r | |
374 | if GuidHdrLen not in [None, '']:\r | |
375 | Cmd += ["-l", GuidHdrLen]\r | |
376 | if len(GuidAttr) != 0:\r | |
377 | #Add each guided attribute\r | |
378 | for Attr in GuidAttr:\r | |
379 | Cmd += ["-r", Attr]\r | |
380 | if InputAlign != None:\r | |
381 | #Section Align is only for dummy section without section type\r | |
382 | for SecAlign in InputAlign:\r | |
383 | Cmd += ["--sectionalign", SecAlign]\r | |
384 | \r | |
385 | CommandFile = Output + '.txt'\r | |
386 | if Ui not in [None, '']:\r | |
387 | #Cmd += ["-n", '"' + Ui + '"']\r | |
47fea6af | 388 | SectionData = array.array('B', [0, 0, 0, 0])\r |
f51461c8 LG |
389 | SectionData.fromstring(Ui.encode("utf_16_le"))\r |
390 | SectionData.append(0)\r | |
391 | SectionData.append(0)\r | |
392 | Len = len(SectionData)\r | |
393 | GenFdsGlobalVariable.SectionHeader.pack_into(SectionData, 0, Len & 0xff, (Len >> 8) & 0xff, (Len >> 16) & 0xff, 0x15)\r | |
47fea6af | 394 | SaveFileOnChange(Output, SectionData.tostring())\r |
f51461c8 LG |
395 | elif Ver not in [None, '']:\r |
396 | Cmd += ["-n", Ver]\r | |
397 | if BuildNumber:\r | |
398 | Cmd += ["-j", BuildNumber]\r | |
399 | Cmd += ["-o", Output]\r | |
400 | \r | |
401 | SaveFileOnChange(CommandFile, ' '.join(Cmd), False)\r | |
402 | if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):\r | |
403 | return\r | |
404 | \r | |
405 | GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section")\r | |
406 | else:\r | |
407 | Cmd += ["-o", Output]\r | |
408 | Cmd += Input\r | |
409 | \r | |
410 | SaveFileOnChange(CommandFile, ' '.join(Cmd), False)\r | |
411 | if GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):\r | |
412 | GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))\r | |
413 | GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section")\r | |
414 | \r | |
415 | if (os.path.getsize(Output) >= GenFdsGlobalVariable.LARGE_FILE_SIZE and\r | |
416 | GenFdsGlobalVariable.LargeFileInFvFlags):\r | |
417 | GenFdsGlobalVariable.LargeFileInFvFlags[-1] = True \r | |
418 | \r | |
419 | @staticmethod\r | |
420 | def GetAlignment (AlignString):\r | |
421 | if AlignString == None:\r | |
422 | return 0\r | |
52302d4d LG |
423 | if AlignString in ("1K", "2K", "4K", "8K", "16K", "32K", "64K"):\r |
424 | return int (AlignString.rstrip('K')) * 1024\r | |
425 | else:\r | |
426 | return int (AlignString)\r | |
f51461c8 LG |
427 | \r |
428 | @staticmethod\r | |
429 | def GenerateFfs(Output, Input, Type, Guid, Fixed=False, CheckSum=False, Align=None,\r | |
430 | SectionAlign=None):\r | |
431 | Cmd = ["GenFfs", "-t", Type, "-g", Guid]\r | |
432 | if Fixed == True:\r | |
433 | Cmd += ["-x"]\r | |
434 | if CheckSum:\r | |
435 | Cmd += ["-s"]\r | |
436 | if Align not in [None, '']:\r | |
437 | Cmd += ["-a", Align]\r | |
438 | \r | |
439 | Cmd += ["-o", Output]\r | |
440 | for I in range(0, len(Input)):\r | |
441 | Cmd += ("-i", Input[I])\r | |
442 | if SectionAlign not in [None, '', []] and SectionAlign[I] not in [None, '']:\r | |
443 | Cmd += ("-n", SectionAlign[I])\r | |
444 | \r | |
445 | CommandFile = Output + '.txt'\r | |
446 | SaveFileOnChange(CommandFile, ' '.join(Cmd), False)\r | |
447 | if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):\r | |
448 | return\r | |
449 | GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))\r | |
450 | \r | |
451 | GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FFS")\r | |
452 | \r | |
453 | @staticmethod\r | |
454 | def GenerateFirmwareVolume(Output, Input, BaseAddress=None, ForceRebase=None, Capsule=False, Dump=False,\r | |
455 | AddressFile=None, MapFile=None, FfsList=[], FileSystemGuid=None):\r | |
456 | if not GenFdsGlobalVariable.NeedsUpdate(Output, Input+FfsList):\r | |
457 | return\r | |
458 | GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))\r | |
459 | \r | |
460 | Cmd = ["GenFv"]\r | |
461 | if BaseAddress not in [None, '']:\r | |
462 | Cmd += ["-r", BaseAddress]\r | |
47fea6af | 463 | \r |
f51461c8 | 464 | if ForceRebase == False:\r |
47fea6af | 465 | Cmd += ["-F", "FALSE"]\r |
f51461c8 | 466 | elif ForceRebase == True:\r |
47fea6af YZ |
467 | Cmd += ["-F", "TRUE"]\r |
468 | \r | |
f51461c8 LG |
469 | if Capsule:\r |
470 | Cmd += ["-c"]\r | |
471 | if Dump:\r | |
472 | Cmd += ["-p"]\r | |
473 | if AddressFile not in [None, '']:\r | |
474 | Cmd += ["-a", AddressFile]\r | |
475 | if MapFile not in [None, '']:\r | |
476 | Cmd += ["-m", MapFile]\r | |
477 | if FileSystemGuid:\r | |
478 | Cmd += ["-g", FileSystemGuid]\r | |
479 | Cmd += ["-o", Output]\r | |
480 | for I in Input:\r | |
481 | Cmd += ["-i", I]\r | |
482 | \r | |
483 | GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FV")\r | |
484 | \r | |
485 | @staticmethod\r | |
486 | def GenerateVtf(Output, Input, BaseAddress=None, FvSize=None):\r | |
487 | if not GenFdsGlobalVariable.NeedsUpdate(Output, Input):\r | |
488 | return\r | |
489 | GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))\r | |
490 | \r | |
491 | Cmd = ["GenVtf"]\r | |
492 | if BaseAddress not in [None, ''] and FvSize not in [None, ''] \\r | |
493 | and len(BaseAddress) == len(FvSize):\r | |
494 | for I in range(0, len(BaseAddress)):\r | |
495 | Cmd += ["-r", BaseAddress[I], "-s", FvSize[I]]\r | |
496 | Cmd += ["-o", Output]\r | |
497 | for F in Input:\r | |
498 | Cmd += ["-f", F]\r | |
499 | \r | |
500 | GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate VTF")\r | |
501 | \r | |
502 | @staticmethod\r | |
503 | def GenerateFirmwareImage(Output, Input, Type="efi", SubType=None, Zero=False,\r | |
504 | Strip=False, Replace=False, TimeStamp=None, Join=False,\r | |
505 | Align=None, Padding=None, Convert=False):\r | |
506 | if not GenFdsGlobalVariable.NeedsUpdate(Output, Input):\r | |
507 | return\r | |
508 | GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))\r | |
509 | \r | |
510 | Cmd = ["GenFw"]\r | |
511 | if Type.lower() == "te":\r | |
512 | Cmd += ["-t"]\r | |
513 | if SubType not in [None, '']:\r | |
514 | Cmd += ["-e", SubType]\r | |
515 | if TimeStamp not in [None, '']:\r | |
516 | Cmd += ["-s", TimeStamp]\r | |
517 | if Align not in [None, '']:\r | |
518 | Cmd += ["-a", Align]\r | |
519 | if Padding not in [None, '']:\r | |
520 | Cmd += ["-p", Padding]\r | |
521 | if Zero:\r | |
522 | Cmd += ["-z"]\r | |
523 | if Strip:\r | |
524 | Cmd += ["-l"]\r | |
525 | if Replace:\r | |
526 | Cmd += ["-r"]\r | |
527 | if Join:\r | |
528 | Cmd += ["-j"]\r | |
529 | if Convert:\r | |
530 | Cmd += ["-m"]\r | |
531 | Cmd += ["-o", Output]\r | |
532 | Cmd += Input\r | |
533 | \r | |
534 | GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate firmware image")\r | |
535 | \r | |
536 | @staticmethod\r | |
537 | def GenerateOptionRom(Output, EfiInput, BinaryInput, Compress=False, ClassCode=None,\r | |
538 | Revision=None, DeviceId=None, VendorId=None):\r | |
539 | InputList = [] \r | |
540 | Cmd = ["EfiRom"]\r | |
541 | if len(EfiInput) > 0:\r | |
542 | \r | |
543 | if Compress:\r | |
544 | Cmd += ["-ec"]\r | |
545 | else:\r | |
546 | Cmd += ["-e"]\r | |
547 | \r | |
548 | for EfiFile in EfiInput:\r | |
549 | Cmd += [EfiFile]\r | |
550 | InputList.append (EfiFile)\r | |
551 | \r | |
552 | if len(BinaryInput) > 0:\r | |
553 | Cmd += ["-b"]\r | |
554 | for BinFile in BinaryInput:\r | |
555 | Cmd += [BinFile]\r | |
556 | InputList.append (BinFile)\r | |
557 | \r | |
558 | # Check List\r | |
559 | if not GenFdsGlobalVariable.NeedsUpdate(Output, InputList):\r | |
560 | return\r | |
561 | GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, InputList))\r | |
562 | \r | |
563 | if ClassCode != None:\r | |
564 | Cmd += ["-l", ClassCode]\r | |
565 | if Revision != None:\r | |
566 | Cmd += ["-r", Revision]\r | |
567 | if DeviceId != None:\r | |
568 | Cmd += ["-i", DeviceId]\r | |
569 | if VendorId != None:\r | |
570 | Cmd += ["-f", VendorId]\r | |
571 | \r | |
47fea6af | 572 | Cmd += ["-o", Output]\r |
f51461c8 LG |
573 | GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate option rom")\r |
574 | \r | |
575 | @staticmethod\r | |
576 | def GuidTool(Output, Input, ToolPath, Options='', returnValue=[]):\r | |
577 | if not GenFdsGlobalVariable.NeedsUpdate(Output, Input):\r | |
578 | return\r | |
579 | GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))\r | |
580 | \r | |
581 | Cmd = [ToolPath, ]\r | |
582 | Cmd += Options.split(' ')\r | |
583 | Cmd += ["-o", Output]\r | |
584 | Cmd += Input\r | |
585 | \r | |
586 | GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to call " + ToolPath, returnValue)\r | |
587 | \r | |
588 | def CallExternalTool (cmd, errorMess, returnValue=[]):\r | |
589 | \r | |
590 | if type(cmd) not in (tuple, list):\r | |
591 | GenFdsGlobalVariable.ErrorLogger("ToolError! Invalid parameter type in call to CallExternalTool")\r | |
592 | \r | |
593 | if GenFdsGlobalVariable.DebugLevel != -1:\r | |
594 | cmd += ('--debug', str(GenFdsGlobalVariable.DebugLevel))\r | |
595 | GenFdsGlobalVariable.InfLogger (cmd)\r | |
596 | \r | |
597 | if GenFdsGlobalVariable.VerboseMode:\r | |
598 | cmd += ('-v',)\r | |
599 | GenFdsGlobalVariable.InfLogger (cmd)\r | |
600 | else:\r | |
601 | sys.stdout.write ('#')\r | |
602 | sys.stdout.flush()\r | |
603 | GenFdsGlobalVariable.SharpCounter = GenFdsGlobalVariable.SharpCounter + 1\r | |
604 | if GenFdsGlobalVariable.SharpCounter % GenFdsGlobalVariable.SharpNumberPerLine == 0:\r | |
605 | sys.stdout.write('\n')\r | |
606 | \r | |
607 | try:\r | |
47fea6af | 608 | PopenObject = subprocess.Popen(' '.join(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)\r |
f51461c8 LG |
609 | except Exception, X:\r |
610 | EdkLogger.error("GenFds", COMMAND_FAILURE, ExtraData="%s: %s" % (str(X), cmd[0]))\r | |
611 | (out, error) = PopenObject.communicate()\r | |
612 | \r | |
613 | while PopenObject.returncode == None :\r | |
614 | PopenObject.wait()\r | |
615 | if returnValue != [] and returnValue[0] != 0:\r | |
616 | #get command return value\r | |
617 | returnValue[0] = PopenObject.returncode\r | |
618 | return\r | |
619 | if PopenObject.returncode != 0 or GenFdsGlobalVariable.VerboseMode or GenFdsGlobalVariable.DebugLevel != -1:\r | |
47fea6af | 620 | GenFdsGlobalVariable.InfLogger ("Return Value = %d" % PopenObject.returncode)\r |
f51461c8 LG |
621 | GenFdsGlobalVariable.InfLogger (out)\r |
622 | GenFdsGlobalVariable.InfLogger (error)\r | |
623 | if PopenObject.returncode != 0:\r | |
624 | print "###", cmd\r | |
625 | EdkLogger.error("GenFds", COMMAND_FAILURE, errorMess)\r | |
626 | \r | |
627 | def VerboseLogger (msg):\r | |
628 | EdkLogger.verbose(msg)\r | |
629 | \r | |
630 | def InfLogger (msg):\r | |
631 | EdkLogger.info(msg)\r | |
632 | \r | |
47fea6af | 633 | def ErrorLogger (msg, File=None, Line=None, ExtraData=None):\r |
f51461c8 LG |
634 | EdkLogger.error('GenFds', GENFDS_ERROR, msg, File, Line, ExtraData)\r |
635 | \r | |
636 | def DebugLogger (Level, msg):\r | |
637 | EdkLogger.debug(Level, msg)\r | |
638 | \r | |
639 | ## ReplaceWorkspaceMacro()\r | |
640 | #\r | |
641 | # @param Str String that may contain macro\r | |
642 | # @param MacroDict Dictionary that contains macro value pair\r | |
643 | #\r | |
47fea6af | 644 | def MacroExtend (Str, MacroDict={}, Arch='COMMON'):\r |
f51461c8 LG |
645 | if Str == None :\r |
646 | return None\r | |
647 | \r | |
648 | Dict = {'$(WORKSPACE)' : GenFdsGlobalVariable.WorkSpaceDir,\r | |
649 | '$(EDK_SOURCE)' : GenFdsGlobalVariable.EdkSourceDir,\r | |
650 | # '$(OUTPUT_DIRECTORY)': GenFdsGlobalVariable.OutputDirFromDsc,\r | |
651 | '$(TARGET)' : GenFdsGlobalVariable.TargetName,\r | |
97fa0ee9 YL |
652 | '$(TOOL_CHAIN_TAG)' : GenFdsGlobalVariable.ToolChainTag,\r |
653 | '$(SPACE)' : ' '\r | |
f51461c8 LG |
654 | }\r |
655 | OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[GenFdsGlobalVariable.ArchList[0]]\r | |
656 | if Arch != 'COMMON' and Arch in GenFdsGlobalVariable.ArchList:\r | |
657 | OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[Arch]\r | |
658 | \r | |
659 | Dict['$(OUTPUT_DIRECTORY)'] = OutputDir\r | |
660 | \r | |
661 | if MacroDict != None and len (MacroDict) != 0:\r | |
662 | Dict.update(MacroDict)\r | |
663 | \r | |
664 | for key in Dict.keys():\r | |
665 | if Str.find(key) >= 0 :\r | |
666 | Str = Str.replace (key, Dict[key])\r | |
667 | \r | |
668 | if Str.find('$(ARCH)') >= 0:\r | |
669 | if len(GenFdsGlobalVariable.ArchList) == 1:\r | |
670 | Str = Str.replace('$(ARCH)', GenFdsGlobalVariable.ArchList[0])\r | |
671 | else:\r | |
672 | EdkLogger.error("GenFds", GENFDS_ERROR, "No way to determine $(ARCH) for %s" % Str)\r | |
673 | \r | |
674 | return Str\r | |
675 | \r | |
676 | ## GetPcdValue()\r | |
677 | #\r | |
678 | # @param PcdPattern pattern that labels a PCD.\r | |
679 | #\r | |
680 | def GetPcdValue (PcdPattern):\r | |
681 | if PcdPattern == None :\r | |
682 | return None\r | |
683 | PcdPair = PcdPattern.lstrip('PCD(').rstrip(')').strip().split('.')\r | |
684 | TokenSpace = PcdPair[0]\r | |
685 | TokenCName = PcdPair[1]\r | |
686 | \r | |
687 | PcdValue = ''\r | |
688 | for Arch in GenFdsGlobalVariable.ArchList:\r | |
689 | Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r | |
690 | PcdDict = Platform.Pcds\r | |
691 | for Key in PcdDict:\r | |
692 | PcdObj = PcdDict[Key]\r | |
693 | if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace):\r | |
694 | if PcdObj.Type != 'FixedAtBuild':\r | |
695 | EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern)\r | |
696 | if PcdObj.DatumType != 'VOID*':\r | |
697 | EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern)\r | |
698 | \r | |
699 | PcdValue = PcdObj.DefaultValue\r | |
700 | return PcdValue\r | |
47fea6af YZ |
701 | \r |
702 | for Package in GenFdsGlobalVariable.WorkSpace.GetPackageList(GenFdsGlobalVariable.ActivePlatform,\r | |
703 | Arch,\r | |
704 | GenFdsGlobalVariable.TargetName,\r | |
f51461c8 LG |
705 | GenFdsGlobalVariable.ToolChainTag):\r |
706 | PcdDict = Package.Pcds\r | |
707 | for Key in PcdDict:\r | |
708 | PcdObj = PcdDict[Key]\r | |
709 | if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace):\r | |
710 | if PcdObj.Type != 'FixedAtBuild':\r | |
711 | EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern)\r | |
712 | if PcdObj.DatumType != 'VOID*':\r | |
713 | EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern)\r | |
714 | \r | |
715 | PcdValue = PcdObj.DefaultValue\r | |
716 | return PcdValue\r | |
717 | \r | |
718 | return PcdValue\r | |
719 | \r | |
720 | SetDir = staticmethod(SetDir)\r | |
721 | ReplaceWorkspaceMacro = staticmethod(ReplaceWorkspaceMacro)\r | |
722 | CallExternalTool = staticmethod(CallExternalTool)\r | |
723 | VerboseLogger = staticmethod(VerboseLogger)\r | |
724 | InfLogger = staticmethod(InfLogger)\r | |
725 | ErrorLogger = staticmethod(ErrorLogger)\r | |
726 | DebugLogger = staticmethod(DebugLogger)\r | |
727 | MacroExtend = staticmethod (MacroExtend)\r | |
728 | GetPcdValue = staticmethod(GetPcdValue)\r |