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 import Common
.LongFilePathOs
as os
24 from Common
.BuildToolError
import *
25 from Common
import EdkLogger
26 from Common
.Misc
import SaveFileOnChange
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 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
34 from Common
.MultipleWorkspace
import MultipleWorkspace
as mws
39 class GenFdsGlobalVariable
:
43 # will be FvDir + os.sep + 'Ffs'
51 OutputDirFromDscDict
= {}
58 FvAddressFileName
= ''
62 SharpNumberPerLine
= 40
65 FixedLoadAddress
= False
68 BuildRuleFamily
= "MSFT"
69 ToolChainFamily
= "MSFT"
70 __BuildRuleDatabase
= None
71 GuidToolDefinition
= {}
76 EnableGenfdsMultiThread
= False
79 # The list whose element are flags to indicate if large FFS or SECTION files exist in FV.
80 # At the beginning of each generation of FV, false flag is appended to the list,
81 # after the call to GenerateSection returns, check the size of the output file,
82 # if it is greater than 0xFFFFFF, the tail flag in list is set to true,
83 # and EFI_FIRMWARE_FILE_SYSTEM3_GUID is passed to C GenFv.
84 # At the end of generation of FV, pop the flag.
85 # List is used as a stack to handle nested FV generation.
87 LargeFileInFvFlags
= []
88 EFI_FIRMWARE_FILE_SYSTEM3_GUID
= '5473C07A-3DCB-4dca-BD6F-1E9689E7349A'
89 LARGE_FILE_SIZE
= 0x1000000
91 SectionHeader
= struct
.Struct("3B 1B")
96 def __LoadBuildRule():
97 if GenFdsGlobalVariable
.__BuildRuleDatabase
:
98 return GenFdsGlobalVariable
.__BuildRuleDatabase
99 BuildConfigurationFile
= os
.path
.normpath(os
.path
.join(GenFdsGlobalVariable
.ConfDir
, "target.txt"))
100 TargetTxt
= TargetTxtClassObject()
101 if os
.path
.isfile(BuildConfigurationFile
) == True:
102 TargetTxt
.LoadTargetTxtFile(BuildConfigurationFile
)
103 if DataType
.TAB_TAT_DEFINES_BUILD_RULE_CONF
in TargetTxt
.TargetTxtDictionary
:
104 BuildRuleFile
= TargetTxt
.TargetTxtDictionary
[DataType
.TAB_TAT_DEFINES_BUILD_RULE_CONF
]
105 if BuildRuleFile
in [None, '']:
106 BuildRuleFile
= 'Conf/build_rule.txt'
107 GenFdsGlobalVariable
.__BuildRuleDatabase
= BuildRule(BuildRuleFile
)
108 ToolDefinitionFile
= TargetTxt
.TargetTxtDictionary
[DataType
.TAB_TAT_DEFINES_TOOL_CHAIN_CONF
]
109 if ToolDefinitionFile
== '':
110 ToolDefinitionFile
= "Conf/tools_def.txt"
111 if os
.path
.isfile(ToolDefinitionFile
):
112 ToolDef
= ToolDefClassObject()
113 ToolDef
.LoadToolDefFile(ToolDefinitionFile
)
114 ToolDefinition
= ToolDef
.ToolsDefTxtDatabase
115 if DataType
.TAB_TOD_DEFINES_BUILDRULEFAMILY
in ToolDefinition \
116 and GenFdsGlobalVariable
.ToolChainTag
in ToolDefinition
[DataType
.TAB_TOD_DEFINES_BUILDRULEFAMILY
] \
117 and ToolDefinition
[DataType
.TAB_TOD_DEFINES_BUILDRULEFAMILY
][GenFdsGlobalVariable
.ToolChainTag
]:
118 GenFdsGlobalVariable
.BuildRuleFamily
= ToolDefinition
[DataType
.TAB_TOD_DEFINES_BUILDRULEFAMILY
][GenFdsGlobalVariable
.ToolChainTag
]
120 if DataType
.TAB_TOD_DEFINES_FAMILY
in ToolDefinition \
121 and GenFdsGlobalVariable
.ToolChainTag
in ToolDefinition
[DataType
.TAB_TOD_DEFINES_FAMILY
] \
122 and ToolDefinition
[DataType
.TAB_TOD_DEFINES_FAMILY
][GenFdsGlobalVariable
.ToolChainTag
]:
123 GenFdsGlobalVariable
.ToolChainFamily
= ToolDefinition
[DataType
.TAB_TOD_DEFINES_FAMILY
][GenFdsGlobalVariable
.ToolChainTag
]
124 return GenFdsGlobalVariable
.__BuildRuleDatabase
127 # @param Inf: object of InfBuildData
128 # @param Arch: current arch
131 def GetBuildRules(Inf
, Arch
):
135 if not Arch
in GenFdsGlobalVariable
.OutputDirDict
:
138 BuildRuleDatabase
= GenFdsGlobalVariable
.__LoadBuildRule
()
139 if not BuildRuleDatabase
:
142 PathClassObj
= PathClass(Inf
.MetaFile
.File
,
143 GenFdsGlobalVariable
.WorkSpaceDir
)
145 Macro
["WORKSPACE" ] = GenFdsGlobalVariable
.WorkSpaceDir
146 Macro
["MODULE_NAME" ] = Inf
.BaseName
147 Macro
["MODULE_GUID" ] = Inf
.Guid
148 Macro
["MODULE_VERSION" ] = Inf
.Version
149 Macro
["MODULE_TYPE" ] = Inf
.ModuleType
150 Macro
["MODULE_FILE" ] = str(PathClassObj
)
151 Macro
["MODULE_FILE_BASE_NAME" ] = PathClassObj
.BaseName
152 Macro
["MODULE_RELATIVE_DIR" ] = PathClassObj
.SubDir
153 Macro
["MODULE_DIR" ] = PathClassObj
.SubDir
155 Macro
["BASE_NAME" ] = Inf
.BaseName
157 Macro
["ARCH" ] = Arch
158 Macro
["TOOLCHAIN" ] = GenFdsGlobalVariable
.ToolChainTag
159 Macro
["TOOLCHAIN_TAG" ] = GenFdsGlobalVariable
.ToolChainTag
160 Macro
["TOOL_CHAIN_TAG" ] = GenFdsGlobalVariable
.ToolChainTag
161 Macro
["TARGET" ] = GenFdsGlobalVariable
.TargetName
163 Macro
["BUILD_DIR" ] = GenFdsGlobalVariable
.OutputDirDict
[Arch
]
164 Macro
["BIN_DIR" ] = os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[Arch
], Arch
)
165 Macro
["LIB_DIR" ] = os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[Arch
], Arch
)
166 BuildDir
= os
.path
.join(
167 GenFdsGlobalVariable
.OutputDirDict
[Arch
],
170 PathClassObj
.BaseName
172 Macro
["MODULE_BUILD_DIR" ] = BuildDir
173 Macro
["OUTPUT_DIR" ] = os
.path
.join(BuildDir
, "OUTPUT")
174 Macro
["DEBUG_DIR" ] = os
.path
.join(BuildDir
, "DEBUG")
177 for Type
in BuildRuleDatabase
.FileTypeList
:
178 #first try getting build rule by BuildRuleFamily
179 RuleObject
= BuildRuleDatabase
[Type
, Inf
.BuildType
, Arch
, GenFdsGlobalVariable
.BuildRuleFamily
]
181 # build type is always module type, but ...
182 if Inf
.ModuleType
!= Inf
.BuildType
:
183 RuleObject
= BuildRuleDatabase
[Type
, Inf
.ModuleType
, Arch
, GenFdsGlobalVariable
.BuildRuleFamily
]
184 #second try getting build rule by ToolChainFamily
186 RuleObject
= BuildRuleDatabase
[Type
, Inf
.BuildType
, Arch
, GenFdsGlobalVariable
.ToolChainFamily
]
188 # build type is always module type, but ...
189 if Inf
.ModuleType
!= Inf
.BuildType
:
190 RuleObject
= BuildRuleDatabase
[Type
, Inf
.ModuleType
, Arch
, GenFdsGlobalVariable
.ToolChainFamily
]
193 RuleObject
= RuleObject
.Instantiate(Macro
)
194 BuildRules
[Type
] = RuleObject
195 for Ext
in RuleObject
.SourceFileExtList
:
196 BuildRules
[Ext
] = RuleObject
199 ## GetModuleCodaTargetList
201 # @param Inf: object of InfBuildData
202 # @param Arch: current arch
205 def GetModuleCodaTargetList(Inf
, Arch
):
206 BuildRules
= GenFdsGlobalVariable
.GetBuildRules(Inf
, Arch
)
213 if not Inf
.IsBinaryModule
:
214 for File
in Inf
.Sources
:
215 if File
.TagName
in ("", "*", GenFdsGlobalVariable
.ToolChainTag
) and \
216 File
.ToolChainFamily
in ("", "*", GenFdsGlobalVariable
.ToolChainFamily
):
217 FileList
.append((File
, DataType
.TAB_UNKNOWN_FILE
))
219 for File
in Inf
.Binaries
:
220 if File
.Target
in ['COMMON', '*', GenFdsGlobalVariable
.TargetName
]:
221 FileList
.append((File
, File
.Type
))
223 for File
, FileType
in FileList
:
228 while Index
< len(SourceList
):
229 Source
= SourceList
[Index
]
232 if File
.IsBinary
and File
== Source
and Inf
.Binaries
is not None and File
in Inf
.Binaries
:
233 # Skip all files that are not binary libraries
234 if not Inf
.LibraryClass
:
236 RuleObject
= BuildRules
[DataType
.TAB_DEFAULT_BINARY_FILE
]
237 elif FileType
in BuildRules
:
238 RuleObject
= BuildRules
[FileType
]
239 elif Source
.Ext
in BuildRules
:
240 RuleObject
= BuildRules
[Source
.Ext
]
242 # stop at no more rules
244 TargetList
.add(str(LastTarget
))
247 FileType
= RuleObject
.SourceFileType
249 # stop at STATIC_LIBRARY for library
250 if Inf
.LibraryClass
and FileType
== DataType
.TAB_STATIC_LIBRARY
:
252 TargetList
.add(str(LastTarget
))
255 Target
= RuleObject
.Apply(Source
)
258 TargetList
.add(str(LastTarget
))
260 elif not Target
.Outputs
:
261 # Only do build for target with outputs
262 TargetList
.add(str(Target
))
264 # to avoid cyclic rule
265 if FileType
in RuleChain
:
268 RuleChain
.append(FileType
)
269 SourceList
.extend(Target
.Outputs
)
271 FileType
= DataType
.TAB_UNKNOWN_FILE
272 for Cmd
in Target
.Commands
:
273 if "$(CP)" == Cmd
.split()[0]:
274 CpTarget
= Cmd
.split()[2]
275 TargetList
.add(CpTarget
)
277 return list(TargetList
)
281 # @param OutputDir Output directory
282 # @param FdfParser FDF contents parser
283 # @param Workspace The directory of workspace
284 # @param ArchList The Arch list of platform
286 def SetDir (OutputDir
, FdfParser
, WorkSpace
, ArchList
):
287 GenFdsGlobalVariable
.VerboseLogger("GenFdsGlobalVariable.OutputDir :%s" % OutputDir
)
288 # GenFdsGlobalVariable.OutputDirDict = OutputDir
289 GenFdsGlobalVariable
.FdfParser
= FdfParser
290 GenFdsGlobalVariable
.WorkSpace
= WorkSpace
291 GenFdsGlobalVariable
.FvDir
= os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[ArchList
[0]], 'FV')
292 if not os
.path
.exists(GenFdsGlobalVariable
.FvDir
) :
293 os
.makedirs(GenFdsGlobalVariable
.FvDir
)
294 GenFdsGlobalVariable
.FfsDir
= os
.path
.join(GenFdsGlobalVariable
.FvDir
, 'Ffs')
295 if not os
.path
.exists(GenFdsGlobalVariable
.FfsDir
) :
296 os
.makedirs(GenFdsGlobalVariable
.FfsDir
)
300 # Create FV Address inf file
302 GenFdsGlobalVariable
.FvAddressFileName
= os
.path
.join(GenFdsGlobalVariable
.FfsDir
, 'FvAddress.inf')
303 FvAddressFile
= open(GenFdsGlobalVariable
.FvAddressFileName
, 'w')
307 FvAddressFile
.writelines("[options]" + T_CHAR_LF
)
309 for Arch
in ArchList
:
310 if GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
].BsBaseAddress
:
311 BsAddress
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
].BsBaseAddress
314 FvAddressFile
.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \
319 for Arch
in ArchList
:
320 if GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
].RtBaseAddress
:
321 RtAddress
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
].RtBaseAddress
323 FvAddressFile
.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \
327 FvAddressFile
.close()
329 def SetEnv(FdfParser
, WorkSpace
, ArchList
, GlobalData
):
330 GenFdsGlobalVariable
.ModuleFile
= WorkSpace
.ModuleFile
331 GenFdsGlobalVariable
.FdfParser
= FdfParser
332 GenFdsGlobalVariable
.WorkSpace
= WorkSpace
.Db
333 GenFdsGlobalVariable
.ArchList
= ArchList
334 GenFdsGlobalVariable
.ToolChainTag
= GlobalData
.gGlobalDefines
["TOOL_CHAIN_TAG"]
335 GenFdsGlobalVariable
.TargetName
= GlobalData
.gGlobalDefines
["TARGET"]
336 GenFdsGlobalVariable
.ActivePlatform
= GlobalData
.gActivePlatform
337 GenFdsGlobalVariable
.EdkSourceDir
= GlobalData
.gGlobalDefines
["EDK_SOURCE"]
338 GenFdsGlobalVariable
.ConfDir
= GlobalData
.gConfDirectory
339 GenFdsGlobalVariable
.EnableGenfdsMultiThread
= GlobalData
.gEnableGenfdsMultiThread
340 for Arch
in ArchList
:
341 GenFdsGlobalVariable
.OutputDirDict
[Arch
] = os
.path
.normpath(
342 os
.path
.join(GlobalData
.gWorkspace
,
343 WorkSpace
.Db
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
,GlobalData
.gGlobalDefines
['TARGET'],
344 GlobalData
.gGlobalDefines
['TOOLCHAIN']].OutputDirectory
,
345 GlobalData
.gGlobalDefines
['TARGET'] +'_' + GlobalData
.gGlobalDefines
['TOOLCHAIN']))
346 GenFdsGlobalVariable
.OutputDirFromDscDict
[Arch
] = os
.path
.normpath(
347 WorkSpace
.Db
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
,
348 GlobalData
.gGlobalDefines
['TARGET'], GlobalData
.gGlobalDefines
['TOOLCHAIN']].OutputDirectory
)
349 GenFdsGlobalVariable
.PlatformName
= WorkSpace
.Db
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
,
350 GlobalData
.gGlobalDefines
['TARGET'],
351 GlobalData
.gGlobalDefines
['TOOLCHAIN']].PlatformName
352 GenFdsGlobalVariable
.FvDir
= os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[ArchList
[0]], 'FV')
353 if not os
.path
.exists(GenFdsGlobalVariable
.FvDir
):
354 os
.makedirs(GenFdsGlobalVariable
.FvDir
)
355 GenFdsGlobalVariable
.FfsDir
= os
.path
.join(GenFdsGlobalVariable
.FvDir
, 'Ffs')
356 if not os
.path
.exists(GenFdsGlobalVariable
.FfsDir
):
357 os
.makedirs(GenFdsGlobalVariable
.FfsDir
)
361 # Create FV Address inf file
363 GenFdsGlobalVariable
.FvAddressFileName
= os
.path
.join(GenFdsGlobalVariable
.FfsDir
, 'FvAddress.inf')
364 FvAddressFile
= open(GenFdsGlobalVariable
.FvAddressFileName
, 'w')
368 FvAddressFile
.writelines("[options]" + T_CHAR_LF
)
370 for Arch
in ArchList
:
371 BsAddress
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
,
372 GlobalData
.gGlobalDefines
['TARGET'],
373 GlobalData
.gGlobalDefines
["TOOL_CHAIN_TAG"]].BsBaseAddress
377 FvAddressFile
.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \
382 for Arch
in ArchList
:
383 if GenFdsGlobalVariable
.WorkSpace
.BuildObject
[
384 GenFdsGlobalVariable
.ActivePlatform
, Arch
, GlobalData
.gGlobalDefines
['TARGET'],
385 GlobalData
.gGlobalDefines
["TOOL_CHAIN_TAG"]].RtBaseAddress
:
386 RtAddress
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[
387 GenFdsGlobalVariable
.ActivePlatform
, Arch
, GlobalData
.gGlobalDefines
['TARGET'],
388 GlobalData
.gGlobalDefines
["TOOL_CHAIN_TAG"]].RtBaseAddress
390 FvAddressFile
.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \
394 FvAddressFile
.close()
396 ## ReplaceWorkspaceMacro()
398 # @param String String that may contain macro
400 def ReplaceWorkspaceMacro(String
):
401 String
= mws
.handleWsMacro(String
)
402 Str
= String
.replace('$(WORKSPACE)', GenFdsGlobalVariable
.WorkSpaceDir
)
403 if os
.path
.exists(Str
):
404 if not os
.path
.isabs(Str
):
405 Str
= os
.path
.abspath(Str
)
407 Str
= mws
.join(GenFdsGlobalVariable
.WorkSpaceDir
, String
)
408 return os
.path
.normpath(Str
)
410 ## Check if the input files are newer than output files
412 # @param Output Path of output file
413 # @param Input Path list of input files
415 # @retval True if Output doesn't exist, or any Input is newer
416 # @retval False if all Input is older than Output
419 def NeedsUpdate(Output
, Input
):
420 if not os
.path
.exists(Output
):
422 # always update "Output" if no "Input" given
423 if Input
is None or len(Input
) == 0:
426 # if fdf file is changed after the 'Output" is generated, update the 'Output'
427 OutputTime
= os
.path
.getmtime(Output
)
428 if GenFdsGlobalVariable
.FdfFileTimeStamp
> OutputTime
:
432 # always update "Output" if any "Input" doesn't exist
433 if not os
.path
.exists(F
):
435 # always update "Output" if any "Input" is newer than "Output"
436 if os
.path
.getmtime(F
) > OutputTime
:
441 def GenerateSection(Output
, Input
, Type
=None, CompressionType
=None, Guid
=None,
442 GuidHdrLen
=None, GuidAttr
=[], Ui
=None, Ver
=None, InputAlign
=None, BuildNumber
=None, DummyFile
=None, IsMakefile
=False):
444 if Type
not in [None, '']:
446 if CompressionType
not in [None, '']:
447 Cmd
+= ["-c", CompressionType
]
450 if DummyFile
is not None:
451 Cmd
+= ["--dummy", DummyFile
]
452 if GuidHdrLen
not in [None, '']:
453 Cmd
+= ["-l", GuidHdrLen
]
454 if len(GuidAttr
) != 0:
455 #Add each guided attribute
456 for Attr
in GuidAttr
:
458 if InputAlign
is not None:
459 #Section Align is only for dummy section without section type
460 for SecAlign
in InputAlign
:
461 Cmd
+= ["--sectionalign", SecAlign
]
463 CommandFile
= Output
+ '.txt'
464 if Ui
not in [None, '']:
465 #Cmd += ["-n", '"' + Ui + '"']
467 if Ui
== "$(MODULE_NAME)":
470 Cmd
+= ["-n", '"' + Ui
+ '"']
471 Cmd
+= ["-o", Output
]
472 if ' '.join(Cmd
).strip() not in GenFdsGlobalVariable
.SecCmdList
:
473 GenFdsGlobalVariable
.SecCmdList
.append(' '.join(Cmd
).strip())
475 SectionData
= array
.array('B', [0, 0, 0, 0])
476 SectionData
.fromstring(Ui
.encode("utf_16_le"))
477 SectionData
.append(0)
478 SectionData
.append(0)
479 Len
= len(SectionData
)
480 GenFdsGlobalVariable
.SectionHeader
.pack_into(SectionData
, 0, Len
& 0xff, (Len
>> 8) & 0xff, (Len
>> 16) & 0xff, 0x15)
481 SaveFileOnChange(Output
, SectionData
.tostring())
483 elif Ver
not in [None, '']:
486 Cmd
+= ["-j", BuildNumber
]
487 Cmd
+= ["-o", Output
]
489 SaveFileOnChange(CommandFile
, ' '.join(Cmd
), False)
491 if ' '.join(Cmd
).strip() not in GenFdsGlobalVariable
.SecCmdList
:
492 GenFdsGlobalVariable
.SecCmdList
.append(' '.join(Cmd
).strip())
494 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, list(Input
) + [CommandFile
]):
496 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate section")
498 Cmd
+= ["-o", Output
]
501 SaveFileOnChange(CommandFile
, ' '.join(Cmd
), False)
503 if ' '.join(Cmd
).strip() not in GenFdsGlobalVariable
.SecCmdList
:
504 GenFdsGlobalVariable
.SecCmdList
.append(' '.join(Cmd
).strip())
505 elif GenFdsGlobalVariable
.NeedsUpdate(Output
, list(Input
) + [CommandFile
]):
506 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
507 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate section")
508 if (os
.path
.getsize(Output
) >= GenFdsGlobalVariable
.LARGE_FILE_SIZE
and
509 GenFdsGlobalVariable
.LargeFileInFvFlags
):
510 GenFdsGlobalVariable
.LargeFileInFvFlags
[-1] = True
513 def GetAlignment (AlignString
):
514 if AlignString
is None:
516 if AlignString
in ("1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K"):
517 return int (AlignString
.rstrip('K')) * 1024
518 elif AlignString
in ("1M", "2M", "4M", "8M", "16M"):
519 return int (AlignString
.rstrip('M')) * 1024 * 1024
521 return int (AlignString
)
524 def GenerateFfs(Output
, Input
, Type
, Guid
, Fixed
=False, CheckSum
=False, Align
=None,
525 SectionAlign
=None, MakefilePath
=None):
526 Cmd
= ["GenFfs", "-t", Type
, "-g", Guid
]
527 mFfsValidAlign
= ["0", "8", "16", "128", "512", "1K", "4K", "32K", "64K", "128K", "256K", "512K", "1M", "2M", "4M", "8M", "16M"]
532 if Align
not in [None, '']:
533 if Align
not in mFfsValidAlign
:
534 Align
= GenFdsGlobalVariable
.GetAlignment (Align
)
535 for index
in range(0, len(mFfsValidAlign
) - 1):
536 if ((Align
> GenFdsGlobalVariable
.GetAlignment(mFfsValidAlign
[index
])) and (Align
<= GenFdsGlobalVariable
.GetAlignment(mFfsValidAlign
[index
+ 1]))):
538 Align
= mFfsValidAlign
[index
+ 1]
541 Cmd
+= ["-o", Output
]
542 for I
in range(0, len(Input
)):
543 Cmd
+= ("-i", Input
[I
])
544 if SectionAlign
not in [None, '', []] and SectionAlign
[I
] not in [None, '']:
545 Cmd
+= ("-n", SectionAlign
[I
])
547 CommandFile
= Output
+ '.txt'
548 SaveFileOnChange(CommandFile
, ' '.join(Cmd
), False)
550 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
552 if (tuple(Cmd
),tuple(GenFdsGlobalVariable
.SecCmdList
),tuple(GenFdsGlobalVariable
.CopyList
)) not in GenFdsGlobalVariable
.FfsCmdDict
.keys():
553 GenFdsGlobalVariable
.FfsCmdDict
[tuple(Cmd
), tuple(GenFdsGlobalVariable
.SecCmdList
), tuple(GenFdsGlobalVariable
.CopyList
)] = MakefilePath
554 GenFdsGlobalVariable
.SecCmdList
= []
555 GenFdsGlobalVariable
.CopyList
= []
557 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, list(Input
) + [CommandFile
]):
559 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate FFS")
562 def GenerateFirmwareVolume(Output
, Input
, BaseAddress
=None, ForceRebase
=None, Capsule
=False, Dump
=False,
563 AddressFile
=None, MapFile
=None, FfsList
=[], FileSystemGuid
=None):
564 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, Input
+FfsList
):
566 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
569 if BaseAddress
not in [None, '']:
570 Cmd
+= ["-r", BaseAddress
]
572 if ForceRebase
== False:
573 Cmd
+= ["-F", "FALSE"]
574 elif ForceRebase
== True:
575 Cmd
+= ["-F", "TRUE"]
581 if AddressFile
not in [None, '']:
582 Cmd
+= ["-a", AddressFile
]
583 if MapFile
not in [None, '']:
584 Cmd
+= ["-m", MapFile
]
586 Cmd
+= ["-g", FileSystemGuid
]
587 Cmd
+= ["-o", Output
]
591 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate FV")
594 def GenerateVtf(Output
, Input
, BaseAddress
=None, FvSize
=None):
595 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, Input
):
597 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
600 if BaseAddress
not in [None, ''] and FvSize
not in [None, ''] \
601 and len(BaseAddress
) == len(FvSize
):
602 for I
in range(0, len(BaseAddress
)):
603 Cmd
+= ["-r", BaseAddress
[I
], "-s", FvSize
[I
]]
604 Cmd
+= ["-o", Output
]
608 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate VTF")
611 def GenerateFirmwareImage(Output
, Input
, Type
="efi", SubType
=None, Zero
=False,
612 Strip
=False, Replace
=False, TimeStamp
=None, Join
=False,
613 Align
=None, Padding
=None, Convert
=False, IsMakefile
=False):
614 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, Input
) and not IsMakefile
:
616 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
619 if Type
.lower() == "te":
621 if SubType
not in [None, '']:
622 Cmd
+= ["-e", SubType
]
623 if TimeStamp
not in [None, '']:
624 Cmd
+= ["-s", TimeStamp
]
625 if Align
not in [None, '']:
627 if Padding
not in [None, '']:
628 Cmd
+= ["-p", Padding
]
639 Cmd
+= ["-o", Output
]
642 if " ".join(Cmd
).strip() not in GenFdsGlobalVariable
.SecCmdList
:
643 GenFdsGlobalVariable
.SecCmdList
.append(" ".join(Cmd
).strip())
645 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate firmware image")
648 def GenerateOptionRom(Output
, EfiInput
, BinaryInput
, Compress
=False, ClassCode
=None,
649 Revision
=None, DeviceId
=None, VendorId
=None, IsMakefile
=False):
652 if len(EfiInput
) > 0:
659 for EfiFile
in EfiInput
:
661 InputList
.append (EfiFile
)
663 if len(BinaryInput
) > 0:
665 for BinFile
in BinaryInput
:
667 InputList
.append (BinFile
)
670 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, InputList
) and not IsMakefile
:
672 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, InputList
))
674 if ClassCode
is not None:
675 Cmd
+= ["-l", ClassCode
]
676 if Revision
is not None:
677 Cmd
+= ["-r", Revision
]
678 if DeviceId
is not None:
679 Cmd
+= ["-i", DeviceId
]
680 if VendorId
is not None:
681 Cmd
+= ["-f", VendorId
]
683 Cmd
+= ["-o", Output
]
685 if " ".join(Cmd
).strip() not in GenFdsGlobalVariable
.SecCmdList
:
686 GenFdsGlobalVariable
.SecCmdList
.append(" ".join(Cmd
).strip())
688 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate option rom")
691 def GuidTool(Output
, Input
, ToolPath
, Options
='', returnValue
=[], IsMakefile
=False):
692 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, Input
) and not IsMakefile
:
694 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
697 Cmd
+= Options
.split(' ')
698 Cmd
+= ["-o", Output
]
701 if " ".join(Cmd
).strip() not in GenFdsGlobalVariable
.SecCmdList
:
702 GenFdsGlobalVariable
.SecCmdList
.append(" ".join(Cmd
).strip())
704 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to call " + ToolPath
, returnValue
)
706 def CallExternalTool (cmd
, errorMess
, returnValue
=[]):
708 if type(cmd
) not in (tuple, list):
709 GenFdsGlobalVariable
.ErrorLogger("ToolError! Invalid parameter type in call to CallExternalTool")
711 if GenFdsGlobalVariable
.DebugLevel
!= -1:
712 cmd
+= ('--debug', str(GenFdsGlobalVariable
.DebugLevel
))
713 GenFdsGlobalVariable
.InfLogger (cmd
)
715 if GenFdsGlobalVariable
.VerboseMode
:
717 GenFdsGlobalVariable
.InfLogger (cmd
)
719 sys
.stdout
.write ('#')
721 GenFdsGlobalVariable
.SharpCounter
= GenFdsGlobalVariable
.SharpCounter
+ 1
722 if GenFdsGlobalVariable
.SharpCounter
% GenFdsGlobalVariable
.SharpNumberPerLine
== 0:
723 sys
.stdout
.write('\n')
726 PopenObject
= subprocess
.Popen(' '.join(cmd
), stdout
=subprocess
.PIPE
, stderr
=subprocess
.PIPE
, shell
=True)
728 EdkLogger
.error("GenFds", COMMAND_FAILURE
, ExtraData
="%s: %s" % (str(X
), cmd
[0]))
729 (out
, error
) = PopenObject
.communicate()
731 while PopenObject
.returncode
is None :
733 if returnValue
!= [] and returnValue
[0] != 0:
734 #get command return value
735 returnValue
[0] = PopenObject
.returncode
737 if PopenObject
.returncode
!= 0 or GenFdsGlobalVariable
.VerboseMode
or GenFdsGlobalVariable
.DebugLevel
!= -1:
738 GenFdsGlobalVariable
.InfLogger ("Return Value = %d" % PopenObject
.returncode
)
739 GenFdsGlobalVariable
.InfLogger (out
)
740 GenFdsGlobalVariable
.InfLogger (error
)
741 if PopenObject
.returncode
!= 0:
743 EdkLogger
.error("GenFds", COMMAND_FAILURE
, errorMess
)
745 def VerboseLogger (msg
):
746 EdkLogger
.verbose(msg
)
751 def ErrorLogger (msg
, File
=None, Line
=None, ExtraData
=None):
752 EdkLogger
.error('GenFds', GENFDS_ERROR
, msg
, File
, Line
, ExtraData
)
754 def DebugLogger (Level
, msg
):
755 EdkLogger
.debug(Level
, msg
)
757 ## ReplaceWorkspaceMacro()
759 # @param Str String that may contain macro
760 # @param MacroDict Dictionary that contains macro value pair
762 def MacroExtend (Str
, MacroDict
={}, Arch
='COMMON'):
766 Dict
= {'$(WORKSPACE)' : GenFdsGlobalVariable
.WorkSpaceDir
,
767 '$(EDK_SOURCE)' : GenFdsGlobalVariable
.EdkSourceDir
,
768 # '$(OUTPUT_DIRECTORY)': GenFdsGlobalVariable.OutputDirFromDsc,
769 '$(TARGET)' : GenFdsGlobalVariable
.TargetName
,
770 '$(TOOL_CHAIN_TAG)' : GenFdsGlobalVariable
.ToolChainTag
,
773 OutputDir
= GenFdsGlobalVariable
.OutputDirFromDscDict
[GenFdsGlobalVariable
.ArchList
[0]]
774 if Arch
!= 'COMMON' and Arch
in GenFdsGlobalVariable
.ArchList
:
775 OutputDir
= GenFdsGlobalVariable
.OutputDirFromDscDict
[Arch
]
777 Dict
['$(OUTPUT_DIRECTORY)'] = OutputDir
779 if MacroDict
is not None and len (MacroDict
) != 0:
780 Dict
.update(MacroDict
)
782 for key
in Dict
.keys():
783 if Str
.find(key
) >= 0 :
784 Str
= Str
.replace (key
, Dict
[key
])
786 if Str
.find('$(ARCH)') >= 0:
787 if len(GenFdsGlobalVariable
.ArchList
) == 1:
788 Str
= Str
.replace('$(ARCH)', GenFdsGlobalVariable
.ArchList
[0])
790 EdkLogger
.error("GenFds", GENFDS_ERROR
, "No way to determine $(ARCH) for %s" % Str
)
796 # @param PcdPattern pattern that labels a PCD.
798 def GetPcdValue (PcdPattern
):
799 if PcdPattern
is None :
801 PcdPair
= PcdPattern
.lstrip('PCD(').rstrip(')').strip().split('.')
802 TokenSpace
= PcdPair
[0]
803 TokenCName
= PcdPair
[1]
806 for Arch
in GenFdsGlobalVariable
.ArchList
:
807 Platform
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
808 PcdDict
= Platform
.Pcds
810 PcdObj
= PcdDict
[Key
]
811 if (PcdObj
.TokenCName
== TokenCName
) and (PcdObj
.TokenSpaceGuidCName
== TokenSpace
):
812 if PcdObj
.Type
!= 'FixedAtBuild':
813 EdkLogger
.error("GenFds", GENFDS_ERROR
, "%s is not FixedAtBuild type." % PcdPattern
)
814 if PcdObj
.DatumType
!= 'VOID*':
815 EdkLogger
.error("GenFds", GENFDS_ERROR
, "%s is not VOID* datum type." % PcdPattern
)
817 PcdValue
= PcdObj
.DefaultValue
820 for Package
in GenFdsGlobalVariable
.WorkSpace
.GetPackageList(GenFdsGlobalVariable
.ActivePlatform
,
822 GenFdsGlobalVariable
.TargetName
,
823 GenFdsGlobalVariable
.ToolChainTag
):
824 PcdDict
= Package
.Pcds
826 PcdObj
= PcdDict
[Key
]
827 if (PcdObj
.TokenCName
== TokenCName
) and (PcdObj
.TokenSpaceGuidCName
== TokenSpace
):
828 if PcdObj
.Type
!= 'FixedAtBuild':
829 EdkLogger
.error("GenFds", GENFDS_ERROR
, "%s is not FixedAtBuild type." % PcdPattern
)
830 if PcdObj
.DatumType
!= 'VOID*':
831 EdkLogger
.error("GenFds", GENFDS_ERROR
, "%s is not VOID* datum type." % PcdPattern
)
833 PcdValue
= PcdObj
.DefaultValue
838 SetDir
= staticmethod(SetDir
)
839 SetEnv
= staticmethod(SetEnv
)
840 ReplaceWorkspaceMacro
= staticmethod(ReplaceWorkspaceMacro
)
841 CallExternalTool
= staticmethod(CallExternalTool
)
842 VerboseLogger
= staticmethod(VerboseLogger
)
843 InfLogger
= staticmethod(InfLogger
)
844 ErrorLogger
= staticmethod(ErrorLogger
)
845 DebugLogger
= staticmethod(DebugLogger
)
846 MacroExtend
= staticmethod (MacroExtend
)
847 GetPcdValue
= staticmethod(GetPcdValue
)