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