2014-01-27 06:23:15 +01:00
## @file
# generate flash image
#
2019-01-09 20:00:41 +01:00
# Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>
2014-01-27 06:23:15 +01:00
#
2019-04-04 01:03:11 +02:00
# SPDX-License-Identifier: BSD-2-Clause-Patent
2014-01-27 06:23:15 +01:00
#
##
# Import Modules
#
2018-10-15 02:27:53 +02:00
from __future__ import print_function
from __future__ import absolute_import
2018-10-23 19:29:19 +02:00
from re import compile
2014-01-27 06:23:15 +01:00
from optparse import OptionParser
2018-10-23 19:29:19 +02:00
from sys import exit
from glob import glob
from struct import unpack
from linecache import getlines
2018-06-25 12:31:36 +02:00
from io import BytesIO
2018-10-23 19:29:19 +02:00
import Common . LongFilePathOs as os
from Common . TargetTxtClassObject import TargetTxtClassObject
2017-02-15 07:47:47 +01:00
from Common . DataType import *
2014-01-27 06:23:15 +01:00
import Common . GlobalData as GlobalData
from Common import EdkLogger
2018-10-23 19:29:19 +02:00
from Common . StringUtils import NormPath
from Common . Misc import DirCache , PathClass , GuidStructureStringToGuidString
from Common . Misc import SaveFileOnChange , ClearDuplicatedInf
2014-01-27 06:23:15 +01:00
from Common . BuildVersion import gBUILD_VERSION
2015-10-08 11:27:14 +02:00
from Common . MultipleWorkspace import MultipleWorkspace as mws
2018-11-23 08:04:45 +01:00
from Common . BuildToolError import FatalError , GENFDS_ERROR , CODE_ERROR , FORMAT_INVALID , RESOURCE_NOT_AVAILABLE , FILE_NOT_FOUND , OPTION_MISSING , FORMAT_NOT_SUPPORTED , OPTION_VALUE_INVALID , PARAMETER_INVALID
2018-10-23 19:29:19 +02:00
from Workspace . WorkspaceDatabase import WorkspaceDatabase
from . FdfParser import FdfParser , Warning
from . GenFdsGlobalVariable import GenFdsGlobalVariable
from . FfsFileStatement import FileStatement
2018-12-20 12:12:12 +01:00
import Common . DataType as DataType
from struct import Struct
2014-01-27 06:23:15 +01:00
## Version and Copyright
versionNumber = " 1.0 " + ' ' + gBUILD_VERSION
__version__ = " % prog Version " + versionNumber
2018-07-05 11:40:04 +02:00
__copyright__ = " Copyright (c) 2007 - 2018, Intel Corporation All rights reserved. "
2014-01-27 06:23:15 +01:00
## Tool entrance method
#
# This method mainly dispatch specific methods per the command line options.
# If no error found, return zero value so the caller of this tool can know
# if it's executed successfully or not.
#
# @retval 0 Tool was successful
# @retval 1 Tool failed
#
def main ( ) :
global Options
Options = myOptionParser ( )
2018-11-23 08:04:45 +01:00
EdkLogger . Initialize ( )
return GenFdsApi ( OptionsToCommandDict ( Options ) )
2014-01-27 06:23:15 +01:00
2018-12-20 12:12:12 +01:00
def resetFdsGlobalVariable ( ) :
GenFdsGlobalVariable . FvDir = ' '
GenFdsGlobalVariable . OutputDirDict = { }
GenFdsGlobalVariable . BinDir = ' '
# will be FvDir + os.sep + 'Ffs'
GenFdsGlobalVariable . FfsDir = ' '
GenFdsGlobalVariable . FdfParser = None
GenFdsGlobalVariable . LibDir = ' '
GenFdsGlobalVariable . WorkSpace = None
GenFdsGlobalVariable . WorkSpaceDir = ' '
GenFdsGlobalVariable . ConfDir = ' '
GenFdsGlobalVariable . OutputDirFromDscDict = { }
GenFdsGlobalVariable . TargetName = ' '
GenFdsGlobalVariable . ToolChainTag = ' '
GenFdsGlobalVariable . RuleDict = { }
GenFdsGlobalVariable . ArchList = None
GenFdsGlobalVariable . ActivePlatform = None
GenFdsGlobalVariable . FvAddressFileName = ' '
GenFdsGlobalVariable . VerboseMode = False
GenFdsGlobalVariable . DebugLevel = - 1
GenFdsGlobalVariable . SharpCounter = 0
GenFdsGlobalVariable . SharpNumberPerLine = 40
GenFdsGlobalVariable . FdfFile = ' '
GenFdsGlobalVariable . FdfFileTimeStamp = 0
GenFdsGlobalVariable . FixedLoadAddress = False
GenFdsGlobalVariable . PlatformName = ' '
GenFdsGlobalVariable . BuildRuleFamily = DataType . TAB_COMPILER_MSFT
GenFdsGlobalVariable . ToolChainFamily = DataType . TAB_COMPILER_MSFT
GenFdsGlobalVariable . __BuildRuleDatabase = None
GenFdsGlobalVariable . GuidToolDefinition = { }
GenFdsGlobalVariable . FfsCmdDict = { }
GenFdsGlobalVariable . SecCmdList = [ ]
GenFdsGlobalVariable . CopyList = [ ]
GenFdsGlobalVariable . ModuleFile = ' '
GenFdsGlobalVariable . EnableGenfdsMultiThread = False
GenFdsGlobalVariable . LargeFileInFvFlags = [ ]
GenFdsGlobalVariable . EFI_FIRMWARE_FILE_SYSTEM3_GUID = ' 5473C07A-3DCB-4dca-BD6F-1E9689E7349A '
GenFdsGlobalVariable . LARGE_FILE_SIZE = 0x1000000
GenFdsGlobalVariable . SectionHeader = Struct ( " 3B 1B " )
# FvName, FdName, CapName in FDF, Image file name
GenFdsGlobalVariable . ImageBinDict = { }
2018-11-23 08:04:45 +01:00
def GenFdsApi ( FdsCommandDict , WorkSpaceDataBase = None ) :
2014-01-27 06:23:15 +01:00
global Workspace
Workspace = " "
ArchList = None
ReturnCode = 0
2018-12-20 12:12:12 +01:00
resetFdsGlobalVariable ( )
2014-01-27 06:23:15 +01:00
try :
2018-11-23 08:04:45 +01:00
if FdsCommandDict . get ( " verbose " ) :
2014-01-27 06:23:15 +01:00
EdkLogger . SetLevel ( EdkLogger . VERBOSE )
GenFdsGlobalVariable . VerboseMode = True
2018-07-05 11:40:04 +02:00
2018-11-23 08:04:45 +01:00
if FdsCommandDict . get ( " FixedAddress " ) :
2014-01-27 06:23:15 +01:00
GenFdsGlobalVariable . FixedLoadAddress = True
2018-07-05 11:40:04 +02:00
2018-11-23 08:04:45 +01:00
if FdsCommandDict . get ( " quiet " ) :
2014-01-27 06:23:15 +01:00
EdkLogger . SetLevel ( EdkLogger . QUIET )
2018-11-23 08:04:45 +01:00
if FdsCommandDict . get ( " debug " ) :
EdkLogger . SetLevel ( FdsCommandDict . get ( " debug " ) + 1 )
GenFdsGlobalVariable . DebugLevel = FdsCommandDict . get ( " debug " )
2014-01-27 06:23:15 +01:00
else :
EdkLogger . SetLevel ( EdkLogger . INFO )
2018-11-23 08:04:45 +01:00
if not FdsCommandDict . get ( " Workspace " , os . environ . get ( ' WORKSPACE ' ) ) :
2014-01-27 06:23:15 +01:00
EdkLogger . error ( " GenFds " , OPTION_MISSING , " WORKSPACE not defined " ,
ExtraData = " Please use ' -w ' switch to pass it or set the WORKSPACE environment variable. " )
2018-11-23 08:04:45 +01:00
elif not os . path . exists ( FdsCommandDict . get ( " Workspace " , os . environ . get ( ' WORKSPACE ' ) ) ) :
2014-01-27 06:23:15 +01:00
EdkLogger . error ( " GenFds " , PARAMETER_INVALID , " WORKSPACE is invalid " ,
ExtraData = " Please use ' -w ' switch to pass it or set the WORKSPACE environment variable. " )
else :
2018-11-23 08:04:45 +01:00
Workspace = os . path . normcase ( FdsCommandDict . get ( " Workspace " , os . environ . get ( ' WORKSPACE ' ) ) )
2014-01-27 06:23:15 +01:00
GenFdsGlobalVariable . WorkSpaceDir = Workspace
2018-11-23 08:04:45 +01:00
if FdsCommandDict . get ( " debug " ) :
2015-12-01 05:22:16 +01:00
GenFdsGlobalVariable . VerboseLogger ( " Using Workspace: " + Workspace )
2018-11-23 08:04:45 +01:00
if FdsCommandDict . get ( " GenfdsMultiThread " ) :
2017-11-22 08:42:25 +01:00
GenFdsGlobalVariable . EnableGenfdsMultiThread = True
2014-01-27 06:23:15 +01:00
os . chdir ( GenFdsGlobalVariable . WorkSpaceDir )
2018-07-05 11:40:04 +02:00
2015-10-08 11:27:14 +02:00
# set multiple workspace
PackagesPath = os . getenv ( " PACKAGES_PATH " )
mws . setWs ( GenFdsGlobalVariable . WorkSpaceDir , PackagesPath )
2014-01-27 06:23:15 +01:00
2018-11-23 08:04:45 +01:00
if FdsCommandDict . get ( " fdf_file " ) :
FdfFilename = FdsCommandDict . get ( " fdf_file " ) [ 0 ] . Path
2014-01-27 06:23:15 +01:00
FdfFilename = GenFdsGlobalVariable . ReplaceWorkspaceMacro ( FdfFilename )
if FdfFilename [ 0 : 2 ] == ' .. ' :
FdfFilename = os . path . realpath ( FdfFilename )
2015-12-01 05:22:16 +01:00
if not os . path . isabs ( FdfFilename ) :
2015-10-08 11:27:14 +02:00
FdfFilename = mws . join ( GenFdsGlobalVariable . WorkSpaceDir , FdfFilename )
2014-01-27 06:23:15 +01:00
if not os . path . exists ( FdfFilename ) :
EdkLogger . error ( " GenFds " , FILE_NOT_FOUND , ExtraData = FdfFilename )
GenFdsGlobalVariable . FdfFile = FdfFilename
GenFdsGlobalVariable . FdfFileTimeStamp = os . path . getmtime ( FdfFilename )
else :
EdkLogger . error ( " GenFds " , OPTION_MISSING , " Missing FDF filename " )
2018-11-23 08:04:45 +01:00
if FdsCommandDict . get ( " build_target " ) :
GenFdsGlobalVariable . TargetName = FdsCommandDict . get ( " build_target " )
2014-01-27 06:23:15 +01:00
2018-11-23 08:04:45 +01:00
if FdsCommandDict . get ( " toolchain_tag " ) :
GenFdsGlobalVariable . ToolChainTag = FdsCommandDict . get ( " toolchain_tag " )
2014-01-27 06:23:15 +01:00
2018-11-23 08:04:45 +01:00
if FdsCommandDict . get ( " active_platform " ) :
ActivePlatform = FdsCommandDict . get ( " active_platform " )
2014-01-27 06:23:15 +01:00
ActivePlatform = GenFdsGlobalVariable . ReplaceWorkspaceMacro ( ActivePlatform )
if ActivePlatform [ 0 : 2 ] == ' .. ' :
ActivePlatform = os . path . realpath ( ActivePlatform )
if not os . path . isabs ( ActivePlatform ) :
2015-10-08 11:27:14 +02:00
ActivePlatform = mws . join ( GenFdsGlobalVariable . WorkSpaceDir , ActivePlatform )
2014-01-27 06:23:15 +01:00
2018-10-23 19:29:19 +02:00
if not os . path . exists ( ActivePlatform ) :
2014-01-27 06:23:15 +01:00
EdkLogger . error ( " GenFds " , FILE_NOT_FOUND , " ActivePlatform doesn ' t exist! " )
else :
EdkLogger . error ( " GenFds " , OPTION_MISSING , " Missing active platform " )
2016-04-18 09:38:15 +02:00
GenFdsGlobalVariable . ActivePlatform = PathClass ( NormPath ( ActivePlatform ) )
2014-01-27 06:23:15 +01:00
2018-11-23 08:04:45 +01:00
if FdsCommandDict . get ( " conf_directory " ) :
2014-08-28 15:53:34 +02:00
# Get alternate Conf location, if it is absolute, then just use the absolute directory name
2018-11-23 08:04:45 +01:00
ConfDirectoryPath = os . path . normpath ( FdsCommandDict . get ( " conf_directory " ) )
2014-08-28 15:53:34 +02:00
if ConfDirectoryPath . startswith ( ' " ' ) :
ConfDirectoryPath = ConfDirectoryPath [ 1 : ]
if ConfDirectoryPath . endswith ( ' " ' ) :
ConfDirectoryPath = ConfDirectoryPath [ : - 1 ]
if not os . path . isabs ( ConfDirectoryPath ) :
# Since alternate directory name is not absolute, the alternate directory is located within the WORKSPACE
# This also handles someone specifying the Conf directory in the workspace. Using --conf=Conf
ConfDirectoryPath = os . path . join ( GenFdsGlobalVariable . WorkSpaceDir , ConfDirectoryPath )
else :
2018-04-17 16:40:15 +02:00
if " CONF_PATH " in os . environ :
2016-08-18 04:07:36 +02:00
ConfDirectoryPath = os . path . normcase ( os . environ [ " CONF_PATH " ] )
else :
# Get standard WORKSPACE/Conf, use the absolute path to the WORKSPACE/Conf
ConfDirectoryPath = mws . join ( GenFdsGlobalVariable . WorkSpaceDir , ' Conf ' )
2014-08-28 15:53:34 +02:00
GenFdsGlobalVariable . ConfDir = ConfDirectoryPath
2018-03-01 03:23:14 +01:00
if not GlobalData . gConfDirectory :
GlobalData . gConfDirectory = GenFdsGlobalVariable . ConfDir
2014-08-28 15:53:34 +02:00
BuildConfigurationFile = os . path . normpath ( os . path . join ( ConfDirectoryPath , " target.txt " ) )
2014-01-27 06:23:15 +01:00
if os . path . isfile ( BuildConfigurationFile ) == True :
2018-10-23 19:29:19 +02:00
TargetTxt = TargetTxtClassObject ( )
2016-05-06 09:20:23 +02:00
TargetTxt . LoadTargetTxtFile ( BuildConfigurationFile )
# if no build target given in command line, get it from target.txt
if not GenFdsGlobalVariable . TargetName :
2018-11-23 08:04:45 +01:00
BuildTargetList = TargetTxt . TargetTxtDictionary [ TAB_TAT_DEFINES_TARGET ]
2016-05-06 09:20:23 +02:00
if len ( BuildTargetList ) != 1 :
EdkLogger . error ( " GenFds " , OPTION_VALUE_INVALID , ExtraData = " Only allows one instance for Target. " )
GenFdsGlobalVariable . TargetName = BuildTargetList [ 0 ]
# if no tool chain given in command line, get it from target.txt
if not GenFdsGlobalVariable . ToolChainTag :
2018-11-23 08:04:45 +01:00
ToolChainList = TargetTxt . TargetTxtDictionary [ TAB_TAT_DEFINES_TOOL_CHAIN_TAG ]
2018-03-26 22:25:43 +02:00
if ToolChainList is None or len ( ToolChainList ) == 0 :
2016-05-06 09:20:23 +02:00
EdkLogger . error ( " GenFds " , RESOURCE_NOT_AVAILABLE , ExtraData = " No toolchain given. Don ' t know how to build. " )
if len ( ToolChainList ) != 1 :
EdkLogger . error ( " GenFds " , OPTION_VALUE_INVALID , ExtraData = " Only allows one instance for ToolChain. " )
GenFdsGlobalVariable . ToolChainTag = ToolChainList [ 0 ]
2014-01-27 06:23:15 +01:00
else :
EdkLogger . error ( " GenFds " , FILE_NOT_FOUND , ExtraData = BuildConfigurationFile )
2014-08-28 15:53:34 +02:00
#Set global flag for build mode
2018-11-23 08:04:45 +01:00
GlobalData . gIgnoreSource = FdsCommandDict . get ( " IgnoreSources " )
2014-08-28 15:53:34 +02:00
2018-11-23 08:04:45 +01:00
if FdsCommandDict . get ( " macro " ) :
for Pair in FdsCommandDict . get ( " macro " ) :
2014-08-28 15:53:34 +02:00
if Pair . startswith ( ' " ' ) :
Pair = Pair [ 1 : ]
if Pair . endswith ( ' " ' ) :
Pair = Pair [ : - 1 ]
2014-01-27 06:23:15 +01:00
List = Pair . split ( ' = ' )
if len ( List ) == 2 :
2016-05-06 09:20:23 +02:00
if not List [ 1 ] . strip ( ) :
EdkLogger . error ( " GenFds " , OPTION_VALUE_INVALID , ExtraData = " No Value given for Macro %s " % List [ 0 ] )
2019-01-09 07:44:36 +01:00
if List [ 0 ] . strip ( ) in [ " WORKSPACE " , " TARGET " , " TOOLCHAIN " ] :
2014-01-27 06:23:15 +01:00
GlobalData . gGlobalDefines [ List [ 0 ] . strip ( ) ] = List [ 1 ] . strip ( )
else :
GlobalData . gCommandLineDefines [ List [ 0 ] . strip ( ) ] = List [ 1 ] . strip ( )
else :
GlobalData . gCommandLineDefines [ List [ 0 ] . strip ( ) ] = " TRUE "
os . environ [ " WORKSPACE " ] = Workspace
2016-05-06 09:20:23 +02:00
# Use the -t and -b option as gGlobalDefines's TOOLCHAIN and TARGET if they are not defined
2018-04-17 16:40:15 +02:00
if " TARGET " not in GlobalData . gGlobalDefines :
2016-05-06 09:20:23 +02:00
GlobalData . gGlobalDefines [ " TARGET " ] = GenFdsGlobalVariable . TargetName
2018-04-17 16:40:15 +02:00
if " TOOLCHAIN " not in GlobalData . gGlobalDefines :
2016-05-06 09:20:23 +02:00
GlobalData . gGlobalDefines [ " TOOLCHAIN " ] = GenFdsGlobalVariable . ToolChainTag
2018-04-17 16:40:15 +02:00
if " TOOL_CHAIN_TAG " not in GlobalData . gGlobalDefines :
2016-05-06 09:20:23 +02:00
GlobalData . gGlobalDefines [ ' TOOL_CHAIN_TAG ' ] = GenFdsGlobalVariable . ToolChainTag
2014-01-27 06:23:15 +01:00
""" call Workspace build create database """
2014-08-28 15:53:34 +02:00
GlobalData . gDatabasePath = os . path . normpath ( os . path . join ( ConfDirectoryPath , GlobalData . gDatabasePath ) )
2018-11-09 08:41:02 +01:00
2018-11-23 08:04:45 +01:00
if WorkSpaceDataBase :
BuildWorkSpace = WorkSpaceDataBase
else :
2018-11-09 08:41:02 +01:00
BuildWorkSpace = WorkspaceDatabase ( )
2014-01-27 06:23:15 +01:00
#
# Get files real name in workspace dir
#
GlobalData . gAllFiles = DirCache ( Workspace )
GlobalData . gWorkspace = Workspace
2018-11-23 08:04:45 +01:00
if FdsCommandDict . get ( " build_architecture_list " ) :
ArchList = FdsCommandDict . get ( " build_architecture_list " ) . split ( ' , ' )
2014-01-27 06:23:15 +01:00
else :
2018-11-23 08:04:45 +01:00
ArchList = BuildWorkSpace . BuildObject [ GenFdsGlobalVariable . ActivePlatform , TAB_COMMON , FdsCommandDict . get ( " build_target " ) , FdsCommandDict . get ( " toolchain_tag " ) ] . SupArchList
2014-01-27 06:23:15 +01:00
2018-11-23 08:04:45 +01:00
TargetArchList = set ( BuildWorkSpace . BuildObject [ GenFdsGlobalVariable . ActivePlatform , TAB_COMMON , FdsCommandDict . get ( " build_target " ) , FdsCommandDict . get ( " toolchain_tag " ) ] . SupArchList ) & set ( ArchList )
2014-01-27 06:23:15 +01:00
if len ( TargetArchList ) == 0 :
2018-04-16 15:52:13 +02:00
EdkLogger . error ( " GenFds " , GENFDS_ERROR , " Target ARCH %s not in platform supported ARCH %s " % ( str ( ArchList ) , str ( BuildWorkSpace . BuildObject [ GenFdsGlobalVariable . ActivePlatform , TAB_COMMON ] . SupArchList ) ) )
2018-07-05 11:40:04 +02:00
2014-01-27 06:23:15 +01:00
for Arch in ArchList :
2018-11-23 08:04:45 +01:00
GenFdsGlobalVariable . OutputDirFromDscDict [ Arch ] = NormPath ( BuildWorkSpace . BuildObject [ GenFdsGlobalVariable . ActivePlatform , Arch , FdsCommandDict . get ( " build_target " ) , FdsCommandDict . get ( " toolchain_tag " ) ] . OutputDirectory )
2014-01-27 06:23:15 +01:00
2018-10-23 19:29:19 +02:00
# assign platform name based on last entry in ArchList
2018-11-23 08:04:45 +01:00
GenFdsGlobalVariable . PlatformName = BuildWorkSpace . BuildObject [ GenFdsGlobalVariable . ActivePlatform , ArchList [ - 1 ] , FdsCommandDict . get ( " build_target " ) , FdsCommandDict . get ( " toolchain_tag " ) ] . PlatformName
2018-10-23 19:29:19 +02:00
2018-11-23 08:04:45 +01:00
if FdsCommandDict . get ( " platform_build_directory " ) :
OutputDirFromCommandLine = GenFdsGlobalVariable . ReplaceWorkspaceMacro ( FdsCommandDict . get ( " platform_build_directory " ) )
2014-01-27 06:23:15 +01:00
if not os . path . isabs ( OutputDirFromCommandLine ) :
OutputDirFromCommandLine = os . path . join ( GenFdsGlobalVariable . WorkSpaceDir , OutputDirFromCommandLine )
for Arch in ArchList :
GenFdsGlobalVariable . OutputDirDict [ Arch ] = OutputDirFromCommandLine
else :
for Arch in ArchList :
GenFdsGlobalVariable . OutputDirDict [ Arch ] = os . path . join ( GenFdsGlobalVariable . OutputDirFromDscDict [ Arch ] , GenFdsGlobalVariable . TargetName + ' _ ' + GenFdsGlobalVariable . ToolChainTag )
for Key in GenFdsGlobalVariable . OutputDirDict :
OutputDir = GenFdsGlobalVariable . OutputDirDict [ Key ]
if OutputDir [ 0 : 2 ] == ' .. ' :
OutputDir = os . path . realpath ( OutputDir )
if OutputDir [ 1 ] != ' : ' :
OutputDir = os . path . join ( GenFdsGlobalVariable . WorkSpaceDir , OutputDir )
if not os . path . exists ( OutputDir ) :
EdkLogger . error ( " GenFds " , FILE_NOT_FOUND , ExtraData = OutputDir )
GenFdsGlobalVariable . OutputDirDict [ Key ] = OutputDir
""" Parse Fdf file, has to place after build Workspace as FDF may contain macros from DSC file """
2018-11-23 08:04:45 +01:00
if WorkSpaceDataBase :
FdfParserObj = GlobalData . gFdfParser
else :
FdfParserObj = FdfParser ( FdfFilename )
FdfParserObj . ParseFile ( )
2014-01-27 06:23:15 +01:00
if FdfParserObj . CycleReferenceCheck ( ) :
EdkLogger . error ( " GenFds " , FORMAT_NOT_SUPPORTED , " Cycle Reference Detected in FDF file " )
2018-11-23 08:04:45 +01:00
if FdsCommandDict . get ( " fd " ) :
if FdsCommandDict . get ( " fd " ) [ 0 ] . upper ( ) in FdfParserObj . Profile . FdDict :
GenFds . OnlyGenerateThisFd = FdsCommandDict . get ( " fd " ) [ 0 ]
2014-01-27 06:23:15 +01:00
else :
EdkLogger . error ( " GenFds " , OPTION_VALUE_INVALID ,
2018-11-23 08:04:45 +01:00
" No such an FD in FDF file: %s " % FdsCommandDict . get ( " fd " ) [ 0 ] )
2014-01-27 06:23:15 +01:00
2018-11-23 08:04:45 +01:00
if FdsCommandDict . get ( " fv " ) :
if FdsCommandDict . get ( " fv " ) [ 0 ] . upper ( ) in FdfParserObj . Profile . FvDict :
GenFds . OnlyGenerateThisFv = FdsCommandDict . get ( " fv " ) [ 0 ]
2014-01-27 06:23:15 +01:00
else :
EdkLogger . error ( " GenFds " , OPTION_VALUE_INVALID ,
2018-11-23 08:04:45 +01:00
" No such an FV in FDF file: %s " % FdsCommandDict . get ( " fv " ) [ 0 ] )
2014-01-27 06:23:15 +01:00
2018-11-23 08:04:45 +01:00
if FdsCommandDict . get ( " cap " ) :
if FdsCommandDict . get ( " cap " ) [ 0 ] . upper ( ) in FdfParserObj . Profile . CapsuleDict :
GenFds . OnlyGenerateThisCap = FdsCommandDict . get ( " cap " ) [ 0 ]
2014-01-27 06:23:15 +01:00
else :
EdkLogger . error ( " GenFds " , OPTION_VALUE_INVALID ,
2018-11-23 08:04:45 +01:00
" No such a Capsule in FDF file: %s " % FdsCommandDict . get ( " cap " ) [ 0 ] )
2014-01-27 06:23:15 +01:00
2016-04-20 03:32:52 +02:00
GenFdsGlobalVariable . WorkSpace = BuildWorkSpace
2018-10-23 19:29:19 +02:00
if ArchList :
2016-04-20 03:32:52 +02:00
GenFdsGlobalVariable . ArchList = ArchList
2018-01-31 09:49:14 +01:00
# Dsc Build Data will handle Pcd Settings from CommandLine.
2016-04-20 03:32:52 +02:00
2014-01-27 06:23:15 +01:00
""" Modify images from build output if the feature of loading driver at fixed address is on. """
if GenFdsGlobalVariable . FixedLoadAddress :
GenFds . PreprocessImage ( BuildWorkSpace , GenFdsGlobalVariable . ActivePlatform )
2017-03-13 08:11:38 +01:00
# Record the FV Region info that may specific in the FD
if FdfParserObj . Profile . FvDict and FdfParserObj . Profile . FdDict :
2018-10-23 19:29:19 +02:00
for FvObj in FdfParserObj . Profile . FvDict . values ( ) :
for FdObj in FdfParserObj . Profile . FdDict . values ( ) :
2017-03-13 08:11:38 +01:00
for RegionObj in FdObj . RegionList :
2018-04-26 18:57:56 +02:00
if RegionObj . RegionType != BINARY_FILE_TYPE_FV :
2017-03-13 08:11:38 +01:00
continue
for RegionData in RegionObj . RegionDataList :
if FvObj . UiFvName . upper ( ) == RegionData . upper ( ) :
2018-12-26 08:23:04 +01:00
if not FvObj . BaseAddress :
FvObj . BaseAddress = ' 0x %x ' % ( int ( FdObj . BaseAddress , 0 ) + RegionObj . Offset )
2017-03-13 08:11:38 +01:00
if FvObj . FvRegionInFD :
if FvObj . FvRegionInFD != RegionObj . Size :
EdkLogger . error ( " GenFds " , FORMAT_INVALID , " The FV %s ' s region is specified in multiple FD with different value. " % FvObj . UiFvName )
else :
FvObj . FvRegionInFD = RegionObj . Size
RegionObj . BlockInfoOfRegion ( FdObj . BlockSizeList , FvObj )
2014-01-27 06:23:15 +01:00
""" Call GenFds """
GenFds . GenFd ( ' ' , FdfParserObj , BuildWorkSpace , ArchList )
""" Generate GUID cross reference file """
2017-11-15 17:06:45 +01:00
GenFds . GenerateGuidXRefFile ( BuildWorkSpace , ArchList , FdfParserObj )
2014-01-27 06:23:15 +01:00
""" Display FV space info. """
GenFds . DisplayFvSpaceInfo ( FdfParserObj )
2018-10-23 19:29:19 +02:00
except Warning as X :
2015-12-01 05:22:16 +01:00
EdkLogger . error ( X . ToolName , FORMAT_INVALID , File = X . FileName , Line = X . LineNumber , ExtraData = X . Message , RaiseError = False )
2014-01-27 06:23:15 +01:00
ReturnCode = FORMAT_INVALID
2018-06-25 12:31:25 +02:00
except FatalError as X :
2018-11-23 08:04:45 +01:00
if FdsCommandDict . get ( " debug " ) is not None :
2014-01-27 06:23:15 +01:00
import traceback
EdkLogger . quiet ( traceback . format_exc ( ) )
ReturnCode = X . args [ 0 ]
except :
import traceback
EdkLogger . error (
" \n Python " ,
CODE_ERROR ,
" Tools code failure " ,
2019-05-21 04:06:52 +02:00
ExtraData = " Please send email to %s for help, attaching following call stack trace! \n " % MSG_EDKII_MAIL_ADDR ,
2014-01-27 06:23:15 +01:00
RaiseError = False
)
EdkLogger . quiet ( traceback . format_exc ( ) )
ReturnCode = CODE_ERROR
2014-08-28 15:53:34 +02:00
finally :
ClearDuplicatedInf ( )
2014-01-27 06:23:15 +01:00
return ReturnCode
2018-11-23 08:04:45 +01:00
def OptionsToCommandDict ( Options ) :
FdsCommandDict = { }
FdsCommandDict [ " verbose " ] = Options . verbose
FdsCommandDict [ " FixedAddress " ] = Options . FixedAddress
FdsCommandDict [ " quiet " ] = Options . quiet
FdsCommandDict [ " debug " ] = Options . debug
FdsCommandDict [ " Workspace " ] = Options . Workspace
FdsCommandDict [ " GenfdsMultiThread " ] = Options . GenfdsMultiThread
FdsCommandDict [ " fdf_file " ] = [ PathClass ( Options . filename ) ] if Options . filename else [ ]
FdsCommandDict [ " build_target " ] = Options . BuildTarget
FdsCommandDict [ " toolchain_tag " ] = Options . ToolChain
FdsCommandDict [ " active_platform " ] = Options . activePlatform
FdsCommandDict [ " OptionPcd " ] = Options . OptionPcd
FdsCommandDict [ " conf_directory " ] = Options . ConfDirectory
FdsCommandDict [ " IgnoreSources " ] = Options . IgnoreSources
FdsCommandDict [ " macro " ] = Options . Macros
FdsCommandDict [ " build_architecture_list " ] = Options . archList
FdsCommandDict [ " platform_build_directory " ] = Options . outputDir
FdsCommandDict [ " fd " ] = [ Options . uiFdName ] if Options . uiFdName else [ ]
FdsCommandDict [ " fv " ] = [ Options . uiFvName ] if Options . uiFvName else [ ]
FdsCommandDict [ " cap " ] = [ Options . uiCapName ] if Options . uiCapName else [ ]
return FdsCommandDict
2014-01-27 06:23:15 +01:00
gParamCheck = [ ]
def SingleCheckCallback ( option , opt_str , value , parser ) :
if option not in gParamCheck :
setattr ( parser . values , option . dest , value )
gParamCheck . append ( option )
else :
parser . error ( " Option %s only allows one instance in command line! " % option )
2016-04-20 03:32:52 +02:00
2014-01-27 06:23:15 +01:00
## Parse command line options
#
# Using standard Python module optparse to parse command line option of this tool.
#
# @retval Opt A optparse.Values object containing the parsed options
#
def myOptionParser ( ) :
usage = " % prog [options] -f input_file -a arch_list -b build_target -p active_platform -t tool_chain_tag -D \" MacroName [= MacroValue] \" "
2015-12-01 05:22:16 +01:00
Parser = OptionParser ( usage = usage , description = __copyright__ , version = " % prog " + str ( versionNumber ) )
2014-01-27 06:23:15 +01:00
Parser . add_option ( " -f " , " --file " , dest = " filename " , type = " string " , help = " Name of FDF file to convert " , action = " callback " , callback = SingleCheckCallback )
Parser . add_option ( " -a " , " --arch " , dest = " archList " , help = " comma separated list containing one or more of: IA32, X64, IPF, ARM, AARCH64 or EBC which should be built, overrides target.txt?s TARGET_ARCH " )
Parser . add_option ( " -q " , " --quiet " , action = " store_true " , type = None , help = " Disable all messages except FATAL ERRORS. " )
Parser . add_option ( " -v " , " --verbose " , action = " store_true " , type = None , help = " Turn on verbose output with informational messages printed. " )
Parser . add_option ( " -d " , " --debug " , action = " store " , type = " int " , help = " Enable debug messages at specified level. " )
Parser . add_option ( " -p " , " --platform " , type = " string " , dest = " activePlatform " , help = " Set the ACTIVE_PLATFORM, overrides target.txt ACTIVE_PLATFORM setting. " ,
action = " callback " , callback = SingleCheckCallback )
Parser . add_option ( " -w " , " --workspace " , type = " string " , dest = " Workspace " , default = os . environ . get ( ' WORKSPACE ' ) , help = " Set the WORKSPACE " ,
action = " callback " , callback = SingleCheckCallback )
Parser . add_option ( " -o " , " --outputDir " , type = " string " , dest = " outputDir " , help = " Name of Build Output directory " ,
action = " callback " , callback = SingleCheckCallback )
Parser . add_option ( " -r " , " --rom_image " , dest = " uiFdName " , help = " Build the image using the [FD] section named by FdUiName. " )
Parser . add_option ( " -i " , " --FvImage " , dest = " uiFvName " , help = " Build the FV image using the [FV] section named by UiFvName " )
Parser . add_option ( " -C " , " --CapsuleImage " , dest = " uiCapName " , help = " Build the Capsule image using the [Capsule] section named by UiCapName " )
Parser . add_option ( " -b " , " --buildtarget " , type = " string " , dest = " BuildTarget " , help = " Set the build TARGET, overrides target.txt TARGET setting. " ,
action = " callback " , callback = SingleCheckCallback )
Parser . add_option ( " -t " , " --tagname " , type = " string " , dest = " ToolChain " , help = " Using the tools: TOOL_CHAIN_TAG name to build the platform. " ,
action = " callback " , callback = SingleCheckCallback )
Parser . add_option ( " -D " , " --define " , action = " append " , type = " string " , dest = " Macros " , help = " Macro: \" Name [= Value] \" . " )
Parser . add_option ( " -s " , " --specifyaddress " , dest = " FixedAddress " , action = " store_true " , type = None , help = " Specify driver load address. " )
2014-08-28 15:53:34 +02:00
Parser . add_option ( " --conf " , action = " store " , type = " string " , dest = " ConfDirectory " , help = " Specify the customized Conf directory. " )
Parser . add_option ( " --ignore-sources " , action = " store_true " , dest = " IgnoreSources " , default = False , help = " Focus to a binary build and ignore all source files " )
2016-04-20 03:32:52 +02:00
Parser . add_option ( " --pcd " , action = " append " , dest = " OptionPcd " , help = " Set PCD value by command line. Format: \" PcdName=Value \" " )
2017-11-22 08:42:25 +01:00
Parser . add_option ( " --genfds-multi-thread " , action = " store_true " , dest = " GenfdsMultiThread " , default = False , help = " Enable GenFds multi thread to generate ffs file. " )
2014-08-28 15:53:34 +02:00
2018-10-23 19:29:19 +02:00
Options , _ = Parser . parse_args ( )
2014-01-27 06:23:15 +01:00
return Options
## The class implementing the EDK2 flash image generation process
#
# This process includes:
# 1. Collect workspace information, includes platform and module information
# 2. Call methods of Fd class to generate FD
# 3. Call methods of Fv class to generate FV that not belong to FD
#
2018-10-23 19:29:19 +02:00
class GenFds ( object ) :
2014-01-27 06:23:15 +01:00
FdfParsef = None
OnlyGenerateThisFd = None
OnlyGenerateThisFv = None
OnlyGenerateThisCap = None
## GenFd()
#
# @param OutputDir Output directory
2018-10-23 19:29:19 +02:00
# @param FdfParserObject FDF contents parser
2014-01-27 06:23:15 +01:00
# @param Workspace The directory of workspace
# @param ArchList The Arch list of platform
#
2018-10-23 19:29:19 +02:00
@staticmethod
def GenFd ( OutputDir , FdfParserObject , WorkSpace , ArchList ) :
GenFdsGlobalVariable . SetDir ( ' ' , FdfParserObject , WorkSpace , ArchList )
2014-01-27 06:23:15 +01:00
GenFdsGlobalVariable . VerboseLogger ( " Generate all Fd images and their required FV and Capsule images! " )
2018-04-17 16:40:15 +02:00
if GenFds . OnlyGenerateThisCap is not None and GenFds . OnlyGenerateThisCap . upper ( ) in GenFdsGlobalVariable . FdfParser . Profile . CapsuleDict :
CapsuleObj = GenFdsGlobalVariable . FdfParser . Profile . CapsuleDict [ GenFds . OnlyGenerateThisCap . upper ( ) ]
2018-03-26 22:25:43 +02:00
if CapsuleObj is not None :
2014-01-27 06:23:15 +01:00
CapsuleObj . GenCapsule ( )
return
2018-04-17 16:40:15 +02:00
if GenFds . OnlyGenerateThisFd is not None and GenFds . OnlyGenerateThisFd . upper ( ) in GenFdsGlobalVariable . FdfParser . Profile . FdDict :
FdObj = GenFdsGlobalVariable . FdfParser . Profile . FdDict [ GenFds . OnlyGenerateThisFd . upper ( ) ]
2018-03-26 22:25:43 +02:00
if FdObj is not None :
2014-01-27 06:23:15 +01:00
FdObj . GenFd ( )
return
2018-03-26 22:25:43 +02:00
elif GenFds . OnlyGenerateThisFd is None and GenFds . OnlyGenerateThisFv is None :
2018-04-17 16:40:15 +02:00
for FdObj in GenFdsGlobalVariable . FdfParser . Profile . FdDict . values ( ) :
2014-01-27 06:23:15 +01:00
FdObj . GenFd ( )
GenFdsGlobalVariable . VerboseLogger ( " \n Generate other FV images! " )
2018-04-17 16:40:15 +02:00
if GenFds . OnlyGenerateThisFv is not None and GenFds . OnlyGenerateThisFv . upper ( ) in GenFdsGlobalVariable . FdfParser . Profile . FvDict :
FvObj = GenFdsGlobalVariable . FdfParser . Profile . FvDict [ GenFds . OnlyGenerateThisFv . upper ( ) ]
2018-03-26 22:25:43 +02:00
if FvObj is not None :
2018-06-25 12:31:36 +02:00
Buffer = BytesIO ( )
2014-01-27 06:23:15 +01:00
FvObj . AddToBuffer ( Buffer )
Buffer . close ( )
return
2018-03-26 22:25:43 +02:00
elif GenFds . OnlyGenerateThisFv is None :
2018-04-17 16:40:15 +02:00
for FvObj in GenFdsGlobalVariable . FdfParser . Profile . FvDict . values ( ) :
2019-01-23 03:16:00 +01:00
Buffer = BytesIO ( )
2014-01-27 06:23:15 +01:00
FvObj . AddToBuffer ( Buffer )
Buffer . close ( )
2018-07-05 11:40:04 +02:00
2018-03-26 22:25:43 +02:00
if GenFds . OnlyGenerateThisFv is None and GenFds . OnlyGenerateThisFd is None and GenFds . OnlyGenerateThisCap is None :
2014-01-27 06:23:15 +01:00
if GenFdsGlobalVariable . FdfParser . Profile . CapsuleDict != { } :
GenFdsGlobalVariable . VerboseLogger ( " \n Generate other Capsule images! " )
2018-04-17 16:40:15 +02:00
for CapsuleObj in GenFdsGlobalVariable . FdfParser . Profile . CapsuleDict . values ( ) :
2014-01-27 06:23:15 +01:00
CapsuleObj . GenCapsule ( )
if GenFdsGlobalVariable . FdfParser . Profile . OptRomDict != { } :
GenFdsGlobalVariable . VerboseLogger ( " \n Generate all Option ROM! " )
2018-04-17 16:40:15 +02:00
for OptRomObj in GenFdsGlobalVariable . FdfParser . Profile . OptRomDict . values ( ) :
2014-01-27 06:23:15 +01:00
OptRomObj . AddToBuffer ( None )
2018-10-23 19:29:19 +02:00
2017-11-22 08:42:25 +01:00
@staticmethod
2018-10-23 19:29:19 +02:00
def GenFfsMakefile ( OutputDir , FdfParserObject , WorkSpace , ArchList , GlobalData ) :
GenFdsGlobalVariable . SetEnv ( FdfParserObject , WorkSpace , ArchList , GlobalData )
2018-04-17 16:40:15 +02:00
for FdObj in GenFdsGlobalVariable . FdfParser . Profile . FdDict . values ( ) :
2017-11-22 08:42:25 +01:00
FdObj . GenFd ( Flag = True )
2018-04-17 16:40:15 +02:00
for FvObj in GenFdsGlobalVariable . FdfParser . Profile . FvDict . values ( ) :
2017-11-22 08:42:25 +01:00
FvObj . AddToBuffer ( Buffer = None , Flag = True )
if GenFdsGlobalVariable . FdfParser . Profile . OptRomDict != { } :
2018-04-17 16:40:15 +02:00
for OptRomObj in GenFdsGlobalVariable . FdfParser . Profile . OptRomDict . values ( ) :
2017-11-22 08:42:25 +01:00
OptRomObj . AddToBuffer ( Buffer = None , Flag = True )
return GenFdsGlobalVariable . FfsCmdDict
2014-01-27 06:23:15 +01:00
## GetFvBlockSize()
#
# @param FvObj Whose block size to get
# @retval int Block size value
#
2018-10-23 19:29:19 +02:00
@staticmethod
2014-01-27 06:23:15 +01:00
def GetFvBlockSize ( FvObj ) :
DefaultBlockSize = 0x1
FdObj = None
2018-04-17 16:40:15 +02:00
if GenFds . OnlyGenerateThisFd is not None and GenFds . OnlyGenerateThisFd . upper ( ) in GenFdsGlobalVariable . FdfParser . Profile . FdDict :
2014-01-27 06:23:15 +01:00
FdObj = GenFdsGlobalVariable . FdfParser . Profile . FdDict [ GenFds . OnlyGenerateThisFd . upper ( ) ]
2018-03-26 22:25:43 +02:00
if FdObj is None :
2014-01-27 06:23:15 +01:00
for ElementFd in GenFdsGlobalVariable . FdfParser . Profile . FdDict . values ( ) :
for ElementRegion in ElementFd . RegionList :
2018-04-26 18:57:56 +02:00
if ElementRegion . RegionType == BINARY_FILE_TYPE_FV :
2014-01-27 06:23:15 +01:00
for ElementRegionData in ElementRegion . RegionDataList :
2018-03-26 22:25:43 +02:00
if ElementRegionData is not None and ElementRegionData . upper ( ) == FvObj . UiFvName :
2014-01-27 06:23:15 +01:00
if FvObj . BlockSizeList != [ ] :
return FvObj . BlockSizeList [ 0 ] [ 0 ]
else :
return ElementRegion . BlockSizeOfRegion ( ElementFd . BlockSizeList )
if FvObj . BlockSizeList != [ ] :
return FvObj . BlockSizeList [ 0 ] [ 0 ]
return DefaultBlockSize
else :
for ElementRegion in FdObj . RegionList :
2018-04-26 18:57:56 +02:00
if ElementRegion . RegionType == BINARY_FILE_TYPE_FV :
2014-01-27 06:23:15 +01:00
for ElementRegionData in ElementRegion . RegionDataList :
2018-03-26 22:25:43 +02:00
if ElementRegionData is not None and ElementRegionData . upper ( ) == FvObj . UiFvName :
2014-01-27 06:23:15 +01:00
if FvObj . BlockSizeList != [ ] :
return FvObj . BlockSizeList [ 0 ] [ 0 ]
else :
return ElementRegion . BlockSizeOfRegion ( ElementFd . BlockSizeList )
return DefaultBlockSize
## DisplayFvSpaceInfo()
#
# @param FvObj Whose block size to get
# @retval None
#
2018-10-23 19:29:19 +02:00
@staticmethod
def DisplayFvSpaceInfo ( FdfParserObject ) :
2018-07-05 11:40:04 +02:00
2014-01-27 06:23:15 +01:00
FvSpaceInfoList = [ ]
MaxFvNameLength = 0
2018-10-23 19:29:19 +02:00
for FvName in FdfParserObject . Profile . FvDict :
2014-01-27 06:23:15 +01:00
if len ( FvName ) > MaxFvNameLength :
MaxFvNameLength = len ( FvName )
FvSpaceInfoFileName = os . path . join ( GenFdsGlobalVariable . FvDir , FvName . upper ( ) + ' .Fv.map ' )
if os . path . exists ( FvSpaceInfoFileName ) :
2018-10-23 19:29:19 +02:00
FileLinesList = getlines ( FvSpaceInfoFileName )
2014-01-27 06:23:15 +01:00
TotalFound = False
Total = ' '
UsedFound = False
Used = ' '
FreeFound = False
Free = ' '
for Line in FileLinesList :
NameValue = Line . split ( ' = ' )
if len ( NameValue ) == 2 :
if NameValue [ 0 ] . strip ( ) == ' EFI_FV_TOTAL_SIZE ' :
TotalFound = True
Total = NameValue [ 1 ] . strip ( )
if NameValue [ 0 ] . strip ( ) == ' EFI_FV_TAKEN_SIZE ' :
UsedFound = True
Used = NameValue [ 1 ] . strip ( )
if NameValue [ 0 ] . strip ( ) == ' EFI_FV_SPACE_SIZE ' :
FreeFound = True
Free = NameValue [ 1 ] . strip ( )
2018-07-05 11:40:04 +02:00
2014-01-27 06:23:15 +01:00
if TotalFound and UsedFound and FreeFound :
FvSpaceInfoList . append ( ( FvName , Total , Used , Free ) )
2018-07-05 11:40:04 +02:00
2014-01-27 06:23:15 +01:00
GenFdsGlobalVariable . InfLogger ( ' \n FV Space Information ' )
for FvSpaceInfo in FvSpaceInfoList :
Name = FvSpaceInfo [ 0 ]
2018-12-03 03:29:40 +01:00
TotalSizeValue = int ( FvSpaceInfo [ 1 ] , 0 )
UsedSizeValue = int ( FvSpaceInfo [ 2 ] , 0 )
FreeSizeValue = int ( FvSpaceInfo [ 3 ] , 0 )
2014-01-27 06:23:15 +01:00
if UsedSizeValue == TotalSizeValue :
Percentage = ' 100 '
else :
2015-12-01 05:22:16 +01:00
Percentage = str ( ( UsedSizeValue + 0.0 ) / TotalSizeValue ) [ 0 : 4 ] . lstrip ( ' 0. ' )
2014-01-27 06:23:15 +01:00
GenFdsGlobalVariable . InfLogger ( Name + ' ' + ' [ ' + Percentage + ' %F ull] ' + str ( TotalSizeValue ) + ' total, ' + str ( UsedSizeValue ) + ' used, ' + str ( FreeSizeValue ) + ' free ' )
## PreprocessImage()
#
# @param BuildDb Database from build meta data files
# @param DscFile modules from dsc file will be preprocessed
# @retval None
#
2018-10-23 19:29:19 +02:00
@staticmethod
2014-01-27 06:23:15 +01:00
def PreprocessImage ( BuildDb , DscFile ) :
2018-04-16 15:52:13 +02:00
PcdDict = BuildDb . BuildObject [ DscFile , TAB_COMMON , GenFdsGlobalVariable . TargetName , GenFdsGlobalVariable . ToolChainTag ] . Pcds
2014-01-27 06:23:15 +01:00
PcdValue = ' '
for Key in PcdDict :
PcdObj = PcdDict [ Key ]
if PcdObj . TokenCName == ' PcdBsBaseAddress ' :
PcdValue = PcdObj . DefaultValue
break
2018-07-05 11:40:04 +02:00
2014-01-27 06:23:15 +01:00
if PcdValue == ' ' :
return
2018-07-05 11:40:04 +02:00
2018-12-03 03:29:40 +01:00
Int64PcdValue = int ( PcdValue , 0 )
2018-07-05 11:40:04 +02:00
if Int64PcdValue == 0 or Int64PcdValue < - 1 :
2014-01-27 06:23:15 +01:00
return
2018-07-05 11:40:04 +02:00
2014-01-27 06:23:15 +01:00
TopAddress = 0
if Int64PcdValue > 0 :
TopAddress = Int64PcdValue
2018-07-05 11:40:04 +02:00
2018-04-16 15:52:13 +02:00
ModuleDict = BuildDb . BuildObject [ DscFile , TAB_COMMON , GenFdsGlobalVariable . TargetName , GenFdsGlobalVariable . ToolChainTag ] . Modules
2014-01-27 06:23:15 +01:00
for Key in ModuleDict :
2018-04-16 15:52:13 +02:00
ModuleObj = BuildDb . BuildObject [ Key , TAB_COMMON , GenFdsGlobalVariable . TargetName , GenFdsGlobalVariable . ToolChainTag ]
2018-06-25 12:31:26 +02:00
print ( ModuleObj . BaseName + ' ' + ModuleObj . ModuleType )
2014-01-27 06:23:15 +01:00
2018-10-23 19:29:19 +02:00
@staticmethod
2017-11-15 17:06:45 +01:00
def GenerateGuidXRefFile ( BuildDb , ArchList , FdfParserObj ) :
2014-01-27 06:23:15 +01:00
GuidXRefFileName = os . path . join ( GenFdsGlobalVariable . FvDir , " Guid.xref " )
2019-01-23 03:16:00 +01:00
GuidXRefFile = [ ]
2018-08-28 04:08:08 +02:00
PkgGuidDict = { }
2014-07-01 09:10:10 +02:00
GuidDict = { }
2017-11-15 17:06:45 +01:00
ModuleList = [ ]
FileGuidList = [ ]
2018-12-26 08:23:04 +01:00
VariableGuidSet = set ( )
2014-01-27 06:23:15 +01:00
for Arch in ArchList :
PlatformDataBase = BuildDb . BuildObject [ GenFdsGlobalVariable . ActivePlatform , Arch , GenFdsGlobalVariable . TargetName , GenFdsGlobalVariable . ToolChainTag ]
2018-08-28 04:08:08 +02:00
PkgList = GenFdsGlobalVariable . WorkSpace . GetPackageList ( GenFdsGlobalVariable . ActivePlatform , Arch , GenFdsGlobalVariable . TargetName , GenFdsGlobalVariable . ToolChainTag )
for P in PkgList :
PkgGuidDict . update ( P . Guids )
2018-10-15 02:27:53 +02:00
for Name , Guid in PlatformDataBase . Pcds :
2018-08-28 04:08:08 +02:00
Pcd = PlatformDataBase . Pcds [ Name , Guid ]
if Pcd . Type in [ TAB_PCDS_DYNAMIC_HII , TAB_PCDS_DYNAMIC_EX_HII ] :
for SkuId in Pcd . SkuInfoList :
Sku = Pcd . SkuInfoList [ SkuId ]
2018-12-26 08:23:04 +01:00
if Sku . VariableGuid in VariableGuidSet : continue
VariableGuidSet . add ( Sku . VariableGuid )
2018-08-28 04:08:08 +02:00
if Sku . VariableGuid and Sku . VariableGuid in PkgGuidDict . keys ( ) :
GuidDict [ Sku . VariableGuid ] = PkgGuidDict [ Sku . VariableGuid ]
2014-01-27 06:23:15 +01:00
for ModuleFile in PlatformDataBase . Modules :
Module = BuildDb . BuildObject [ ModuleFile , Arch , GenFdsGlobalVariable . TargetName , GenFdsGlobalVariable . ToolChainTag ]
2017-11-15 17:06:45 +01:00
if Module in ModuleList :
continue
else :
ModuleList . append ( Module )
2018-10-23 19:29:19 +02:00
if GlobalData . gGuidPattern . match ( ModuleFile . BaseName ) :
2019-01-23 03:16:00 +01:00
GuidXRefFile . append ( " %s %s \n " % ( ModuleFile . BaseName , Module . BaseName ) )
2018-07-31 03:44:41 +02:00
else :
2019-01-23 03:16:00 +01:00
GuidXRefFile . append ( " %s %s \n " % ( Module . Guid , Module . BaseName ) )
2018-10-23 19:29:19 +02:00
GuidDict . update ( Module . Protocols )
GuidDict . update ( Module . Guids )
GuidDict . update ( Module . Ppis )
2017-11-15 17:06:45 +01:00
for FvName in FdfParserObj . Profile . FvDict :
for FfsObj in FdfParserObj . Profile . FvDict [ FvName ] . FfsList :
2018-10-23 19:29:19 +02:00
if not isinstance ( FfsObj , FileStatement ) :
2017-11-15 17:06:45 +01:00
InfPath = PathClass ( NormPath ( mws . join ( GenFdsGlobalVariable . WorkSpaceDir , FfsObj . InfFileName ) ) )
FdfModule = BuildDb . BuildObject [ InfPath , Arch , GenFdsGlobalVariable . TargetName , GenFdsGlobalVariable . ToolChainTag ]
if FdfModule in ModuleList :
continue
else :
ModuleList . append ( FdfModule )
2019-01-23 03:16:00 +01:00
GuidXRefFile . append ( " %s %s \n " % ( FdfModule . Guid , FdfModule . BaseName ) )
2018-10-23 19:29:19 +02:00
GuidDict . update ( FdfModule . Protocols )
GuidDict . update ( FdfModule . Guids )
GuidDict . update ( FdfModule . Ppis )
2017-11-15 17:06:45 +01:00
else :
FileStatementGuid = FfsObj . NameGuid
if FileStatementGuid in FileGuidList :
continue
else :
FileGuidList . append ( FileStatementGuid )
Name = [ ]
FfsPath = os . path . join ( GenFdsGlobalVariable . FvDir , ' Ffs ' )
2018-11-16 16:40:04 +01:00
FfsPath = glob ( os . path . join ( FfsPath , FileStatementGuid ) + TAB_STAR )
2017-11-15 17:06:45 +01:00
if not FfsPath :
continue
if not os . path . exists ( FfsPath [ 0 ] ) :
continue
MatchDict = { }
2018-10-23 19:29:19 +02:00
ReFileEnds = compile ( ' \ S+(.ui)$| \ S+(fv.sec.txt)$| \ S+(.pe32.txt)$| \ S+(.te.txt)$| \ S+(.pic.txt)$| \ S+(.raw.txt)$| \ S+(.ffs.txt)$ ' )
2017-11-15 17:06:45 +01:00
FileList = os . listdir ( FfsPath [ 0 ] )
for File in FileList :
Match = ReFileEnds . search ( File )
if Match :
for Index in range ( 1 , 8 ) :
if Match . group ( Index ) and Match . group ( Index ) in MatchDict :
MatchDict [ Match . group ( Index ) ] . append ( File )
elif Match . group ( Index ) :
MatchDict [ Match . group ( Index ) ] = [ File ]
if not MatchDict :
continue
if ' .ui ' in MatchDict :
for File in MatchDict [ ' .ui ' ] :
with open ( os . path . join ( FfsPath [ 0 ] , File ) , ' rb ' ) as F :
F . read ( )
length = F . tell ( )
F . seek ( 4 )
2018-12-07 05:34:44 +01:00
TmpStr = unpack ( ' %d h ' % ( ( length - 4 ) / / 2 ) , F . read ( ) )
2018-04-28 00:32:54 +02:00
Name = ' ' . join ( chr ( c ) for c in TmpStr [ : - 1 ] )
2017-11-15 17:06:45 +01:00
else :
FileList = [ ]
if ' fv.sec.txt ' in MatchDict :
FileList = MatchDict [ ' fv.sec.txt ' ]
elif ' .pe32.txt ' in MatchDict :
FileList = MatchDict [ ' .pe32.txt ' ]
elif ' .te.txt ' in MatchDict :
FileList = MatchDict [ ' .te.txt ' ]
elif ' .pic.txt ' in MatchDict :
FileList = MatchDict [ ' .pic.txt ' ]
elif ' .raw.txt ' in MatchDict :
FileList = MatchDict [ ' .raw.txt ' ]
elif ' .ffs.txt ' in MatchDict :
FileList = MatchDict [ ' .ffs.txt ' ]
else :
pass
for File in FileList :
with open ( os . path . join ( FfsPath [ 0 ] , File ) , ' r ' ) as F :
Name . append ( ( F . read ( ) . split ( ) [ - 1 ] ) )
if not Name :
continue
2018-06-25 12:31:35 +02:00
Name = ' ' . join ( Name ) if isinstance ( Name , type ( [ ] ) ) else Name
2019-01-23 03:16:00 +01:00
GuidXRefFile . append ( " %s %s \n " % ( FileStatementGuid , Name ) )
2017-11-15 17:06:45 +01:00
2014-07-01 09:10:10 +02:00
# Append GUIDs, Protocols, and PPIs to the Xref file
2019-01-23 03:16:00 +01:00
GuidXRefFile . append ( " \n " )
2014-07-01 09:10:10 +02:00
for key , item in GuidDict . items ( ) :
2019-01-23 03:16:00 +01:00
GuidXRefFile . append ( " %s %s \n " % ( GuidStructureStringToGuidString ( item ) . upper ( ) , key ) )
2014-07-01 09:10:10 +02:00
2019-01-23 03:16:00 +01:00
if GuidXRefFile :
GuidXRefFile = ' ' . join ( GuidXRefFile )
SaveFileOnChange ( GuidXRefFileName , GuidXRefFile , False )
2014-01-27 06:23:15 +01:00
GenFdsGlobalVariable . InfLogger ( " \n GUID cross reference file can be found at %s " % GuidXRefFileName )
elif os . path . exists ( GuidXRefFileName ) :
os . remove ( GuidXRefFileName )
2018-11-23 08:04:45 +01:00
2014-01-27 06:23:15 +01:00
if __name__ == ' __main__ ' :
r = main ( )
## 0-127 is a safe return range, and 1 is a standard default error
2018-10-23 19:29:19 +02:00
if r < 0 or r > 127 :
r = 1
exit ( r )
2014-01-27 06:23:15 +01:00