2009-07-17 11:10:31 +02:00
## @file
# process FFS generation from INF statement
#
2015-02-06 04:40:27 +01:00
# Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>
Add support for ${s_*} and ${d_*} macros for in FDF file for the INF files, and for each statement in the build rules.
The following keywords are supported:
"src", "s_path", "s_dir", "s_name", "s_base", "s_ext", "dst", "d_path", "d_name", "d_base", "d_ext"
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Abner Chang <abner.chang@hp.com>
Reviewed-by: Yingke Liu <yingke.d.liu@intel.com>
Reviewed-by: Larry Hauch <larry.hauch@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16094 6f19259b-4bc3-4df7-8a09-765794883524
2014-09-11 08:44:17 +02:00
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.<BR>
2009-07-17 11:10:31 +02:00
#
2010-05-18 07:04:32 +02:00
# This program and the accompanying materials
2009-07-17 11:10:31 +02:00
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
##
# Import Modules
#
import Rule
2014-08-15 05:06:48 +02:00
import Common . LongFilePathOs as os
2011-05-11 12:26:49 +02:00
import StringIO
from struct import *
2009-07-17 11:10:31 +02:00
from GenFdsGlobalVariable import GenFdsGlobalVariable
import Ffs
import subprocess
import sys
import Section
import RuleSimpleFile
import RuleComplexFile
from CommonDataClass . FdfClass import FfsInfStatementClassObject
from Common . String import *
from Common . Misc import PathClass
from Common . Misc import GuidStructureByteArrayToGuidString
2014-08-28 15:53:34 +02:00
from Common . Misc import ProcessDuplicatedInf
2015-02-06 04:40:27 +01:00
from Common . Misc import GetVariableOffset
2009-07-17 11:10:31 +02:00
from Common import EdkLogger
from Common . BuildToolError import *
2010-03-01 00:39:39 +01:00
from GuidSection import GuidSection
from FvImageSection import FvImageSection
from Common . Misc import PeImageClass
2011-09-18 14:17:25 +02:00
from AutoGen . GenDepex import DependencyExpression
2013-11-18 08:41:21 +01:00
from PatchPcdValue . PatchPcdValue import PatchBinaryFile
2014-08-15 05:06:48 +02:00
from Common . LongFilePathSupport import CopyLongFilePath
from Common . LongFilePathSupport import OpenLongFilePath as open
2009-07-17 11:10:31 +02:00
## generate FFS from INF
#
#
class FfsInfStatement ( FfsInfStatementClassObject ) :
2014-01-10 06:25:50 +01:00
## The mapping dictionary from datum type to its maximum number.
_MAX_SIZE_TYPE = { " BOOLEAN " : 0x01 , " UINT8 " : 0xFF , " UINT16 " : 0xFFFF , " UINT32 " : 0xFFFFFFFF , " UINT64 " : 0xFFFFFFFFFFFFFFFF }
2009-07-17 11:10:31 +02:00
## The constructor
#
# @param self The object pointer
#
def __init__ ( self ) :
FfsInfStatementClassObject . __init__ ( self )
self . TargetOverrideList = [ ]
self . ShadowFromInfFile = None
self . KeepRelocFromRule = None
self . InDsc = True
self . OptRomDefs = { }
2011-05-11 12:26:49 +02:00
self . PiSpecVersion = ' 0x00000000 '
2011-08-26 09:46:26 +02:00
self . InfModule = None
2011-09-18 14:17:25 +02:00
self . FinalTargetSuffixMap = { }
2011-10-11 04:49:48 +02:00
self . CurrentLineNum = None
self . CurrentLineContent = None
self . FileName = None
self . InfFileName = None
2014-08-28 15:53:34 +02:00
self . OverrideGuid = None
self . PatchedBinFile = ' '
2014-09-12 08:57:22 +02:00
self . MacroDict = { }
2011-08-26 09:46:26 +02:00
2011-09-18 14:17:25 +02:00
## GetFinalTargetSuffixMap() method
2011-08-26 09:46:26 +02:00
#
# Get final build target list
2011-09-18 14:17:25 +02:00
def GetFinalTargetSuffixMap ( self ) :
2011-08-26 09:46:26 +02:00
if not self . InfModule or not self . CurrentArch :
return [ ]
2011-09-18 14:17:25 +02:00
if not self . FinalTargetSuffixMap :
FinalBuildTargetList = GenFdsGlobalVariable . GetModuleCodaTargetList ( self . InfModule , self . CurrentArch )
for File in FinalBuildTargetList :
self . FinalTargetSuffixMap . setdefault ( os . path . splitext ( File ) [ 1 ] , [ ] ) . append ( File )
# Check if current INF module has DEPEX
if ' .depex ' not in self . FinalTargetSuffixMap and self . InfModule . ModuleType != " USER_DEFINED " \
and not self . InfModule . DxsFile and not self . InfModule . LibraryClass :
ModuleType = self . InfModule . ModuleType
PlatformDataBase = GenFdsGlobalVariable . WorkSpace . BuildObject [ GenFdsGlobalVariable . ActivePlatform , self . CurrentArch , GenFdsGlobalVariable . TargetName , GenFdsGlobalVariable . ToolChainTag ]
if ModuleType != DataType . SUP_MODULE_USER_DEFINED :
for LibraryClass in PlatformDataBase . LibraryClasses . GetKeys ( ) :
if LibraryClass . startswith ( " NULL " ) and PlatformDataBase . LibraryClasses [ LibraryClass , ModuleType ] :
self . InfModule . LibraryClasses [ LibraryClass ] = PlatformDataBase . LibraryClasses [ LibraryClass , ModuleType ]
StrModule = str ( self . InfModule )
PlatformModule = None
if StrModule in PlatformDataBase . Modules :
PlatformModule = PlatformDataBase . Modules [ StrModule ]
for LibraryClass in PlatformModule . LibraryClasses :
if LibraryClass . startswith ( " NULL " ) :
self . InfModule . LibraryClasses [ LibraryClass ] = PlatformModule . LibraryClasses [ LibraryClass ]
DependencyList = [ self . InfModule ]
LibraryInstance = { }
DepexList = [ ]
while len ( DependencyList ) > 0 :
Module = DependencyList . pop ( 0 )
if not Module :
continue
for Dep in Module . Depex [ self . CurrentArch , ModuleType ] :
if DepexList != [ ] :
DepexList . append ( ' AND ' )
DepexList . append ( ' ( ' )
DepexList . extend ( Dep )
if DepexList [ - 1 ] == ' END ' : # no need of a END at this time
DepexList . pop ( )
DepexList . append ( ' ) ' )
if ' BEFORE ' in DepexList or ' AFTER ' in DepexList :
break
for LibName in Module . LibraryClasses :
if LibName in LibraryInstance :
continue
if PlatformModule and LibName in PlatformModule . LibraryClasses :
LibraryPath = PlatformModule . LibraryClasses [ LibName ]
else :
LibraryPath = PlatformDataBase . LibraryClasses [ LibName , ModuleType ]
if not LibraryPath :
LibraryPath = Module . LibraryClasses [ LibName ]
if not LibraryPath :
continue
LibraryModule = GenFdsGlobalVariable . WorkSpace . BuildObject [ LibraryPath , self . CurrentArch , GenFdsGlobalVariable . TargetName , GenFdsGlobalVariable . ToolChainTag ]
LibraryInstance [ LibName ] = LibraryModule
DependencyList . append ( LibraryModule )
if DepexList :
Dpx = DependencyExpression ( DepexList , ModuleType , True )
if len ( Dpx . PostfixNotation ) != 0 :
# It means this module has DEPEX
self . FinalTargetSuffixMap [ ' .depex ' ] = [ os . path . join ( self . EfiOutputPath , self . BaseName ) + ' .depex ' ]
return self . FinalTargetSuffixMap
2011-08-26 09:46:26 +02:00
2009-07-17 11:10:31 +02:00
## __InfParse() method
#
# Parse inf file to get module information
#
# @param self The object pointer
# @param Dict dictionary contains macro and value pair
#
def __InfParse__ ( self , Dict = { } ) :
GenFdsGlobalVariable . VerboseLogger ( " Begine parsing INf file : %s " % self . InfFileName )
self . InfFileName = self . InfFileName . replace ( ' $(WORKSPACE) ' , ' ' )
2014-08-28 15:53:34 +02:00
if len ( self . InfFileName ) > 1 and self . InfFileName [ 0 ] == ' \\ ' and self . InfFileName [ 1 ] == ' \\ ' :
pass
elif self . InfFileName [ 0 ] == ' \\ ' or self . InfFileName [ 0 ] == ' / ' :
2009-07-17 11:10:31 +02:00
self . InfFileName = self . InfFileName [ 1 : ]
if self . InfFileName . find ( ' $ ' ) == - 1 :
InfPath = NormPath ( self . InfFileName )
if not os . path . exists ( InfPath ) :
InfPath = GenFdsGlobalVariable . ReplaceWorkspaceMacro ( InfPath )
if not os . path . exists ( InfPath ) :
EdkLogger . error ( " GenFds " , GENFDS_ERROR , " Non-existant Module %s ! " % ( self . InfFileName ) )
self . CurrentArch = self . GetCurrentArch ( )
#
# Get the InfClass object
#
PathClassObj = PathClass ( self . InfFileName , GenFdsGlobalVariable . WorkSpaceDir )
2010-09-06 03:58:00 +02:00
ErrorCode , ErrorInfo = PathClassObj . Validate ( " .inf " )
2009-07-17 11:10:31 +02:00
if ErrorCode != 0 :
EdkLogger . error ( " GenFds " , ErrorCode , ExtraData = ErrorInfo )
2014-08-28 15:53:34 +02:00
if self . OverrideGuid :
PathClassObj = ProcessDuplicatedInf ( PathClassObj , self . OverrideGuid , GenFdsGlobalVariable . WorkSpaceDir )
2009-07-17 11:10:31 +02:00
if self . CurrentArch != None :
2011-10-29 08:59:30 +02:00
Inf = GenFdsGlobalVariable . WorkSpace . BuildObject [ PathClassObj , self . CurrentArch , GenFdsGlobalVariable . TargetName , GenFdsGlobalVariable . ToolChainTag ]
2009-07-17 11:10:31 +02:00
#
# Set Ffs BaseName, MdouleGuid, ModuleType, Version, OutputPath
#
self . BaseName = Inf . BaseName
self . ModuleGuid = Inf . Guid
self . ModuleType = Inf . ModuleType
2010-03-01 00:39:39 +01:00
if Inf . Specification != None and ' PI_SPECIFICATION_VERSION ' in Inf . Specification :
2009-11-09 12:47:35 +01:00
self . PiSpecVersion = Inf . Specification [ ' PI_SPECIFICATION_VERSION ' ]
2009-07-17 11:10:31 +02:00
if Inf . AutoGenVersion < 0x00010005 :
self . ModuleType = Inf . ComponentType
self . VersionString = Inf . Version
self . BinFileList = Inf . Binaries
self . SourceFileList = Inf . Sources
if self . KeepReloc == None and Inf . Shadow :
self . ShadowFromInfFile = Inf . Shadow
else :
2011-10-29 08:59:30 +02:00
Inf = GenFdsGlobalVariable . WorkSpace . BuildObject [ PathClassObj , ' COMMON ' , GenFdsGlobalVariable . TargetName , GenFdsGlobalVariable . ToolChainTag ]
2009-07-17 11:10:31 +02:00
self . BaseName = Inf . BaseName
self . ModuleGuid = Inf . Guid
self . ModuleType = Inf . ModuleType
2010-03-01 00:39:39 +01:00
if Inf . Specification != None and ' PI_SPECIFICATION_VERSION ' in Inf . Specification :
2009-11-09 12:47:35 +01:00
self . PiSpecVersion = Inf . Specification [ ' PI_SPECIFICATION_VERSION ' ]
2009-07-17 11:10:31 +02:00
self . VersionString = Inf . Version
self . BinFileList = Inf . Binaries
self . SourceFileList = Inf . Sources
if self . BinFileList == [ ] :
EdkLogger . error ( " GenFds " , GENFDS_ERROR ,
" INF %s specified in FDF could not be found in build ARCH %s ! " \
% ( self . InfFileName , GenFdsGlobalVariable . ArchList ) )
2014-08-28 15:53:34 +02:00
if self . OverrideGuid :
self . ModuleGuid = self . OverrideGuid
2009-07-17 11:10:31 +02:00
if len ( self . SourceFileList ) != 0 and not self . InDsc :
EdkLogger . warn ( " GenFds " , GENFDS_ERROR , " Module %s NOT found in DSC file; Is it really a binary module? " % ( self . InfFileName ) )
2011-05-11 12:26:49 +02:00
if self . ModuleType == ' SMM_CORE ' and int ( self . PiSpecVersion , 16 ) < 0x0001000A :
2009-11-09 12:47:35 +01:00
EdkLogger . error ( " GenFds " , FORMAT_NOT_SUPPORTED , " SMM_CORE module type can ' t be used in the module with PI_SPECIFICATION_VERSION less than 0x0001000A " , File = self . InfFileName )
2009-07-17 11:10:31 +02:00
if Inf . _Defs != None and len ( Inf . _Defs ) > 0 :
self . OptRomDefs . update ( Inf . _Defs )
2014-01-10 06:25:50 +01:00
2013-11-18 08:41:21 +01:00
self . PatchPcds = [ ]
InfPcds = Inf . Pcds
Platform = GenFdsGlobalVariable . WorkSpace . BuildObject [ GenFdsGlobalVariable . ActivePlatform , self . CurrentArch , GenFdsGlobalVariable . TargetName , GenFdsGlobalVariable . ToolChainTag ]
FdfPcdDict = GenFdsGlobalVariable . FdfParser . Profile . PcdDict
2014-01-10 06:25:50 +01:00
# Workaround here: both build and GenFds tool convert the workspace path to lower case
# But INF file path in FDF and DSC file may have real case characters.
# Try to convert the path to lower case to see if PCDs value are override by DSC.
2013-11-18 08:41:21 +01:00
DscModules = { }
for DscModule in Platform . Modules :
DscModules [ str ( DscModule ) . lower ( ) ] = Platform . Modules [ DscModule ]
for PcdKey in InfPcds :
Pcd = InfPcds [ PcdKey ]
if not hasattr ( Pcd , ' Offset ' ) :
continue
if Pcd . Type != ' PatchableInModule ' :
continue
2014-01-10 06:25:50 +01:00
# Override Patchable PCD value by the value from DSC
2013-11-18 08:41:21 +01:00
PatchPcd = None
InfLowerPath = str ( PathClassObj ) . lower ( )
if InfLowerPath in DscModules and PcdKey in DscModules [ InfLowerPath ] . Pcds :
PatchPcd = DscModules [ InfLowerPath ] . Pcds [ PcdKey ]
elif PcdKey in Platform . Pcds :
PatchPcd = Platform . Pcds [ PcdKey ]
DscOverride = False
if PatchPcd and Pcd . Type == PatchPcd . Type :
DefaultValue = PatchPcd . DefaultValue
DscOverride = True
2014-01-10 06:25:50 +01:00
# Override Patchable PCD value by the value from FDF
2013-11-18 08:41:21 +01:00
FdfOverride = False
if PcdKey in FdfPcdDict :
DefaultValue = FdfPcdDict [ PcdKey ]
FdfOverride = True
2014-01-10 06:25:50 +01:00
2013-11-18 08:41:21 +01:00
if not DscOverride and not FdfOverride :
continue
2014-01-10 06:25:50 +01:00
# Check value, if value are equal, no need to patch
2013-11-18 08:41:21 +01:00
if Pcd . DatumType == " VOID* " :
if Pcd . DefaultValue == DefaultValue or DefaultValue in [ None , ' ' ] :
continue
2014-01-10 06:25:50 +01:00
# Get the string size from FDF or DSC
2013-11-18 08:41:21 +01:00
if DefaultValue [ 0 ] == ' L ' :
2014-01-10 06:25:50 +01:00
# Remove L"", but the '\0' must be appended
2013-11-18 08:41:21 +01:00
MaxDatumSize = str ( ( len ( DefaultValue ) - 2 ) * 2 )
elif DefaultValue [ 0 ] == ' { ' :
MaxDatumSize = str ( len ( DefaultValue . split ( ' , ' ) ) )
else :
MaxDatumSize = str ( len ( DefaultValue ) - 1 )
if DscOverride :
Pcd . MaxDatumSize = PatchPcd . MaxDatumSize
2014-01-10 06:25:50 +01:00
# If no defined the maximum size in DSC, try to get current size from INF
2013-11-18 08:41:21 +01:00
if Pcd . MaxDatumSize in [ ' ' , None ] :
Pcd . MaxDatumSize = str ( len ( Pcd . DefaultValue . split ( ' , ' ) ) )
else :
Base1 = Base2 = 10
if Pcd . DefaultValue . upper ( ) . startswith ( ' 0X ' ) :
Base1 = 16
if DefaultValue . upper ( ) . startswith ( ' 0X ' ) :
Base2 = 16
try :
PcdValueInImg = int ( Pcd . DefaultValue , Base1 )
PcdValueInDscOrFdf = int ( DefaultValue , Base2 )
if PcdValueInImg == PcdValueInDscOrFdf :
continue
except :
continue
2014-01-10 06:25:50 +01:00
# Check the Pcd size and data type
2013-11-18 08:41:21 +01:00
if Pcd . DatumType == " VOID* " :
if int ( MaxDatumSize ) > int ( Pcd . MaxDatumSize ) :
EdkLogger . error ( " GenFds " , GENFDS_ERROR , " The size of VOID* type PCD ' %s . %s ' exceeds its maximum size %d bytes. " \
% ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , int ( MaxDatumSize ) - int ( Pcd . MaxDatumSize ) ) )
else :
if PcdValueInDscOrFdf > FfsInfStatement . _MAX_SIZE_TYPE [ Pcd . DatumType ] \
or PcdValueInImg > FfsInfStatement . _MAX_SIZE_TYPE [ Pcd . DatumType ] :
EdkLogger . error ( " GenFds " , GENFDS_ERROR , " The size of %s type PCD ' %s . %s ' doesn ' t match its data type. " \
% ( Pcd . DatumType , Pcd . TokenSpaceGuidCName , Pcd . TokenCName ) )
2014-08-28 15:53:34 +02:00
self . PatchPcds . append ( ( Pcd , DefaultValue ) )
2011-08-26 09:46:26 +02:00
self . InfModule = Inf
2013-11-18 08:41:21 +01:00
self . PcdIsDriver = Inf . PcdIsDriver
self . IsBinaryModule = Inf . IsBinaryModule
GenFdsGlobalVariable . VerboseLogger ( " BaseName : %s " % self . BaseName )
GenFdsGlobalVariable . VerboseLogger ( " ModuleGuid : %s " % self . ModuleGuid )
GenFdsGlobalVariable . VerboseLogger ( " ModuleType : %s " % self . ModuleType )
GenFdsGlobalVariable . VerboseLogger ( " VersionString : %s " % self . VersionString )
GenFdsGlobalVariable . VerboseLogger ( " InfFileName : %s " % self . InfFileName )
2009-07-17 11:10:31 +02:00
#
# Set OutputPath = ${WorkSpace}\Build\Fv\Ffs\${ModuleGuid}+ ${MdouleName}\
#
self . OutputPath = os . path . join ( GenFdsGlobalVariable . FfsDir , \
self . ModuleGuid + self . BaseName )
if not os . path . exists ( self . OutputPath ) :
os . makedirs ( self . OutputPath )
self . EfiOutputPath = self . __GetEFIOutPutPath__ ( )
GenFdsGlobalVariable . VerboseLogger ( " ModuelEFIPath: " + self . EfiOutputPath )
2014-08-28 15:53:34 +02:00
## PatchEfiFile
2013-11-18 08:41:21 +01:00
#
# Patch EFI file with patch PCD
#
# @param EfiFile: EFI file needs to be patched.
# @retval: Full path of patched EFI file: self.OutputPath + EfiFile base name
# If passed in file does not end with efi, return as is
#
2014-08-28 15:53:34 +02:00
def PatchEfiFile ( self , EfiFile , FileType ) :
2013-11-18 08:41:21 +01:00
if not self . PatchPcds :
return EfiFile
2014-08-28 15:53:34 +02:00
if FileType != ' PE32 ' and self . ModuleType != " USER_DEFINED " :
return EfiFile
if self . PatchedBinFile :
EdkLogger . error ( " GenFds " , GENFDS_ERROR ,
' Only one binary file can be patched: \n '
' a binary file has been patched: %s \n '
' current file: %s ' % ( self . PatchedBinFile , EfiFile ) ,
File = self . InfFileName )
2013-11-18 08:41:21 +01:00
Basename = os . path . basename ( EfiFile )
Output = os . path . join ( self . OutputPath , Basename )
2014-08-15 05:06:48 +02:00
CopyLongFilePath ( EfiFile , Output )
2014-08-28 15:53:34 +02:00
for Pcd , Value in self . PatchPcds :
RetVal , RetStr = PatchBinaryFile ( Output , int ( Pcd . Offset , 0 ) , Pcd . DatumType , Value , Pcd . MaxDatumSize )
2013-11-18 08:41:21 +01:00
if RetVal :
EdkLogger . error ( " GenFds " , GENFDS_ERROR , RetStr , File = self . InfFileName )
2014-08-28 15:53:34 +02:00
self . PatchedBinFile = os . path . normpath ( EfiFile )
2013-11-18 08:41:21 +01:00
return Output
2009-07-17 11:10:31 +02:00
## GenFfs() method
#
# Generate FFS
#
2010-03-01 00:39:39 +01:00
# @param self The object pointer
# @param Dict dictionary contains macro and value pair
# @param FvChildAddr Array of the inside FvImage base address
# @param FvParentAddr Parent Fv base address
# @retval string Generated FFS file name
2009-07-17 11:10:31 +02:00
#
2010-03-01 00:39:39 +01:00
def GenFfs ( self , Dict = { } , FvChildAddr = [ ] , FvParentAddr = None ) :
2009-07-17 11:10:31 +02:00
#
# Parse Inf file get Module related information
#
self . __InfParse__ ( Dict )
Add support for ${s_*} and ${d_*} macros for in FDF file for the INF files, and for each statement in the build rules.
The following keywords are supported:
"src", "s_path", "s_dir", "s_name", "s_base", "s_ext", "dst", "d_path", "d_name", "d_base", "d_ext"
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Abner Chang <abner.chang@hp.com>
Reviewed-by: Yingke Liu <yingke.d.liu@intel.com>
Reviewed-by: Larry Hauch <larry.hauch@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16094 6f19259b-4bc3-4df7-8a09-765794883524
2014-09-11 08:44:17 +02:00
SrcFile = os . path . join ( GenFdsGlobalVariable . WorkSpaceDir , self . InfFileName ) ;
DestFile = os . path . join ( self . OutputPath , self . ModuleGuid + ' .ffs ' )
2010-11-15 03:51:34 +01:00
Add support for ${s_*} and ${d_*} macros for in FDF file for the INF files, and for each statement in the build rules.
The following keywords are supported:
"src", "s_path", "s_dir", "s_name", "s_base", "s_ext", "dst", "d_path", "d_name", "d_base", "d_ext"
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Abner Chang <abner.chang@hp.com>
Reviewed-by: Yingke Liu <yingke.d.liu@intel.com>
Reviewed-by: Larry Hauch <larry.hauch@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16094 6f19259b-4bc3-4df7-8a09-765794883524
2014-09-11 08:44:17 +02:00
SrcFileDir = " . "
SrcPath = os . path . dirname ( SrcFile )
SrcFileName = os . path . basename ( SrcFile )
SrcFileBase , SrcFileExt = os . path . splitext ( SrcFileName )
DestPath = os . path . dirname ( DestFile )
DestFileName = os . path . basename ( DestFile )
DestFileBase , DestFileExt = os . path . splitext ( DestFileName )
self . MacroDict = {
# source file
" $ {src} " : SrcFile ,
" $ {s_path} " : SrcPath ,
" $ {s_dir} " : SrcFileDir ,
" $ {s_name} " : SrcFileName ,
" $ {s_base} " : SrcFileBase ,
" $ {s_ext} " : SrcFileExt ,
# destination file
" $ {dst} " : DestFile ,
" $ {d_path} " : DestPath ,
" $ {d_name} " : DestFileName ,
" $ {d_base} " : DestFileBase ,
" $ {d_ext} " : DestFileExt
}
2010-11-15 03:51:34 +01:00
#
# Allow binary type module not specify override rule in FDF file.
#
2014-08-28 15:53:34 +02:00
if len ( self . BinFileList ) > 0 :
2010-11-15 03:51:34 +01:00
if self . Rule == None or self . Rule == " " :
self . Rule = " BINARY "
2009-07-17 11:10:31 +02:00
#
# Get the rule of how to generate Ffs file
#
Rule = self . __GetRule__ ( )
GenFdsGlobalVariable . VerboseLogger ( " Packing binaries from inf file : %s " % self . InfFileName )
2009-11-09 12:47:35 +01:00
#
# Convert Fv File Type for PI1.1 SMM driver.
#
2011-05-11 12:26:49 +02:00
if self . ModuleType == ' DXE_SMM_DRIVER ' and int ( self . PiSpecVersion , 16 ) > = 0x0001000A :
2009-11-09 12:47:35 +01:00
if Rule . FvFileType == ' DRIVER ' :
Rule . FvFileType = ' SMM '
#
# Framework SMM Driver has no SMM FV file type
#
2011-05-11 12:26:49 +02:00
if self . ModuleType == ' DXE_SMM_DRIVER ' and int ( self . PiSpecVersion , 16 ) < 0x0001000A :
2009-11-09 12:47:35 +01:00
if Rule . FvFileType == ' SMM ' or Rule . FvFileType == ' SMM_CORE ' :
EdkLogger . error ( " GenFds " , FORMAT_NOT_SUPPORTED , " Framework SMM module doesn ' t support SMM or SMM_CORE FV file type " , File = self . InfFileName )
2009-07-17 11:10:31 +02:00
#
# For the rule only has simpleFile
#
if isinstance ( Rule , RuleSimpleFile . RuleSimpleFile ) :
SectionOutputList = self . __GenSimpleFileSection__ ( Rule )
FfsOutput = self . __GenSimpleFileFfs__ ( Rule , SectionOutputList )
return FfsOutput
#
# For Rule has ComplexFile
#
elif isinstance ( Rule , RuleComplexFile . RuleComplexFile ) :
2010-03-01 00:39:39 +01:00
InputSectList , InputSectAlignments = self . __GenComplexFileSection__ ( Rule , FvChildAddr , FvParentAddr )
2009-07-17 11:10:31 +02:00
FfsOutput = self . __GenComplexFileFfs__ ( Rule , InputSectList , InputSectAlignments )
return FfsOutput
## __ExtendMacro__() method
#
# Replace macro with its value
#
# @param self The object pointer
# @param String The string to be replaced
# @retval string Macro replaced string
#
def __ExtendMacro__ ( self , String ) :
MacroDict = {
' $(INF_OUTPUT) ' : self . EfiOutputPath ,
' $(MODULE_NAME) ' : self . BaseName ,
' $(BUILD_NUMBER) ' : self . BuildNum ,
' $(INF_VERSION) ' : self . VersionString ,
' $(NAMED_GUID) ' : self . ModuleGuid
}
String = GenFdsGlobalVariable . MacroExtend ( String , MacroDict )
Add support for ${s_*} and ${d_*} macros for in FDF file for the INF files, and for each statement in the build rules.
The following keywords are supported:
"src", "s_path", "s_dir", "s_name", "s_base", "s_ext", "dst", "d_path", "d_name", "d_base", "d_ext"
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Abner Chang <abner.chang@hp.com>
Reviewed-by: Yingke Liu <yingke.d.liu@intel.com>
Reviewed-by: Larry Hauch <larry.hauch@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16094 6f19259b-4bc3-4df7-8a09-765794883524
2014-09-11 08:44:17 +02:00
String = GenFdsGlobalVariable . MacroExtend ( String , self . MacroDict )
2009-07-17 11:10:31 +02:00
return String
## __GetRule__() method
#
# Get correct rule for generating FFS for this INF
#
# @param self The object pointer
# @retval Rule Rule object
#
def __GetRule__ ( self ) :
CurrentArchList = [ ]
if self . CurrentArch == None :
CurrentArchList = [ ' common ' ]
else :
CurrentArchList . append ( self . CurrentArch )
for CurrentArch in CurrentArchList :
RuleName = ' RULE ' + \
' . ' + \
CurrentArch . upper ( ) + \
' . ' + \
self . ModuleType . upper ( )
if self . Rule != None :
RuleName = RuleName + \
' . ' + \
self . Rule . upper ( )
Rule = GenFdsGlobalVariable . FdfParser . Profile . RuleDict . get ( RuleName )
if Rule != None :
GenFdsGlobalVariable . VerboseLogger ( " Want To Find Rule Name is : " + RuleName )
return Rule
RuleName = ' RULE ' + \
' . ' + \
' COMMON ' + \
' . ' + \
self . ModuleType . upper ( )
if self . Rule != None :
RuleName = RuleName + \
' . ' + \
self . Rule . upper ( )
GenFdsGlobalVariable . VerboseLogger ( ' Trying to apply common rule %s for INF %s ' % ( RuleName , self . InfFileName ) )
Rule = GenFdsGlobalVariable . FdfParser . Profile . RuleDict . get ( RuleName )
if Rule != None :
GenFdsGlobalVariable . VerboseLogger ( " Want To Find Rule Name is : " + RuleName )
return Rule
if Rule == None :
EdkLogger . error ( " GenFds " , GENFDS_ERROR , ' Don \' t Find common rule %s for INF %s ' \
% ( RuleName , self . InfFileName ) )
## __GetPlatformArchList__() method
#
# Get Arch list this INF built under
#
# @param self The object pointer
# @retval list Arch list
#
def __GetPlatformArchList__ ( self ) :
InfFileKey = os . path . normpath ( os . path . join ( GenFdsGlobalVariable . WorkSpaceDir , self . InfFileName ) )
DscArchList = [ ]
2011-10-29 08:59:30 +02:00
PlatformDataBase = GenFdsGlobalVariable . WorkSpace . BuildObject [ GenFdsGlobalVariable . ActivePlatform , ' IA32 ' , GenFdsGlobalVariable . TargetName , GenFdsGlobalVariable . ToolChainTag ]
2009-07-17 11:10:31 +02:00
if PlatformDataBase != None :
if InfFileKey in PlatformDataBase . Modules :
DscArchList . append ( ' IA32 ' )
2011-10-29 08:59:30 +02:00
PlatformDataBase = GenFdsGlobalVariable . WorkSpace . BuildObject [ GenFdsGlobalVariable . ActivePlatform , ' X64 ' , GenFdsGlobalVariable . TargetName , GenFdsGlobalVariable . ToolChainTag ]
2009-07-17 11:10:31 +02:00
if PlatformDataBase != None :
if InfFileKey in PlatformDataBase . Modules :
DscArchList . append ( ' X64 ' )
2011-10-29 08:59:30 +02:00
PlatformDataBase = GenFdsGlobalVariable . WorkSpace . BuildObject [ GenFdsGlobalVariable . ActivePlatform , ' IPF ' , GenFdsGlobalVariable . TargetName , GenFdsGlobalVariable . ToolChainTag ]
2009-07-17 11:10:31 +02:00
if PlatformDataBase != None :
if InfFileKey in ( PlatformDataBase . Modules ) :
DscArchList . append ( ' IPF ' )
2011-10-29 08:59:30 +02:00
PlatformDataBase = GenFdsGlobalVariable . WorkSpace . BuildObject [ GenFdsGlobalVariable . ActivePlatform , ' ARM ' , GenFdsGlobalVariable . TargetName , GenFdsGlobalVariable . ToolChainTag ]
2009-07-17 11:10:31 +02:00
if PlatformDataBase != None :
if InfFileKey in ( PlatformDataBase . Modules ) :
DscArchList . append ( ' ARM ' )
2011-10-29 08:59:30 +02:00
PlatformDataBase = GenFdsGlobalVariable . WorkSpace . BuildObject [ GenFdsGlobalVariable . ActivePlatform , ' EBC ' , GenFdsGlobalVariable . TargetName , GenFdsGlobalVariable . ToolChainTag ]
2009-07-17 11:10:31 +02:00
if PlatformDataBase != None :
if InfFileKey in ( PlatformDataBase . Modules ) :
DscArchList . append ( ' EBC ' )
2013-08-23 04:18:16 +02:00
PlatformDataBase = GenFdsGlobalVariable . WorkSpace . BuildObject [ GenFdsGlobalVariable . ActivePlatform , ' AARCH64 ' , GenFdsGlobalVariable . TargetName , GenFdsGlobalVariable . ToolChainTag ]
if PlatformDataBase != None :
if InfFileKey in ( PlatformDataBase . Modules ) :
DscArchList . append ( ' AARCH64 ' )
2009-07-17 11:10:31 +02:00
return DscArchList
## GetCurrentArch() method
#
# Get Arch list of the module from this INF is to be placed into flash
#
# @param self The object pointer
# @retval list Arch list
#
def GetCurrentArch ( self ) :
TargetArchList = GenFdsGlobalVariable . ArchList
PlatformArchList = self . __GetPlatformArchList__ ( )
CurArchList = TargetArchList
if PlatformArchList != [ ] :
CurArchList = list ( set ( TargetArchList ) & set ( PlatformArchList ) )
GenFdsGlobalVariable . VerboseLogger ( " Valid target architecture(s) is : " + " " . join ( CurArchList ) )
ArchList = [ ]
if self . KeyStringList != [ ] :
for Key in self . KeyStringList :
Key = GenFdsGlobalVariable . MacroExtend ( Key )
Target , Tag , Arch = Key . split ( ' _ ' )
if Arch in CurArchList :
ArchList . append ( Arch )
if Target not in self . TargetOverrideList :
self . TargetOverrideList . append ( Target )
else :
ArchList = CurArchList
UseArchList = TargetArchList
if self . UseArch != None :
UseArchList = [ ]
UseArchList . append ( self . UseArch )
ArchList = list ( set ( UseArchList ) & set ( ArchList ) )
self . InfFileName = NormPath ( self . InfFileName )
if len ( PlatformArchList ) == 0 :
self . InDsc = False
PathClassObj = PathClass ( self . InfFileName , GenFdsGlobalVariable . WorkSpaceDir )
2010-09-06 03:58:00 +02:00
ErrorCode , ErrorInfo = PathClassObj . Validate ( " .inf " )
2009-07-17 11:10:31 +02:00
if ErrorCode != 0 :
EdkLogger . error ( " GenFds " , ErrorCode , ExtraData = ErrorInfo )
if len ( ArchList ) == 1 :
Arch = ArchList [ 0 ]
return Arch
elif len ( ArchList ) > 1 :
if len ( PlatformArchList ) == 0 :
EdkLogger . error ( " GenFds " , GENFDS_ERROR , " GenFds command line option has multiple ARCHs %s . Not able to determine which ARCH is valid for Module %s ! " % ( str ( ArchList ) , self . InfFileName ) )
else :
EdkLogger . error ( " GenFds " , GENFDS_ERROR , " Module built under multiple ARCHs %s . Not able to determine which output to put into flash for Module %s ! " % ( str ( ArchList ) , self . InfFileName ) )
else :
EdkLogger . error ( " GenFds " , GENFDS_ERROR , " Module %s appears under ARCH %s in platform %s , but current deduced ARCH is %s , so NO build output could be put into flash. " \
% ( self . InfFileName , str ( PlatformArchList ) , GenFdsGlobalVariable . ActivePlatform , str ( set ( UseArchList ) & set ( TargetArchList ) ) ) )
## __GetEFIOutPutPath__() method
#
# Get the output path for generated files
#
# @param self The object pointer
# @retval string Path that output files from this INF go to
#
def __GetEFIOutPutPath__ ( self ) :
Arch = ' '
OutputPath = ' '
( ModulePath , FileName ) = os . path . split ( self . InfFileName )
2011-10-11 04:49:48 +02:00
Index = FileName . rfind ( ' . ' )
2009-07-17 11:10:31 +02:00
FileName = FileName [ 0 : Index ]
2014-08-28 15:53:34 +02:00
if self . OverrideGuid :
FileName = self . OverrideGuid
2009-07-17 11:10:31 +02:00
Arch = " NoneArch "
if self . CurrentArch != None :
Arch = self . CurrentArch
OutputPath = os . path . join ( GenFdsGlobalVariable . OutputDirDict [ Arch ] ,
Arch ,
ModulePath ,
FileName ,
' OUTPUT '
)
OutputPath = os . path . realpath ( OutputPath )
return OutputPath
## __GenSimpleFileSection__() method
#
# Generate section by specified file name or a list of files with file extension
#
# @param self The object pointer
# @param Rule The rule object used to generate section
# @retval string File name of the generated section file
#
def __GenSimpleFileSection__ ( self , Rule ) :
#
# Prepare the parameter of GenSection
#
FileList = [ ]
OutputFileList = [ ]
2010-03-01 00:39:39 +01:00
GenSecInputFile = None
2009-07-17 11:10:31 +02:00
if Rule . FileName != None :
GenSecInputFile = self . __ExtendMacro__ ( Rule . FileName )
2011-05-11 12:26:49 +02:00
if os . path . isabs ( GenSecInputFile ) :
GenSecInputFile = os . path . normpath ( GenSecInputFile )
else :
2010-03-01 00:39:39 +01:00
GenSecInputFile = os . path . normpath ( os . path . join ( self . EfiOutputPath , GenSecInputFile ) )
2009-07-17 11:10:31 +02:00
else :
FileList , IsSect = Section . Section . GetFileList ( self , ' ' , Rule . FileExtension )
Index = 1
2009-11-09 12:47:35 +01:00
SectionType = Rule . SectionType
#
# Convert Fv Section Type for PI1.1 SMM driver.
#
2011-05-11 12:26:49 +02:00
if self . ModuleType == ' DXE_SMM_DRIVER ' and int ( self . PiSpecVersion , 16 ) > = 0x0001000A :
2009-11-09 12:47:35 +01:00
if SectionType == ' DXE_DEPEX ' :
SectionType = ' SMM_DEPEX '
#
# Framework SMM Driver has no SMM_DEPEX section type
#
2011-05-11 12:26:49 +02:00
if self . ModuleType == ' DXE_SMM_DRIVER ' and int ( self . PiSpecVersion , 16 ) < 0x0001000A :
2009-11-09 12:47:35 +01:00
if SectionType == ' SMM_DEPEX ' :
EdkLogger . error ( " GenFds " , FORMAT_NOT_SUPPORTED , " Framework SMM module doesn ' t support SMM_DEPEX section type " , File = self . InfFileName )
2009-07-17 11:10:31 +02:00
NoStrip = True
if self . ModuleType in ( ' SEC ' , ' PEI_CORE ' , ' PEIM ' ) :
if self . KeepReloc != None :
NoStrip = self . KeepReloc
elif Rule . KeepReloc != None :
NoStrip = Rule . KeepReloc
elif self . ShadowFromInfFile != None :
NoStrip = self . ShadowFromInfFile
if FileList != [ ] :
for File in FileList :
SecNum = ' %d ' % Index
GenSecOutputFile = self . __ExtendMacro__ ( Rule . NameGuid ) + \
Ffs . Ffs . SectionSuffix [ SectionType ] + ' SEC ' + SecNum
Index = Index + 1
OutputFile = os . path . join ( self . OutputPath , GenSecOutputFile )
2010-03-01 00:39:39 +01:00
File = GenFdsGlobalVariable . MacroExtend ( File , Dict , self . CurrentArch )
#Get PE Section alignment when align is set to AUTO
if self . Alignment == ' Auto ' and ( SectionType == ' PE32 ' or SectionType == ' TE ' ) :
ImageObj = PeImageClass ( File )
if ImageObj . SectionAlignment < 0x400 :
self . Alignment = str ( ImageObj . SectionAlignment )
else :
self . Alignment = str ( ImageObj . SectionAlignment / 0x400 ) + ' K '
2009-07-17 11:10:31 +02:00
if not NoStrip :
FileBeforeStrip = os . path . join ( self . OutputPath , ModuleName + ' .reloc ' )
if not os . path . exists ( FileBeforeStrip ) or \
2014-08-15 05:06:48 +02:00
( os . path . getmtime ( File ) > os . path . getmtime ( FileBeforeStrip ) ) :
CopyLongFilePath ( File , FileBeforeStrip )
2009-07-17 11:10:31 +02:00
StrippedFile = os . path . join ( self . OutputPath , ModuleName + ' .stipped ' )
GenFdsGlobalVariable . GenerateFirmwareImage (
StrippedFile ,
2010-03-01 00:39:39 +01:00
[ File ] ,
2009-07-17 11:10:31 +02:00
Strip = True
)
File = StrippedFile
if SectionType == ' TE ' :
TeFile = os . path . join ( self . OutputPath , self . ModuleGuid + ' Te.raw ' )
GenFdsGlobalVariable . GenerateFirmwareImage (
TeFile ,
2010-03-01 00:39:39 +01:00
[ File ] ,
2009-07-17 11:10:31 +02:00
Type = ' te '
)
File = TeFile
GenFdsGlobalVariable . GenerateSection ( OutputFile , [ File ] , Section . Section . SectionType [ SectionType ] )
OutputFileList . append ( OutputFile )
else :
SecNum = ' %d ' % Index
GenSecOutputFile = self . __ExtendMacro__ ( Rule . NameGuid ) + \
Ffs . Ffs . SectionSuffix [ SectionType ] + ' SEC ' + SecNum
OutputFile = os . path . join ( self . OutputPath , GenSecOutputFile )
2010-03-01 00:39:39 +01:00
GenSecInputFile = GenFdsGlobalVariable . MacroExtend ( GenSecInputFile , Dict , self . CurrentArch )
#Get PE Section alignment when align is set to AUTO
if self . Alignment == ' Auto ' and ( SectionType == ' PE32 ' or SectionType == ' TE ' ) :
ImageObj = PeImageClass ( GenSecInputFile )
if ImageObj . SectionAlignment < 0x400 :
self . Alignment = str ( ImageObj . SectionAlignment )
else :
self . Alignment = str ( ImageObj . SectionAlignment / 0x400 ) + ' K '
2009-07-17 11:10:31 +02:00
if not NoStrip :
FileBeforeStrip = os . path . join ( self . OutputPath , ModuleName + ' .reloc ' )
if not os . path . exists ( FileBeforeStrip ) or \
2014-08-15 05:06:48 +02:00
( os . path . getmtime ( GenSecInputFile ) > os . path . getmtime ( FileBeforeStrip ) ) :
CopyLongFilePath ( GenSecInputFile , FileBeforeStrip )
2009-07-17 11:10:31 +02:00
StrippedFile = os . path . join ( self . OutputPath , ModuleName + ' .stipped ' )
GenFdsGlobalVariable . GenerateFirmwareImage (
StrippedFile ,
2010-03-01 00:39:39 +01:00
[ GenSecInputFile ] ,
2009-07-17 11:10:31 +02:00
Strip = True
)
GenSecInputFile = StrippedFile
if SectionType == ' TE ' :
TeFile = os . path . join ( self . OutputPath , self . ModuleGuid + ' Te.raw ' )
GenFdsGlobalVariable . GenerateFirmwareImage (
TeFile ,
2010-03-01 00:39:39 +01:00
[ GenSecInputFile ] ,
2009-07-17 11:10:31 +02:00
Type = ' te '
)
GenSecInputFile = TeFile
GenFdsGlobalVariable . GenerateSection ( OutputFile , [ GenSecInputFile ] , Section . Section . SectionType [ SectionType ] )
OutputFileList . append ( OutputFile )
return OutputFileList
## __GenSimpleFileFfs__() method
#
# Generate FFS
#
# @param self The object pointer
# @param Rule The rule object used to generate section
# @param InputFileList The output file list from GenSection
# @retval string Generated FFS file name
#
def __GenSimpleFileFfs__ ( self , Rule , InputFileList ) :
FfsOutput = self . OutputPath + \
os . sep + \
self . __ExtendMacro__ ( Rule . NameGuid ) + \
' .ffs '
GenFdsGlobalVariable . VerboseLogger ( self . __ExtendMacro__ ( Rule . NameGuid ) )
InputSection = [ ]
SectionAlignments = [ ]
for InputFile in InputFileList :
InputSection . append ( InputFile )
2010-03-01 00:39:39 +01:00
SectionAlignments . append ( Rule . SectAlignment )
2009-07-17 11:10:31 +02:00
if Rule . NameGuid != None and Rule . NameGuid . startswith ( ' PCD( ' ) :
PcdValue = GenFdsGlobalVariable . GetPcdValue ( Rule . NameGuid )
if len ( PcdValue ) == 0 :
EdkLogger . error ( " GenFds " , GENFDS_ERROR , ' %s NOT defined. ' \
% ( Rule . NameGuid ) )
if PcdValue . startswith ( ' { ' ) :
PcdValue = GuidStructureByteArrayToGuidString ( PcdValue )
RegistryGuidStr = PcdValue
if len ( RegistryGuidStr ) == 0 :
EdkLogger . error ( " GenFds " , GENFDS_ERROR , ' GUID value for %s in wrong format. ' \
% ( Rule . NameGuid ) )
self . ModuleGuid = RegistryGuidStr
GenFdsGlobalVariable . GenerateFfs ( FfsOutput , InputSection ,
Ffs . Ffs . FdfFvFileTypeToFileType [ Rule . FvFileType ] ,
self . ModuleGuid , Fixed = Rule . Fixed ,
CheckSum = Rule . CheckSum , Align = Rule . Alignment ,
SectionAlign = SectionAlignments
)
return FfsOutput
## __GenComplexFileSection__() method
#
# Generate section by sections in Rule
#
2010-03-01 00:39:39 +01:00
# @param self The object pointer
# @param Rule The rule object used to generate section
# @param FvChildAddr Array of the inside FvImage base address
# @param FvParentAddr Parent Fv base address
# @retval string File name of the generated section file
2009-07-17 11:10:31 +02:00
#
2010-03-01 00:39:39 +01:00
def __GenComplexFileSection__ ( self , Rule , FvChildAddr , FvParentAddr ) :
2009-07-17 11:10:31 +02:00
if self . ModuleType in ( ' SEC ' , ' PEI_CORE ' , ' PEIM ' ) :
if Rule . KeepReloc != None :
self . KeepRelocFromRule = Rule . KeepReloc
SectFiles = [ ]
SectAlignments = [ ]
Index = 1
2011-05-11 12:26:49 +02:00
HasGneratedFlag = False
2013-11-18 08:41:21 +01:00
if self . PcdIsDriver == ' PEI_PCD_DRIVER ' :
if self . IsBinaryModule :
PcdExDbFileName = os . path . join ( GenFdsGlobalVariable . FvDir , " PEIPcdDataBase.raw " )
else :
PcdExDbFileName = os . path . join ( self . EfiOutputPath , " PEIPcdDataBase.raw " )
PcdExDbSecName = os . path . join ( self . OutputPath , " PEIPcdDataBaseSec.raw " )
GenFdsGlobalVariable . GenerateSection ( PcdExDbSecName ,
[ PcdExDbFileName ] ,
" EFI_SECTION_RAW " ,
)
SectFiles . append ( PcdExDbSecName )
SectAlignments . append ( None )
elif self . PcdIsDriver == ' DXE_PCD_DRIVER ' :
if self . IsBinaryModule :
PcdExDbFileName = os . path . join ( GenFdsGlobalVariable . FvDir , " DXEPcdDataBase.raw " )
else :
PcdExDbFileName = os . path . join ( self . EfiOutputPath , " DXEPcdDataBase.raw " )
PcdExDbSecName = os . path . join ( self . OutputPath , " DXEPcdDataBaseSec.raw " )
GenFdsGlobalVariable . GenerateSection ( PcdExDbSecName ,
[ PcdExDbFileName ] ,
" EFI_SECTION_RAW " ,
)
SectFiles . append ( PcdExDbSecName )
SectAlignments . append ( None )
2009-07-17 11:10:31 +02:00
for Sect in Rule . SectionList :
SecIndex = ' %d ' % Index
SectList = [ ]
2009-11-09 12:47:35 +01:00
#
# Convert Fv Section Type for PI1.1 SMM driver.
#
2011-05-11 12:26:49 +02:00
if self . ModuleType == ' DXE_SMM_DRIVER ' and int ( self . PiSpecVersion , 16 ) > = 0x0001000A :
2009-11-09 12:47:35 +01:00
if Sect . SectionType == ' DXE_DEPEX ' :
Sect . SectionType = ' SMM_DEPEX '
#
# Framework SMM Driver has no SMM_DEPEX section type
#
2011-05-11 12:26:49 +02:00
if self . ModuleType == ' DXE_SMM_DRIVER ' and int ( self . PiSpecVersion , 16 ) < 0x0001000A :
2009-11-09 12:47:35 +01:00
if Sect . SectionType == ' SMM_DEPEX ' :
EdkLogger . error ( " GenFds " , FORMAT_NOT_SUPPORTED , " Framework SMM module doesn ' t support SMM_DEPEX section type " , File = self . InfFileName )
2010-03-01 00:39:39 +01:00
#
# process the inside FvImage from FvSection or GuidSection
#
if FvChildAddr != [ ] :
if isinstance ( Sect , FvImageSection ) :
Sect . FvAddr = FvChildAddr . pop ( 0 )
elif isinstance ( Sect , GuidSection ) :
Sect . FvAddr = FvChildAddr
if FvParentAddr != None and isinstance ( Sect , GuidSection ) :
Sect . FvParentAddr = FvParentAddr
2009-07-17 11:10:31 +02:00
if Rule . KeyStringList != [ ] :
SectList , Align = Sect . GenSection ( self . OutputPath , self . ModuleGuid , SecIndex , Rule . KeyStringList , self )
else :
SectList , Align = Sect . GenSection ( self . OutputPath , self . ModuleGuid , SecIndex , self . KeyStringList , self )
2011-05-11 12:26:49 +02:00
if not HasGneratedFlag :
UniVfrOffsetFileSection = " "
ModuleFileName = os . path . join ( GenFdsGlobalVariable . WorkSpaceDir , self . InfFileName )
InfData = GenFdsGlobalVariable . WorkSpace . BuildObject [ PathClass ( ModuleFileName ) , self . CurrentArch ]
#
# Search the source list in InfData to find if there are .vfr file exist.
#
VfrUniBaseName = { }
VfrUniOffsetList = [ ]
for SourceFile in InfData . Sources :
if SourceFile . Type . upper ( ) == " .VFR " :
#
# search the .map file to find the offset of vfr binary in the PE32+/TE file.
#
VfrUniBaseName [ SourceFile . BaseName ] = ( SourceFile . BaseName + " Bin " )
if SourceFile . Type . upper ( ) == " .UNI " :
#
# search the .map file to find the offset of Uni strings binary in the PE32+/TE file.
#
VfrUniBaseName [ " UniOffsetName " ] = ( self . BaseName + " Strings " )
if len ( VfrUniBaseName ) > 0 :
VfrUniOffsetList = self . __GetBuildOutputMapFileVfrUniInfo ( VfrUniBaseName )
#
# Generate the Raw data of raw section
#
os . path . join ( self . OutputPath , self . BaseName + ' .offset ' )
UniVfrOffsetFileName = os . path . join ( self . OutputPath , self . BaseName + ' .offset ' )
UniVfrOffsetFileSection = os . path . join ( self . OutputPath , self . BaseName + ' Offset ' + ' .raw ' )
self . __GenUniVfrOffsetFile ( VfrUniOffsetList , UniVfrOffsetFileName )
UniVfrOffsetFileNameList = [ ]
UniVfrOffsetFileNameList . append ( UniVfrOffsetFileName )
""" Call GenSection """
GenFdsGlobalVariable . GenerateSection ( UniVfrOffsetFileSection ,
UniVfrOffsetFileNameList ,
" EFI_SECTION_RAW "
)
os . remove ( UniVfrOffsetFileName )
SectList . append ( UniVfrOffsetFileSection )
HasGneratedFlag = True
2009-07-17 11:10:31 +02:00
for SecName in SectList :
SectFiles . append ( SecName )
SectAlignments . append ( Align )
Index = Index + 1
return SectFiles , SectAlignments
## __GenComplexFileFfs__() method
#
# Generate FFS
#
# @param self The object pointer
# @param Rule The rule object used to generate section
# @param InputFileList The output file list from GenSection
# @retval string Generated FFS file name
#
def __GenComplexFileFfs__ ( self , Rule , InputFile , Alignments ) :
if Rule . NameGuid != None and Rule . NameGuid . startswith ( ' PCD( ' ) :
PcdValue = GenFdsGlobalVariable . GetPcdValue ( Rule . NameGuid )
if len ( PcdValue ) == 0 :
EdkLogger . error ( " GenFds " , GENFDS_ERROR , ' %s NOT defined. ' \
% ( Rule . NameGuid ) )
if PcdValue . startswith ( ' { ' ) :
PcdValue = GuidStructureByteArrayToGuidString ( PcdValue )
RegistryGuidStr = PcdValue
if len ( RegistryGuidStr ) == 0 :
EdkLogger . error ( " GenFds " , GENFDS_ERROR , ' GUID value for %s in wrong format. ' \
% ( Rule . NameGuid ) )
self . ModuleGuid = RegistryGuidStr
FfsOutput = os . path . join ( self . OutputPath , self . ModuleGuid + ' .ffs ' )
GenFdsGlobalVariable . GenerateFfs ( FfsOutput , InputFile ,
Ffs . Ffs . FdfFvFileTypeToFileType [ Rule . FvFileType ] ,
self . ModuleGuid , Fixed = Rule . Fixed ,
CheckSum = Rule . CheckSum , Align = Rule . Alignment ,
SectionAlign = Alignments
)
return FfsOutput
## __GetGenFfsCmdParameter__() method
#
# Create parameter string for GenFfs
#
# @param self The object pointer
# @param Rule The rule object used to generate section
# @retval tuple (FileType, Fixed, CheckSum, Alignment)
#
def __GetGenFfsCmdParameter__ ( self , Rule ) :
result = tuple ( )
result + = ( ' -t ' , Ffs . Ffs . FdfFvFileTypeToFileType [ Rule . FvFileType ] )
if Rule . Fixed != False :
result + = ( ' -x ' , )
if Rule . CheckSum != False :
result + = ( ' -s ' , )
if Rule . Alignment != None and Rule . Alignment != ' ' :
result + = ( ' -a ' , Rule . Alignment )
return result
2011-05-11 12:26:49 +02:00
## __GetBuildOutputMapFileVfrUniInfo() method
#
# Find the offset of UNI/INF object offset in the EFI image file.
#
# @param self The object pointer
# @param VfrUniBaseName A name list contain the UNI/INF object name.
# @retval RetValue A list contain offset of UNI/INF object.
#
def __GetBuildOutputMapFileVfrUniInfo ( self , VfrUniBaseName ) :
MapFileName = os . path . join ( self . EfiOutputPath , self . BaseName + " .map " )
2015-02-06 04:40:27 +01:00
EfiFileName = os . path . join ( self . EfiOutputPath , self . BaseName + " .efi " )
return GetVariableOffset ( MapFileName , EfiFileName , VfrUniBaseName . values ( ) )
2011-05-11 12:26:49 +02:00
## __GenUniVfrOffsetFile() method
#
# Generate the offset file for the module which contain VFR or UNI file.
#
# @param self The object pointer
# @param VfrUniOffsetList A list contain the VFR/UNI offsets in the EFI image file.
# @param UniVfrOffsetFileName The output offset file name.
#
def __GenUniVfrOffsetFile ( self , VfrUniOffsetList , UniVfrOffsetFileName ) :
try :
fInputfile = open ( UniVfrOffsetFileName , " wb+ " , 0 )
except :
EdkLogger . error ( " GenFds " , FILE_OPEN_FAILURE , " File open failed for %s " % UniVfrOffsetFileName , None )
# Use a instance of StringIO to cache data
fStringIO = StringIO . StringIO ( ' ' )
for Item in VfrUniOffsetList :
if ( Item [ 0 ] . find ( " Strings " ) != - 1 ) :
#
# UNI offset in image.
# GUID + Offset
# { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } }
#
UniGuid = [ 0xe0 , 0xc5 , 0x13 , 0x89 , 0xf6 , 0x33 , 0x86 , 0x4d , 0x9b , 0xf1 , 0x43 , 0xef , 0x89 , 0xfc , 0x6 , 0x66 ]
UniGuid = [ chr ( ItemGuid ) for ItemGuid in UniGuid ]
fStringIO . write ( ' ' . join ( UniGuid ) )
UniValue = pack ( ' Q ' , int ( Item [ 1 ] , 16 ) )
fStringIO . write ( UniValue )
else :
#
# VFR binary offset in image.
# GUID + Offset
# { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } };
#
VfrGuid = [ 0xb4 , 0x7c , 0xbc , 0xd0 , 0x47 , 0x6a , 0x5f , 0x49 , 0xaa , 0x11 , 0x71 , 0x7 , 0x46 , 0xda , 0x6 , 0xa2 ]
VfrGuid = [ chr ( ItemGuid ) for ItemGuid in VfrGuid ]
fStringIO . write ( ' ' . join ( VfrGuid ) )
type ( Item [ 1 ] )
VfrValue = pack ( ' Q ' , int ( Item [ 1 ] , 16 ) )
fStringIO . write ( VfrValue )
#
# write data into file.
#
try :
fInputfile . write ( fStringIO . getvalue ( ) )
except :
EdkLogger . error ( " GenFds " , FILE_WRITE_FAILURE , " Write data to file %s failed, please check whether the file been locked or using by other applications. " % UniVfrOffsetFileName , None )
fStringIO . close ( )
fInputfile . close ( )