2014-01-27 05:23:15 +00:00
## @file
# generate flash image
#
2019-01-10 03:00:41 +08:00
# Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>
2014-01-27 05:23:15 +00:00
#
2019-04-03 16:03:11 -07:00
# SPDX-License-Identifier: BSD-2-Clause-Patent
2014-01-27 05:23:15 +00:00
#
##
# Import Modules
#
2018-10-15 08:27:53 +08:00
from __future__ import print_function
from __future__ import absolute_import
2018-10-24 01:29:19 +08:00
from re import compile
2014-01-27 05:23:15 +00:00
from optparse import OptionParser
2018-10-24 01:29:19 +08:00
from sys import exit
from glob import glob
from struct import unpack
from linecache import getlines
2018-06-25 18:31:36 +08:00
from io import BytesIO
2018-10-24 01:29:19 +08:00
import Common.LongFilePathOs as os
2021-09-23 16:59:03 +08:00
from Common.TargetTxtClassObject import TargetTxtDict , gDefaultTargetTxtFile
2017-02-15 14:47:47 +08:00
from Common.DataType import *
2014-01-27 05:23:15 +00:00
import Common.GlobalData as GlobalData
from Common import EdkLogger
2018-10-24 01:29:19 +08:00
from Common.StringUtils import NormPath
from Common.Misc import DirCache , PathClass , GuidStructureStringToGuidString
from Common.Misc import SaveFileOnChange , ClearDuplicatedInf
2014-01-27 05:23:15 +00:00
from Common.BuildVersion import gBUILD_VERSION
2015-10-08 09:27:14 +00:00
from Common.MultipleWorkspace import MultipleWorkspace as mws
2018-11-23 15:04:45 +08: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-24 01:29:19 +08:00
from Workspace.WorkspaceDatabase import WorkspaceDatabase
from .FdfParser import FdfParser , Warning
from .GenFdsGlobalVariable import GenFdsGlobalVariable
from .FfsFileStatement import FileStatement
2018-12-20 19:12:12 +08:00
import Common.DataType as DataType
from struct import Struct
2014-01-27 05:23:15 +00:00
## Version and Copyright
versionNumber = "1.0" + ' ' + gBUILD_VERSION
__version__ = "%prog Version " + versionNumber
2018-07-05 17:40:04 +08:00
__copyright__ = "Copyright (c) 2007 - 2018, Intel Corporation All rights reserved."
2014-01-27 05:23:15 +00: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 15:04:45 +08:00
EdkLogger . Initialize ()
return GenFdsApi ( OptionsToCommandDict ( Options ))
2014-01-27 05:23:15 +00:00
2018-12-20 19:12:12 +08: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 = ''
2019-09-06 21:22:58 +08:00
GenFdsGlobalVariable . EnableGenfdsMultiThread = True
2018-12-20 19:12:12 +08:00
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 15:04:45 +08:00
def GenFdsApi ( FdsCommandDict , WorkSpaceDataBase = None ):
2014-01-27 05:23:15 +00:00
global Workspace
Workspace = ""
ArchList = None
ReturnCode = 0
2018-12-20 19:12:12 +08:00
resetFdsGlobalVariable ()
2014-01-27 05:23:15 +00:00
try :
2018-11-23 15:04:45 +08:00
if FdsCommandDict . get ( "verbose" ):
2014-01-27 05:23:15 +00:00
EdkLogger . SetLevel ( EdkLogger . VERBOSE )
GenFdsGlobalVariable . VerboseMode = True
2018-07-05 17:40:04 +08:00
2018-11-23 15:04:45 +08:00
if FdsCommandDict . get ( "FixedAddress" ):
2014-01-27 05:23:15 +00:00
GenFdsGlobalVariable . FixedLoadAddress = True
2018-07-05 17:40:04 +08:00
2018-11-23 15:04:45 +08:00
if FdsCommandDict . get ( "quiet" ):
2014-01-27 05:23:15 +00:00
EdkLogger . SetLevel ( EdkLogger . QUIET )
2018-11-23 15:04:45 +08:00
if FdsCommandDict . get ( "debug" ):
EdkLogger . SetLevel ( FdsCommandDict . get ( "debug" ) + 1 )
GenFdsGlobalVariable . DebugLevel = FdsCommandDict . get ( "debug" )
2014-01-27 05:23:15 +00:00
else :
EdkLogger . SetLevel ( EdkLogger . INFO )
2018-11-23 15:04:45 +08:00
if not FdsCommandDict . get ( "Workspace" , os . environ . get ( 'WORKSPACE' )):
2014-01-27 05:23:15 +00: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 15:04:45 +08:00
elif not os . path . exists ( FdsCommandDict . get ( "Workspace" , os . environ . get ( 'WORKSPACE' ))):
2014-01-27 05:23:15 +00:00
EdkLogger . error ( "GenFds" , PARAMETER_INVALID , "WORKSPACE is invalid" ,
ExtraData = "Please use '-w' switch to pass it or set the WORKSPACE environment variable." )
else :
2024-12-19 14:01:12 +08:00
Workspace = os . path . normpath ( FdsCommandDict . get ( "Workspace" , os . environ . get ( 'WORKSPACE' )))
2014-01-27 05:23:15 +00:00
GenFdsGlobalVariable . WorkSpaceDir = Workspace
2018-11-23 15:04:45 +08:00
if FdsCommandDict . get ( "debug" ):
2015-12-01 04:22:16 +00:00
GenFdsGlobalVariable . VerboseLogger ( "Using Workspace:" + Workspace )
2018-11-23 15:04:45 +08:00
if FdsCommandDict . get ( "GenfdsMultiThread" ):
2017-11-22 15:42:25 +08:00
GenFdsGlobalVariable . EnableGenfdsMultiThread = True
2019-09-06 21:22:58 +08:00
else :
GenFdsGlobalVariable . EnableGenfdsMultiThread = False
2014-01-27 05:23:15 +00:00
os . chdir ( GenFdsGlobalVariable . WorkSpaceDir )
2018-07-05 17:40:04 +08:00
2015-10-08 09:27:14 +00:00
# set multiple workspace
PackagesPath = os . getenv ( "PACKAGES_PATH" )
mws . setWs ( GenFdsGlobalVariable . WorkSpaceDir , PackagesPath )
2014-01-27 05:23:15 +00:00
2018-11-23 15:04:45 +08:00
if FdsCommandDict . get ( "fdf_file" ):
FdfFilename = FdsCommandDict . get ( "fdf_file" )[ 0 ] . Path
2014-01-27 05:23:15 +00:00
FdfFilename = GenFdsGlobalVariable . ReplaceWorkspaceMacro ( FdfFilename )
if FdfFilename [ 0 : 2 ] == '..' :
2021-10-12 12:07:38 +08:00
FdfFilename = os . path . abspath ( FdfFilename )
2015-12-01 04:22:16 +00:00
if not os . path . isabs ( FdfFilename ):
2015-10-08 09:27:14 +00:00
FdfFilename = mws . join ( GenFdsGlobalVariable . WorkSpaceDir , FdfFilename )
2014-01-27 05:23:15 +00: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 15:04:45 +08:00
if FdsCommandDict . get ( "build_target" ):
GenFdsGlobalVariable . TargetName = FdsCommandDict . get ( "build_target" )
2014-01-27 05:23:15 +00:00
2018-11-23 15:04:45 +08:00
if FdsCommandDict . get ( "toolchain_tag" ):
GenFdsGlobalVariable . ToolChainTag = FdsCommandDict . get ( "toolchain_tag" )
2014-01-27 05:23:15 +00:00
2018-11-23 15:04:45 +08:00
if FdsCommandDict . get ( "active_platform" ):
ActivePlatform = FdsCommandDict . get ( "active_platform" )
2014-01-27 05:23:15 +00:00
ActivePlatform = GenFdsGlobalVariable . ReplaceWorkspaceMacro ( ActivePlatform )
if ActivePlatform [ 0 : 2 ] == '..' :
2021-10-12 12:07:38 +08:00
ActivePlatform = os . path . abspath ( ActivePlatform )
2014-01-27 05:23:15 +00:00
if not os . path . isabs ( ActivePlatform ):
2015-10-08 09:27:14 +00:00
ActivePlatform = mws . join ( GenFdsGlobalVariable . WorkSpaceDir , ActivePlatform )
2014-01-27 05:23:15 +00:00
2018-10-24 01:29:19 +08:00
if not os . path . exists ( ActivePlatform ):
2014-01-27 05:23:15 +00:00
EdkLogger . error ( "GenFds" , FILE_NOT_FOUND , "ActivePlatform doesn't exist!" )
else :
EdkLogger . error ( "GenFds" , OPTION_MISSING , "Missing active platform" )
2016-04-18 15:38:15 +08:00
GenFdsGlobalVariable . ActivePlatform = PathClass ( NormPath ( ActivePlatform ))
2014-01-27 05:23:15 +00:00
2018-11-23 15:04:45 +08:00
if FdsCommandDict . get ( "conf_directory" ):
2014-08-28 13:53:34 +00:00
# Get alternate Conf location, if it is absolute, then just use the absolute directory name
2018-11-23 15:04:45 +08:00
ConfDirectoryPath = os . path . normpath ( FdsCommandDict . get ( "conf_directory" ))
2014-08-28 13:53:34 +00: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 22:40:15 +08:00
if "CONF_PATH" in os . environ :
2024-12-19 14:01:12 +08:00
ConfDirectoryPath = os . path . normpath ( os . environ [ "CONF_PATH" ])
2016-08-18 10:07:36 +08:00
else :
# Get standard WORKSPACE/Conf, use the absolute path to the WORKSPACE/Conf
ConfDirectoryPath = mws . join ( GenFdsGlobalVariable . WorkSpaceDir , 'Conf' )
2014-08-28 13:53:34 +00:00
GenFdsGlobalVariable . ConfDir = ConfDirectoryPath
2018-03-01 10:23:14 +08:00
if not GlobalData . gConfDirectory :
GlobalData . gConfDirectory = GenFdsGlobalVariable . ConfDir
2021-09-23 16:59:03 +08:00
BuildConfigurationFile = os . path . normpath ( os . path . join ( ConfDirectoryPath , gDefaultTargetTxtFile ))
2014-01-27 05:23:15 +00:00
if os . path . isfile ( BuildConfigurationFile ) == True :
2016-05-06 15:20:23 +08:00
# if no build target given in command line, get it from target.txt
2020-01-10 16:29:45 +08:00
TargetObj = TargetTxtDict ()
TargetTxt = TargetObj . Target
2016-05-06 15:20:23 +08:00
if not GenFdsGlobalVariable . TargetName :
2018-11-23 15:04:45 +08:00
BuildTargetList = TargetTxt . TargetTxtDictionary [ TAB_TAT_DEFINES_TARGET ]
2016-05-06 15:20:23 +08: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 15:04:45 +08:00
ToolChainList = TargetTxt . TargetTxtDictionary [ TAB_TAT_DEFINES_TOOL_CHAIN_TAG ]
2018-03-27 04:25:43 +08:00
if ToolChainList is None or len ( ToolChainList ) == 0 :
2016-05-06 15:20:23 +08: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 05:23:15 +00:00
else :
EdkLogger . error ( "GenFds" , FILE_NOT_FOUND , ExtraData = BuildConfigurationFile )
2014-08-28 13:53:34 +00:00
#Set global flag for build mode
2018-11-23 15:04:45 +08:00
GlobalData . gIgnoreSource = FdsCommandDict . get ( "IgnoreSources" )
2014-08-28 13:53:34 +00:00
2018-11-23 15:04:45 +08:00
if FdsCommandDict . get ( "macro" ):
for Pair in FdsCommandDict . get ( "macro" ):
2014-08-28 13:53:34 +00:00
if Pair . startswith ( '"' ):
Pair = Pair [ 1 :]
if Pair . endswith ( '"' ):
Pair = Pair [: - 1 ]
2014-01-27 05:23:15 +00:00
List = Pair . split ( '=' )
if len ( List ) == 2 :
2016-05-06 15:20:23 +08:00
if not List [ 1 ] . strip ():
EdkLogger . error ( "GenFds" , OPTION_VALUE_INVALID , ExtraData = "No Value given for Macro %s " % List [ 0 ])
2019-01-09 14:44:36 +08:00
if List [ 0 ] . strip () in [ "WORKSPACE" , "TARGET" , "TOOLCHAIN" ]:
2014-01-27 05:23:15 +00: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 15:20:23 +08:00
# Use the -t and -b option as gGlobalDefines's TOOLCHAIN and TARGET if they are not defined
2018-04-17 22:40:15 +08:00
if "TARGET" not in GlobalData . gGlobalDefines :
2016-05-06 15:20:23 +08:00
GlobalData . gGlobalDefines [ "TARGET" ] = GenFdsGlobalVariable . TargetName
2018-04-17 22:40:15 +08:00
if "TOOLCHAIN" not in GlobalData . gGlobalDefines :
2016-05-06 15:20:23 +08:00
GlobalData . gGlobalDefines [ "TOOLCHAIN" ] = GenFdsGlobalVariable . ToolChainTag
2018-04-17 22:40:15 +08:00
if "TOOL_CHAIN_TAG" not in GlobalData . gGlobalDefines :
2016-05-06 15:20:23 +08:00
GlobalData . gGlobalDefines [ 'TOOL_CHAIN_TAG' ] = GenFdsGlobalVariable . ToolChainTag
2014-01-27 05:23:15 +00:00
"""call Workspace build create database"""
2014-08-28 13:53:34 +00:00
GlobalData . gDatabasePath = os . path . normpath ( os . path . join ( ConfDirectoryPath , GlobalData . gDatabasePath ))
2018-11-09 15:41:02 +08:00
2018-11-23 15:04:45 +08:00
if WorkSpaceDataBase :
BuildWorkSpace = WorkSpaceDataBase
else :
2018-11-09 15:41:02 +08:00
BuildWorkSpace = WorkspaceDatabase ()
2014-01-27 05:23:15 +00:00
#
# Get files real name in workspace dir
#
GlobalData . gAllFiles = DirCache ( Workspace )
GlobalData . gWorkspace = Workspace
2018-11-23 15:04:45 +08:00
if FdsCommandDict . get ( "build_architecture_list" ):
ArchList = FdsCommandDict . get ( "build_architecture_list" ) . split ( ',' )
2014-01-27 05:23:15 +00:00
else :
2018-11-23 15:04:45 +08:00
ArchList = BuildWorkSpace . BuildObject [ GenFdsGlobalVariable . ActivePlatform , TAB_COMMON , FdsCommandDict . get ( "build_target" ), FdsCommandDict . get ( "toolchain_tag" )] . SupArchList
2014-01-27 05:23:15 +00:00
2018-11-23 15:04:45 +08:00
TargetArchList = set ( BuildWorkSpace . BuildObject [ GenFdsGlobalVariable . ActivePlatform , TAB_COMMON , FdsCommandDict . get ( "build_target" ), FdsCommandDict . get ( "toolchain_tag" )] . SupArchList ) & set ( ArchList )
2014-01-27 05:23:15 +00:00
if len ( TargetArchList ) == 0 :
2018-04-16 21:52:13 +08: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 17:40:04 +08:00
2014-01-27 05:23:15 +00:00
for Arch in ArchList :
2018-11-23 15:04:45 +08:00
GenFdsGlobalVariable . OutputDirFromDscDict [ Arch ] = NormPath ( BuildWorkSpace . BuildObject [ GenFdsGlobalVariable . ActivePlatform , Arch , FdsCommandDict . get ( "build_target" ), FdsCommandDict . get ( "toolchain_tag" )] . OutputDirectory )
2014-01-27 05:23:15 +00:00
2018-10-24 01:29:19 +08:00
# assign platform name based on last entry in ArchList
2018-11-23 15:04:45 +08:00
GenFdsGlobalVariable . PlatformName = BuildWorkSpace . BuildObject [ GenFdsGlobalVariable . ActivePlatform , ArchList [ - 1 ], FdsCommandDict . get ( "build_target" ), FdsCommandDict . get ( "toolchain_tag" )] . PlatformName
2018-10-24 01:29:19 +08:00
2018-11-23 15:04:45 +08:00
if FdsCommandDict . get ( "platform_build_directory" ):
OutputDirFromCommandLine = GenFdsGlobalVariable . ReplaceWorkspaceMacro ( FdsCommandDict . get ( "platform_build_directory" ))
2014-01-27 05:23:15 +00: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 ] == '..' :
2021-10-12 12:07:38 +08:00
OutputDir = os . path . abspath ( OutputDir )
2014-01-27 05:23:15 +00:00
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 15:04:45 +08:00
if WorkSpaceDataBase :
FdfParserObj = GlobalData . gFdfParser
else :
FdfParserObj = FdfParser ( FdfFilename )
FdfParserObj . ParseFile ()
2014-01-27 05:23:15 +00:00
if FdfParserObj . CycleReferenceCheck ():
EdkLogger . error ( "GenFds" , FORMAT_NOT_SUPPORTED , "Cycle Reference Detected in FDF file" )
2018-11-23 15:04:45 +08:00
if FdsCommandDict . get ( "fd" ):
if FdsCommandDict . get ( "fd" )[ 0 ] . upper () in FdfParserObj . Profile . FdDict :
GenFds . OnlyGenerateThisFd = FdsCommandDict . get ( "fd" )[ 0 ]
2014-01-27 05:23:15 +00:00
else :
EdkLogger . error ( "GenFds" , OPTION_VALUE_INVALID ,
2018-11-23 15:04:45 +08:00
"No such an FD in FDF file: %s " % FdsCommandDict . get ( "fd" )[ 0 ])
2014-01-27 05:23:15 +00:00
2018-11-23 15:04:45 +08:00
if FdsCommandDict . get ( "fv" ):
if FdsCommandDict . get ( "fv" )[ 0 ] . upper () in FdfParserObj . Profile . FvDict :
GenFds . OnlyGenerateThisFv = FdsCommandDict . get ( "fv" )[ 0 ]
2014-01-27 05:23:15 +00:00
else :
EdkLogger . error ( "GenFds" , OPTION_VALUE_INVALID ,
2018-11-23 15:04:45 +08:00
"No such an FV in FDF file: %s " % FdsCommandDict . get ( "fv" )[ 0 ])
2014-01-27 05:23:15 +00:00
2018-11-23 15:04:45 +08:00
if FdsCommandDict . get ( "cap" ):
if FdsCommandDict . get ( "cap" )[ 0 ] . upper () in FdfParserObj . Profile . CapsuleDict :
GenFds . OnlyGenerateThisCap = FdsCommandDict . get ( "cap" )[ 0 ]
2014-01-27 05:23:15 +00:00
else :
EdkLogger . error ( "GenFds" , OPTION_VALUE_INVALID ,
2018-11-23 15:04:45 +08:00
"No such a Capsule in FDF file: %s " % FdsCommandDict . get ( "cap" )[ 0 ])
2014-01-27 05:23:15 +00:00
2016-04-20 09:32:52 +08:00
GenFdsGlobalVariable . WorkSpace = BuildWorkSpace
2018-10-24 01:29:19 +08:00
if ArchList :
2016-04-20 09:32:52 +08:00
GenFdsGlobalVariable . ArchList = ArchList
2018-01-31 16:49:14 +08:00
# Dsc Build Data will handle Pcd Settings from CommandLine.
2016-04-20 09:32:52 +08:00
2014-01-27 05:23:15 +00: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 15:11:38 +08:00
# Record the FV Region info that may specific in the FD
if FdfParserObj . Profile . FvDict and FdfParserObj . Profile . FdDict :
2018-10-24 01:29:19 +08:00
for FvObj in FdfParserObj . Profile . FvDict . values ():
for FdObj in FdfParserObj . Profile . FdDict . values ():
2017-03-13 15:11:38 +08:00
for RegionObj in FdObj . RegionList :
2018-04-27 00:57:56 +08:00
if RegionObj . RegionType != BINARY_FILE_TYPE_FV :
2017-03-13 15:11:38 +08:00
continue
for RegionData in RegionObj . RegionDataList :
if FvObj . UiFvName . upper () == RegionData . upper ():
2018-12-26 15:23:04 +08:00
if not FvObj . BaseAddress :
FvObj . BaseAddress = '0x %x ' % ( int ( FdObj . BaseAddress , 0 ) + RegionObj . Offset )
2017-03-13 15:11:38 +08: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 05:23:15 +00:00
"""Call GenFds"""
GenFds . GenFd ( '' , FdfParserObj , BuildWorkSpace , ArchList )
"""Generate GUID cross reference file"""
2017-11-16 00:06:45 +08:00
GenFds . GenerateGuidXRefFile ( BuildWorkSpace , ArchList , FdfParserObj )
2014-01-27 05:23:15 +00:00
"""Display FV space info."""
GenFds . DisplayFvSpaceInfo ( FdfParserObj )
2018-10-24 01:29:19 +08:00
except Warning as X :
2015-12-01 04:22:16 +00:00
EdkLogger . error ( X . ToolName , FORMAT_INVALID , File = X . FileName , Line = X . LineNumber , ExtraData = X . Message , RaiseError = False )
2014-01-27 05:23:15 +00:00
ReturnCode = FORMAT_INVALID
2018-06-25 18:31:25 +08:00
except FatalError as X :
2018-11-23 15:04:45 +08:00
if FdsCommandDict . get ( "debug" ) is not None :
2014-01-27 05:23:15 +00: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 10:06:52 +08:00
ExtraData = "Please send email to %s for help, attaching following call stack trace! \n " % MSG_EDKII_MAIL_ADDR ,
2014-01-27 05:23:15 +00:00
RaiseError = False
)
EdkLogger . quiet ( traceback . format_exc ())
ReturnCode = CODE_ERROR
2014-08-28 13:53:34 +00:00
finally :
ClearDuplicatedInf ()
2014-01-27 05:23:15 +00:00
return ReturnCode
2018-11-23 15:04:45 +08: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
2019-09-06 21:22:58 +08:00
FdsCommandDict [ "GenfdsMultiThread" ] = not Options . NoGenfdsMultiThread
2018-11-23 15:04:45 +08:00
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 05:23:15 +00: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 09:32:52 +08:00
2014-01-27 05:23:15 +00: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 04:22:16 +00:00
Parser = OptionParser ( usage = usage , description = __copyright__ , version = "%prog " + str ( versionNumber ))
2014-01-27 05:23:15 +00: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 13:53:34 +00: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 09:32:52 +08:00
Parser . add_option ( "--pcd" , action = "append" , dest = "OptionPcd" , help = "Set PCD value by command line. Format: \" PcdName=Value \" " )
2019-09-06 21:22:58 +08:00
Parser . add_option ( "--genfds-multi-thread" , action = "store_true" , dest = "GenfdsMultiThread" , default = True , help = "Enable GenFds multi thread to generate ffs file." )
Parser . add_option ( "--no-genfds-multi-thread" , action = "store_true" , dest = "NoGenfdsMultiThread" , default = False , help = "Disable GenFds multi thread to generate ffs file." )
2014-08-28 13:53:34 +00:00
2018-10-24 01:29:19 +08:00
Options , _ = Parser . parse_args ()
2014-01-27 05:23:15 +00: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-24 01:29:19 +08:00
class GenFds ( object ):
2014-01-27 05:23:15 +00:00
FdfParsef = None
OnlyGenerateThisFd = None
OnlyGenerateThisFv = None
OnlyGenerateThisCap = None
## GenFd()
#
# @param OutputDir Output directory
2018-10-24 01:29:19 +08:00
# @param FdfParserObject FDF contents parser
2014-01-27 05:23:15 +00:00
# @param Workspace The directory of workspace
# @param ArchList The Arch list of platform
#
2018-10-24 01:29:19 +08:00
@staticmethod
def GenFd ( OutputDir , FdfParserObject , WorkSpace , ArchList ):
GenFdsGlobalVariable . SetDir ( '' , FdfParserObject , WorkSpace , ArchList )
2014-01-27 05:23:15 +00:00
GenFdsGlobalVariable . VerboseLogger ( " Generate all Fd images and their required FV and Capsule images!" )
2018-04-17 22:40:15 +08: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-27 04:25:43 +08:00
if CapsuleObj is not None :
2014-01-27 05:23:15 +00:00
CapsuleObj . GenCapsule ()
return
2018-04-17 22:40:15 +08: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-27 04:25:43 +08:00
if FdObj is not None :
2014-01-27 05:23:15 +00:00
FdObj . GenFd ()
return
2018-03-27 04:25:43 +08:00
elif GenFds . OnlyGenerateThisFd is None and GenFds . OnlyGenerateThisFv is None :
2018-04-17 22:40:15 +08:00
for FdObj in GenFdsGlobalVariable . FdfParser . Profile . FdDict . values ():
2014-01-27 05:23:15 +00:00
FdObj . GenFd ()
GenFdsGlobalVariable . VerboseLogger ( " \n Generate other FV images! " )
2018-04-17 22:40:15 +08: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-27 04:25:43 +08:00
if FvObj is not None :
2018-06-25 18:31:36 +08:00
Buffer = BytesIO ()
2014-01-27 05:23:15 +00:00
FvObj . AddToBuffer ( Buffer )
Buffer . close ()
return
2018-03-27 04:25:43 +08:00
elif GenFds . OnlyGenerateThisFv is None :
2018-04-17 22:40:15 +08:00
for FvObj in GenFdsGlobalVariable . FdfParser . Profile . FvDict . values ():
2019-01-23 10:16:00 +08:00
Buffer = BytesIO ()
2014-01-27 05:23:15 +00:00
FvObj . AddToBuffer ( Buffer )
Buffer . close ()
2018-07-05 17:40:04 +08:00
2018-03-27 04:25:43 +08:00
if GenFds . OnlyGenerateThisFv is None and GenFds . OnlyGenerateThisFd is None and GenFds . OnlyGenerateThisCap is None :
2014-01-27 05:23:15 +00:00
if GenFdsGlobalVariable . FdfParser . Profile . CapsuleDict != {}:
GenFdsGlobalVariable . VerboseLogger ( " \n Generate other Capsule images!" )
2018-04-17 22:40:15 +08:00
for CapsuleObj in GenFdsGlobalVariable . FdfParser . Profile . CapsuleDict . values ():
2014-01-27 05:23:15 +00:00
CapsuleObj . GenCapsule ()
if GenFdsGlobalVariable . FdfParser . Profile . OptRomDict != {}:
GenFdsGlobalVariable . VerboseLogger ( " \n Generate all Option ROM!" )
2018-04-17 22:40:15 +08:00
for OptRomObj in GenFdsGlobalVariable . FdfParser . Profile . OptRomDict . values ():
2014-01-27 05:23:15 +00:00
OptRomObj . AddToBuffer ( None )
2018-10-24 01:29:19 +08:00
2017-11-22 15:42:25 +08:00
@staticmethod
2018-10-24 01:29:19 +08:00
def GenFfsMakefile ( OutputDir , FdfParserObject , WorkSpace , ArchList , GlobalData ):
GenFdsGlobalVariable . SetEnv ( FdfParserObject , WorkSpace , ArchList , GlobalData )
2018-04-17 22:40:15 +08:00
for FdObj in GenFdsGlobalVariable . FdfParser . Profile . FdDict . values ():
2017-11-22 15:42:25 +08:00
FdObj . GenFd ( Flag = True )
2018-04-17 22:40:15 +08:00
for FvObj in GenFdsGlobalVariable . FdfParser . Profile . FvDict . values ():
2017-11-22 15:42:25 +08:00
FvObj . AddToBuffer ( Buffer = None , Flag = True )
if GenFdsGlobalVariable . FdfParser . Profile . OptRomDict != {}:
2018-04-17 22:40:15 +08:00
for OptRomObj in GenFdsGlobalVariable . FdfParser . Profile . OptRomDict . values ():
2017-11-22 15:42:25 +08:00
OptRomObj . AddToBuffer ( Buffer = None , Flag = True )
return GenFdsGlobalVariable . FfsCmdDict
2014-01-27 05:23:15 +00:00
## GetFvBlockSize()
#
# @param FvObj Whose block size to get
# @retval int Block size value
#
2018-10-24 01:29:19 +08:00
@staticmethod
2014-01-27 05:23:15 +00:00
def GetFvBlockSize ( FvObj ):
DefaultBlockSize = 0x1
FdObj = None
2018-04-17 22:40:15 +08:00
if GenFds . OnlyGenerateThisFd is not None and GenFds . OnlyGenerateThisFd . upper () in GenFdsGlobalVariable . FdfParser . Profile . FdDict :
2014-01-27 05:23:15 +00:00
FdObj = GenFdsGlobalVariable . FdfParser . Profile . FdDict [ GenFds . OnlyGenerateThisFd . upper ()]
2018-03-27 04:25:43 +08:00
if FdObj is None :
2014-01-27 05:23:15 +00:00
for ElementFd in GenFdsGlobalVariable . FdfParser . Profile . FdDict . values ():
for ElementRegion in ElementFd . RegionList :
2018-04-27 00:57:56 +08:00
if ElementRegion . RegionType == BINARY_FILE_TYPE_FV :
2014-01-27 05:23:15 +00:00
for ElementRegionData in ElementRegion . RegionDataList :
2018-03-27 04:25:43 +08:00
if ElementRegionData is not None and ElementRegionData . upper () == FvObj . UiFvName :
2014-01-27 05:23:15 +00: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-27 00:57:56 +08:00
if ElementRegion . RegionType == BINARY_FILE_TYPE_FV :
2014-01-27 05:23:15 +00:00
for ElementRegionData in ElementRegion . RegionDataList :
2018-03-27 04:25:43 +08:00
if ElementRegionData is not None and ElementRegionData . upper () == FvObj . UiFvName :
2014-01-27 05:23:15 +00: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-24 01:29:19 +08:00
@staticmethod
def DisplayFvSpaceInfo ( FdfParserObject ):
2018-07-05 17:40:04 +08:00
2014-01-27 05:23:15 +00:00
FvSpaceInfoList = []
MaxFvNameLength = 0
2018-10-24 01:29:19 +08:00
for FvName in FdfParserObject . Profile . FvDict :
2014-01-27 05:23:15 +00: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-24 01:29:19 +08:00
FileLinesList = getlines ( FvSpaceInfoFileName )
2014-01-27 05:23:15 +00: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 17:40:04 +08:00
2014-01-27 05:23:15 +00:00
if TotalFound and UsedFound and FreeFound :
FvSpaceInfoList . append (( FvName , Total , Used , Free ))
2018-07-05 17:40:04 +08:00
2014-01-27 05:23:15 +00:00
GenFdsGlobalVariable . InfLogger ( ' \n FV Space Information' )
for FvSpaceInfo in FvSpaceInfoList :
Name = FvSpaceInfo [ 0 ]
2018-12-03 10:29:40 +08:00
TotalSizeValue = int ( FvSpaceInfo [ 1 ], 0 )
UsedSizeValue = int ( FvSpaceInfo [ 2 ], 0 )
FreeSizeValue = int ( FvSpaceInfo [ 3 ], 0 )
2014-01-27 05:23:15 +00:00
if UsedSizeValue == TotalSizeValue :
Percentage = '100'
else :
2015-12-01 04:22:16 +00:00
Percentage = str (( UsedSizeValue + 0.0 ) / TotalSizeValue )[ 0 : 4 ] . lstrip ( '0.' )
2020-10-30 08:09:25 +08:00
GenFdsGlobalVariable . InfLogger ( Name + ' ' + '[' + Percentage + ' %F ull] ' \
+ str ( TotalSizeValue ) + ' (' + hex ( TotalSizeValue ) + ')' + ' total, ' \
+ str ( UsedSizeValue ) + ' (' + hex ( UsedSizeValue ) + ')' + ' used, ' \
+ str ( FreeSizeValue ) + ' (' + hex ( FreeSizeValue ) + ')' + ' free' )
2014-01-27 05:23:15 +00:00
## PreprocessImage()
#
# @param BuildDb Database from build meta data files
# @param DscFile modules from dsc file will be preprocessed
# @retval None
#
2018-10-24 01:29:19 +08:00
@staticmethod
2014-01-27 05:23:15 +00:00
def PreprocessImage ( BuildDb , DscFile ):
2018-04-16 21:52:13 +08:00
PcdDict = BuildDb . BuildObject [ DscFile , TAB_COMMON , GenFdsGlobalVariable . TargetName , GenFdsGlobalVariable . ToolChainTag ] . Pcds
2014-01-27 05:23:15 +00:00
PcdValue = ''
for Key in PcdDict :
PcdObj = PcdDict [ Key ]
if PcdObj . TokenCName == 'PcdBsBaseAddress' :
PcdValue = PcdObj . DefaultValue
break
2018-07-05 17:40:04 +08:00
2014-01-27 05:23:15 +00:00
if PcdValue == '' :
return
2018-07-05 17:40:04 +08:00
2018-12-03 10:29:40 +08:00
Int64PcdValue = int ( PcdValue , 0 )
2018-07-05 17:40:04 +08:00
if Int64PcdValue == 0 or Int64PcdValue < - 1 :
2014-01-27 05:23:15 +00:00
return
2018-07-05 17:40:04 +08:00
2014-01-27 05:23:15 +00:00
TopAddress = 0
if Int64PcdValue > 0 :
TopAddress = Int64PcdValue
2018-07-05 17:40:04 +08:00
2018-04-16 21:52:13 +08:00
ModuleDict = BuildDb . BuildObject [ DscFile , TAB_COMMON , GenFdsGlobalVariable . TargetName , GenFdsGlobalVariable . ToolChainTag ] . Modules
2014-01-27 05:23:15 +00:00
for Key in ModuleDict :
2018-04-16 21:52:13 +08:00
ModuleObj = BuildDb . BuildObject [ Key , TAB_COMMON , GenFdsGlobalVariable . TargetName , GenFdsGlobalVariable . ToolChainTag ]
2018-06-25 18:31:26 +08:00
print ( ModuleObj . BaseName + ' ' + ModuleObj . ModuleType )
2014-01-27 05:23:15 +00:00
2018-10-24 01:29:19 +08:00
@staticmethod
2017-11-16 00:06:45 +08:00
def GenerateGuidXRefFile ( BuildDb , ArchList , FdfParserObj ):
2014-01-27 05:23:15 +00:00
GuidXRefFileName = os . path . join ( GenFdsGlobalVariable . FvDir , "Guid.xref" )
2019-01-23 10:16:00 +08:00
GuidXRefFile = []
2018-08-28 10:08:08 +08:00
PkgGuidDict = {}
2014-07-01 07:10:10 +00:00
GuidDict = {}
2017-11-16 00:06:45 +08:00
ModuleList = []
FileGuidList = []
2018-12-26 15:23:04 +08:00
VariableGuidSet = set ()
2014-01-27 05:23:15 +00:00
for Arch in ArchList :
PlatformDataBase = BuildDb . BuildObject [ GenFdsGlobalVariable . ActivePlatform , Arch , GenFdsGlobalVariable . TargetName , GenFdsGlobalVariable . ToolChainTag ]
2018-08-28 10:08:08 +08:00
PkgList = GenFdsGlobalVariable . WorkSpace . GetPackageList ( GenFdsGlobalVariable . ActivePlatform , Arch , GenFdsGlobalVariable . TargetName , GenFdsGlobalVariable . ToolChainTag )
for P in PkgList :
PkgGuidDict . update ( P . Guids )
2018-10-15 08:27:53 +08:00
for Name , Guid in PlatformDataBase . Pcds :
2018-08-28 10:08:08 +08: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 15:23:04 +08:00
if Sku . VariableGuid in VariableGuidSet : continue
VariableGuidSet . add ( Sku . VariableGuid )
2018-08-28 10:08:08 +08:00
if Sku . VariableGuid and Sku . VariableGuid in PkgGuidDict . keys ():
GuidDict [ Sku . VariableGuid ] = PkgGuidDict [ Sku . VariableGuid ]
2014-01-27 05:23:15 +00:00
for ModuleFile in PlatformDataBase . Modules :
Module = BuildDb . BuildObject [ ModuleFile , Arch , GenFdsGlobalVariable . TargetName , GenFdsGlobalVariable . ToolChainTag ]
2017-11-16 00:06:45 +08:00
if Module in ModuleList :
continue
else :
ModuleList . append ( Module )
2018-10-24 01:29:19 +08:00
if GlobalData . gGuidPattern . match ( ModuleFile . BaseName ):
2019-01-23 10:16:00 +08:00
GuidXRefFile . append ( " %s %s \n " % ( ModuleFile . BaseName , Module . BaseName ))
2018-07-31 09:44:41 +08:00
else :
2019-01-23 10:16:00 +08:00
GuidXRefFile . append ( " %s %s \n " % ( Module . Guid , Module . BaseName ))
2018-10-24 01:29:19 +08:00
GuidDict . update ( Module . Protocols )
GuidDict . update ( Module . Guids )
GuidDict . update ( Module . Ppis )
2017-11-16 00:06:45 +08:00
for FvName in FdfParserObj . Profile . FvDict :
for FfsObj in FdfParserObj . Profile . FvDict [ FvName ] . FfsList :
2018-10-24 01:29:19 +08:00
if not isinstance ( FfsObj , FileStatement ):
2017-11-16 00:06:45 +08: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 10:16:00 +08:00
GuidXRefFile . append ( " %s %s \n " % ( FdfModule . Guid , FdfModule . BaseName ))
2018-10-24 01:29:19 +08:00
GuidDict . update ( FdfModule . Protocols )
GuidDict . update ( FdfModule . Guids )
GuidDict . update ( FdfModule . Ppis )
2017-11-16 00:06:45 +08: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 23:40:04 +08:00
FfsPath = glob ( os . path . join ( FfsPath , FileStatementGuid ) + TAB_STAR )
2017-11-16 00:06:45 +08:00
if not FfsPath :
continue
if not os . path . exists ( FfsPath [ 0 ]):
continue
MatchDict = {}
2023-12-06 12:27:02 -08:00
ReFileEnds = compile ( r '\S+(.ui)$|\S+(fv.sec.txt)$|\S+(.pe32.txt)$|\S+(.te.txt)$|\S+(.pic.txt)$|\S+(.raw.txt)$|\S+(.ffs.txt)$' )
2017-11-16 00:06:45 +08: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 12:34:44 +08:00
TmpStr = unpack ( ' %d h' % (( length - 4 ) // 2 ), F . read ())
2018-04-28 06:32:54 +08:00
Name = '' . join ( chr ( c ) for c in TmpStr [: - 1 ])
2017-11-16 00:06:45 +08: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 18:31:35 +08:00
Name = ' ' . join ( Name ) if isinstance ( Name , type ([])) else Name
2019-01-23 10:16:00 +08:00
GuidXRefFile . append ( " %s %s \n " % ( FileStatementGuid , Name ))
2017-11-16 00:06:45 +08:00
2014-07-01 07:10:10 +00:00
# Append GUIDs, Protocols, and PPIs to the Xref file
2019-01-23 10:16:00 +08:00
GuidXRefFile . append ( " \n " )
2014-07-01 07:10:10 +00:00
for key , item in GuidDict . items ():
2019-01-23 10:16:00 +08:00
GuidXRefFile . append ( " %s %s \n " % ( GuidStructureStringToGuidString ( item ) . upper (), key ))
2014-07-01 07:10:10 +00:00
2019-01-23 10:16:00 +08:00
if GuidXRefFile :
GuidXRefFile = '' . join ( GuidXRefFile )
SaveFileOnChange ( GuidXRefFileName , GuidXRefFile , False )
2014-01-27 05:23:15 +00: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 15:04:45 +08:00
2014-01-27 05:23:15 +00:00
if __name__ == '__main__' :
r = main ()
## 0-127 is a safe return range, and 1 is a standard default error
2018-10-24 01:29:19 +08:00
if r < 0 or r > 127 :
r = 1
exit ( r )
2014-01-27 05:23:15 +00:00