2 # Global variables for GenFds
4 # Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
6 # This program and the accompanying materials
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
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.
18 from __future__
import print_function
19 import Common
.LongFilePathOs
as os
25 from Common
.BuildToolError
import *
26 from Common
import EdkLogger
27 from Common
.Misc
import SaveFileOnChange
29 from Common
.TargetTxtClassObject
import TargetTxtClassObject
30 from Common
.ToolDefClassObject
import ToolDefClassObject
31 from AutoGen
.BuildEngine
import BuildRule
32 import Common
.DataType
as DataType
33 from Common
.Misc
import PathClass
34 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
35 from Common
.MultipleWorkspace
import MultipleWorkspace
as mws
40 class GenFdsGlobalVariable
:
44 # will be FvDir + os.sep + 'Ffs'
52 OutputDirFromDscDict
= {}
59 FvAddressFileName
= ''
63 SharpNumberPerLine
= 40
66 FixedLoadAddress
= False
69 BuildRuleFamily
= "MSFT"
70 ToolChainFamily
= "MSFT"
71 __BuildRuleDatabase
= None
72 GuidToolDefinition
= {}
77 EnableGenfdsMultiThread
= False
80 # The list whose element are flags to indicate if large FFS or SECTION files exist in FV.
81 # At the beginning of each generation of FV, false flag is appended to the list,
82 # after the call to GenerateSection returns, check the size of the output file,
83 # if it is greater than 0xFFFFFF, the tail flag in list is set to true,
84 # and EFI_FIRMWARE_FILE_SYSTEM3_GUID is passed to C GenFv.
85 # At the end of generation of FV, pop the flag.
86 # List is used as a stack to handle nested FV generation.
88 LargeFileInFvFlags
= []
89 EFI_FIRMWARE_FILE_SYSTEM3_GUID
= '5473C07A-3DCB-4dca-BD6F-1E9689E7349A'
90 LARGE_FILE_SIZE
= 0x1000000
92 SectionHeader
= struct
.Struct("3B 1B")
97 def __LoadBuildRule():
98 if GenFdsGlobalVariable
.__BuildRuleDatabase
:
99 return GenFdsGlobalVariable
.__BuildRuleDatabase
100 BuildConfigurationFile
= os
.path
.normpath(os
.path
.join(GenFdsGlobalVariable
.ConfDir
, "target.txt"))
101 TargetTxt
= TargetTxtClassObject()
102 if os
.path
.isfile(BuildConfigurationFile
) == True:
103 TargetTxt
.LoadTargetTxtFile(BuildConfigurationFile
)
104 if DataType
.TAB_TAT_DEFINES_BUILD_RULE_CONF
in TargetTxt
.TargetTxtDictionary
:
105 BuildRuleFile
= TargetTxt
.TargetTxtDictionary
[DataType
.TAB_TAT_DEFINES_BUILD_RULE_CONF
]
106 if not BuildRuleFile
:
107 BuildRuleFile
= 'Conf/build_rule.txt'
108 GenFdsGlobalVariable
.__BuildRuleDatabase
= BuildRule(BuildRuleFile
)
109 ToolDefinitionFile
= TargetTxt
.TargetTxtDictionary
[DataType
.TAB_TAT_DEFINES_TOOL_CHAIN_CONF
]
110 if ToolDefinitionFile
== '':
111 ToolDefinitionFile
= "Conf/tools_def.txt"
112 if os
.path
.isfile(ToolDefinitionFile
):
113 ToolDef
= ToolDefClassObject()
114 ToolDef
.LoadToolDefFile(ToolDefinitionFile
)
115 ToolDefinition
= ToolDef
.ToolsDefTxtDatabase
116 if DataType
.TAB_TOD_DEFINES_BUILDRULEFAMILY
in ToolDefinition \
117 and GenFdsGlobalVariable
.ToolChainTag
in ToolDefinition
[DataType
.TAB_TOD_DEFINES_BUILDRULEFAMILY
] \
118 and ToolDefinition
[DataType
.TAB_TOD_DEFINES_BUILDRULEFAMILY
][GenFdsGlobalVariable
.ToolChainTag
]:
119 GenFdsGlobalVariable
.BuildRuleFamily
= ToolDefinition
[DataType
.TAB_TOD_DEFINES_BUILDRULEFAMILY
][GenFdsGlobalVariable
.ToolChainTag
]
121 if DataType
.TAB_TOD_DEFINES_FAMILY
in ToolDefinition \
122 and GenFdsGlobalVariable
.ToolChainTag
in ToolDefinition
[DataType
.TAB_TOD_DEFINES_FAMILY
] \
123 and ToolDefinition
[DataType
.TAB_TOD_DEFINES_FAMILY
][GenFdsGlobalVariable
.ToolChainTag
]:
124 GenFdsGlobalVariable
.ToolChainFamily
= ToolDefinition
[DataType
.TAB_TOD_DEFINES_FAMILY
][GenFdsGlobalVariable
.ToolChainTag
]
125 return GenFdsGlobalVariable
.__BuildRuleDatabase
128 # @param Inf: object of InfBuildData
129 # @param Arch: current arch
132 def GetBuildRules(Inf
, Arch
):
134 Arch
= DataType
.TAB_COMMON
136 if not Arch
in GenFdsGlobalVariable
.OutputDirDict
:
139 BuildRuleDatabase
= GenFdsGlobalVariable
.__LoadBuildRule
()
140 if not BuildRuleDatabase
:
143 PathClassObj
= PathClass(Inf
.MetaFile
.File
,
144 GenFdsGlobalVariable
.WorkSpaceDir
)
146 Macro
["WORKSPACE" ] = GenFdsGlobalVariable
.WorkSpaceDir
147 Macro
["MODULE_NAME" ] = Inf
.BaseName
148 Macro
["MODULE_GUID" ] = Inf
.Guid
149 Macro
["MODULE_VERSION" ] = Inf
.Version
150 Macro
["MODULE_TYPE" ] = Inf
.ModuleType
151 Macro
["MODULE_FILE" ] = str(PathClassObj
)
152 Macro
["MODULE_FILE_BASE_NAME" ] = PathClassObj
.BaseName
153 Macro
["MODULE_RELATIVE_DIR" ] = PathClassObj
.SubDir
154 Macro
["MODULE_DIR" ] = PathClassObj
.SubDir
156 Macro
["BASE_NAME" ] = Inf
.BaseName
158 Macro
["ARCH" ] = Arch
159 Macro
["TOOLCHAIN" ] = GenFdsGlobalVariable
.ToolChainTag
160 Macro
["TOOLCHAIN_TAG" ] = GenFdsGlobalVariable
.ToolChainTag
161 Macro
["TOOL_CHAIN_TAG" ] = GenFdsGlobalVariable
.ToolChainTag
162 Macro
["TARGET" ] = GenFdsGlobalVariable
.TargetName
164 Macro
["BUILD_DIR" ] = GenFdsGlobalVariable
.OutputDirDict
[Arch
]
165 Macro
["BIN_DIR" ] = os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[Arch
], Arch
)
166 Macro
["LIB_DIR" ] = os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[Arch
], Arch
)
167 BuildDir
= os
.path
.join(
168 GenFdsGlobalVariable
.OutputDirDict
[Arch
],
171 PathClassObj
.BaseName
173 Macro
["MODULE_BUILD_DIR" ] = BuildDir
174 Macro
["OUTPUT_DIR" ] = os
.path
.join(BuildDir
, "OUTPUT")
175 Macro
["DEBUG_DIR" ] = os
.path
.join(BuildDir
, "DEBUG")
178 for Type
in BuildRuleDatabase
.FileTypeList
:
179 #first try getting build rule by BuildRuleFamily
180 RuleObject
= BuildRuleDatabase
[Type
, Inf
.BuildType
, Arch
, GenFdsGlobalVariable
.BuildRuleFamily
]
182 # build type is always module type, but ...
183 if Inf
.ModuleType
!= Inf
.BuildType
:
184 RuleObject
= BuildRuleDatabase
[Type
, Inf
.ModuleType
, Arch
, GenFdsGlobalVariable
.BuildRuleFamily
]
185 #second try getting build rule by ToolChainFamily
187 RuleObject
= BuildRuleDatabase
[Type
, Inf
.BuildType
, Arch
, GenFdsGlobalVariable
.ToolChainFamily
]
189 # build type is always module type, but ...
190 if Inf
.ModuleType
!= Inf
.BuildType
:
191 RuleObject
= BuildRuleDatabase
[Type
, Inf
.ModuleType
, Arch
, GenFdsGlobalVariable
.ToolChainFamily
]
194 RuleObject
= RuleObject
.Instantiate(Macro
)
195 BuildRules
[Type
] = RuleObject
196 for Ext
in RuleObject
.SourceFileExtList
:
197 BuildRules
[Ext
] = RuleObject
200 ## GetModuleCodaTargetList
202 # @param Inf: object of InfBuildData
203 # @param Arch: current arch
206 def GetModuleCodaTargetList(Inf
, Arch
):
207 BuildRules
= GenFdsGlobalVariable
.GetBuildRules(Inf
, Arch
)
214 if not Inf
.IsBinaryModule
:
215 for File
in Inf
.Sources
:
216 if File
.TagName
in ("", "*", GenFdsGlobalVariable
.ToolChainTag
) and \
217 File
.ToolChainFamily
in ("", "*", GenFdsGlobalVariable
.ToolChainFamily
):
218 FileList
.append((File
, DataType
.TAB_UNKNOWN_FILE
))
220 for File
in Inf
.Binaries
:
221 if File
.Target
in [DataType
.TAB_COMMON
, '*', GenFdsGlobalVariable
.TargetName
]:
222 FileList
.append((File
, File
.Type
))
224 for File
, FileType
in FileList
:
229 while Index
< len(SourceList
):
230 Source
= SourceList
[Index
]
233 if File
.IsBinary
and File
== Source
and Inf
.Binaries
is not None and File
in Inf
.Binaries
:
234 # Skip all files that are not binary libraries
235 if not Inf
.LibraryClass
:
237 RuleObject
= BuildRules
[DataType
.TAB_DEFAULT_BINARY_FILE
]
238 elif FileType
in BuildRules
:
239 RuleObject
= BuildRules
[FileType
]
240 elif Source
.Ext
in BuildRules
:
241 RuleObject
= BuildRules
[Source
.Ext
]
243 # stop at no more rules
245 TargetList
.add(str(LastTarget
))
248 FileType
= RuleObject
.SourceFileType
250 # stop at STATIC_LIBRARY for library
251 if Inf
.LibraryClass
and FileType
== DataType
.TAB_STATIC_LIBRARY
:
253 TargetList
.add(str(LastTarget
))
256 Target
= RuleObject
.Apply(Source
)
259 TargetList
.add(str(LastTarget
))
261 elif not Target
.Outputs
:
262 # Only do build for target with outputs
263 TargetList
.add(str(Target
))
265 # to avoid cyclic rule
266 if FileType
in RuleChain
:
269 RuleChain
.append(FileType
)
270 SourceList
.extend(Target
.Outputs
)
272 FileType
= DataType
.TAB_UNKNOWN_FILE
273 for Cmd
in Target
.Commands
:
274 if "$(CP)" == Cmd
.split()[0]:
275 CpTarget
= Cmd
.split()[2]
276 TargetList
.add(CpTarget
)
278 return list(TargetList
)
282 # @param OutputDir Output directory
283 # @param FdfParser FDF contents parser
284 # @param Workspace The directory of workspace
285 # @param ArchList The Arch list of platform
287 def SetDir (OutputDir
, FdfParser
, WorkSpace
, ArchList
):
288 GenFdsGlobalVariable
.VerboseLogger("GenFdsGlobalVariable.OutputDir :%s" % OutputDir
)
289 # GenFdsGlobalVariable.OutputDirDict = OutputDir
290 GenFdsGlobalVariable
.FdfParser
= FdfParser
291 GenFdsGlobalVariable
.WorkSpace
= WorkSpace
292 GenFdsGlobalVariable
.FvDir
= os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[ArchList
[0]], DataType
.TAB_FV_DIRECTORY
)
293 if not os
.path
.exists(GenFdsGlobalVariable
.FvDir
) :
294 os
.makedirs(GenFdsGlobalVariable
.FvDir
)
295 GenFdsGlobalVariable
.FfsDir
= os
.path
.join(GenFdsGlobalVariable
.FvDir
, 'Ffs')
296 if not os
.path
.exists(GenFdsGlobalVariable
.FfsDir
) :
297 os
.makedirs(GenFdsGlobalVariable
.FfsDir
)
301 # Create FV Address inf file
303 GenFdsGlobalVariable
.FvAddressFileName
= os
.path
.join(GenFdsGlobalVariable
.FfsDir
, 'FvAddress.inf')
304 FvAddressFile
= open(GenFdsGlobalVariable
.FvAddressFileName
, 'w')
308 FvAddressFile
.writelines("[options]" + T_CHAR_LF
)
310 for Arch
in ArchList
:
311 if GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
].BsBaseAddress
:
312 BsAddress
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
].BsBaseAddress
315 FvAddressFile
.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \
320 for Arch
in ArchList
:
321 if GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
].RtBaseAddress
:
322 RtAddress
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
].RtBaseAddress
324 FvAddressFile
.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \
328 FvAddressFile
.close()
330 def SetEnv(FdfParser
, WorkSpace
, ArchList
, GlobalData
):
331 GenFdsGlobalVariable
.ModuleFile
= WorkSpace
.ModuleFile
332 GenFdsGlobalVariable
.FdfParser
= FdfParser
333 GenFdsGlobalVariable
.WorkSpace
= WorkSpace
.Db
334 GenFdsGlobalVariable
.ArchList
= ArchList
335 GenFdsGlobalVariable
.ToolChainTag
= GlobalData
.gGlobalDefines
["TOOL_CHAIN_TAG"]
336 GenFdsGlobalVariable
.TargetName
= GlobalData
.gGlobalDefines
["TARGET"]
337 GenFdsGlobalVariable
.ActivePlatform
= GlobalData
.gActivePlatform
338 GenFdsGlobalVariable
.EdkSourceDir
= GlobalData
.gGlobalDefines
["EDK_SOURCE"]
339 GenFdsGlobalVariable
.ConfDir
= GlobalData
.gConfDirectory
340 GenFdsGlobalVariable
.EnableGenfdsMultiThread
= GlobalData
.gEnableGenfdsMultiThread
341 for Arch
in ArchList
:
342 GenFdsGlobalVariable
.OutputDirDict
[Arch
] = os
.path
.normpath(
343 os
.path
.join(GlobalData
.gWorkspace
,
344 WorkSpace
.Db
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
, GlobalData
.gGlobalDefines
['TARGET'],
345 GlobalData
.gGlobalDefines
['TOOLCHAIN']].OutputDirectory
,
346 GlobalData
.gGlobalDefines
['TARGET'] +'_' + GlobalData
.gGlobalDefines
['TOOLCHAIN']))
347 GenFdsGlobalVariable
.OutputDirFromDscDict
[Arch
] = os
.path
.normpath(
348 WorkSpace
.Db
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
,
349 GlobalData
.gGlobalDefines
['TARGET'], GlobalData
.gGlobalDefines
['TOOLCHAIN']].OutputDirectory
)
350 GenFdsGlobalVariable
.PlatformName
= WorkSpace
.Db
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
,
351 GlobalData
.gGlobalDefines
['TARGET'],
352 GlobalData
.gGlobalDefines
['TOOLCHAIN']].PlatformName
353 GenFdsGlobalVariable
.FvDir
= os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[ArchList
[0]], DataType
.TAB_FV_DIRECTORY
)
354 if not os
.path
.exists(GenFdsGlobalVariable
.FvDir
):
355 os
.makedirs(GenFdsGlobalVariable
.FvDir
)
356 GenFdsGlobalVariable
.FfsDir
= os
.path
.join(GenFdsGlobalVariable
.FvDir
, 'Ffs')
357 if not os
.path
.exists(GenFdsGlobalVariable
.FfsDir
):
358 os
.makedirs(GenFdsGlobalVariable
.FfsDir
)
362 # Create FV Address inf file
364 GenFdsGlobalVariable
.FvAddressFileName
= os
.path
.join(GenFdsGlobalVariable
.FfsDir
, 'FvAddress.inf')
365 FvAddressFile
= open(GenFdsGlobalVariable
.FvAddressFileName
, 'w')
369 FvAddressFile
.writelines("[options]" + T_CHAR_LF
)
371 for Arch
in ArchList
:
372 BsAddress
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
,
373 GlobalData
.gGlobalDefines
['TARGET'],
374 GlobalData
.gGlobalDefines
["TOOL_CHAIN_TAG"]].BsBaseAddress
378 FvAddressFile
.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \
383 for Arch
in ArchList
:
384 if GenFdsGlobalVariable
.WorkSpace
.BuildObject
[
385 GenFdsGlobalVariable
.ActivePlatform
, Arch
, GlobalData
.gGlobalDefines
['TARGET'],
386 GlobalData
.gGlobalDefines
["TOOL_CHAIN_TAG"]].RtBaseAddress
:
387 RtAddress
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[
388 GenFdsGlobalVariable
.ActivePlatform
, Arch
, GlobalData
.gGlobalDefines
['TARGET'],
389 GlobalData
.gGlobalDefines
["TOOL_CHAIN_TAG"]].RtBaseAddress
391 FvAddressFile
.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \
395 FvAddressFile
.close()
397 ## ReplaceWorkspaceMacro()
399 # @param String String that may contain macro
401 def ReplaceWorkspaceMacro(String
):
402 String
= mws
.handleWsMacro(String
)
403 Str
= String
.replace('$(WORKSPACE)', GenFdsGlobalVariable
.WorkSpaceDir
)
404 if os
.path
.exists(Str
):
405 if not os
.path
.isabs(Str
):
406 Str
= os
.path
.abspath(Str
)
408 Str
= mws
.join(GenFdsGlobalVariable
.WorkSpaceDir
, String
)
409 return os
.path
.normpath(Str
)
411 ## Check if the input files are newer than output files
413 # @param Output Path of output file
414 # @param Input Path list of input files
416 # @retval True if Output doesn't exist, or any Input is newer
417 # @retval False if all Input is older than Output
420 def NeedsUpdate(Output
, Input
):
421 if not os
.path
.exists(Output
):
423 # always update "Output" if no "Input" given
424 if Input
is None or len(Input
) == 0:
427 # if fdf file is changed after the 'Output" is generated, update the 'Output'
428 OutputTime
= os
.path
.getmtime(Output
)
429 if GenFdsGlobalVariable
.FdfFileTimeStamp
> OutputTime
:
433 # always update "Output" if any "Input" doesn't exist
434 if not os
.path
.exists(F
):
436 # always update "Output" if any "Input" is newer than "Output"
437 if os
.path
.getmtime(F
) > OutputTime
:
442 def GenerateSection(Output
, Input
, Type
=None, CompressionType
=None, Guid
=None,
443 GuidHdrLen
=None, GuidAttr
=[], Ui
=None, Ver
=None, InputAlign
=[], BuildNumber
=None, DummyFile
=None, IsMakefile
=False):
448 Cmd
+= ("-c", CompressionType
)
451 if DummyFile
is not None:
452 Cmd
+= ("--dummy", DummyFile
)
454 Cmd
+= ("-l", GuidHdrLen
)
455 #Add each guided attribute
456 for Attr
in GuidAttr
:
458 #Section Align is only for dummy section without section type
459 for SecAlign
in InputAlign
:
460 Cmd
+= ("--sectionalign", SecAlign
)
462 CommandFile
= Output
+ '.txt'
465 if Ui
== "$(MODULE_NAME)":
468 Cmd
+= ("-n", '"' + Ui
+ '"')
469 Cmd
+= ("-o", Output
)
470 if ' '.join(Cmd
).strip() not in GenFdsGlobalVariable
.SecCmdList
:
471 GenFdsGlobalVariable
.SecCmdList
.append(' '.join(Cmd
).strip())
473 SectionData
= array
.array('B', [0, 0, 0, 0])
474 SectionData
.fromstring(Ui
.encode("utf_16_le"))
475 SectionData
.append(0)
476 SectionData
.append(0)
477 Len
= len(SectionData
)
478 GenFdsGlobalVariable
.SectionHeader
.pack_into(SectionData
, 0, Len
& 0xff, (Len
>> 8) & 0xff, (Len
>> 16) & 0xff, 0x15)
479 SaveFileOnChange(Output
, SectionData
.tostring())
484 Cmd
+= ("-j", BuildNumber
)
485 Cmd
+= ("-o", Output
)
487 SaveFileOnChange(CommandFile
, ' '.join(Cmd
), False)
489 if ' '.join(Cmd
).strip() not in GenFdsGlobalVariable
.SecCmdList
:
490 GenFdsGlobalVariable
.SecCmdList
.append(' '.join(Cmd
).strip())
492 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, list(Input
) + [CommandFile
]):
494 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate section")
496 Cmd
+= ("-o", Output
)
499 SaveFileOnChange(CommandFile
, ' '.join(Cmd
), False)
501 if ' '.join(Cmd
).strip() not in GenFdsGlobalVariable
.SecCmdList
:
502 GenFdsGlobalVariable
.SecCmdList
.append(' '.join(Cmd
).strip())
503 elif GenFdsGlobalVariable
.NeedsUpdate(Output
, list(Input
) + [CommandFile
]):
504 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
505 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate section")
506 if (os
.path
.getsize(Output
) >= GenFdsGlobalVariable
.LARGE_FILE_SIZE
and
507 GenFdsGlobalVariable
.LargeFileInFvFlags
):
508 GenFdsGlobalVariable
.LargeFileInFvFlags
[-1] = True
511 def GetAlignment (AlignString
):
512 if AlignString
is None:
514 if AlignString
in ("1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K"):
515 return int (AlignString
.rstrip('K')) * 1024
516 elif AlignString
in ("1M", "2M", "4M", "8M", "16M"):
517 return int (AlignString
.rstrip('M')) * 1024 * 1024
519 return int (AlignString
)
522 def GenerateFfs(Output
, Input
, Type
, Guid
, Fixed
=False, CheckSum
=False, Align
=None,
523 SectionAlign
=None, MakefilePath
=None):
524 Cmd
= ["GenFfs", "-t", Type
, "-g", Guid
]
525 mFfsValidAlign
= ["0", "8", "16", "128", "512", "1K", "4K", "32K", "64K", "128K", "256K", "512K", "1M", "2M", "4M", "8M", "16M"]
531 if Align
not in mFfsValidAlign
:
532 Align
= GenFdsGlobalVariable
.GetAlignment (Align
)
533 for index
in range(0, len(mFfsValidAlign
) - 1):
534 if ((Align
> GenFdsGlobalVariable
.GetAlignment(mFfsValidAlign
[index
])) and (Align
<= GenFdsGlobalVariable
.GetAlignment(mFfsValidAlign
[index
+ 1]))):
536 Align
= mFfsValidAlign
[index
+ 1]
539 Cmd
+= ("-o", Output
)
540 for I
in range(0, len(Input
)):
541 Cmd
+= ("-i", Input
[I
])
542 if SectionAlign
and SectionAlign
[I
]:
543 Cmd
+= ("-n", SectionAlign
[I
])
545 CommandFile
= Output
+ '.txt'
546 SaveFileOnChange(CommandFile
, ' '.join(Cmd
), False)
548 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
550 if (tuple(Cmd
), tuple(GenFdsGlobalVariable
.SecCmdList
), tuple(GenFdsGlobalVariable
.CopyList
)) not in GenFdsGlobalVariable
.FfsCmdDict
:
551 GenFdsGlobalVariable
.FfsCmdDict
[tuple(Cmd
), tuple(GenFdsGlobalVariable
.SecCmdList
), tuple(GenFdsGlobalVariable
.CopyList
)] = MakefilePath
552 GenFdsGlobalVariable
.SecCmdList
= []
553 GenFdsGlobalVariable
.CopyList
= []
555 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, list(Input
) + [CommandFile
]):
557 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate FFS")
560 def GenerateFirmwareVolume(Output
, Input
, BaseAddress
=None, ForceRebase
=None, Capsule
=False, Dump
=False,
561 AddressFile
=None, MapFile
=None, FfsList
=[], FileSystemGuid
=None):
562 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, Input
+FfsList
):
564 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
568 Cmd
+= ("-r", BaseAddress
)
570 if ForceRebase
== False:
571 Cmd
+= ("-F", "FALSE")
572 elif ForceRebase
== True:
573 Cmd
+= ("-F", "TRUE")
580 Cmd
+= ("-a", AddressFile
)
582 Cmd
+= ("-m", MapFile
)
584 Cmd
+= ("-g", FileSystemGuid
)
585 Cmd
+= ("-o", Output
)
589 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate FV")
592 def GenerateVtf(Output
, Input
, BaseAddress
=None, FvSize
=None):
593 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, Input
):
595 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
598 if BaseAddress
and FvSize \
599 and len(BaseAddress
) == len(FvSize
):
600 for I
in range(0, len(BaseAddress
)):
601 Cmd
+= ("-r", BaseAddress
[I
], "-s", FvSize
[I
])
602 Cmd
+= ("-o", Output
)
606 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate VTF")
609 def GenerateFirmwareImage(Output
, Input
, Type
="efi", SubType
=None, Zero
=False,
610 Strip
=False, Replace
=False, TimeStamp
=None, Join
=False,
611 Align
=None, Padding
=None, Convert
=False, IsMakefile
=False):
612 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, Input
) and not IsMakefile
:
614 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
617 if Type
.lower() == "te":
620 Cmd
+= ("-e", SubType
)
622 Cmd
+= ("-s", TimeStamp
)
626 Cmd
+= ("-p", Padding
)
637 Cmd
+= ("-o", Output
)
640 if " ".join(Cmd
).strip() not in GenFdsGlobalVariable
.SecCmdList
:
641 GenFdsGlobalVariable
.SecCmdList
.append(" ".join(Cmd
).strip())
643 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate firmware image")
646 def GenerateOptionRom(Output
, EfiInput
, BinaryInput
, Compress
=False, ClassCode
=None,
647 Revision
=None, DeviceId
=None, VendorId
=None, IsMakefile
=False):
650 if len(EfiInput
) > 0:
657 for EfiFile
in EfiInput
:
659 InputList
.append (EfiFile
)
661 if len(BinaryInput
) > 0:
663 for BinFile
in BinaryInput
:
665 InputList
.append (BinFile
)
668 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, InputList
) and not IsMakefile
:
670 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, InputList
))
672 if ClassCode
is not None:
673 Cmd
+= ("-l", ClassCode
)
674 if Revision
is not None:
675 Cmd
+= ("-r", Revision
)
676 if DeviceId
is not None:
677 Cmd
+= ("-i", DeviceId
)
678 if VendorId
is not None:
679 Cmd
+= ("-f", VendorId
)
681 Cmd
+= ("-o", Output
)
683 if " ".join(Cmd
).strip() not in GenFdsGlobalVariable
.SecCmdList
:
684 GenFdsGlobalVariable
.SecCmdList
.append(" ".join(Cmd
).strip())
686 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate option rom")
689 def GuidTool(Output
, Input
, ToolPath
, Options
='', returnValue
=[], IsMakefile
=False):
690 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, Input
) and not IsMakefile
:
692 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
695 Cmd
+= Options
.split(' ')
696 Cmd
+= ("-o", Output
)
699 if " ".join(Cmd
).strip() not in GenFdsGlobalVariable
.SecCmdList
:
700 GenFdsGlobalVariable
.SecCmdList
.append(" ".join(Cmd
).strip())
702 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to call " + ToolPath
, returnValue
)
704 def CallExternalTool (cmd
, errorMess
, returnValue
=[]):
706 if type(cmd
) not in (tuple, list):
707 GenFdsGlobalVariable
.ErrorLogger("ToolError! Invalid parameter type in call to CallExternalTool")
709 if GenFdsGlobalVariable
.DebugLevel
!= -1:
710 cmd
+= ('--debug', str(GenFdsGlobalVariable
.DebugLevel
))
711 GenFdsGlobalVariable
.InfLogger (cmd
)
713 if GenFdsGlobalVariable
.VerboseMode
:
715 GenFdsGlobalVariable
.InfLogger (cmd
)
717 sys
.stdout
.write ('#')
719 GenFdsGlobalVariable
.SharpCounter
= GenFdsGlobalVariable
.SharpCounter
+ 1
720 if GenFdsGlobalVariable
.SharpCounter
% GenFdsGlobalVariable
.SharpNumberPerLine
== 0:
721 sys
.stdout
.write('\n')
724 PopenObject
= subprocess
.Popen(' '.join(cmd
), stdout
=subprocess
.PIPE
, stderr
=subprocess
.PIPE
, shell
=True)
725 except Exception as X
:
726 EdkLogger
.error("GenFds", COMMAND_FAILURE
, ExtraData
="%s: %s" % (str(X
), cmd
[0]))
727 (out
, error
) = PopenObject
.communicate()
729 while PopenObject
.returncode
is None :
731 if returnValue
!= [] and returnValue
[0] != 0:
732 #get command return value
733 returnValue
[0] = PopenObject
.returncode
735 if PopenObject
.returncode
!= 0 or GenFdsGlobalVariable
.VerboseMode
or GenFdsGlobalVariable
.DebugLevel
!= -1:
736 GenFdsGlobalVariable
.InfLogger ("Return Value = %d" % PopenObject
.returncode
)
737 GenFdsGlobalVariable
.InfLogger (out
)
738 GenFdsGlobalVariable
.InfLogger (error
)
739 if PopenObject
.returncode
!= 0:
741 EdkLogger
.error("GenFds", COMMAND_FAILURE
, errorMess
)
743 def VerboseLogger (msg
):
744 EdkLogger
.verbose(msg
)
749 def ErrorLogger (msg
, File
=None, Line
=None, ExtraData
=None):
750 EdkLogger
.error('GenFds', GENFDS_ERROR
, msg
, File
, Line
, ExtraData
)
752 def DebugLogger (Level
, msg
):
753 EdkLogger
.debug(Level
, msg
)
755 ## ReplaceWorkspaceMacro()
757 # @param Str String that may contain macro
758 # @param MacroDict Dictionary that contains macro value pair
760 def MacroExtend (Str
, MacroDict
={}, Arch
=DataType
.TAB_COMMON
):
764 Dict
= {'$(WORKSPACE)' : GenFdsGlobalVariable
.WorkSpaceDir
,
765 '$(EDK_SOURCE)' : GenFdsGlobalVariable
.EdkSourceDir
,
766 # '$(OUTPUT_DIRECTORY)': GenFdsGlobalVariable.OutputDirFromDsc,
767 '$(TARGET)' : GenFdsGlobalVariable
.TargetName
,
768 '$(TOOL_CHAIN_TAG)' : GenFdsGlobalVariable
.ToolChainTag
,
771 OutputDir
= GenFdsGlobalVariable
.OutputDirFromDscDict
[GenFdsGlobalVariable
.ArchList
[0]]
772 if Arch
!= DataType
.TAB_COMMON
and Arch
in GenFdsGlobalVariable
.ArchList
:
773 OutputDir
= GenFdsGlobalVariable
.OutputDirFromDscDict
[Arch
]
775 Dict
['$(OUTPUT_DIRECTORY)'] = OutputDir
777 if MacroDict
is not None and len (MacroDict
) != 0:
778 Dict
.update(MacroDict
)
781 if Str
.find(key
) >= 0 :
782 Str
= Str
.replace (key
, Dict
[key
])
784 if Str
.find('$(ARCH)') >= 0:
785 if len(GenFdsGlobalVariable
.ArchList
) == 1:
786 Str
= Str
.replace('$(ARCH)', GenFdsGlobalVariable
.ArchList
[0])
788 EdkLogger
.error("GenFds", GENFDS_ERROR
, "No way to determine $(ARCH) for %s" % Str
)
794 # @param PcdPattern pattern that labels a PCD.
796 def GetPcdValue (PcdPattern
):
797 if PcdPattern
is None :
799 PcdPair
= PcdPattern
.lstrip('PCD(').rstrip(')').strip().split('.')
800 TokenSpace
= PcdPair
[0]
801 TokenCName
= PcdPair
[1]
804 for Arch
in GenFdsGlobalVariable
.ArchList
:
805 Platform
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
806 PcdDict
= Platform
.Pcds
808 PcdObj
= PcdDict
[Key
]
809 if (PcdObj
.TokenCName
== TokenCName
) and (PcdObj
.TokenSpaceGuidCName
== TokenSpace
):
810 if PcdObj
.Type
!= DataType
.TAB_PCDS_FIXED_AT_BUILD
:
811 EdkLogger
.error("GenFds", GENFDS_ERROR
, "%s is not FixedAtBuild type." % PcdPattern
)
812 if PcdObj
.DatumType
!= DataType
.TAB_VOID
:
813 EdkLogger
.error("GenFds", GENFDS_ERROR
, "%s is not VOID* datum type." % PcdPattern
)
815 PcdValue
= PcdObj
.DefaultValue
818 for Package
in GenFdsGlobalVariable
.WorkSpace
.GetPackageList(GenFdsGlobalVariable
.ActivePlatform
,
820 GenFdsGlobalVariable
.TargetName
,
821 GenFdsGlobalVariable
.ToolChainTag
):
822 PcdDict
= Package
.Pcds
824 PcdObj
= PcdDict
[Key
]
825 if (PcdObj
.TokenCName
== TokenCName
) and (PcdObj
.TokenSpaceGuidCName
== TokenSpace
):
826 if PcdObj
.Type
!= DataType
.TAB_PCDS_FIXED_AT_BUILD
:
827 EdkLogger
.error("GenFds", GENFDS_ERROR
, "%s is not FixedAtBuild type." % PcdPattern
)
828 if PcdObj
.DatumType
!= DataType
.TAB_VOID
:
829 EdkLogger
.error("GenFds", GENFDS_ERROR
, "%s is not VOID* datum type." % PcdPattern
)
831 PcdValue
= PcdObj
.DefaultValue
836 SetDir
= staticmethod(SetDir
)
837 SetEnv
= staticmethod(SetEnv
)
838 ReplaceWorkspaceMacro
= staticmethod(ReplaceWorkspaceMacro
)
839 CallExternalTool
= staticmethod(CallExternalTool
)
840 VerboseLogger
= staticmethod(VerboseLogger
)
841 InfLogger
= staticmethod(InfLogger
)
842 ErrorLogger
= staticmethod(ErrorLogger
)
843 DebugLogger
= staticmethod(DebugLogger
)
844 MacroExtend
= staticmethod (MacroExtend
)
845 GetPcdValue
= staticmethod(GetPcdValue
)