2019-09-03 11:58:42 +02:00
## @file
# This file is used to create a database used by build tool
#
# Copyright (c) 2008 - 2019, Intel Corporation. All rights reserved.<BR>
# (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
## Platform build information from DSC file
#
# This class is used to retrieve information stored in database and convert them
# into PlatformBuildClassObject form for easier use for AutoGen.
#
from __future__ import print_function
from __future__ import absolute_import
from Common . StringUtils import *
from Common . DataType import *
from Common . Misc import *
from types import *
from Common . Expression import *
from CommonDataClass . CommonClass import SkuInfoClass
from Common . TargetTxtClassObject import TargetTxt
from Common . ToolDefClassObject import ToolDef
from . MetaDataTable import *
from . MetaFileTable import *
from . MetaFileParser import *
from . WorkspaceCommon import GetDeclaredPcd
from Common . Misc import AnalyzeDscPcd
from Common . Misc import ProcessDuplicatedInf , RemoveCComments , ArrayIndex
import re
from Common . Parsing import IsValidWord
from Common . VariableAttributes import VariableAttributes
import Common . GlobalData as GlobalData
import subprocess
from functools import reduce
from Common . Misc import SaveFileOnChange
from Workspace . BuildClassObject import PlatformBuildClassObject , StructurePcd , PcdClassObject , ModuleBuildClassObject
from collections import OrderedDict , defaultdict
def _IsFieldValueAnArray ( Value ) :
Value = Value . strip ( )
if Value . startswith ( TAB_GUID ) and Value . endswith ( ' ) ' ) :
return True
if Value . startswith ( ' L " ' ) and Value . endswith ( ' " ' ) and len ( list ( Value [ 2 : - 1 ] ) ) > 1 :
return True
if Value [ 0 ] == ' " ' and Value [ - 1 ] == ' " ' and len ( list ( Value [ 1 : - 1 ] ) ) > 1 :
return True
if Value [ 0 ] == ' { ' and Value [ - 1 ] == ' } ' :
return True
if Value . startswith ( " L ' " ) and Value . endswith ( " ' " ) and len ( list ( Value [ 2 : - 1 ] ) ) > 1 :
return True
if Value [ 0 ] == " ' " and Value [ - 1 ] == " ' " and len ( list ( Value [ 1 : - 1 ] ) ) > 1 :
return True
return False
PcdValueInitName = ' PcdValueInit '
PcdMainCHeader = '''
/ * *
DO NOT EDIT
FILE auto - generated
* * /
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <PcdValueCommon.h>
'''
PcdMainCEntry = '''
int
main (
int argc ,
char * argv [ ]
)
{
return PcdValueMain ( argc , argv ) ;
}
'''
PcdMakefileHeader = '''
#
# DO NOT EDIT
# This file is auto-generated by build utility
#
'''
WindowsCFLAGS = ' CFLAGS = $(CFLAGS) /wd4200 /wd4034 /wd4101 '
LinuxCFLAGS = ' BUILD_CFLAGS += -Wno-pointer-to-int-cast -Wno-unused-variable '
PcdMakefileEnd = '''
! INCLUDE $ ( BASE_TOOLS_PATH ) \Source \C \Makefiles \ms . common
LIBS = $ ( LIB_PATH ) \Common . lib
! INCLUDE $ ( BASE_TOOLS_PATH ) \Source \C \Makefiles \ms . app
'''
AppTarget = '''
all : $ ( APPFILE )
$ ( APPFILE ) : $ ( OBJECTS )
% s
'''
PcdGccMakefile = '''
MAKEROOT ? = $ ( EDK_TOOLS_PATH ) / Source / C
LIBS = - lCommon
'''
variablePattern = re . compile ( r ' [ \ t \ s]*0[xX][a-fA-F0-9]+$ ' )
SkuIdPattern = re . compile ( r ' ^[a-zA-Z_][a-zA-Z0-9_]*$ ' )
## regular expressions for finding decimal and hex numbers
Pattern = re . compile ( ' ^[1-9] \ d*|0$ ' )
HexPattern = re . compile ( r ' 0[xX][0-9a-fA-F]+$ ' )
## Regular expression for finding header file inclusions
from AutoGen . GenMake import gIncludePattern
## Find dependencies for one source file
#
# By searching recursively "#include" directive in file, find out all the
# files needed by given source file. The dependecies will be only searched
# in given search path list.
#
# @param SearchPathList The list of search path
#
# @retval list The list of files the given source file depends on
#
def GetDependencyList ( FileStack , SearchPathList ) :
DepDb = dict ( )
DependencySet = set ( FileStack )
while len ( FileStack ) > 0 :
F = FileStack . pop ( )
FullPathDependList = [ ]
CurrentFileDependencyList = [ ]
if F in DepDb :
CurrentFileDependencyList = DepDb [ F ]
else :
try :
Fd = open ( F , ' r ' )
FileContent = Fd . read ( )
except BaseException as X :
EdkLogger . error ( " build " , FILE_OPEN_FAILURE , ExtraData = F + " \n \t " + str ( X ) )
finally :
if " Fd " in dir ( locals ( ) ) :
Fd . close ( )
if len ( FileContent ) == 0 :
continue
try :
if FileContent [ 0 ] == 0xff or FileContent [ 0 ] == 0xfe :
FileContent = FileContent . decode ( ' utf-16 ' )
else :
FileContent = FileContent . decode ( )
except :
# The file is not txt file. for example .mcb file
continue
IncludedFileList = gIncludePattern . findall ( FileContent )
for Inc in IncludedFileList :
Inc = Inc . strip ( )
Inc = os . path . normpath ( Inc )
CurrentFileDependencyList . append ( Inc )
DepDb [ F ] = CurrentFileDependencyList
CurrentFilePath = os . path . dirname ( F )
PathList = [ CurrentFilePath ] + SearchPathList
for Inc in CurrentFileDependencyList :
for SearchPath in PathList :
FilePath = os . path . join ( SearchPath , Inc )
if not os . path . exists ( FilePath ) :
continue
if FilePath not in DependencySet :
FileStack . append ( FilePath )
FullPathDependList . append ( FilePath )
break
DependencySet . update ( FullPathDependList )
DependencyList = list ( DependencySet ) # remove duplicate ones
return DependencyList
class DscBuildData ( PlatformBuildClassObject ) :
# dict used to convert PCD type in database to string used by build tool
_PCD_TYPE_STRING_ = {
MODEL_PCD_FIXED_AT_BUILD : TAB_PCDS_FIXED_AT_BUILD ,
MODEL_PCD_PATCHABLE_IN_MODULE : TAB_PCDS_PATCHABLE_IN_MODULE ,
MODEL_PCD_FEATURE_FLAG : TAB_PCDS_FEATURE_FLAG ,
MODEL_PCD_DYNAMIC : TAB_PCDS_DYNAMIC ,
MODEL_PCD_DYNAMIC_DEFAULT : TAB_PCDS_DYNAMIC ,
MODEL_PCD_DYNAMIC_HII : TAB_PCDS_DYNAMIC_HII ,
MODEL_PCD_DYNAMIC_VPD : TAB_PCDS_DYNAMIC_VPD ,
MODEL_PCD_DYNAMIC_EX : TAB_PCDS_DYNAMIC_EX ,
MODEL_PCD_DYNAMIC_EX_DEFAULT : TAB_PCDS_DYNAMIC_EX ,
MODEL_PCD_DYNAMIC_EX_HII : TAB_PCDS_DYNAMIC_EX_HII ,
MODEL_PCD_DYNAMIC_EX_VPD : TAB_PCDS_DYNAMIC_EX_VPD ,
}
# dict used to convert part of [Defines] to members of DscBuildData directly
_PROPERTY_ = {
#
# Required Fields
#
TAB_DSC_DEFINES_PLATFORM_NAME : " _PlatformName " ,
TAB_DSC_DEFINES_PLATFORM_GUID : " _Guid " ,
TAB_DSC_DEFINES_PLATFORM_VERSION : " _Version " ,
TAB_DSC_DEFINES_DSC_SPECIFICATION : " _DscSpecification " ,
# TAB_DSC_DEFINES_OUTPUT_DIRECTORY : "_OutputDirectory",
# TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : "_SupArchList",
# TAB_DSC_DEFINES_BUILD_TARGETS : "_BuildTargets",
TAB_DSC_DEFINES_SKUID_IDENTIFIER : " _SkuName " ,
# TAB_DSC_DEFINES_FLASH_DEFINITION : "_FlashDefinition",
TAB_DSC_DEFINES_BUILD_NUMBER : " _BuildNumber " ,
TAB_DSC_DEFINES_MAKEFILE_NAME : " _MakefileName " ,
TAB_DSC_DEFINES_BS_BASE_ADDRESS : " _BsBaseAddress " ,
TAB_DSC_DEFINES_RT_BASE_ADDRESS : " _RtBaseAddress " ,
# TAB_DSC_DEFINES_RFC_LANGUAGES : "_RFCLanguages",
# TAB_DSC_DEFINES_ISO_LANGUAGES : "_ISOLanguages",
}
# used to compose dummy library class name for those forced library instances
_NullLibraryNumber = 0
## Constructor of DscBuildData
#
# Initialize object of DscBuildData
#
# @param FilePath The path of platform description file
# @param RawData The raw data of DSC file
# @param BuildDataBase Database used to retrieve module/package information
# @param Arch The target architecture
# @param Platform (not used for DscBuildData)
# @param Macros Macros used for replacement in DSC file
#
def __init__ ( self , FilePath , RawData , BuildDataBase , Arch = TAB_ARCH_COMMON , Target = None , Toolchain = None ) :
self . MetaFile = FilePath
self . _RawData = RawData
self . _Bdb = BuildDataBase
self . _Arch = Arch
self . _Target = Target
self . _Toolchain = Toolchain
self . _ToolChainFamily = None
self . _Clear ( )
self . WorkspaceDir = os . getenv ( " WORKSPACE " ) if os . getenv ( " WORKSPACE " ) else " "
self . DefaultStores = None
self . SkuIdMgr = SkuClass ( self . SkuName , self . SkuIds )
@property
def OutputPath ( self ) :
if os . getenv ( " WORKSPACE " ) :
return os . path . join ( os . getenv ( " WORKSPACE " ) , self . OutputDirectory , self . _Target + " _ " + self . _Toolchain , PcdValueInitName )
else :
return os . path . dirname ( self . DscFile )
## XXX[key] = value
def __setitem__ ( self , key , value ) :
self . __dict__ [ self . _PROPERTY_ [ key ] ] = value
## value = XXX[key]
def __getitem__ ( self , key ) :
return self . __dict__ [ self . _PROPERTY_ [ key ] ]
## "in" test support
def __contains__ ( self , key ) :
return key in self . _PROPERTY_
## Set all internal used members of DscBuildData to None
def _Clear ( self ) :
self . _Header = None
self . _PlatformName = None
self . _Guid = None
self . _Version = None
self . _DscSpecification = None
self . _OutputDirectory = None
self . _SupArchList = None
self . _BuildTargets = None
self . _SkuName = None
self . _PcdInfoFlag = None
self . _VarCheckFlag = None
self . _FlashDefinition = None
self . _Prebuild = None
self . _Postbuild = None
self . _BuildNumber = None
self . _MakefileName = None
self . _BsBaseAddress = None
self . _RtBaseAddress = None
self . _SkuIds = None
self . _Modules = None
self . _LibraryInstances = None
self . _LibraryClasses = None
self . _Pcds = None
self . _DecPcds = None
self . _BuildOptions = None
self . _ModuleTypeOptions = None
self . _LoadFixAddress = None
self . _RFCLanguages = None
self . _ISOLanguages = None
self . _VpdToolGuid = None
self . _MacroDict = None
self . DefaultStores = None
## Get current effective macros
@property
def _Macros ( self ) :
if self . _MacroDict is None :
self . _MacroDict = { }
self . _MacroDict . update ( GlobalData . gPlatformDefines )
self . _MacroDict . update ( GlobalData . gGlobalDefines )
self . _MacroDict . update ( GlobalData . gCommandLineDefines )
return self . _MacroDict
## Get architecture
@property
def Arch ( self ) :
return self . _Arch
@property
def Dir ( self ) :
return self . MetaFile . Dir
## Retrieve all information in [Defines] section
#
# (Retrieving all [Defines] information in one-shot is just to save time.)
#
def _GetHeaderInfo ( self ) :
RecordList = self . _RawData [ MODEL_META_DATA_HEADER , self . _Arch ]
for Record in RecordList :
Name = Record [ 1 ]
# items defined _PROPERTY_ don't need additional processing
# some special items in [Defines] section need special treatment
if Name == TAB_DSC_DEFINES_OUTPUT_DIRECTORY :
self . _OutputDirectory = NormPath ( Record [ 2 ] , self . _Macros )
if ' ' in self . _OutputDirectory :
EdkLogger . error ( " build " , FORMAT_NOT_SUPPORTED , " No space is allowed in OUTPUT_DIRECTORY " ,
File = self . MetaFile , Line = Record [ - 1 ] ,
ExtraData = self . _OutputDirectory )
elif Name == TAB_DSC_DEFINES_FLASH_DEFINITION :
self . _FlashDefinition = PathClass ( NormPath ( Record [ 2 ] , self . _Macros ) , GlobalData . gWorkspace )
ErrorCode , ErrorInfo = self . _FlashDefinition . Validate ( ' .fdf ' )
if ErrorCode != 0 :
EdkLogger . error ( ' build ' , ErrorCode , File = self . MetaFile , Line = Record [ - 1 ] ,
ExtraData = ErrorInfo )
elif Name == TAB_DSC_PREBUILD :
PrebuildValue = Record [ 2 ]
if Record [ 2 ] [ 0 ] == ' " ' :
if Record [ 2 ] [ - 1 ] != ' " ' :
EdkLogger . error ( ' build ' , FORMAT_INVALID , ' Missing double quotes in the end of %s statement. ' % TAB_DSC_PREBUILD ,
File = self . MetaFile , Line = Record [ - 1 ] )
PrebuildValue = Record [ 2 ] [ 1 : - 1 ]
self . _Prebuild = PrebuildValue
elif Name == TAB_DSC_POSTBUILD :
PostbuildValue = Record [ 2 ]
if Record [ 2 ] [ 0 ] == ' " ' :
if Record [ 2 ] [ - 1 ] != ' " ' :
EdkLogger . error ( ' build ' , FORMAT_INVALID , ' Missing double quotes in the end of %s statement. ' % TAB_DSC_POSTBUILD ,
File = self . MetaFile , Line = Record [ - 1 ] )
PostbuildValue = Record [ 2 ] [ 1 : - 1 ]
self . _Postbuild = PostbuildValue
elif Name == TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES :
self . _SupArchList = GetSplitValueList ( Record [ 2 ] , TAB_VALUE_SPLIT )
elif Name == TAB_DSC_DEFINES_BUILD_TARGETS :
self . _BuildTargets = GetSplitValueList ( Record [ 2 ] )
elif Name == TAB_DSC_DEFINES_SKUID_IDENTIFIER :
if self . _SkuName is None :
self . _SkuName = Record [ 2 ]
if GlobalData . gSKUID_CMD :
self . _SkuName = GlobalData . gSKUID_CMD
elif Name == TAB_DSC_DEFINES_PCD_INFO_GENERATION :
self . _PcdInfoFlag = Record [ 2 ]
elif Name == TAB_DSC_DEFINES_PCD_VAR_CHECK_GENERATION :
self . _VarCheckFlag = Record [ 2 ]
elif Name == TAB_FIX_LOAD_TOP_MEMORY_ADDRESS :
try :
self . _LoadFixAddress = int ( Record [ 2 ] , 0 )
except :
EdkLogger . error ( " build " , PARAMETER_INVALID , " FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string " % ( Record [ 2 ] ) )
elif Name == TAB_DSC_DEFINES_RFC_LANGUAGES :
if not Record [ 2 ] or Record [ 2 ] [ 0 ] != ' " ' or Record [ 2 ] [ - 1 ] != ' " ' or len ( Record [ 2 ] ) == 1 :
EdkLogger . error ( ' build ' , FORMAT_NOT_SUPPORTED , ' language code for RFC_LANGUAGES must have double quotes around it, for example: RFC_LANGUAGES = " en-us;zh-hans " ' ,
File = self . MetaFile , Line = Record [ - 1 ] )
LanguageCodes = Record [ 2 ] [ 1 : - 1 ]
if not LanguageCodes :
EdkLogger . error ( ' build ' , FORMAT_NOT_SUPPORTED , ' one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement ' ,
File = self . MetaFile , Line = Record [ - 1 ] )
LanguageList = GetSplitValueList ( LanguageCodes , TAB_SEMI_COLON_SPLIT )
# check whether there is empty entries in the list
if None in LanguageList :
EdkLogger . error ( ' build ' , FORMAT_NOT_SUPPORTED , ' one or more empty language code is in RFC_LANGUAGES statement ' ,
File = self . MetaFile , Line = Record [ - 1 ] )
self . _RFCLanguages = LanguageList
elif Name == TAB_DSC_DEFINES_ISO_LANGUAGES :
if not Record [ 2 ] or Record [ 2 ] [ 0 ] != ' " ' or Record [ 2 ] [ - 1 ] != ' " ' or len ( Record [ 2 ] ) == 1 :
EdkLogger . error ( ' build ' , FORMAT_NOT_SUPPORTED , ' language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = " engchn " ' ,
File = self . MetaFile , Line = Record [ - 1 ] )
LanguageCodes = Record [ 2 ] [ 1 : - 1 ]
if not LanguageCodes :
EdkLogger . error ( ' build ' , FORMAT_NOT_SUPPORTED , ' one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement ' ,
File = self . MetaFile , Line = Record [ - 1 ] )
if len ( LanguageCodes ) % 3 :
EdkLogger . error ( ' build ' , FORMAT_NOT_SUPPORTED , ' bad ISO639-2 format for ISO_LANGUAGES ' ,
File = self . MetaFile , Line = Record [ - 1 ] )
LanguageList = [ ]
for i in range ( 0 , len ( LanguageCodes ) , 3 ) :
LanguageList . append ( LanguageCodes [ i : i + 3 ] )
self . _ISOLanguages = LanguageList
elif Name == TAB_DSC_DEFINES_VPD_TOOL_GUID :
#
# try to convert GUID to a real UUID value to see whether the GUID is format
# for VPD_TOOL_GUID is correct.
#
try :
uuid . UUID ( Record [ 2 ] )
except :
EdkLogger . error ( " build " , FORMAT_INVALID , " Invalid GUID format for VPD_TOOL_GUID " , File = self . MetaFile )
self . _VpdToolGuid = Record [ 2 ]
elif Name in self :
self [ Name ] = Record [ 2 ]
# set _Header to non-None in order to avoid database re-querying
self . _Header = ' DUMMY '
## Retrieve platform name
@property
def PlatformName ( self ) :
if self . _PlatformName is None :
if self . _Header is None :
self . _GetHeaderInfo ( )
if self . _PlatformName is None :
EdkLogger . error ( ' build ' , ATTRIBUTE_NOT_AVAILABLE , " No PLATFORM_NAME " , File = self . MetaFile )
return self . _PlatformName
@property
def Platform ( self ) :
return self . PlatformName
## Retrieve file guid
@property
def Guid ( self ) :
if self . _Guid is None :
if self . _Header is None :
self . _GetHeaderInfo ( )
if self . _Guid is None :
EdkLogger . error ( ' build ' , ATTRIBUTE_NOT_AVAILABLE , " No PLATFORM_GUID " , File = self . MetaFile )
return self . _Guid
## Retrieve platform version
@property
def Version ( self ) :
if self . _Version is None :
if self . _Header is None :
self . _GetHeaderInfo ( )
if self . _Version is None :
EdkLogger . error ( ' build ' , ATTRIBUTE_NOT_AVAILABLE , " No PLATFORM_VERSION " , File = self . MetaFile )
return self . _Version
## Retrieve platform description file version
@property
def DscSpecification ( self ) :
if self . _DscSpecification is None :
if self . _Header is None :
self . _GetHeaderInfo ( )
if self . _DscSpecification is None :
EdkLogger . error ( ' build ' , ATTRIBUTE_NOT_AVAILABLE , " No DSC_SPECIFICATION " , File = self . MetaFile )
return self . _DscSpecification
## Retrieve OUTPUT_DIRECTORY
@property
def OutputDirectory ( self ) :
if self . _OutputDirectory is None :
if self . _Header is None :
self . _GetHeaderInfo ( )
if self . _OutputDirectory is None :
self . _OutputDirectory = os . path . join ( " Build " , self . _PlatformName )
return self . _OutputDirectory
## Retrieve SUPPORTED_ARCHITECTURES
@property
def SupArchList ( self ) :
if self . _SupArchList is None :
if self . _Header is None :
self . _GetHeaderInfo ( )
if self . _SupArchList is None :
EdkLogger . error ( ' build ' , ATTRIBUTE_NOT_AVAILABLE , " No SUPPORTED_ARCHITECTURES " , File = self . MetaFile )
return self . _SupArchList
## Retrieve BUILD_TARGETS
@property
def BuildTargets ( self ) :
if self . _BuildTargets is None :
if self . _Header is None :
self . _GetHeaderInfo ( )
if self . _BuildTargets is None :
EdkLogger . error ( ' build ' , ATTRIBUTE_NOT_AVAILABLE , " No BUILD_TARGETS " , File = self . MetaFile )
return self . _BuildTargets
@property
def PcdInfoFlag ( self ) :
if self . _PcdInfoFlag is None or self . _PcdInfoFlag . upper ( ) == ' FALSE ' :
return False
elif self . _PcdInfoFlag . upper ( ) == ' TRUE ' :
return True
else :
return False
@property
def VarCheckFlag ( self ) :
if self . _VarCheckFlag is None or self . _VarCheckFlag . upper ( ) == ' FALSE ' :
return False
elif self . _VarCheckFlag . upper ( ) == ' TRUE ' :
return True
else :
return False
# # Retrieve SKUID_IDENTIFIER
@property
def SkuName ( self ) :
if self . _SkuName is None :
if self . _Header is None :
self . _GetHeaderInfo ( )
if self . _SkuName is None :
self . _SkuName = TAB_DEFAULT
return self . _SkuName
## Override SKUID_IDENTIFIER
@SkuName.setter
def SkuName ( self , Value ) :
self . _SkuName = Value
@property
def FlashDefinition ( self ) :
if self . _FlashDefinition is None :
if self . _Header is None :
self . _GetHeaderInfo ( )
if self . _FlashDefinition is None :
self . _FlashDefinition = ' '
return self . _FlashDefinition
@property
def Prebuild ( self ) :
if self . _Prebuild is None :
if self . _Header is None :
self . _GetHeaderInfo ( )
if self . _Prebuild is None :
self . _Prebuild = ' '
return self . _Prebuild
@property
def Postbuild ( self ) :
if self . _Postbuild is None :
if self . _Header is None :
self . _GetHeaderInfo ( )
if self . _Postbuild is None :
self . _Postbuild = ' '
return self . _Postbuild
## Retrieve FLASH_DEFINITION
@property
def BuildNumber ( self ) :
if self . _BuildNumber is None :
if self . _Header is None :
self . _GetHeaderInfo ( )
if self . _BuildNumber is None :
self . _BuildNumber = ' '
return self . _BuildNumber
## Retrieve MAKEFILE_NAME
@property
def MakefileName ( self ) :
if self . _MakefileName is None :
if self . _Header is None :
self . _GetHeaderInfo ( )
if self . _MakefileName is None :
self . _MakefileName = ' '
return self . _MakefileName
## Retrieve BsBaseAddress
@property
def BsBaseAddress ( self ) :
if self . _BsBaseAddress is None :
if self . _Header is None :
self . _GetHeaderInfo ( )
if self . _BsBaseAddress is None :
self . _BsBaseAddress = ' '
return self . _BsBaseAddress
## Retrieve RtBaseAddress
@property
def RtBaseAddress ( self ) :
if self . _RtBaseAddress is None :
if self . _Header is None :
self . _GetHeaderInfo ( )
if self . _RtBaseAddress is None :
self . _RtBaseAddress = ' '
return self . _RtBaseAddress
## Retrieve the top address for the load fix address
@property
def LoadFixAddress ( self ) :
if self . _LoadFixAddress is None :
if self . _Header is None :
self . _GetHeaderInfo ( )
if self . _LoadFixAddress is None :
self . _LoadFixAddress = self . _Macros . get ( TAB_FIX_LOAD_TOP_MEMORY_ADDRESS , ' 0 ' )
try :
self . _LoadFixAddress = int ( self . _LoadFixAddress , 0 )
except :
EdkLogger . error ( " build " , PARAMETER_INVALID , " FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string " % ( self . _LoadFixAddress ) )
#
# If command line defined, should override the value in DSC file.
#
if ' FIX_LOAD_TOP_MEMORY_ADDRESS ' in GlobalData . gCommandLineDefines :
try :
self . _LoadFixAddress = int ( GlobalData . gCommandLineDefines [ ' FIX_LOAD_TOP_MEMORY_ADDRESS ' ] , 0 )
except :
EdkLogger . error ( " build " , PARAMETER_INVALID , " FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string " % ( GlobalData . gCommandLineDefines [ ' FIX_LOAD_TOP_MEMORY_ADDRESS ' ] ) )
if self . _LoadFixAddress < 0 :
EdkLogger . error ( " build " , PARAMETER_INVALID , " FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value 0x %x " % ( self . _LoadFixAddress ) )
if self . _LoadFixAddress != 0xFFFFFFFFFFFFFFFF and self . _LoadFixAddress % 0x1000 != 0 :
EdkLogger . error ( " build " , PARAMETER_INVALID , " FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value 0x %x " % ( self . _LoadFixAddress ) )
return self . _LoadFixAddress
## Retrieve RFCLanguage filter
@property
def RFCLanguages ( self ) :
if self . _RFCLanguages is None :
if self . _Header is None :
self . _GetHeaderInfo ( )
if self . _RFCLanguages is None :
self . _RFCLanguages = [ ]
return self . _RFCLanguages
## Retrieve ISOLanguage filter
@property
def ISOLanguages ( self ) :
if self . _ISOLanguages is None :
if self . _Header is None :
self . _GetHeaderInfo ( )
if self . _ISOLanguages is None :
self . _ISOLanguages = [ ]
return self . _ISOLanguages
## Retrieve the GUID string for VPD tool
@property
def VpdToolGuid ( self ) :
if self . _VpdToolGuid is None :
if self . _Header is None :
self . _GetHeaderInfo ( )
if self . _VpdToolGuid is None :
self . _VpdToolGuid = ' '
return self . _VpdToolGuid
## Retrieve [SkuIds] section information
@property
def SkuIds ( self ) :
if self . _SkuIds is None :
self . _SkuIds = OrderedDict ( )
RecordList = self . _RawData [ MODEL_EFI_SKU_ID , self . _Arch ]
for Record in RecordList :
if not Record [ 0 ] :
EdkLogger . error ( ' build ' , FORMAT_INVALID , ' No Sku ID number ' ,
File = self . MetaFile , Line = Record [ - 1 ] )
if not Record [ 1 ] :
EdkLogger . error ( ' build ' , FORMAT_INVALID , ' No Sku ID name ' ,
File = self . MetaFile , Line = Record [ - 1 ] )
if not Pattern . match ( Record [ 0 ] ) and not HexPattern . match ( Record [ 0 ] ) :
EdkLogger . error ( ' build ' , FORMAT_INVALID , " The format of the Sku ID number is invalid. It only support Integer and HexNumber " ,
File = self . MetaFile , Line = Record [ - 1 ] )
if not SkuIdPattern . match ( Record [ 1 ] ) or ( Record [ 2 ] and not SkuIdPattern . match ( Record [ 2 ] ) ) :
EdkLogger . error ( ' build ' , FORMAT_INVALID , " The format of the Sku ID name is invalid. The correct format is ' (a-zA-Z_)(a-zA-Z0-9_)* ' " ,
File = self . MetaFile , Line = Record [ - 1 ] )
self . _SkuIds [ Record [ 1 ] . upper ( ) ] = ( str ( DscBuildData . ToInt ( Record [ 0 ] ) ) , Record [ 1 ] . upper ( ) , Record [ 2 ] . upper ( ) )
if TAB_DEFAULT not in self . _SkuIds :
self . _SkuIds [ TAB_DEFAULT ] = ( " 0 " , TAB_DEFAULT , TAB_DEFAULT )
if TAB_COMMON not in self . _SkuIds :
self . _SkuIds [ TAB_COMMON ] = ( " 0 " , TAB_DEFAULT , TAB_DEFAULT )
return self . _SkuIds
@staticmethod
def ToInt ( intstr ) :
return int ( intstr , 16 ) if intstr . upper ( ) . startswith ( " 0X " ) else int ( intstr )
def _GetDefaultStores ( self ) :
if self . DefaultStores is None :
self . DefaultStores = OrderedDict ( )
RecordList = self . _RawData [ MODEL_EFI_DEFAULT_STORES , self . _Arch ]
for Record in RecordList :
if not Record [ 0 ] :
EdkLogger . error ( ' build ' , FORMAT_INVALID , ' No DefaultStores ID number ' ,
File = self . MetaFile , Line = Record [ - 1 ] )
if not Record [ 1 ] :
EdkLogger . error ( ' build ' , FORMAT_INVALID , ' No DefaultStores ID name ' ,
File = self . MetaFile , Line = Record [ - 1 ] )
if not Pattern . match ( Record [ 0 ] ) and not HexPattern . match ( Record [ 0 ] ) :
EdkLogger . error ( ' build ' , FORMAT_INVALID , " The format of the DefaultStores ID number is invalid. It only support Integer and HexNumber " ,
File = self . MetaFile , Line = Record [ - 1 ] )
if not IsValidWord ( Record [ 1 ] ) :
EdkLogger . error ( ' build ' , FORMAT_INVALID , " The format of the DefaultStores ID name is invalid. The correct format is ' (a-zA-Z0-9_)(a-zA-Z0-9_-.)* ' " ,
File = self . MetaFile , Line = Record [ - 1 ] )
self . DefaultStores [ Record [ 1 ] . upper ( ) ] = ( DscBuildData . ToInt ( Record [ 0 ] ) , Record [ 1 ] . upper ( ) )
if TAB_DEFAULT_STORES_DEFAULT not in self . DefaultStores :
self . DefaultStores [ TAB_DEFAULT_STORES_DEFAULT ] = ( 0 , TAB_DEFAULT_STORES_DEFAULT )
GlobalData . gDefaultStores = sorted ( self . DefaultStores . keys ( ) )
return self . DefaultStores
def OverrideDuplicateModule ( self ) :
RecordList = self . _RawData [ MODEL_META_DATA_COMPONENT , self . _Arch ]
Macros = self . _Macros
Components = { }
for Record in RecordList :
ModuleId = Record [ 6 ]
file_guid = self . _RawData [ MODEL_META_DATA_HEADER , self . _Arch , None , ModuleId ]
file_guid_str = file_guid [ 0 ] [ 2 ] if file_guid else " NULL "
ModuleFile = PathClass ( NormPath ( Record [ 0 ] , Macros ) , GlobalData . gWorkspace , Arch = self . _Arch )
if self . _Arch != TAB_ARCH_COMMON and ( file_guid_str , str ( ModuleFile ) ) in Components :
self . _RawData . DisableOverrideComponent ( Components [ ( file_guid_str , str ( ModuleFile ) ) ] )
Components [ ( file_guid_str , str ( ModuleFile ) ) ] = ModuleId
self . _RawData . _PostProcessed = False
## Retrieve [Components] section information
@property
def Modules ( self ) :
if self . _Modules is not None :
return self . _Modules
self . OverrideDuplicateModule ( )
self . _Modules = OrderedDict ( )
RecordList = self . _RawData [ MODEL_META_DATA_COMPONENT , self . _Arch ]
Macros = self . _Macros
for Record in RecordList :
ModuleFile = PathClass ( NormPath ( Record [ 0 ] , Macros ) , GlobalData . gWorkspace , Arch = self . _Arch )
ModuleId = Record [ 6 ]
LineNo = Record [ 7 ]
# check the file validation
ErrorCode , ErrorInfo = ModuleFile . Validate ( ' .inf ' )
if ErrorCode != 0 :
EdkLogger . error ( ' build ' , ErrorCode , File = self . MetaFile , Line = LineNo ,
ExtraData = ErrorInfo )
Module = ModuleBuildClassObject ( )
Module . MetaFile = ModuleFile
# get module private library instance
RecordList = self . _RawData [ MODEL_EFI_LIBRARY_CLASS , self . _Arch , None , ModuleId ]
for Record in RecordList :
LibraryClass = Record [ 0 ]
LibraryPath = PathClass ( NormPath ( Record [ 1 ] , Macros ) , GlobalData . gWorkspace , Arch = self . _Arch )
LineNo = Record [ - 1 ]
# check the file validation
ErrorCode , ErrorInfo = LibraryPath . Validate ( ' .inf ' )
if ErrorCode != 0 :
EdkLogger . error ( ' build ' , ErrorCode , File = self . MetaFile , Line = LineNo ,
ExtraData = ErrorInfo )
if LibraryClass == ' ' or LibraryClass == ' NULL ' :
self . _NullLibraryNumber + = 1
LibraryClass = ' NULL %d ' % self . _NullLibraryNumber
EdkLogger . verbose ( " Found forced library for %s \n \t %s [ %s ] " % ( ModuleFile , LibraryPath , LibraryClass ) )
Module . LibraryClasses [ LibraryClass ] = LibraryPath
if LibraryPath not in self . LibraryInstances :
self . LibraryInstances . append ( LibraryPath )
# get module private PCD setting
for Type in [ MODEL_PCD_FIXED_AT_BUILD , MODEL_PCD_PATCHABLE_IN_MODULE , \
MODEL_PCD_FEATURE_FLAG , MODEL_PCD_DYNAMIC , MODEL_PCD_DYNAMIC_EX ] :
RecordList = self . _RawData [ Type , self . _Arch , None , ModuleId ]
for TokenSpaceGuid , PcdCName , Setting , Dummy1 , Dummy2 , Dummy3 , Dummy4 , Dummy5 in RecordList :
TokenList = GetSplitValueList ( Setting )
DefaultValue = TokenList [ 0 ]
# the format is PcdName| Value | VOID* | MaxDatumSize
if len ( TokenList ) > 2 :
MaxDatumSize = TokenList [ 2 ]
else :
MaxDatumSize = ' '
TypeString = self . _PCD_TYPE_STRING_ [ Type ]
Pcd = PcdClassObject (
PcdCName ,
TokenSpaceGuid ,
TypeString ,
' ' ,
DefaultValue ,
' ' ,
MaxDatumSize ,
{ } ,
False ,
None
)
Module . Pcds [ PcdCName , TokenSpaceGuid ] = Pcd
# get module private build options
RecordList = self . _RawData [ MODEL_META_DATA_BUILD_OPTION , self . _Arch , None , ModuleId ]
for ToolChainFamily , ToolChain , Option , Dummy1 , Dummy2 , Dummy3 , Dummy4 , Dummy5 in RecordList :
if ( ToolChainFamily , ToolChain ) not in Module . BuildOptions :
Module . BuildOptions [ ToolChainFamily , ToolChain ] = Option
else :
OptionString = Module . BuildOptions [ ToolChainFamily , ToolChain ]
Module . BuildOptions [ ToolChainFamily , ToolChain ] = OptionString + " " + Option
RecordList = self . _RawData [ MODEL_META_DATA_HEADER , self . _Arch , None , ModuleId ]
if RecordList :
if len ( RecordList ) != 1 :
EdkLogger . error ( ' build ' , OPTION_UNKNOWN , ' Only FILE_GUID can be listed in <Defines> section. ' ,
File = self . MetaFile , ExtraData = str ( ModuleFile ) , Line = LineNo )
ModuleFile = ProcessDuplicatedInf ( ModuleFile , RecordList [ 0 ] [ 2 ] , GlobalData . gWorkspace )
ModuleFile . Arch = self . _Arch
self . _Modules [ ModuleFile ] = Module
return self . _Modules
## Retrieve all possible library instances used in this platform
@property
def LibraryInstances ( self ) :
if self . _LibraryInstances is None :
self . LibraryClasses
return self . _LibraryInstances
## Retrieve [LibraryClasses] information
@property
def LibraryClasses ( self ) :
if self . _LibraryClasses is None :
self . _LibraryInstances = [ ]
#
# tdict is a special dict kind of type, used for selecting correct
# library instance for given library class and module type
#
LibraryClassDict = tdict ( True , 3 )
# track all library class names
LibraryClassSet = set ( )
RecordList = self . _RawData [ MODEL_EFI_LIBRARY_CLASS , self . _Arch , None , - 1 ]
Macros = self . _Macros
for Record in RecordList :
LibraryClass , LibraryInstance , Dummy , Arch , ModuleType , Dummy , Dummy , LineNo = Record
if LibraryClass == ' ' or LibraryClass == ' NULL ' :
self . _NullLibraryNumber + = 1
LibraryClass = ' NULL %d ' % self . _NullLibraryNumber
EdkLogger . verbose ( " Found forced library for arch= %s \n \t %s [ %s ] " % ( Arch , LibraryInstance , LibraryClass ) )
LibraryClassSet . add ( LibraryClass )
LibraryInstance = PathClass ( NormPath ( LibraryInstance , Macros ) , GlobalData . gWorkspace , Arch = self . _Arch )
# check the file validation
ErrorCode , ErrorInfo = LibraryInstance . Validate ( ' .inf ' )
if ErrorCode != 0 :
EdkLogger . error ( ' build ' , ErrorCode , File = self . MetaFile , Line = LineNo ,
ExtraData = ErrorInfo )
if ModuleType != TAB_COMMON and ModuleType not in SUP_MODULE_LIST :
EdkLogger . error ( ' build ' , OPTION_UNKNOWN , " Unknown module type [ %s ] " % ModuleType ,
File = self . MetaFile , ExtraData = LibraryInstance , Line = LineNo )
LibraryClassDict [ Arch , ModuleType , LibraryClass ] = LibraryInstance
if LibraryInstance not in self . _LibraryInstances :
self . _LibraryInstances . append ( LibraryInstance )
# resolve the specific library instance for each class and each module type
self . _LibraryClasses = tdict ( True )
for LibraryClass in LibraryClassSet :
# try all possible module types
for ModuleType in SUP_MODULE_LIST :
LibraryInstance = LibraryClassDict [ self . _Arch , ModuleType , LibraryClass ]
if LibraryInstance is None :
continue
self . _LibraryClasses [ LibraryClass , ModuleType ] = LibraryInstance
RecordList = self . _RawData [ MODEL_EFI_LIBRARY_INSTANCE , self . _Arch ]
for Record in RecordList :
File = PathClass ( NormPath ( Record [ 0 ] , Macros ) , GlobalData . gWorkspace , Arch = self . _Arch )
LineNo = Record [ - 1 ]
# check the file validation
ErrorCode , ErrorInfo = File . Validate ( ' .inf ' )
if ErrorCode != 0 :
EdkLogger . error ( ' build ' , ErrorCode , File = self . MetaFile , Line = LineNo ,
ExtraData = ErrorInfo )
if File not in self . _LibraryInstances :
self . _LibraryInstances . append ( File )
#
# we need the module name as the library class name, so we have
# to parse it here. (self._Bdb[] will trigger a file parse if it
# hasn't been parsed)
#
Library = self . _Bdb [ File , self . _Arch , self . _Target , self . _Toolchain ]
self . _LibraryClasses [ Library . BaseName , ' :dummy: ' ] = Library
return self . _LibraryClasses
def _ValidatePcd ( self , PcdCName , TokenSpaceGuid , Setting , PcdType , LineNo ) :
if not self . _DecPcds :
FdfInfList = [ ]
if GlobalData . gFdfParser :
FdfInfList = GlobalData . gFdfParser . Profile . InfList
PkgSet = set ( )
for Inf in FdfInfList :
ModuleFile = PathClass ( NormPath ( Inf ) , GlobalData . gWorkspace , Arch = self . _Arch )
if ModuleFile in self . _Modules :
continue
ModuleData = self . _Bdb [ ModuleFile , self . _Arch , self . _Target , self . _Toolchain ]
PkgSet . update ( ModuleData . Packages )
self . _DecPcds , self . _GuidDict = GetDeclaredPcd ( self , self . _Bdb , self . _Arch , self . _Target , self . _Toolchain , PkgSet )
self . _GuidDict . update ( GlobalData . gPlatformPcds )
if ( PcdCName , TokenSpaceGuid ) not in self . _DecPcds :
EdkLogger . error ( ' build ' , PARSER_ERROR ,
" Pcd ( %s . %s ) defined in DSC is not declared in DEC files referenced in INF files in FDF. Arch: [ ' %s ' ] " % ( TokenSpaceGuid , PcdCName , self . _Arch ) ,
File = self . MetaFile , Line = LineNo )
ValueList , IsValid , Index = AnalyzeDscPcd ( Setting , PcdType , self . _DecPcds [ PcdCName , TokenSpaceGuid ] . DatumType )
if not IsValid :
if PcdType not in [ MODEL_PCD_FEATURE_FLAG , MODEL_PCD_FIXED_AT_BUILD ] :
EdkLogger . error ( ' build ' , FORMAT_INVALID , " Pcd format incorrect. " , File = self . MetaFile , Line = LineNo ,
ExtraData = " %s . %s | %s " % ( TokenSpaceGuid , PcdCName , Setting ) )
else :
if ValueList [ 2 ] == ' -1 ' :
EdkLogger . error ( ' build ' , FORMAT_INVALID , " Pcd format incorrect. " , File = self . MetaFile , Line = LineNo ,
ExtraData = " %s . %s | %s " % ( TokenSpaceGuid , PcdCName , Setting ) )
if ValueList [ Index ] :
DatumType = self . _DecPcds [ PcdCName , TokenSpaceGuid ] . DatumType
if " { CODE( " not in ValueList [ Index ] :
try :
ValueList [ Index ] = ValueExpressionEx ( ValueList [ Index ] , DatumType , self . _GuidDict ) ( True )
except BadExpression as Value :
EdkLogger . error ( ' Parser ' , FORMAT_INVALID , Value , File = self . MetaFile , Line = LineNo ,
ExtraData = " PCD [ %s . %s ] Value \" %s \" " % (
TokenSpaceGuid , PcdCName , ValueList [ Index ] ) )
except EvaluationException as Excpt :
if hasattr ( Excpt , ' Pcd ' ) :
if Excpt . Pcd in GlobalData . gPlatformOtherPcds :
EdkLogger . error ( ' Parser ' , FORMAT_INVALID , " Cannot use this PCD ( %s ) in an expression as "
" it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section "
" of the DSC file " % Excpt . Pcd ,
File = self . MetaFile , Line = LineNo )
else :
EdkLogger . error ( ' Parser ' , FORMAT_INVALID , " PCD ( %s ) is not defined in DSC file " % Excpt . Pcd ,
File = self . MetaFile , Line = LineNo )
else :
EdkLogger . error ( ' Parser ' , FORMAT_INVALID , " Invalid expression: %s " % str ( Excpt ) ,
File = self . MetaFile , Line = LineNo )
if ValueList [ Index ] :
Valid , ErrStr = CheckPcdDatum ( self . _DecPcds [ PcdCName , TokenSpaceGuid ] . DatumType , ValueList [ Index ] )
if not Valid :
EdkLogger . error ( ' build ' , FORMAT_INVALID , ErrStr , File = self . MetaFile , Line = LineNo ,
ExtraData = " %s . %s " % ( TokenSpaceGuid , PcdCName ) )
if PcdType in ( MODEL_PCD_DYNAMIC_DEFAULT , MODEL_PCD_DYNAMIC_EX_DEFAULT , MODEL_PCD_FIXED_AT_BUILD , MODEL_PCD_PATCHABLE_IN_MODULE ) :
if self . _DecPcds [ PcdCName , TokenSpaceGuid ] . DatumType . strip ( ) != ValueList [ 1 ] . strip ( ) :
DecPcd = self . _DecPcds [ PcdCName , TokenSpaceGuid ]
EdkLogger . error ( ' build ' , FORMAT_INVALID ,
" Pcd datumtype used in DSC file is not the same as its declaration. DatumType: %s " % DecPcd . DatumType ,
File = self . MetaFile , Line = LineNo ,
ExtraData = " Dsc: %s . %s | %s \n Dec: %s . %s | %s | %s | %s " % ( TokenSpaceGuid , PcdCName , Setting , TokenSpaceGuid , \
PcdCName , DecPcd . DefaultValue , DecPcd . DatumType , DecPcd . TokenValue ) )
if ( TokenSpaceGuid + ' . ' + PcdCName ) in GlobalData . gPlatformPcds :
if GlobalData . gPlatformPcds [ TokenSpaceGuid + ' . ' + PcdCName ] != ValueList [ Index ] :
GlobalData . gPlatformPcds [ TokenSpaceGuid + ' . ' + PcdCName ] = ValueList [ Index ]
return ValueList
def _FilterPcdBySkuUsage ( self , Pcds ) :
available_sku = self . SkuIdMgr . AvailableSkuIdSet
sku_usage = self . SkuIdMgr . SkuUsageType
if sku_usage == SkuClass . SINGLE :
for pcdname in Pcds :
pcd = Pcds [ pcdname ]
Pcds [ pcdname ] . SkuInfoList = { TAB_DEFAULT : pcd . SkuInfoList [ skuid ] for skuid in pcd . SkuInfoList if skuid in available_sku }
if isinstance ( pcd , StructurePcd ) and pcd . SkuOverrideValues :
Pcds [ pcdname ] . SkuOverrideValues = { TAB_DEFAULT : pcd . SkuOverrideValues [ skuid ] for skuid in pcd . SkuOverrideValues if skuid in available_sku }
else :
for pcdname in Pcds :
pcd = Pcds [ pcdname ]
Pcds [ pcdname ] . SkuInfoList = { skuid : pcd . SkuInfoList [ skuid ] for skuid in pcd . SkuInfoList if skuid in available_sku }
if isinstance ( pcd , StructurePcd ) and pcd . SkuOverrideValues :
Pcds [ pcdname ] . SkuOverrideValues = { skuid : pcd . SkuOverrideValues [ skuid ] for skuid in pcd . SkuOverrideValues if skuid in available_sku }
return Pcds
def CompleteHiiPcdsDefaultStores ( self , Pcds ) :
HiiPcd = [ Pcds [ pcd ] for pcd in Pcds if Pcds [ pcd ] . Type in [ self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_HII ] , self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_EX_HII ] ] ]
DefaultStoreMgr = DefaultStore ( self . DefaultStores )
for pcd in HiiPcd :
for skuid in pcd . SkuInfoList :
skuobj = pcd . SkuInfoList . get ( skuid )
if TAB_DEFAULT_STORES_DEFAULT not in skuobj . DefaultStoreDict :
PcdDefaultStoreSet = set ( defaultstorename for defaultstorename in skuobj . DefaultStoreDict )
mindefaultstorename = DefaultStoreMgr . GetMin ( PcdDefaultStoreSet )
skuobj . DefaultStoreDict [ TAB_DEFAULT_STORES_DEFAULT ] = skuobj . DefaultStoreDict [ mindefaultstorename ]
return Pcds
def RecoverCommandLinePcd ( self ) :
def UpdateCommandLineValue ( pcd ) :
if pcd . Type in [ self . _PCD_TYPE_STRING_ [ MODEL_PCD_FIXED_AT_BUILD ] ,
self . _PCD_TYPE_STRING_ [ MODEL_PCD_PATCHABLE_IN_MODULE ] ] :
pcd . PcdValueFromComm = pcd . DefaultValue
elif pcd . Type in [ self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_HII ] , self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_EX_HII ] ] :
pcd . PcdValueFromComm = pcd . SkuInfoList . get ( TAB_DEFAULT ) . HiiDefaultValue
else :
pcd . PcdValueFromComm = pcd . SkuInfoList . get ( TAB_DEFAULT ) . DefaultValue
for pcd in self . _Pcds :
if isinstance ( self . _Pcds [ pcd ] , StructurePcd ) and ( self . _Pcds [ pcd ] . PcdValueFromComm or self . _Pcds [ pcd ] . PcdFieldValueFromComm ) :
UpdateCommandLineValue ( self . _Pcds [ pcd ] )
def __ParsePcdFromCommandLine ( self ) :
if GlobalData . BuildOptionPcd :
for i , pcd in enumerate ( GlobalData . BuildOptionPcd ) :
if isinstance ( pcd , tuple ) :
continue
( pcdname , pcdvalue ) = pcd . split ( ' = ' )
if not pcdvalue :
EdkLogger . error ( ' build ' , AUTOGEN_ERROR , " No Value specified for the PCD %s . " % ( pcdname ) )
if ' . ' in pcdname :
( Name1 , Name2 ) = pcdname . split ( ' . ' , 1 )
if " . " in Name2 :
( Name3 , FieldName ) = Name2 . split ( " . " , 1 )
if ( ( Name3 , Name1 ) ) in self . DecPcds :
HasTokenSpace = True
TokenCName = Name3
TokenSpaceGuidCName = Name1
else :
FieldName = Name2
TokenCName = Name1
TokenSpaceGuidCName = ' '
HasTokenSpace = False
else :
if ( ( Name2 , Name1 ) ) in self . DecPcds :
HasTokenSpace = True
TokenCName = Name2
TokenSpaceGuidCName = Name1
FieldName = " "
else :
FieldName = Name2
TokenCName = Name1
TokenSpaceGuidCName = ' '
HasTokenSpace = False
else :
FieldName = " "
TokenCName = pcdname
TokenSpaceGuidCName = ' '
HasTokenSpace = False
TokenSpaceGuidCNameList = [ ]
FoundFlag = False
PcdDatumType = ' '
DisplayName = TokenCName
if FieldName :
DisplayName = TokenCName + ' . ' + FieldName
if not HasTokenSpace :
for key in self . DecPcds :
PcdItem = self . DecPcds [ key ]
if TokenCName == PcdItem . TokenCName :
if not PcdItem . TokenSpaceGuidCName in TokenSpaceGuidCNameList :
if len ( TokenSpaceGuidCNameList ) < 1 :
TokenSpaceGuidCNameList . append ( PcdItem . TokenSpaceGuidCName )
TokenSpaceGuidCName = PcdItem . TokenSpaceGuidCName
PcdDatumType = PcdItem . DatumType
FoundFlag = True
else :
EdkLogger . error (
' build ' ,
AUTOGEN_ERROR ,
" The Pcd %s is found under multiple different TokenSpaceGuid: %s and %s . " % ( DisplayName , PcdItem . TokenSpaceGuidCName , TokenSpaceGuidCNameList [ 0 ] )
)
else :
if ( TokenCName , TokenSpaceGuidCName ) in self . DecPcds :
PcdDatumType = self . DecPcds [ ( TokenCName , TokenSpaceGuidCName ) ] . DatumType
FoundFlag = True
if not FoundFlag :
if HasTokenSpace :
EdkLogger . error ( ' build ' , AUTOGEN_ERROR , " The Pcd %s . %s is not found in the DEC file. " % ( TokenSpaceGuidCName , DisplayName ) )
else :
EdkLogger . error ( ' build ' , AUTOGEN_ERROR , " The Pcd %s is not found in the DEC file. " % ( DisplayName ) )
pcdvalue = pcdvalue . replace ( " \\ \\ \\ ' " , ' \\ \\ \\ " ' ) . replace ( ' \\ \' ' , ' \' ' ) . replace ( ' \\ \\ \\ " ' , " \\ ' " )
if FieldName :
pcdvalue = DscBuildData . HandleFlexiblePcd ( TokenSpaceGuidCName , TokenCName , pcdvalue , PcdDatumType , self . _GuidDict , FieldName )
else :
pcdvalue = DscBuildData . HandleFlexiblePcd ( TokenSpaceGuidCName , TokenCName , pcdvalue , PcdDatumType , self . _GuidDict )
IsValid , Cause = CheckPcdDatum ( PcdDatumType , pcdvalue )
if not IsValid :
EdkLogger . error ( " build " , FORMAT_INVALID , Cause , ExtraData = " %s . %s " % ( TokenSpaceGuidCName , TokenCName ) )
GlobalData . BuildOptionPcd [ i ] = ( TokenSpaceGuidCName , TokenCName , FieldName , pcdvalue , ( " build command options " , 1 ) )
if GlobalData . BuildOptionPcd :
inf_objs = [ item for item in self . _Bdb . _CACHE_ . values ( ) if item . Arch == self . Arch and item . MetaFile . Ext . lower ( ) == ' .inf ' ]
for pcd in GlobalData . BuildOptionPcd :
( TokenSpaceGuidCName , TokenCName , FieldName , pcdvalue , _ ) = pcd
for BuildData in inf_objs :
for key in BuildData . Pcds :
PcdItem = BuildData . Pcds [ key ]
if ( TokenSpaceGuidCName , TokenCName ) == ( PcdItem . TokenSpaceGuidCName , PcdItem . TokenCName ) and FieldName == " " :
PcdItem . DefaultValue = pcdvalue
PcdItem . PcdValueFromComm = pcdvalue
#In command line, the latter full assign value in commandLine should override the former field assign value.
#For example, --pcd Token.pcd.field="" --pcd Token.pcd=H"{}"
delete_assign = [ ]
field_assign = { }
if GlobalData . BuildOptionPcd :
for pcdTuple in GlobalData . BuildOptionPcd :
TokenSpaceGuid , Token , Field = pcdTuple [ 0 ] , pcdTuple [ 1 ] , pcdTuple [ 2 ]
if Field :
if ( TokenSpaceGuid , Token ) not in field_assign :
field_assign [ TokenSpaceGuid , Token ] = [ ]
field_assign [ TokenSpaceGuid , Token ] . append ( pcdTuple )
else :
if ( TokenSpaceGuid , Token ) in field_assign :
delete_assign . extend ( field_assign [ TokenSpaceGuid , Token ] )
field_assign [ TokenSpaceGuid , Token ] = [ ]
for item in delete_assign :
GlobalData . BuildOptionPcd . remove ( item )
@staticmethod
def HandleFlexiblePcd ( TokenSpaceGuidCName , TokenCName , PcdValue , PcdDatumType , GuidDict , FieldName = ' ' ) :
if FieldName :
IsArray = False
TokenCName + = ' . ' + FieldName
if PcdValue . startswith ( ' H ' ) :
if FieldName and _IsFieldValueAnArray ( PcdValue [ 1 : ] ) :
PcdDatumType = TAB_VOID
IsArray = True
if FieldName and not IsArray :
return PcdValue
try :
PcdValue = ValueExpressionEx ( PcdValue [ 1 : ] , PcdDatumType , GuidDict ) ( True )
except BadExpression as Value :
EdkLogger . error ( ' Parser ' , FORMAT_INVALID , ' PCD [ %s . %s ] Value " %s " , %s ' %
( TokenSpaceGuidCName , TokenCName , PcdValue , Value ) )
elif PcdValue . startswith ( " L ' " ) or PcdValue . startswith ( " ' " ) :
if FieldName and _IsFieldValueAnArray ( PcdValue ) :
PcdDatumType = TAB_VOID
IsArray = True
if FieldName and not IsArray :
return PcdValue
try :
PcdValue = ValueExpressionEx ( PcdValue , PcdDatumType , GuidDict ) ( True )
except BadExpression as Value :
EdkLogger . error ( ' Parser ' , FORMAT_INVALID , ' PCD [ %s . %s ] Value " %s " , %s ' %
( TokenSpaceGuidCName , TokenCName , PcdValue , Value ) )
elif PcdValue . startswith ( ' L ' ) :
PcdValue = ' L " ' + PcdValue [ 1 : ] + ' " '
if FieldName and _IsFieldValueAnArray ( PcdValue ) :
PcdDatumType = TAB_VOID
IsArray = True
if FieldName and not IsArray :
return PcdValue
try :
PcdValue = ValueExpressionEx ( PcdValue , PcdDatumType , GuidDict ) ( True )
except BadExpression as Value :
EdkLogger . error ( ' Parser ' , FORMAT_INVALID , ' PCD [ %s . %s ] Value " %s " , %s ' %
( TokenSpaceGuidCName , TokenCName , PcdValue , Value ) )
else :
if PcdValue . upper ( ) == ' FALSE ' :
PcdValue = str ( 0 )
if PcdValue . upper ( ) == ' TRUE ' :
PcdValue = str ( 1 )
if not FieldName :
if PcdDatumType not in TAB_PCD_NUMERIC_TYPES :
PcdValue = ' " ' + PcdValue + ' " '
elif not PcdValue . isdigit ( ) and not PcdValue . upper ( ) . startswith ( ' 0X ' ) :
PcdValue = ' " ' + PcdValue + ' " '
else :
IsArray = False
Base = 10
if PcdValue . upper ( ) . startswith ( ' 0X ' ) :
Base = 16
try :
Num = int ( PcdValue , Base )
except :
PcdValue = ' " ' + PcdValue + ' " '
if _IsFieldValueAnArray ( PcdValue ) :
PcdDatumType = TAB_VOID
IsArray = True
if not IsArray :
return PcdValue
try :
PcdValue = ValueExpressionEx ( PcdValue , PcdDatumType , GuidDict ) ( True )
except BadExpression as Value :
EdkLogger . error ( ' Parser ' , FORMAT_INVALID , ' PCD [ %s . %s ] Value " %s " , %s ' %
( TokenSpaceGuidCName , TokenCName , PcdValue , Value ) )
return PcdValue
## Retrieve all PCD settings in platform
@property
def Pcds ( self ) :
if self . _Pcds is None :
self . _Pcds = OrderedDict ( )
self . __ParsePcdFromCommandLine ( )
self . _Pcds . update ( self . _GetPcd ( MODEL_PCD_FIXED_AT_BUILD ) )
self . _Pcds . update ( self . _GetPcd ( MODEL_PCD_PATCHABLE_IN_MODULE ) )
self . _Pcds . update ( self . _GetPcd ( MODEL_PCD_FEATURE_FLAG ) )
self . _Pcds . update ( self . _GetDynamicPcd ( MODEL_PCD_DYNAMIC_DEFAULT ) )
self . _Pcds . update ( self . _GetDynamicHiiPcd ( MODEL_PCD_DYNAMIC_HII ) )
self . _Pcds . update ( self . _GetDynamicVpdPcd ( MODEL_PCD_DYNAMIC_VPD ) )
self . _Pcds . update ( self . _GetDynamicPcd ( MODEL_PCD_DYNAMIC_EX_DEFAULT ) )
self . _Pcds . update ( self . _GetDynamicHiiPcd ( MODEL_PCD_DYNAMIC_EX_HII ) )
self . _Pcds . update ( self . _GetDynamicVpdPcd ( MODEL_PCD_DYNAMIC_EX_VPD ) )
self . _Pcds = self . CompletePcdValues ( self . _Pcds )
self . _Pcds = self . OverrideByFdfOverAll ( self . _Pcds )
self . _Pcds = self . OverrideByCommOverAll ( self . _Pcds )
self . _Pcds = self . UpdateStructuredPcds ( MODEL_PCD_TYPE_LIST , self . _Pcds )
self . _Pcds = self . CompleteHiiPcdsDefaultStores ( self . _Pcds )
self . _Pcds = self . _FilterPcdBySkuUsage ( self . _Pcds )
self . RecoverCommandLinePcd ( )
return self . _Pcds
## Retrieve [BuildOptions]
@property
def BuildOptions ( self ) :
if self . _BuildOptions is None :
self . _BuildOptions = OrderedDict ( )
#
# Retrieve build option for EDKII and EDK style module
#
for CodeBase in ( EDKII_NAME , EDK_NAME ) :
RecordList = self . _RawData [ MODEL_META_DATA_BUILD_OPTION , self . _Arch , CodeBase ]
for ToolChainFamily , ToolChain , Option , Dummy1 , Dummy2 , Dummy3 , Dummy4 , Dummy5 in RecordList :
if Dummy3 . upper ( ) != TAB_COMMON :
continue
CurKey = ( ToolChainFamily , ToolChain , CodeBase )
#
# Only flags can be appended
#
if CurKey not in self . _BuildOptions or not ToolChain . endswith ( ' _FLAGS ' ) or Option . startswith ( ' = ' ) :
self . _BuildOptions [ CurKey ] = Option
else :
if ' ' + Option not in self . _BuildOptions [ CurKey ] :
self . _BuildOptions [ CurKey ] + = ' ' + Option
return self . _BuildOptions
def GetBuildOptionsByPkg ( self , Module , ModuleType ) :
local_pkg = os . path . split ( Module . LocalPkg ( ) ) [ 0 ]
if self . _ModuleTypeOptions is None :
self . _ModuleTypeOptions = OrderedDict ( )
if ModuleType not in self . _ModuleTypeOptions :
options = OrderedDict ( )
self . _ModuleTypeOptions [ ModuleType ] = options
RecordList = self . _RawData [ MODEL_META_DATA_BUILD_OPTION , self . _Arch ]
for ToolChainFamily , ToolChain , Option , Dummy1 , Dummy2 , Dummy3 , Dummy4 , Dummy5 in RecordList :
if Dummy2 not in ( TAB_COMMON , local_pkg . upper ( ) , " EDKII " ) :
continue
Type = Dummy3
if Type . upper ( ) == ModuleType . upper ( ) :
Key = ( ToolChainFamily , ToolChain )
if Key not in options or not ToolChain . endswith ( ' _FLAGS ' ) or Option . startswith ( ' = ' ) :
options [ Key ] = Option
else :
if ' ' + Option not in options [ Key ] :
options [ Key ] + = ' ' + Option
return self . _ModuleTypeOptions [ ModuleType ]
def GetBuildOptionsByModuleType ( self , Edk , ModuleType ) :
if self . _ModuleTypeOptions is None :
self . _ModuleTypeOptions = OrderedDict ( )
if ( Edk , ModuleType ) not in self . _ModuleTypeOptions :
options = OrderedDict ( )
self . _ModuleTypeOptions [ Edk , ModuleType ] = options
DriverType = ' %s . %s ' % ( Edk , ModuleType )
CommonDriverType = ' %s . %s ' % ( TAB_COMMON , ModuleType )
RecordList = self . _RawData [ MODEL_META_DATA_BUILD_OPTION , self . _Arch ]
for ToolChainFamily , ToolChain , Option , Dummy1 , Dummy2 , Dummy3 , Dummy4 , Dummy5 in RecordList :
Type = Dummy2 + ' . ' + Dummy3
if Type . upper ( ) == DriverType . upper ( ) or Type . upper ( ) == CommonDriverType . upper ( ) :
Key = ( ToolChainFamily , ToolChain , Edk )
if Key not in options or not ToolChain . endswith ( ' _FLAGS ' ) or Option . startswith ( ' = ' ) :
options [ Key ] = Option
else :
if ' ' + Option not in options [ Key ] :
options [ Key ] + = ' ' + Option
return self . _ModuleTypeOptions [ Edk , ModuleType ]
@staticmethod
def GetStructurePcdInfo ( PcdSet ) :
structure_pcd_data = defaultdict ( list )
for item in PcdSet :
structure_pcd_data [ ( item [ 0 ] , item [ 1 ] ) ] . append ( item )
return structure_pcd_data
@staticmethod
def OverrideByFdf ( StruPcds , workspace ) :
if GlobalData . gFdfParser is None :
return StruPcds
StructurePcdInFdf = OrderedDict ( )
fdfpcd = GlobalData . gFdfParser . Profile . PcdDict
fdfpcdlocation = GlobalData . gFdfParser . Profile . PcdLocalDict
for item in fdfpcd :
if len ( item [ 2 ] ) and ( item [ 0 ] , item [ 1 ] ) in StruPcds :
StructurePcdInFdf [ ( item [ 1 ] , item [ 0 ] , item [ 2 ] ) ] = fdfpcd [ item ]
GlobalPcds = { ( item [ 0 ] , item [ 1 ] ) for item in StructurePcdInFdf }
for Pcd in StruPcds . values ( ) :
if ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName ) not in GlobalPcds :
continue
FieldValues = OrderedDict ( )
for item in StructurePcdInFdf :
if ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName ) == ( item [ 0 ] , item [ 1 ] ) and item [ 2 ] :
FieldValues [ item [ 2 ] ] = StructurePcdInFdf [ item ]
for field in FieldValues :
if field not in Pcd . PcdFieldValueFromFdf :
Pcd . PcdFieldValueFromFdf [ field ] = [ " " , " " , " " ]
Pcd . PcdFieldValueFromFdf [ field ] [ 0 ] = FieldValues [ field ]
Pcd . PcdFieldValueFromFdf [ field ] [ 1 ] = os . path . relpath ( fdfpcdlocation [ ( Pcd . TokenCName , Pcd . TokenSpaceGuidCName , field ) ] [ 0 ] , workspace )
Pcd . PcdFieldValueFromFdf [ field ] [ 2 ] = fdfpcdlocation [ ( Pcd . TokenCName , Pcd . TokenSpaceGuidCName , field ) ] [ 1 ]
return StruPcds
@staticmethod
def OverrideByComm ( StruPcds ) :
StructurePcdInCom = OrderedDict ( )
for item in GlobalData . BuildOptionPcd :
if len ( item ) == 5 and ( item [ 1 ] , item [ 0 ] ) in StruPcds :
StructurePcdInCom [ ( item [ 0 ] , item [ 1 ] , item [ 2 ] ) ] = ( item [ 3 ] , item [ 4 ] )
GlobalPcds = { ( item [ 0 ] , item [ 1 ] ) for item in StructurePcdInCom }
for Pcd in StruPcds . values ( ) :
if ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName ) not in GlobalPcds :
continue
FieldValues = OrderedDict ( )
for item in StructurePcdInCom :
if ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName ) == ( item [ 0 ] , item [ 1 ] ) and item [ 2 ] :
FieldValues [ item [ 2 ] ] = StructurePcdInCom [ item ]
for field in FieldValues :
if field not in Pcd . PcdFieldValueFromComm :
Pcd . PcdFieldValueFromComm [ field ] = [ " " , " " , " " ]
Pcd . PcdFieldValueFromComm [ field ] [ 0 ] = FieldValues [ field ] [ 0 ]
Pcd . PcdFieldValueFromComm [ field ] [ 1 ] = FieldValues [ field ] [ 1 ] [ 0 ]
Pcd . PcdFieldValueFromComm [ field ] [ 2 ] = FieldValues [ field ] [ 1 ] [ 1 ]
return StruPcds
def OverrideByCommOverAll ( self , AllPcds ) :
def CheckStructureInComm ( commpcds ) :
if not commpcds :
return False
if len ( commpcds [ 0 ] ) == 5 :
return True
return False
NoFiledValues = OrderedDict ( )
if CheckStructureInComm ( GlobalData . BuildOptionPcd ) :
StructurePcdInCom = OrderedDict ( )
for item in GlobalData . BuildOptionPcd :
StructurePcdInCom [ ( item [ 0 ] , item [ 1 ] , item [ 2 ] ) ] = ( item [ 3 ] , item [ 4 ] )
for item in StructurePcdInCom :
if not item [ 2 ] :
NoFiledValues [ ( item [ 0 ] , item [ 1 ] ) ] = StructurePcdInCom [ item ]
else :
for item in GlobalData . BuildOptionPcd :
NoFiledValues [ ( item [ 0 ] , item [ 1 ] ) ] = [ item [ 2 ] ]
for Guid , Name in NoFiledValues :
if ( Name , Guid ) in AllPcds :
Pcd = AllPcds . get ( ( Name , Guid ) )
if isinstance ( self . _DecPcds . get ( ( Pcd . TokenCName , Pcd . TokenSpaceGuidCName ) , None ) , StructurePcd ) :
self . _DecPcds . get ( ( Pcd . TokenCName , Pcd . TokenSpaceGuidCName ) ) . PcdValueFromComm = NoFiledValues [ ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName ) ] [ 0 ]
else :
Pcd . PcdValueFromComm = NoFiledValues [ ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName ) ] [ 0 ]
Pcd . DefaultValue = NoFiledValues [ ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName ) ] [ 0 ]
for sku in Pcd . SkuInfoList :
SkuInfo = Pcd . SkuInfoList [ sku ]
if SkuInfo . DefaultValue :
SkuInfo . DefaultValue = NoFiledValues [ ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName ) ] [ 0 ]
else :
SkuInfo . HiiDefaultValue = NoFiledValues [ ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName ) ] [ 0 ]
for defaultstore in SkuInfo . DefaultStoreDict :
SkuInfo . DefaultStoreDict [ defaultstore ] = NoFiledValues [ ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName ) ] [ 0 ]
if Pcd . Type in [ self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_EX_HII ] , self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_HII ] ] :
if Pcd . DatumType == TAB_VOID :
if not Pcd . MaxDatumSize :
Pcd . MaxDatumSize = ' 0 '
CurrentSize = int ( Pcd . MaxDatumSize , 16 ) if Pcd . MaxDatumSize . upper ( ) . startswith ( " 0X " ) else int ( Pcd . MaxDatumSize )
OptionSize = len ( ( StringToArray ( Pcd . PcdValueFromComm ) ) . split ( " , " ) )
MaxSize = max ( CurrentSize , OptionSize )
Pcd . MaxDatumSize = str ( MaxSize )
else :
PcdInDec = self . DecPcds . get ( ( Name , Guid ) )
if PcdInDec :
PcdInDec . PcdValueFromComm = NoFiledValues [ ( Guid , Name ) ] [ 0 ]
if PcdInDec . Type in [ self . _PCD_TYPE_STRING_ [ MODEL_PCD_FIXED_AT_BUILD ] ,
self . _PCD_TYPE_STRING_ [ MODEL_PCD_PATCHABLE_IN_MODULE ] ,
self . _PCD_TYPE_STRING_ [ MODEL_PCD_FEATURE_FLAG ] ,
self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC ] ,
self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_EX ] ] :
self . _Pcds [ Name , Guid ] = copy . deepcopy ( PcdInDec )
self . _Pcds [ Name , Guid ] . DefaultValue = NoFiledValues [ ( Guid , Name ) ] [ 0 ]
if PcdInDec . Type in [ self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC ] ,
self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_EX ] ] :
self . _Pcds [ Name , Guid ] . SkuInfoList = { TAB_DEFAULT : SkuInfoClass ( TAB_DEFAULT , self . SkuIds [ TAB_DEFAULT ] [ 0 ] , ' ' , ' ' , ' ' , ' ' , ' ' , NoFiledValues [ ( Guid , Name ) ] [ 0 ] ) }
return AllPcds
def OverrideByFdfOverAll ( self , AllPcds ) :
if GlobalData . gFdfParser is None :
return AllPcds
NoFiledValues = GlobalData . gFdfParser . Profile . PcdDict
for Name , Guid , Field in NoFiledValues :
if len ( Field ) :
continue
Value = NoFiledValues [ ( Name , Guid , Field ) ]
if ( Name , Guid ) in AllPcds :
Pcd = AllPcds . get ( ( Name , Guid ) )
if isinstance ( self . _DecPcds . get ( ( Pcd . TokenCName , Pcd . TokenSpaceGuidCName ) , None ) , StructurePcd ) :
self . _DecPcds . get ( ( Pcd . TokenCName , Pcd . TokenSpaceGuidCName ) ) . PcdValueFromComm = Value
else :
Pcd . PcdValueFromComm = Value
Pcd . DefaultValue = Value
for sku in Pcd . SkuInfoList :
SkuInfo = Pcd . SkuInfoList [ sku ]
if SkuInfo . DefaultValue :
SkuInfo . DefaultValue = Value
else :
SkuInfo . HiiDefaultValue = Value
for defaultstore in SkuInfo . DefaultStoreDict :
SkuInfo . DefaultStoreDict [ defaultstore ] = Value
if Pcd . Type in [ self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_EX_HII ] , self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_HII ] ] :
if Pcd . DatumType == TAB_VOID :
if not Pcd . MaxDatumSize :
Pcd . MaxDatumSize = ' 0 '
CurrentSize = int ( Pcd . MaxDatumSize , 16 ) if Pcd . MaxDatumSize . upper ( ) . startswith ( " 0X " ) else int ( Pcd . MaxDatumSize )
OptionSize = len ( ( StringToArray ( Pcd . PcdValueFromComm ) ) . split ( " , " ) )
MaxSize = max ( CurrentSize , OptionSize )
Pcd . MaxDatumSize = str ( MaxSize )
else :
PcdInDec = self . DecPcds . get ( ( Name , Guid ) )
if PcdInDec :
PcdInDec . PcdValueFromFdf = Value
if PcdInDec . Type in [ self . _PCD_TYPE_STRING_ [ MODEL_PCD_FIXED_AT_BUILD ] ,
self . _PCD_TYPE_STRING_ [ MODEL_PCD_PATCHABLE_IN_MODULE ] ,
self . _PCD_TYPE_STRING_ [ MODEL_PCD_FEATURE_FLAG ] ] :
self . _Pcds [ Name , Guid ] = copy . deepcopy ( PcdInDec )
self . _Pcds [ Name , Guid ] . DefaultValue = Value
return AllPcds
def ParsePcdNameStruct ( self , NamePart1 , NamePart2 ) :
TokenSpaceCName = PcdCName = DimensionAttr = Field = " "
if " . " in NamePart1 :
TokenSpaceCName , TempPcdCName = NamePart1 . split ( " . " )
if " [ " in TempPcdCName :
PcdCName = TempPcdCName [ : TempPcdCName . index ( " [ " ) ]
DimensionAttr = TempPcdCName [ TempPcdCName . index ( " [ " ) : ]
else :
PcdCName = TempPcdCName
Field = NamePart2
else :
TokenSpaceCName = NamePart1
if " [ " in NamePart2 :
PcdCName = NamePart2 [ : NamePart2 . index ( " [ " ) ]
DimensionAttr = NamePart2 [ NamePart2 . index ( " [ " ) : ]
else :
PcdCName = NamePart2
return TokenSpaceCName , PcdCName , DimensionAttr , Field
def UpdateStructuredPcds ( self , TypeList , AllPcds ) :
DynamicPcdType = [ self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_DEFAULT ] ,
self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_HII ] ,
self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_VPD ] ,
self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_EX_DEFAULT ] ,
self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_EX_HII ] ,
self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_EX_VPD ] ]
Pcds = AllPcds
DefaultStoreMgr = DefaultStore ( self . DefaultStores )
SkuIds = self . SkuIds
self . SkuIdMgr . AvailableSkuIdSet . update ( { TAB_DEFAULT : 0 } )
DefaultStores = { storename for pcdobj in AllPcds . values ( ) for skuobj in pcdobj . SkuInfoList . values ( ) for storename in skuobj . DefaultStoreDict }
DefaultStores . add ( TAB_DEFAULT_STORES_DEFAULT )
S_PcdSet = [ ]
# Find out all possible PCD candidates for self._Arch
RecordList = [ ]
for Type in TypeList :
RecordList . extend ( self . _RawData [ Type , self . _Arch ] )
for TokenSpaceGuid , PcdCName , Setting , Arch , SkuName , default_store , Dummy4 , Dummy5 in RecordList :
SkuName = SkuName . upper ( )
default_store = default_store . upper ( )
SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
if SkuName not in SkuIds :
continue
TCName , PCName , DimensionAttr , Field = self . ParsePcdNameStruct ( TokenSpaceGuid , PcdCName )
pcd_in_dec = self . _DecPcds . get ( ( PCName , TCName ) , None )
if pcd_in_dec is None :
EdkLogger . error ( ' build ' , PARSER_ERROR ,
" Pcd ( %s . %s ) defined in DSC is not declared in DEC files. Arch: [ ' %s ' ] " % ( TCName , PCName , self . _Arch ) ,
File = self . MetaFile , Line = Dummy5 )
if SkuName in SkuIds and ( " . " in TokenSpaceGuid or " [ " in PcdCName ) :
if not isinstance ( pcd_in_dec , StructurePcd ) :
EdkLogger . error ( ' build ' , PARSER_ERROR ,
" Pcd ( %s . %s ) is not declared as Structure PCD in DEC files. Arch: [ ' %s ' ] " % ( TCName , PCName , self . _Arch ) ,
File = self . MetaFile , Line = Dummy5 )
S_PcdSet . append ( [ TCName , PCName , DimensionAttr , Field , SkuName , default_store , Dummy5 , AnalyzePcdExpression ( Setting ) [ 0 ] ] )
# handle pcd value override
StrPcdSet = DscBuildData . GetStructurePcdInfo ( S_PcdSet )
S_pcd_set = OrderedDict ( )
for str_pcd in StrPcdSet :
str_pcd_obj = Pcds . get ( ( str_pcd [ 1 ] , str_pcd [ 0 ] ) , None )
str_pcd_dec = self . _DecPcds . get ( ( str_pcd [ 1 ] , str_pcd [ 0 ] ) , None )
str_pcd_obj_str = StructurePcd ( )
str_pcd_obj_str . copy ( str_pcd_dec )
if str_pcd_obj :
str_pcd_obj_str . copy ( str_pcd_obj )
if str_pcd_obj . Type in [ self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_HII ] , self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_EX_HII ] ] :
str_pcd_obj_str . DefaultFromDSC = { skuname : { defaultstore : str_pcd_obj . SkuInfoList [ skuname ] . DefaultStoreDict . get ( defaultstore , str_pcd_obj . SkuInfoList [ skuname ] . HiiDefaultValue ) for defaultstore in DefaultStores } for skuname in str_pcd_obj . SkuInfoList }
else :
str_pcd_obj_str . DefaultFromDSC = { skuname : { defaultstore : str_pcd_obj . SkuInfoList [ skuname ] . DefaultStoreDict . get ( defaultstore , str_pcd_obj . SkuInfoList [ skuname ] . DefaultValue ) for defaultstore in DefaultStores } for skuname in str_pcd_obj . SkuInfoList }
for str_pcd_data in StrPcdSet [ str_pcd ] :
if str_pcd_data [ 4 ] in SkuIds :
str_pcd_obj_str . AddOverrideValue ( str_pcd_data [ 3 ] , str ( str_pcd_data [ 7 ] ) , TAB_DEFAULT if str_pcd_data [ 4 ] == TAB_COMMON else str_pcd_data [ 4 ] , TAB_DEFAULT_STORES_DEFAULT if str_pcd_data [ 5 ] == TAB_COMMON else str_pcd_data [ 5 ] , self . MetaFile . File if self . WorkspaceDir not in self . MetaFile . File else self . MetaFile . File [ len ( self . WorkspaceDir ) if self . WorkspaceDir . endswith ( os . path . sep ) else len ( self . WorkspaceDir ) + 1 : ] , LineNo = str_pcd_data [ 6 ] , DimensionAttr = str_pcd_data [ 2 ] )
S_pcd_set [ str_pcd [ 1 ] , str_pcd [ 0 ] ] = str_pcd_obj_str
# Add the Structure PCD that only defined in DEC, don't have override in DSC file
for Pcd in self . DecPcds :
if isinstance ( self . _DecPcds [ Pcd ] , StructurePcd ) :
if Pcd not in S_pcd_set :
str_pcd_obj_str = StructurePcd ( )
str_pcd_obj_str . copy ( self . _DecPcds [ Pcd ] )
str_pcd_obj = Pcds . get ( Pcd , None )
if str_pcd_obj :
str_pcd_obj_str . copy ( str_pcd_obj )
if str_pcd_obj . Type in [ self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_HII ] , self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_EX_HII ] ] :
str_pcd_obj_str . DefaultFromDSC = { skuname : { defaultstore : str_pcd_obj . SkuInfoList [ skuname ] . DefaultStoreDict . get ( defaultstore , str_pcd_obj . SkuInfoList [ skuname ] . HiiDefaultValue ) for defaultstore in DefaultStores } for skuname in str_pcd_obj . SkuInfoList }
else :
str_pcd_obj_str . DefaultFromDSC = { skuname : { defaultstore : str_pcd_obj . SkuInfoList [ skuname ] . DefaultStoreDict . get ( defaultstore , str_pcd_obj . SkuInfoList [ skuname ] . DefaultValue ) for defaultstore in DefaultStores } for skuname in str_pcd_obj . SkuInfoList }
S_pcd_set [ Pcd ] = str_pcd_obj_str
if S_pcd_set :
GlobalData . gStructurePcd [ self . Arch ] = S_pcd_set . copy ( )
self . FilterStrcturePcd ( S_pcd_set )
for stru_pcd in S_pcd_set . values ( ) :
for skuid in SkuIds :
if skuid in stru_pcd . SkuOverrideValues :
continue
nextskuid = self . SkuIdMgr . GetNextSkuId ( skuid )
NoDefault = False
if skuid not in stru_pcd . SkuOverrideValues :
while nextskuid not in stru_pcd . SkuOverrideValues :
if nextskuid == TAB_DEFAULT :
NoDefault = True
break
nextskuid = self . SkuIdMgr . GetNextSkuId ( nextskuid )
stru_pcd . SkuOverrideValues [ skuid ] = copy . deepcopy ( stru_pcd . SkuOverrideValues [ nextskuid ] ) if not NoDefault else copy . deepcopy ( { defaultstorename : stru_pcd . DefaultValues for defaultstorename in DefaultStores } if DefaultStores else { } ) #{TAB_DEFAULT_STORES_DEFAULT:stru_pcd.DefaultValues})
if not NoDefault :
stru_pcd . ValueChain . add ( ( skuid , ' ' ) )
if ' DEFAULT ' in stru_pcd . SkuOverrideValues and not GlobalData . gPcdSkuOverrides . get ( ( stru_pcd . TokenCName , stru_pcd . TokenSpaceGuidCName ) ) :
GlobalData . gPcdSkuOverrides . update (
{ ( stru_pcd . TokenCName , stru_pcd . TokenSpaceGuidCName ) : { ' DEFAULT ' : stru_pcd . SkuOverrideValues [ ' DEFAULT ' ] } } )
if stru_pcd . Type in [ self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_HII ] , self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_EX_HII ] ] :
for skuid in SkuIds :
nextskuid = skuid
NoDefault = False
if skuid not in stru_pcd . SkuOverrideValues :
while nextskuid not in stru_pcd . SkuOverrideValues :
if nextskuid == TAB_DEFAULT :
NoDefault = True
break
nextskuid = self . SkuIdMgr . GetNextSkuId ( nextskuid )
if NoDefault :
continue
PcdDefaultStoreSet = set ( defaultstorename for defaultstorename in stru_pcd . SkuOverrideValues [ nextskuid ] )
mindefaultstorename = DefaultStoreMgr . GetMin ( PcdDefaultStoreSet )
for defaultstoreid in DefaultStores :
if defaultstoreid not in stru_pcd . SkuOverrideValues [ skuid ] :
stru_pcd . SkuOverrideValues [ skuid ] [ defaultstoreid ] = CopyDict ( stru_pcd . SkuOverrideValues [ nextskuid ] [ mindefaultstorename ] )
stru_pcd . ValueChain . add ( ( skuid , defaultstoreid ) )
S_pcd_set = DscBuildData . OverrideByFdf ( S_pcd_set , self . WorkspaceDir )
S_pcd_set = DscBuildData . OverrideByComm ( S_pcd_set )
Str_Pcd_Values = self . GenerateByteArrayValue ( S_pcd_set )
if Str_Pcd_Values :
for ( skuname , StoreName , PcdGuid , PcdName , PcdValue ) in Str_Pcd_Values :
str_pcd_obj = S_pcd_set . get ( ( PcdName , PcdGuid ) )
if str_pcd_obj is None :
print ( PcdName , PcdGuid )
raise
if str_pcd_obj . Type in [ self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_HII ] ,
self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_EX_HII ] ] :
if skuname not in str_pcd_obj . SkuInfoList :
str_pcd_obj . SkuInfoList [ skuname ] = SkuInfoClass ( SkuIdName = skuname , SkuId = self . SkuIds [ skuname ] [ 0 ] , HiiDefaultValue = PcdValue , DefaultStore = { StoreName : PcdValue } )
else :
str_pcd_obj . SkuInfoList [ skuname ] . HiiDefaultValue = PcdValue
str_pcd_obj . SkuInfoList [ skuname ] . DefaultStoreDict . update ( { StoreName : PcdValue } )
elif str_pcd_obj . Type in [ self . _PCD_TYPE_STRING_ [ MODEL_PCD_FIXED_AT_BUILD ] ,
self . _PCD_TYPE_STRING_ [ MODEL_PCD_PATCHABLE_IN_MODULE ] ] :
if skuname in ( self . SkuIdMgr . SystemSkuId , TAB_DEFAULT , TAB_COMMON ) :
str_pcd_obj . DefaultValue = PcdValue
else :
if skuname not in str_pcd_obj . SkuInfoList :
nextskuid = self . SkuIdMgr . GetNextSkuId ( skuname )
NoDefault = False
while nextskuid not in str_pcd_obj . SkuInfoList :
if nextskuid == TAB_DEFAULT :
NoDefault = True
break
nextskuid = self . SkuIdMgr . GetNextSkuId ( nextskuid )
str_pcd_obj . SkuInfoList [ skuname ] = copy . deepcopy ( str_pcd_obj . SkuInfoList [ nextskuid ] ) if not NoDefault else SkuInfoClass ( SkuIdName = skuname , SkuId = self . SkuIds [ skuname ] [ 0 ] , DefaultValue = PcdValue )
str_pcd_obj . SkuInfoList [ skuname ] . SkuId = self . SkuIds [ skuname ] [ 0 ]
str_pcd_obj . SkuInfoList [ skuname ] . SkuIdName = skuname
else :
str_pcd_obj . SkuInfoList [ skuname ] . DefaultValue = PcdValue
for str_pcd_obj in S_pcd_set . values ( ) :
if str_pcd_obj . Type not in [ self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_HII ] ,
self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_EX_HII ] ] :
continue
PcdDefaultStoreSet = set ( defaultstorename for skuobj in str_pcd_obj . SkuInfoList . values ( ) for defaultstorename in skuobj . DefaultStoreDict )
DefaultStoreObj = DefaultStore ( self . _GetDefaultStores ( ) )
mindefaultstorename = DefaultStoreObj . GetMin ( PcdDefaultStoreSet )
str_pcd_obj . SkuInfoList [ self . SkuIdMgr . SystemSkuId ] . HiiDefaultValue = str_pcd_obj . SkuInfoList [ self . SkuIdMgr . SystemSkuId ] . DefaultStoreDict [ mindefaultstorename ]
for str_pcd_obj in S_pcd_set . values ( ) :
str_pcd_obj . MaxDatumSize = DscBuildData . GetStructurePcdMaxSize ( str_pcd_obj )
Pcds [ str_pcd_obj . TokenCName , str_pcd_obj . TokenSpaceGuidCName ] = str_pcd_obj
Pcds [ str_pcd_obj . TokenCName , str_pcd_obj . TokenSpaceGuidCName ] . CustomAttribute [ ' IsStru ' ] = True
for pcdkey in Pcds :
pcd = Pcds [ pcdkey ]
if TAB_DEFAULT not in pcd . SkuInfoList and TAB_COMMON in pcd . SkuInfoList :
pcd . SkuInfoList [ TAB_DEFAULT ] = pcd . SkuInfoList [ TAB_COMMON ]
del pcd . SkuInfoList [ TAB_COMMON ]
elif TAB_DEFAULT in pcd . SkuInfoList and TAB_COMMON in pcd . SkuInfoList :
del pcd . SkuInfoList [ TAB_COMMON ]
list ( map ( self . FilterSkuSettings , [ Pcds [ pcdkey ] for pcdkey in Pcds if Pcds [ pcdkey ] . Type in DynamicPcdType ] ) )
return Pcds
@cached_property
def PlatformUsedPcds ( self ) :
FdfInfList = [ ]
if GlobalData . gFdfParser :
FdfInfList = GlobalData . gFdfParser . Profile . InfList
FdfModuleList = [ PathClass ( NormPath ( Inf ) , GlobalData . gWorkspace , Arch = self . _Arch ) for Inf in FdfInfList ]
AllModulePcds = set ( )
ModuleSet = set ( list ( self . _Modules . keys ( ) ) + FdfModuleList )
for ModuleFile in ModuleSet :
ModuleData = self . _Bdb [ ModuleFile , self . _Arch , self . _Target , self . _Toolchain ]
AllModulePcds = AllModulePcds | ModuleData . PcdsName
for ModuleFile in self . LibraryInstances :
ModuleData = self . _Bdb . CreateBuildObject ( ModuleFile , self . _Arch , self . _Target , self . _Toolchain )
AllModulePcds = AllModulePcds | ModuleData . PcdsName
return AllModulePcds
#Filter the StrucutrePcd that is not used by any module in dsc file and fdf file.
def FilterStrcturePcd ( self , S_pcd_set ) :
UnusedStruPcds = set ( S_pcd_set . keys ( ) ) - self . PlatformUsedPcds
for ( Token , TokenSpaceGuid ) in UnusedStruPcds :
del S_pcd_set [ ( Token , TokenSpaceGuid ) ]
## Retrieve non-dynamic PCD settings
#
# @param Type PCD type
#
# @retval a dict object contains settings of given PCD type
#
def _GetPcd ( self , Type ) :
Pcds = OrderedDict ( )
#
# tdict is a special dict kind of type, used for selecting correct
# PCD settings for certain ARCH
#
AvailableSkuIdSet = copy . copy ( self . SkuIds )
PcdDict = tdict ( True , 4 )
PcdList = [ ]
# Find out all possible PCD candidates for self._Arch
RecordList = self . _RawData [ Type , self . _Arch ]
PcdValueDict = OrderedDict ( )
for TokenSpaceGuid , PcdCName , Setting , Arch , SkuName , Dummy3 , Dummy4 , Dummy5 in RecordList :
SkuName = SkuName . upper ( )
SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
if SkuName not in AvailableSkuIdSet :
EdkLogger . error ( ' build ' , PARAMETER_INVALID , ' Sku %s is not defined in [SkuIds] section ' % SkuName ,
File = self . MetaFile , Line = Dummy5 )
if SkuName in ( self . SkuIdMgr . SystemSkuId , TAB_DEFAULT , TAB_COMMON ) :
if " . " not in TokenSpaceGuid and " [ " not in PcdCName and ( PcdCName , TokenSpaceGuid , SkuName , Dummy5 ) not in PcdList :
PcdList . append ( ( PcdCName , TokenSpaceGuid , SkuName , Dummy5 ) )
PcdDict [ Arch , PcdCName , TokenSpaceGuid , SkuName ] = Setting
for PcdCName , TokenSpaceGuid , SkuName , Dummy4 in PcdList :
Setting = PcdDict [ self . _Arch , PcdCName , TokenSpaceGuid , SkuName ]
if Setting is None :
continue
PcdValue , DatumType , MaxDatumSize = self . _ValidatePcd ( PcdCName , TokenSpaceGuid , Setting , Type , Dummy4 )
if MaxDatumSize :
if int ( MaxDatumSize , 0 ) > 0xFFFF :
EdkLogger . error ( ' build ' , FORMAT_INVALID , " The size value must not exceed the maximum value of 0xFFFF (UINT16) for %s . " % " . " . join ( ( TokenSpaceGuid , PcdCName ) ) ,
File = self . MetaFile , Line = Dummy4 )
if int ( MaxDatumSize , 0 ) < 0 :
EdkLogger . error ( ' build ' , FORMAT_INVALID , " The size value can ' t be set to negative value for %s . " % " . " . join ( ( TokenSpaceGuid , PcdCName ) ) ,
File = self . MetaFile , Line = Dummy4 )
if ( PcdCName , TokenSpaceGuid ) in PcdValueDict :
PcdValueDict [ PcdCName , TokenSpaceGuid ] [ SkuName ] = ( PcdValue , DatumType , MaxDatumSize , Dummy4 )
else :
PcdValueDict [ PcdCName , TokenSpaceGuid ] = { SkuName : ( PcdValue , DatumType , MaxDatumSize , Dummy4 ) }
for ( ( PcdCName , TokenSpaceGuid ) , PcdSetting ) in PcdValueDict . items ( ) :
if self . SkuIdMgr . SystemSkuId in PcdSetting :
PcdValue , DatumType , MaxDatumSize , _ = PcdSetting [ self . SkuIdMgr . SystemSkuId ]
elif TAB_DEFAULT in PcdSetting :
PcdValue , DatumType , MaxDatumSize , _ = PcdSetting [ TAB_DEFAULT ]
elif TAB_COMMON in PcdSetting :
PcdValue , DatumType , MaxDatumSize , _ = PcdSetting [ TAB_COMMON ]
else :
PcdValue = None
DatumType = None
MaxDatumSize = None
Pcds [ PcdCName , TokenSpaceGuid ] = PcdClassObject (
PcdCName ,
TokenSpaceGuid ,
self . _PCD_TYPE_STRING_ [ Type ] ,
DatumType ,
PcdValue ,
' ' ,
MaxDatumSize ,
{ } ,
False ,
None ,
IsDsc = True )
for SkuName in PcdValueDict [ PcdCName , TokenSpaceGuid ] :
Settings = PcdValueDict [ PcdCName , TokenSpaceGuid ] [ SkuName ]
if SkuName not in Pcds [ PcdCName , TokenSpaceGuid ] . DscRawValue :
Pcds [ PcdCName , TokenSpaceGuid ] . DscRawValue [ SkuName ] = { }
Pcds [ PcdCName , TokenSpaceGuid ] . DscRawValueInfo [ SkuName ] = { }
Pcds [ PcdCName , TokenSpaceGuid ] . DscRawValue [ SkuName ] [ TAB_DEFAULT_STORES_DEFAULT ] = Settings [ 0 ]
Pcds [ PcdCName , TokenSpaceGuid ] . DscRawValueInfo [ SkuName ] [ TAB_DEFAULT_STORES_DEFAULT ] = ( self . MetaFile . File , Settings [ 3 ] )
return Pcds
@staticmethod
def GetStructurePcdMaxSize ( str_pcd ) :
pcd_default_value = str_pcd . DefaultValue
sku_values = [ skuobj . HiiDefaultValue if str_pcd . Type in [ DscBuildData . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_HII ] , DscBuildData . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_EX_HII ] ] else skuobj . DefaultValue for skuobj in str_pcd . SkuInfoList . values ( ) ]
sku_values . append ( pcd_default_value )
def get_length ( value ) :
Value = value . strip ( )
if len ( value ) > 1 :
if Value . startswith ( TAB_GUID ) and Value . endswith ( ' ) ' ) :
return 16
if Value . startswith ( ' L " ' ) and Value . endswith ( ' " ' ) :
return len ( Value [ 2 : - 1 ] )
if Value [ 0 ] == ' " ' and Value [ - 1 ] == ' " ' :
return len ( Value ) - 2
if Value . strip ( ) . startswith ( " { CODE( " ) :
tmpValue = RemoveCComments ( Value )
return len ( tmpValue . split ( " , " ) )
if ( Value [ 0 ] == ' { ' and Value [ - 1 ] == ' } ' ) :
return len ( Value . split ( " , " ) )
if Value . startswith ( " L ' " ) and Value . endswith ( " ' " ) and len ( list ( Value [ 2 : - 1 ] ) ) > 1 :
return len ( list ( Value [ 2 : - 1 ] ) )
if Value [ 0 ] == " ' " and Value [ - 1 ] == " ' " and len ( list ( Value [ 1 : - 1 ] ) ) > 1 :
return len ( Value ) - 2
return len ( Value )
return str ( max ( get_length ( item ) for item in sku_values ) )
@staticmethod
def ExecuteCommand ( Command ) :
try :
Process = subprocess . Popen ( Command , stdout = subprocess . PIPE , stderr = subprocess . PIPE , shell = True )
except :
EdkLogger . error ( ' Build ' , COMMAND_FAILURE , ' Can not execute command: %s ' % Command )
Result = Process . communicate ( )
return Process . returncode , Result [ 0 ] . decode ( ) , Result [ 1 ] . decode ( )
@staticmethod
def IntToCString ( Value , ValueSize ) :
Result = ' " '
if not isinstance ( Value , str ) :
for Index in range ( 0 , ValueSize ) :
Result = Result + ' \\ x %02x ' % ( Value & 0xff )
Value = Value >> 8
Result = Result + ' " '
return Result
def GenerateSizeFunction ( self , Pcd ) :
CApp = " // Default Value in Dec \n "
CApp = CApp + " void Cal_ %s _ %s _Size(UINT32 *Size) { \n " % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName )
if Pcd . IsArray ( ) and Pcd . Capacity [ - 1 ] != " -1 " :
CApp + = " *Size = (sizeof ( %s ) > *Size ? sizeof ( %s ) : *Size); \n " % ( Pcd . DatumType , Pcd . DatumType )
else :
if " { CODE( " in Pcd . DefaultValueFromDec :
CApp + = " *Size = (sizeof ( %s _ %s _INIT_Value) > *Size ? sizeof ( %s _ %s _INIT_Value) : *Size); \n " % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , Pcd . TokenSpaceGuidCName , Pcd . TokenCName )
if Pcd . Type in PCD_DYNAMIC_TYPE_SET | PCD_DYNAMIC_EX_TYPE_SET :
for skuname in Pcd . SkuInfoList :
skuobj = Pcd . SkuInfoList [ skuname ]
if skuobj . VariableName :
for defaultstore in skuobj . DefaultStoreDict :
pcddef = self . GetPcdDscRawDefaultValue ( Pcd , skuname , defaultstore )
if pcddef :
if " { CODE( " in pcddef :
CApp + = " *Size = (sizeof ( %s _ %s _ %s _ %s _Value) > *Size ? sizeof ( %s _ %s _ %s _ %s _Value) : *Size); \n " % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , skuname , defaultstore , Pcd . TokenSpaceGuidCName , Pcd . TokenCName , skuname , defaultstore )
else :
CApp + = " *Size = %s > *Size ? %s : *Size; \n " % ( self . GetStructurePcdMaxSize ( Pcd ) , self . GetStructurePcdMaxSize ( Pcd ) )
else :
pcddef = self . GetPcdDscRawDefaultValue ( Pcd , skuname , TAB_DEFAULT_STORES_DEFAULT )
if pcddef :
if " { CODE( " in pcddef :
CApp + = " *Size = (sizeof ( %s _ %s _ %s _ %s _Value) > *Size ? sizeof ( %s _ %s _ %s _ %s _Value) : *Size); \n " % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , skuname , TAB_DEFAULT_STORES_DEFAULT , Pcd . TokenSpaceGuidCName , Pcd . TokenCName , skuname , TAB_DEFAULT_STORES_DEFAULT )
else :
CApp + = " *Size = %s > *Size ? %s : *Size; \n " % ( self . GetStructurePcdMaxSize ( Pcd ) , self . GetStructurePcdMaxSize ( Pcd ) )
else :
pcddef = self . GetPcdDscRawDefaultValue ( Pcd , TAB_DEFAULT , TAB_DEFAULT_STORES_DEFAULT )
if pcddef :
if " { CODE( " in pcddef :
CApp + = " *Size = (sizeof ( %s _ %s _ %s _ %s _Value) > *Size ? sizeof ( %s _ %s _ %s _ %s _Value) : *Size); \n " % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , TAB_DEFAULT , TAB_DEFAULT_STORES_DEFAULT , Pcd . TokenSpaceGuidCName , Pcd . TokenCName , TAB_DEFAULT , TAB_DEFAULT_STORES_DEFAULT )
else :
CApp + = " *Size = %s > *Size ? %s : *Size; \n " % ( self . GetStructurePcdMaxSize ( Pcd ) , self . GetStructurePcdMaxSize ( Pcd ) )
ActualCap = [ ]
for index in Pcd . DefaultValues :
if index :
ActualCap . append ( index )
FieldList = Pcd . DefaultValues [ index ]
if not FieldList :
continue
for FieldName in FieldList :
FieldName = " . " + FieldName
IsArray = _IsFieldValueAnArray ( FieldList [ FieldName . strip ( " . " ) ] [ 0 ] )
if IsArray and not ( FieldList [ FieldName . strip ( " . " ) ] [ 0 ] . startswith ( ' { GUID ' ) and FieldList [ FieldName . strip ( " . " ) ] [ 0 ] . endswith ( ' } ' ) ) :
try :
Value = ValueExpressionEx ( FieldList [ FieldName . strip ( " . " ) ] [ 0 ] , TAB_VOID , self . _GuidDict ) ( True )
except BadExpression :
EdkLogger . error ( ' Build ' , FORMAT_INVALID , " Invalid value format for %s . From %s Line %d " %
( " . " . join ( ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , FieldName . strip ( ' . ' ) ) ) , FieldList [ FieldName . strip ( " . " ) ] [ 1 ] , FieldList [ FieldName . strip ( " . " ) ] [ 2 ] ) )
Value , ValueSize = ParseFieldValue ( Value )
if not Pcd . IsArray ( ) :
CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s , %s , %d / __ARRAY_ELEMENT_SIZE( %s , %s ) + (( %d %% __ARRAY_ELEMENT_SIZE( %s , %s )) ? 1 : 0)); // From %s Line %d Value %s \n ' % ( Pcd . DatumType , FieldName . strip ( " . " ) , ValueSize , Pcd . DatumType , FieldName . strip ( " . " ) , ValueSize , Pcd . DatumType , FieldName . strip ( " . " ) , FieldList [ FieldName . strip ( " . " ) ] [ 1 ] , FieldList [ FieldName . strip ( " . " ) ] [ 2 ] , FieldList [ FieldName . strip ( " . " ) ] [ 0 ] ) ;
else :
NewFieldName = ' '
FieldName_ori = FieldName . strip ( ' . ' )
while ' [ ' in FieldName :
NewFieldName = NewFieldName + FieldName . split ( ' [ ' , 1 ) [ 0 ] + ' [0] '
Array_Index = int ( FieldName . split ( ' [ ' , 1 ) [ 1 ] . split ( ' ] ' , 1 ) [ 0 ] )
FieldName = FieldName . split ( ' ] ' , 1 ) [ 1 ]
FieldName = NewFieldName + FieldName
while ' [ ' in FieldName and not Pcd . IsArray ( ) :
FieldName = FieldName . rsplit ( ' [ ' , 1 ) [ 0 ]
CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s , %s , %d ); // From %s Line %d Value %s \n ' % ( Pcd . DatumType , FieldName . strip ( " . " ) , Array_Index + 1 , FieldList [ FieldName_ori ] [ 1 ] , FieldList [ FieldName_ori ] [ 2 ] , FieldList [ FieldName_ori ] [ 0 ] )
for skuname in Pcd . SkuOverrideValues :
if skuname == TAB_COMMON :
continue
for defaultstorenameitem in Pcd . SkuOverrideValues [ skuname ] :
CApp = CApp + " // SkuName: %s , DefaultStoreName: %s \n " % ( skuname , defaultstorenameitem )
for index in Pcd . SkuOverrideValues [ skuname ] [ defaultstorenameitem ] :
if index :
ActualCap . append ( index )
for FieldList in [ Pcd . SkuOverrideValues [ skuname ] [ defaultstorenameitem ] [ index ] ] :
if not FieldList :
continue
for FieldName in FieldList :
FieldName = " . " + FieldName
IsArray = _IsFieldValueAnArray ( FieldList [ FieldName . strip ( " . " ) ] [ 0 ] )
if IsArray and not ( FieldList [ FieldName . strip ( " . " ) ] [ 0 ] . startswith ( ' { GUID ' ) and FieldList [ FieldName . strip ( " . " ) ] [ 0 ] . endswith ( ' } ' ) ) :
try :
Value = ValueExpressionEx ( FieldList [ FieldName . strip ( " . " ) ] [ 0 ] , TAB_VOID , self . _GuidDict ) ( True )
except BadExpression :
EdkLogger . error ( ' Build ' , FORMAT_INVALID , " Invalid value format for %s . From %s Line %d " %
( " . " . join ( ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , FieldName . strip ( ' . ' ) ) ) , FieldList [ FieldName . strip ( " . " ) ] [ 1 ] , FieldList [ FieldName . strip ( " . " ) ] [ 2 ] ) )
Value , ValueSize = ParseFieldValue ( Value )
if not Pcd . IsArray ( ) :
CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s , %s , %d / __ARRAY_ELEMENT_SIZE( %s , %s ) + (( %d %% __ARRAY_ELEMENT_SIZE( %s , %s )) ? 1 : 0)); // From %s Line %d Value %s \n ' % ( Pcd . DatumType , FieldName . strip ( " . " ) , ValueSize , Pcd . DatumType , FieldName . strip ( " . " ) , ValueSize , Pcd . DatumType , FieldName . strip ( " . " ) , FieldList [ FieldName . strip ( " . " ) ] [ 1 ] , FieldList [ FieldName . strip ( " . " ) ] [ 2 ] , FieldList [ FieldName . strip ( " . " ) ] [ 0 ] ) ;
else :
NewFieldName = ' '
FieldName_ori = FieldName . strip ( ' . ' )
while ' [ ' in FieldName :
NewFieldName = NewFieldName + FieldName . split ( ' [ ' , 1 ) [ 0 ] + ' [0] '
Array_Index = int ( FieldName . split ( ' [ ' , 1 ) [ 1 ] . split ( ' ] ' , 1 ) [ 0 ] )
FieldName = FieldName . split ( ' ] ' , 1 ) [ 1 ]
FieldName = NewFieldName + FieldName
while ' [ ' in FieldName and not Pcd . IsArray ( ) :
FieldName = FieldName . rsplit ( ' [ ' , 1 ) [ 0 ]
CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s , %s , %d ); // From %s Line %d Value %s \n ' % ( Pcd . DatumType , FieldName . strip ( " . " ) , Array_Index + 1 , FieldList [ FieldName_ori ] [ 1 ] , FieldList [ FieldName_ori ] [ 2 ] , FieldList [ FieldName_ori ] [ 0 ] )
if Pcd . PcdFieldValueFromFdf :
CApp = CApp + " // From fdf \n "
for FieldName in Pcd . PcdFieldValueFromFdf :
FieldName = " . " + FieldName
IsArray = _IsFieldValueAnArray ( Pcd . PcdFieldValueFromFdf [ FieldName . strip ( " . " ) ] [ 0 ] )
if IsArray and not ( Pcd . PcdFieldValueFromFdf [ FieldName . strip ( " . " ) ] [ 0 ] . startswith ( ' { GUID ' ) and Pcd . PcdFieldValueFromFdf [ FieldName . strip ( " . " ) ] [ 0 ] . endswith ( ' } ' ) ) :
try :
Value = ValueExpressionEx ( Pcd . PcdFieldValueFromFdf [ FieldName . strip ( " . " ) ] [ 0 ] , TAB_VOID , self . _GuidDict ) ( True )
except BadExpression :
EdkLogger . error ( ' Build ' , FORMAT_INVALID , " Invalid value format for %s . From %s Line %d " %
( " . " . join ( ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , FieldName . strip ( ' . ' ) ) ) , Pcd . PcdFieldValueFromFdf [ FieldName . strip ( " . " ) ] [ 1 ] , Pcd . PcdFieldValueFromFdf [ FieldName . strip ( " . " ) ] [ 2 ] ) )
Value , ValueSize = ParseFieldValue ( Value )
if not Pcd . IsArray ( ) :
CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s , %s , %d / __ARRAY_ELEMENT_SIZE( %s , %s ) + (( %d %% __ARRAY_ELEMENT_SIZE( %s , %s )) ? 1 : 0)); // From %s Line %d Value %s \n ' % ( Pcd . DatumType , FieldName . strip ( " . " ) , ValueSize , Pcd . DatumType , FieldName . strip ( " . " ) , ValueSize , Pcd . DatumType , FieldName . strip ( " . " ) , Pcd . PcdFieldValueFromFdf [ FieldName . strip ( " . " ) ] [ 1 ] , Pcd . PcdFieldValueFromFdf [ FieldName . strip ( " . " ) ] [ 2 ] , Pcd . PcdFieldValueFromFdf [ FieldName . strip ( " . " ) ] [ 0 ] ) ;
else :
NewFieldName = ' '
FieldName_ori = FieldName . strip ( ' . ' )
while ' [ ' in FieldName :
NewFieldName = NewFieldName + FieldName . split ( ' [ ' , 1 ) [ 0 ] + ' [0] '
Array_Index = int ( FieldName . split ( ' [ ' , 1 ) [ 1 ] . split ( ' ] ' , 1 ) [ 0 ] )
FieldName = FieldName . split ( ' ] ' , 1 ) [ 1 ]
FieldName = NewFieldName + FieldName
while ' [ ' in FieldName :
FieldName = FieldName . rsplit ( ' [ ' , 1 ) [ 0 ]
CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s , %s , %d ); // From %s Line %s Value %s \n ' % ( Pcd . DatumType , FieldName . strip ( " . " ) , Array_Index + 1 , Pcd . PcdFieldValueFromFdf [ FieldName_ori ] [ 1 ] , Pcd . PcdFieldValueFromFdf [ FieldName_ori ] [ 2 ] , Pcd . PcdFieldValueFromFdf [ FieldName_ori ] [ 0 ] )
if Pcd . PcdFieldValueFromComm :
CApp = CApp + " // From Command Line \n "
for FieldName in Pcd . PcdFieldValueFromComm :
FieldName = " . " + FieldName
IsArray = _IsFieldValueAnArray ( Pcd . PcdFieldValueFromComm [ FieldName . strip ( " . " ) ] [ 0 ] )
if IsArray and not ( Pcd . PcdFieldValueFromComm [ FieldName . strip ( " . " ) ] [ 0 ] . startswith ( ' { GUID ' ) and Pcd . PcdFieldValueFromComm [ FieldName . strip ( " . " ) ] [ 0 ] . endswith ( ' } ' ) ) :
try :
Value = ValueExpressionEx ( Pcd . PcdFieldValueFromComm [ FieldName . strip ( " . " ) ] [ 0 ] , TAB_VOID , self . _GuidDict ) ( True )
except BadExpression :
EdkLogger . error ( ' Build ' , FORMAT_INVALID , " Invalid value format for %s . From %s Line %d " %
( " . " . join ( ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , FieldName . strip ( ' . ' ) ) ) , Pcd . PcdFieldValueFromComm [ FieldName . strip ( " . " ) ] [ 1 ] , Pcd . PcdFieldValueFromComm [ FieldName . strip ( " . " ) ] [ 2 ] ) )
Value , ValueSize = ParseFieldValue ( Value )
if not Pcd . IsArray ( ) :
CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s , %s , %d / __ARRAY_ELEMENT_SIZE( %s , %s ) + (( %d %% __ARRAY_ELEMENT_SIZE( %s , %s )) ? 1 : 0)); // From %s Line %d Value %s \n ' % ( Pcd . DatumType , FieldName . strip ( " . " ) , ValueSize , Pcd . DatumType , FieldName . strip ( " . " ) , ValueSize , Pcd . DatumType , FieldName . strip ( " . " ) , Pcd . PcdFieldValueFromComm [ FieldName . strip ( " . " ) ] [ 1 ] , Pcd . PcdFieldValueFromComm [ FieldName . strip ( " . " ) ] [ 2 ] , Pcd . PcdFieldValueFromComm [ FieldName . strip ( " . " ) ] [ 0 ] ) ;
else :
NewFieldName = ' '
FieldName_ori = FieldName . strip ( ' . ' )
while ' [ ' in FieldName :
NewFieldName = NewFieldName + FieldName . split ( ' [ ' , 1 ) [ 0 ] + ' [0] '
Array_Index = int ( FieldName . split ( ' [ ' , 1 ) [ 1 ] . split ( ' ] ' , 1 ) [ 0 ] )
FieldName = FieldName . split ( ' ] ' , 1 ) [ 1 ]
FieldName = NewFieldName + FieldName
while ' [ ' in FieldName and not Pcd . IsArray ( ) :
FieldName = FieldName . rsplit ( ' [ ' , 1 ) [ 0 ]
CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s , %s , %d ); // From %s Line %d Value %s \n ' % ( Pcd . DatumType , FieldName . strip ( " . " ) , Array_Index + 1 , Pcd . PcdFieldValueFromComm [ FieldName_ori ] [ 1 ] , Pcd . PcdFieldValueFromComm [ FieldName_ori ] [ 2 ] , Pcd . PcdFieldValueFromComm [ FieldName_ori ] [ 0 ] )
if Pcd . GetPcdMaxSize ( ) :
CApp = CApp + " *Size = ( %d > *Size ? %d : *Size); // The Pcd maxsize is %d \n " % ( Pcd . GetPcdMaxSize ( ) , Pcd . GetPcdMaxSize ( ) , Pcd . GetPcdMaxSize ( ) )
ArraySizeByAssign = self . CalculateActualCap ( ActualCap )
if ArraySizeByAssign > 1 :
CApp = CApp + " *Size = ( %d > *Size ? %d : *Size); \n " % ( ArraySizeByAssign , ArraySizeByAssign )
CApp = CApp + " } \n "
return CApp
def CalculateActualCap ( self , ActualCap ) :
if not ActualCap :
return 1
maxsize = 1
for item in ActualCap :
index_elements = ArrayIndex . findall ( item )
rt = 1
for index_e in index_elements :
index_num = index_e . lstrip ( " [ " ) . rstrip ( " ] " ) . strip ( )
if not index_num :
# Not support flexiable pcd array assignment
return 1
index_num = int ( index_num , 16 ) if index_num . startswith ( ( " 0x " , " 0X " ) ) else int ( index_num )
rt = rt * ( index_num + 1 )
if rt > maxsize :
maxsize = rt
return maxsize
@staticmethod
def GenerateSizeStatments ( Pcd , skuname , defaultstorename ) :
if Pcd . IsArray ( ) :
r_datatype = [ Pcd . BaseDatumType ]
lastoneisEmpty = False
for dem in Pcd . Capacity :
if lastoneisEmpty :
EdkLogger . error ( ' Build ' , FORMAT_INVALID , " Invalid value format for %s . " %
( " . " . join ( ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName ) ) ) )
if dem == ' 0 ' or dem == " -1 " :
r_datatype . append ( " [1] " )
lastoneisEmpty = True
else :
r_datatype . append ( " [ " + dem + " ] " )
if Pcd . Type in [ MODEL_PCD_DYNAMIC_EX_HII , MODEL_PCD_DYNAMIC_HII ] :
PcdDefValue = Pcd . SkuInfoList . get ( skuname ) . DefaultStoreDict . get ( defaultstorename )
elif Pcd . Type in [ MODEL_PCD_DYNAMIC_EX_DEFAULT , MODEL_PCD_DYNAMIC_VPD , MODEL_PCD_DYNAMIC_DEFAULT , MODEL_PCD_DYNAMIC_EX_VPD ] :
PcdDefValue = Pcd . SkuInfoList . get ( skuname ) . DefaultValue
else :
PcdDefValue = Pcd . DefaultValue
if lastoneisEmpty :
if " { CODE( " not in PcdDefValue :
sizebasevalue_plus = " ( %s / sizeof( %s ) + 1) " % ( ( DscBuildData . GetStructurePcdMaxSize ( Pcd ) , Pcd . BaseDatumType ) )
sizebasevalue = " ( %s / sizeof( %s )) " % ( ( DscBuildData . GetStructurePcdMaxSize ( Pcd ) , Pcd . BaseDatumType ) )
sizeof = " sizeof( %s ) " % Pcd . BaseDatumType
CApp = ' int ArraySize = %s %% %s ? %s : %s ; \n ' % ( ( DscBuildData . GetStructurePcdMaxSize ( Pcd ) , sizeof , sizebasevalue_plus , sizebasevalue ) )
CApp + = ' Size = ArraySize * sizeof( %s ); \n ' % Pcd . BaseDatumType
else :
CApp = " Size = 0; \n "
else :
CApp = ' Size = sizeof( %s ); \n ' % ( " " . join ( r_datatype ) )
else :
CApp = ' Size = sizeof( %s ); \n ' % ( Pcd . DatumType )
CApp = CApp + ' Cal_ %s _ %s _Size(&Size); \n ' % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName )
return CApp
def GetIndicator ( self , index , FieldName , Pcd ) :
def cleanupindex ( indexstr ) :
return indexstr . strip ( " [ " ) . strip ( " ] " ) . strip ( )
index_elements = ArrayIndex . findall ( index )
pcd_capacity = Pcd . Capacity
if index :
indicator = " (Pcd "
if len ( pcd_capacity ) > 2 :
for i in range ( 0 , len ( index_elements ) ) :
index_ele = index_elements [ i ]
index_num = index_ele . strip ( " [ " ) . strip ( " ] " ) . strip ( )
if i == len ( index_elements ) - 2 :
indicator + = " + %d *Size/sizeof( %s )/ %d + %s ) " % ( int ( cleanupindex ( index_elements [ i + 1 ] ) ) , Pcd . BaseDatumType , reduce ( lambda x , y : int ( x ) * int ( y ) , pcd_capacity [ : - 1 ] ) , cleanupindex ( index_elements [ i ] ) )
break
else :
indicator + = " + %d * %s *Size/sizeof( %s )/ %d " % ( int ( cleanupindex ( index_elements [ i ] ) ) , reduce ( lambda x , y : int ( x ) * int ( y ) , pcd_capacity [ i + 1 : - 1 ] ) , Pcd . BaseDatumType , reduce ( lambda x , y : int ( x ) * int ( y ) , pcd_capacity [ : - 1 ] ) )
elif len ( pcd_capacity ) == 2 :
indicator + = " + %d *Size/sizeof( %s )/ %d + %s ) " % ( int ( cleanupindex ( index_elements [ 0 ] ) ) , Pcd . BaseDatumType , int ( pcd_capacity [ 0 ] ) , index_elements [ 1 ] . strip ( " [ " ) . strip ( " ] " ) . strip ( ) )
elif len ( pcd_capacity ) == 1 :
index_ele = index_elements [ 0 ]
index_num = index_ele . strip ( " [ " ) . strip ( " ] " ) . strip ( )
indicator + = " + %s ) " % ( index_num )
else :
indicator = " Pcd "
if FieldName :
indicator + = " -> " + FieldName
return indicator
def GetStarNum ( self , Pcd ) :
if not Pcd . IsArray ( ) :
return 1
elif Pcd . IsSimpleTypeArray ( ) :
return len ( Pcd . Capacity )
else :
return len ( Pcd . Capacity ) + 1
def GenerateDefaultValueAssignFunction ( self , Pcd ) :
CApp = " // Default value in Dec \n "
CApp = CApp + " void Assign_ %s _ %s _Default_Value( %s *Pcd) { \n " % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , Pcd . BaseDatumType )
CApp = CApp + ' UINT32 FieldSize; \n '
CApp = CApp + ' CHAR8 *Value; \n '
CApp = CApp + ' UINT32 PcdArraySize; \n '
DefaultValueFromDec = Pcd . DefaultValueFromDec
IsArray = _IsFieldValueAnArray ( Pcd . DefaultValueFromDec )
if IsArray :
try :
DefaultValueFromDec = ValueExpressionEx ( Pcd . DefaultValueFromDec , TAB_VOID ) ( True )
except BadExpression :
EdkLogger . error ( " Build " , FORMAT_INVALID , " Invalid value format for %s . %s , from DEC: %s " %
( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , DefaultValueFromDec ) )
DefaultValueFromDec = StringToArray ( DefaultValueFromDec )
Value , ValueSize = ParseFieldValue ( DefaultValueFromDec )
if IsArray :
#
# Use memcpy() to copy value into field
#
if Pcd . IsArray ( ) :
pcdarraysize = Pcd . PcdArraySize ( )
if " { CODE( " in Pcd . DefaultValueFromDec :
if Pcd . Capacity [ - 1 ] != " -1 " :
CApp = CApp + ' __STATIC_ASSERT(sizeof( %s _ %s _INIT_Value) < %d * sizeof( %s ), " Pcd %s . %s Value in Dec exceed the array capability %s " ); // From %s Line %s \n ' % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , pcdarraysize , Pcd . BaseDatumType , Pcd . TokenSpaceGuidCName , Pcd . TokenCName , Pcd . DatumType , Pcd . DefaultValueFromDecInfo [ 0 ] , Pcd . DefaultValueFromDecInfo [ 1 ] )
CApp = CApp + ' PcdArraySize = sizeof( %s _ %s _INIT_Value); \n ' % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName )
CApp = CApp + ' memcpy (Pcd, %s _ %s _INIT_Value,PcdArraySize); \n ' % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName )
else :
if Pcd . Capacity [ - 1 ] != " -1 " :
CApp = CApp + ' __STATIC_ASSERT( %d < %d * sizeof( %s ), " Pcd %s . %s Value in Dec exceed the array capability %s " ); // From %s Line %s \n ' % ( ValueSize , pcdarraysize , Pcd . BaseDatumType , Pcd . TokenSpaceGuidCName , Pcd . TokenCName , Pcd . DatumType , Pcd . DefaultValueFromDecInfo [ 0 ] , Pcd . DefaultValueFromDecInfo [ 1 ] )
CApp = CApp + ' PcdArraySize = %d ; \n ' % ValueSize
CApp = CApp + ' Value = %s ; // From DEC Default Value %s \n ' % ( DscBuildData . IntToCString ( Value , ValueSize ) , Pcd . DefaultValueFromDec )
CApp = CApp + ' memcpy (Pcd, Value, PcdArraySize); \n '
else :
if " { CODE( " in Pcd . DefaultValueFromDec :
CApp = CApp + ' PcdArraySize = sizeof( %s _ %s _INIT_Value); \n ' % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName )
CApp = CApp + ' memcpy (Pcd, & %s _ %s _INIT_Value,PcdArraySize); \n ' % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName )
else :
CApp = CApp + ' Value = %s ; // From DEC Default Value %s \n ' % ( DscBuildData . IntToCString ( Value , ValueSize ) , Pcd . DefaultValueFromDec )
CApp = CApp + ' memcpy (Pcd, Value, %d ); \n ' % ( ValueSize )
elif isinstance ( Value , str ) :
CApp = CApp + ' Pcd = %s ; // From DEC Default Value %s \n ' % ( Value , Pcd . DefaultValueFromDec )
for index in Pcd . DefaultValues :
FieldList = Pcd . DefaultValues [ index ]
if not FieldList :
continue
for FieldName in FieldList :
IsArray = _IsFieldValueAnArray ( FieldList [ FieldName ] [ 0 ] )
if IsArray :
try :
FieldList [ FieldName ] [ 0 ] = ValueExpressionEx ( FieldList [ FieldName ] [ 0 ] , TAB_VOID , self . _GuidDict ) ( True )
except BadExpression :
EdkLogger . error ( ' Build ' , FORMAT_INVALID , " Invalid value format for %s . From %s Line %d " %
( " . " . join ( ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , FieldName ) ) , FieldList [ FieldName ] [ 1 ] , FieldList [ FieldName ] [ 2 ] ) )
try :
Value , ValueSize = ParseFieldValue ( FieldList [ FieldName ] [ 0 ] )
except Exception :
EdkLogger . error ( ' Build ' , FORMAT_INVALID , " Invalid value format for %s . From %s Line %d " % ( " . " . join ( ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , FieldName ) ) , FieldList [ FieldName ] [ 1 ] , FieldList [ FieldName ] [ 2 ] ) )
indicator = self . GetIndicator ( index , FieldName , Pcd )
if IsArray :
#
# Use memcpy() to copy value into field
#
CApp = CApp + ' FieldSize = __FIELD_SIZE( %s , %s ); \n ' % ( Pcd . BaseDatumType , FieldName )
CApp = CApp + ' Value = %s ; // From %s Line %d Value %s \n ' % ( DscBuildData . IntToCString ( Value , ValueSize ) , FieldList [ FieldName ] [ 1 ] , FieldList [ FieldName ] [ 2 ] , FieldList [ FieldName ] [ 0 ] )
CApp = CApp + ' __STATIC_ASSERT((__FIELD_SIZE( %s , %s ) >= %d ) || (__FIELD_SIZE( %s , %s ) == 0), " Input buffer exceeds the buffer array " ); // From %s Line %d Value %s \n ' % ( Pcd . BaseDatumType , FieldName , ValueSize , Pcd . BaseDatumType , FieldName , FieldList [ FieldName ] [ 1 ] , FieldList [ FieldName ] [ 2 ] , FieldList [ FieldName ] [ 0 ] )
CApp = CApp + ' memcpy (& %s , Value, (FieldSize > 0 && FieldSize < %d ) ? FieldSize : %d ); \n ' % ( indicator , ValueSize , ValueSize )
elif isinstance ( Value , str ) :
CApp = CApp + ' %s = %s ; // From %s Line %d Value %s \n ' % ( indicator , Value , FieldList [ FieldName ] [ 1 ] , FieldList [ FieldName ] [ 2 ] , FieldList [ FieldName ] [ 0 ] )
else :
if ' [ ' in FieldName and ' ] ' in FieldName :
Index = int ( FieldName . split ( ' [ ' ) [ 1 ] . split ( ' ] ' ) [ 0 ] )
CApp = CApp + ' __STATIC_ASSERT(( %d < __ARRAY_SIZE(Pcd-> %s )) || (__ARRAY_SIZE(Pcd-> %s ) == 0), " array index exceeds the array number " ); // From %s Line %d Index of %s \n ' % ( Index , FieldName . split ( ' [ ' ) [ 0 ] , FieldName . split ( ' [ ' ) [ 0 ] , FieldList [ FieldName ] [ 1 ] , FieldList [ FieldName ] [ 2 ] , FieldName )
if ValueSize > 4 :
CApp = CApp + ' %s = %d ULL; // From %s Line %d Value %s \n ' % ( indicator , Value , FieldList [ FieldName ] [ 1 ] , FieldList [ FieldName ] [ 2 ] , FieldList [ FieldName ] [ 0 ] )
else :
CApp = CApp + ' %s = %d ; // From %s Line %d Value %s \n ' % ( indicator , Value , FieldList [ FieldName ] [ 1 ] , FieldList [ FieldName ] [ 2 ] , FieldList [ FieldName ] [ 0 ] )
CApp = CApp + " } \n "
return CApp
@staticmethod
def GenerateDefaultValueAssignStatement ( Pcd ) :
CApp = ' Assign_ %s _ %s _Default_Value(Pcd); \n ' % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName )
return CApp
def GetPcdDscRawDefaultValue ( self , Pcd , SkuName , DefaultStoreName ) :
if Pcd . Type in PCD_DYNAMIC_TYPE_SET or Pcd . Type in PCD_DYNAMIC_EX_TYPE_SET :
if ( SkuName , DefaultStoreName ) == ( TAB_DEFAULT , TAB_DEFAULT_STORES_DEFAULT ) :
pcddefaultvalue = Pcd . DefaultFromDSC . get ( TAB_DEFAULT , { } ) . get ( TAB_DEFAULT_STORES_DEFAULT ) if Pcd . DefaultFromDSC else None
else :
pcddefaultvalue = Pcd . DscRawValue . get ( SkuName , { } ) . get ( DefaultStoreName )
else :
pcddefaultvalue = Pcd . DscRawValue . get ( SkuName , { } ) . get ( TAB_DEFAULT_STORES_DEFAULT )
return pcddefaultvalue
def GetPcdDscRawValueInfo ( self , Pcd , SkuName , DefaultStoreName ) :
DscValueInfo = Pcd . DscRawValueInfo . get ( SkuName , { } ) . get ( DefaultStoreName )
if DscValueInfo :
dscfilepath , lineno = DscValueInfo
else :
dscfilepath = self . MetaFile . File
lineno = " "
return dscfilepath , lineno
def GenerateInitValueFunction ( self , Pcd , SkuName , DefaultStoreName ) :
CApp = " // Value in Dsc for Sku: %s , DefaultStore %s \n " % ( SkuName , DefaultStoreName )
CApp = CApp + " void Assign_ %s _ %s _ %s _ %s _Value( %s *Pcd) { \n " % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , SkuName , DefaultStoreName , Pcd . BaseDatumType )
CApp = CApp + ' UINT32 FieldSize; \n '
CApp = CApp + ' CHAR8 *Value; \n '
CApp = CApp + ' UINT32 PcdArraySize; \n '
CApp = CApp + " // SkuName: %s , DefaultStoreName: %s \n " % ( TAB_DEFAULT , TAB_DEFAULT_STORES_DEFAULT )
inherit_OverrideValues = Pcd . SkuOverrideValues [ SkuName ]
dscfilepath , lineno = self . GetPcdDscRawValueInfo ( Pcd , SkuName , DefaultStoreName )
if lineno :
valuefrom = " %s Line %s " % ( dscfilepath , str ( lineno ) )
else :
valuefrom = dscfilepath
pcddefaultvalue = self . GetPcdDscRawDefaultValue ( Pcd , SkuName , DefaultStoreName )
if pcddefaultvalue :
FieldList = pcddefaultvalue
IsArray = _IsFieldValueAnArray ( FieldList )
if IsArray :
if " { CODE( " not in FieldList :
try :
FieldList = ValueExpressionEx ( FieldList , TAB_VOID ) ( True )
except BadExpression :
EdkLogger . error ( " Build " , FORMAT_INVALID , " Invalid value format for %s . %s , from DSC: %s " %
( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , FieldList ) )
Value , ValueSize = ParseFieldValue ( FieldList )
if ( SkuName , DefaultStoreName ) == ( TAB_DEFAULT , TAB_DEFAULT_STORES_DEFAULT ) :
if isinstance ( Value , str ) :
if " { CODE( " in Value :
if Pcd . IsArray ( ) and Pcd . Capacity [ - 1 ] != " -1 " :
pcdarraysize = Pcd . PcdArraySize ( )
CApp = CApp + ' __STATIC_ASSERT(sizeof( %s _ %s _ %s _ %s _Value) < %d * sizeof( %s ), " Pcd %s . %s Value in Dsc exceed the array capability %s " ); // From %s \n ' % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , SkuName , DefaultStoreName , pcdarraysize , Pcd . BaseDatumType , Pcd . TokenSpaceGuidCName , Pcd . TokenCName , Pcd . DatumType , valuefrom )
CApp = CApp + ' PcdArraySize = sizeof( %s _ %s _ %s _ %s _Value); \n ' % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , SkuName , DefaultStoreName )
CApp = CApp + ' memcpy (Pcd, & %s _ %s _ %s _ %s _Value,PcdArraySize); \n ' % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , SkuName , DefaultStoreName )
else :
CApp = CApp + ' Pcd = %s ; // From DSC Default Value %s \n ' % ( Value , Pcd . DefaultFromDSC . get ( TAB_DEFAULT , { } ) . get ( TAB_DEFAULT_STORES_DEFAULT , Pcd . DefaultValue ) if Pcd . DefaultFromDSC else Pcd . DefaultValue )
elif IsArray :
#
# Use memcpy() to copy value into field
#
if Pcd . IsArray ( ) :
pcdarraysize = Pcd . PcdArraySize ( )
if " { CODE( " in pcddefaultvalue :
if Pcd . Capacity [ - 1 ] != " -1 " :
CApp = CApp + ' __STATIC_ASSERT(sizeof( %s _ %s _ %s _ %s _Value) < %d * sizeof( %s ), " Pcd %s . %s Value in Dsc exceed the array capability %s " ); // From %s \n ' % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , SkuName , DefaultStoreName , pcdarraysize , Pcd . BaseDatumType , Pcd . TokenSpaceGuidCName , Pcd . TokenCName , Pcd . DatumType , valuefrom )
CApp = CApp + ' PcdArraySize = sizeof( %s _ %s _ %s _ %s _Value); \n ' % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , SkuName , DefaultStoreName )
CApp = CApp + ' memcpy (Pcd, %s _ %s _ %s _ %s _Value, PcdArraySize); \n ' % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , SkuName , DefaultStoreName )
else :
if Pcd . Capacity [ - 1 ] != " -1 " :
CApp = CApp + ' __STATIC_ASSERT( %d < %d * sizeof( %s ), " Pcd %s . %s Value in Dsc exceed the array capability %s " ); // From %s \n ' % ( ValueSize , pcdarraysize , Pcd . BaseDatumType , Pcd . TokenSpaceGuidCName , Pcd . TokenCName , Pcd . DatumType , valuefrom )
CApp = CApp + ' PcdArraySize = %d ; \n ' % ValueSize
CApp = CApp + ' Value = %s ; // From DSC Default Value %s \n ' % ( DscBuildData . IntToCString ( Value , ValueSize ) , Pcd . DefaultFromDSC . get ( TAB_DEFAULT , { } ) . get ( TAB_DEFAULT_STORES_DEFAULT , Pcd . DefaultValue ) if Pcd . DefaultFromDSC else Pcd . DefaultValue )
CApp = CApp + ' memcpy (Pcd, Value, PcdArraySize); \n '
else :
if " { CODE( " in pcddefaultvalue :
CApp = CApp + ' PcdArraySize = %d < sizeof( %s ) * %d ? %d : sizeof( %s ) * %d ; \n ' % ( ValueSize , Pcd . BaseDatumType , pcdarraysize , ValueSize , Pcd . BaseDatumType , pcdarraysize )
CApp = CApp + ' memcpy (Pcd, & %s _ %s _ %s _ %s _Value, PcdArraySize); \n ' % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , SkuName , DefaultStoreName )
else :
CApp = CApp + ' Value = %s ; // From DSC Default Value %s \n ' % ( DscBuildData . IntToCString ( Value , ValueSize ) , Pcd . DefaultFromDSC . get ( TAB_DEFAULT , { } ) . get ( TAB_DEFAULT_STORES_DEFAULT , Pcd . DefaultValue ) if Pcd . DefaultFromDSC else Pcd . DefaultValue )
CApp = CApp + ' memcpy (Pcd, Value, %d ); \n ' % ( ValueSize )
else :
if isinstance ( Value , str ) :
if " { CODE( " in Value :
if Pcd . IsArray ( ) and Pcd . Capacity [ - 1 ] != " -1 " :
pcdarraysize = Pcd . PcdArraySize ( )
CApp = CApp + ' __STATIC_ASSERT(sizeof( %s _ %s _ %s _ %s _Value) < %d * sizeof( %s ), " Pcd %s . %s Value in Dsc exceed the array capability %s " ); // From %s \n ' % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , SkuName , DefaultStoreName , pcdarraysize , Pcd . BaseDatumType , Pcd . TokenSpaceGuidCName , Pcd . TokenCName , Pcd . DatumType , valuefrom )
CApp = CApp + ' PcdArraySize = sizeof( %s _ %s _ %s _ %s _Value); \n ' % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , SkuName , DefaultStoreName )
CApp = CApp + ' memcpy (Pcd, & %s _ %s _ %s _ %s _Value, PcdArraySize); \n ' % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , SkuName , DefaultStoreName )
else :
CApp = CApp + ' Pcd = %s ; // From DSC Default Value %s \n ' % ( Value , Pcd . DscRawValue . get ( SkuName , { } ) . get ( DefaultStoreName ) )
elif IsArray :
#
# Use memcpy() to copy value into field
#
if Pcd . IsArray ( ) :
pcdarraysize = Pcd . PcdArraySize ( )
if " { CODE( " in pcddefaultvalue :
if Pcd . Capacity [ - 1 ] != " -1 " :
CApp = CApp + ' __STATIC_ASSERT(sizeof( %s _ %s _ %s _ %s _Value) < %d * sizeof( %s ), " Pcd %s . %s Value in Dsc exceed the array capability %s " ); // From %s \n ' % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , SkuName , DefaultStoreName , pcdarraysize , Pcd . BaseDatumType , Pcd . TokenSpaceGuidCName , Pcd . TokenCName , Pcd . DatumType , valuefrom )
CApp + ' PcdArraySize = sizeof( %s _ %s _ %s _ %s _Value); \n ' % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , SkuName , DefaultStoreName )
CApp = CApp + ' memcpy (Pcd, %s _ %s _ %s _ %s _Value, PcdArraySize); \n ' % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , SkuName , DefaultStoreName )
else :
if Pcd . Capacity [ - 1 ] != " -1 " :
CApp = CApp + ' __STATIC_ASSERT( %d < %d * sizeof( %s ), " Pcd %s . %s Value in Dsc exceed the array capability %s " ); // From %s \n ' % ( ValueSize , pcdarraysize , Pcd . BaseDatumType , Pcd . TokenSpaceGuidCName , Pcd . TokenCName , Pcd . DatumType , valuefrom )
CApp = CApp + ' PcdArraySize = %d ; \n ' % ValueSize
CApp = CApp + ' Value = %s ; // From DSC Default Value %s \n ' % ( DscBuildData . IntToCString ( Value , ValueSize ) , Pcd . DscRawValue . get ( TAB_DEFAULT , { } ) . get ( TAB_DEFAULT_STORES_DEFAULT , Pcd . DefaultValue ) if Pcd . DefaultFromDSC else Pcd . DefaultValue )
CApp = CApp + ' memcpy (Pcd, Value, PcdArraySize); \n '
else :
if " { CODE( " in pcddefaultvalue :
CApp = CApp + ' PcdArraySize = %d < sizeof( %s ) * %d ? %d : sizeof( %s ) * %d ; \n ' % ( ValueSize , Pcd . BaseDatumType , pcdarraysize , ValueSize , Pcd . BaseDatumType , pcdarraysize )
CApp = CApp + ' memcpy (Pcd, & %s _ %s _ %s _ %s _Value, PcdArraySize); \n ' % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , SkuName , DefaultStoreName )
else :
CApp = CApp + ' Value = %s ; // From DSC Default Value %s \n ' % ( DscBuildData . IntToCString ( Value , ValueSize ) , Pcd . DscRawValue . get ( SkuName , { } ) . get ( DefaultStoreName ) )
CApp = CApp + ' memcpy (Pcd, Value, %d ); \n ' % ( ValueSize )
inheritvalue = inherit_OverrideValues . get ( DefaultStoreName )
if not inheritvalue :
inheritvalue = [ ]
for index in inheritvalue :
FieldList = inheritvalue [ index ]
if not FieldList :
continue
if ( SkuName , DefaultStoreName ) == ( TAB_DEFAULT , TAB_DEFAULT_STORES_DEFAULT ) or ( ( ( SkuName , ' ' ) not in Pcd . ValueChain ) and ( ( SkuName , DefaultStoreName ) not in Pcd . ValueChain ) ) :
for FieldName in FieldList :
indicator = self . GetIndicator ( index , FieldName , Pcd )
IsArray = _IsFieldValueAnArray ( FieldList [ FieldName ] [ 0 ] )
if IsArray :
try :
FieldList [ FieldName ] [ 0 ] = ValueExpressionEx ( FieldList [ FieldName ] [ 0 ] , TAB_VOID , self . _GuidDict ) ( True )
except BadExpression :
EdkLogger . error ( ' Build ' , FORMAT_INVALID , " Invalid value format for %s . From %s Line %d " %
( " . " . join ( ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , FieldName ) ) , FieldList [ FieldName ] [ 1 ] , FieldList [ FieldName ] [ 2 ] ) )
try :
Value , ValueSize = ParseFieldValue ( FieldList [ FieldName ] [ 0 ] )
except Exception :
EdkLogger . error ( ' Build ' , FORMAT_INVALID , " Invalid value format for %s . From %s Line %d " % ( " . " . join ( ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , FieldName ) ) , FieldList [ FieldName ] [ 1 ] , FieldList [ FieldName ] [ 2 ] ) )
if isinstance ( Value , str ) :
CApp = CApp + ' Pcd-> %s = %s ; // From %s Line %d Value %s \n ' % ( FieldName , Value , FieldList [ FieldName ] [ 1 ] , FieldList [ FieldName ] [ 2 ] , FieldList [ FieldName ] [ 0 ] )
elif IsArray :
#
# Use memcpy() to copy value into field
#
CApp = CApp + ' FieldSize = __FIELD_SIZE( %s , %s ); \n ' % ( Pcd . BaseDatumType , FieldName )
CApp = CApp + ' Value = %s ; // From %s Line %d Value %s \n ' % ( DscBuildData . IntToCString ( Value , ValueSize ) , FieldList [ FieldName ] [ 1 ] , FieldList [ FieldName ] [ 2 ] , FieldList [ FieldName ] [ 0 ] )
CApp = CApp + ' __STATIC_ASSERT((__FIELD_SIZE( %s , %s ) >= %d ) || (__FIELD_SIZE( %s , %s ) == 0), " Input buffer exceeds the buffer array " ); // From %s Line %d Value %s \n ' % ( Pcd . BaseDatumType , FieldName , ValueSize , Pcd . BaseDatumType , FieldName , FieldList [ FieldName ] [ 1 ] , FieldList [ FieldName ] [ 2 ] , FieldList [ FieldName ] [ 0 ] )
CApp = CApp + ' memcpy (& %s , Value, (FieldSize > 0 && FieldSize < %d ) ? FieldSize : %d ); \n ' % ( indicator , ValueSize , ValueSize )
else :
if ' [ ' in FieldName and ' ] ' in FieldName :
Index = int ( FieldName . split ( ' [ ' ) [ 1 ] . split ( ' ] ' ) [ 0 ] )
CApp = CApp + ' __STATIC_ASSERT(( %d < __ARRAY_SIZE(Pcd-> %s )) || (__ARRAY_SIZE(Pcd-> %s ) == 0), " array index exceeds the array number " ); // From %s Line %d Index of %s \n ' % ( Index , FieldName . split ( ' [ ' ) [ 0 ] , FieldName . split ( ' [ ' ) [ 0 ] , FieldList [ FieldName ] [ 1 ] , FieldList [ FieldName ] [ 2 ] , FieldName )
if ValueSize > 4 :
CApp = CApp + ' %s = %d ULL; // From %s Line %d Value %s \n ' % ( indicator , Value , FieldList [ FieldName ] [ 1 ] , FieldList [ FieldName ] [ 2 ] , FieldList [ FieldName ] [ 0 ] )
else :
CApp = CApp + ' %s = %d ; // From %s Line %d Value %s \n ' % ( indicator , Value , FieldList [ FieldName ] [ 1 ] , FieldList [ FieldName ] [ 2 ] , FieldList [ FieldName ] [ 0 ] )
CApp = CApp + " } \n "
return CApp
@staticmethod
def GenerateInitValueStatement ( Pcd , SkuName , DefaultStoreName ) :
CApp = ' Assign_ %s _ %s _ %s _ %s _Value(Pcd); \n ' % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , SkuName , DefaultStoreName )
return CApp
def GenerateCommandLineValue ( self , Pcd ) :
CApp = " // Value in CommandLine \n "
CApp = CApp + " void Assign_ %s _ %s _CommandLine_Value( %s *Pcd) { \n " % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , Pcd . BaseDatumType )
CApp = CApp + ' UINT32 FieldSize; \n '
CApp = CApp + ' CHAR8 *Value; \n '
pcddefaultvalue = Pcd . PcdValueFromComm
for FieldList in [ pcddefaultvalue , Pcd . PcdFieldValueFromComm ] :
if not FieldList :
continue
if pcddefaultvalue and FieldList == pcddefaultvalue :
IsArray = _IsFieldValueAnArray ( FieldList )
if IsArray :
try :
FieldList = ValueExpressionEx ( FieldList , TAB_VOID ) ( True )
except BadExpression :
EdkLogger . error ( " Build " , FORMAT_INVALID , " Invalid value format for %s . %s , from Command: %s " %
( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , FieldList ) )
Value , ValueSize = ParseFieldValue ( FieldList )
if isinstance ( Value , str ) :
CApp = CApp + ' Pcd = %s ; // From Command Line \n ' % ( Value )
elif IsArray :
#
# Use memcpy() to copy value into field
#
CApp = CApp + ' Value = %s ; // From Command Line. \n ' % ( DscBuildData . IntToCString ( Value , ValueSize ) )
CApp = CApp + ' memcpy (Pcd, Value, %d ); \n ' % ( ValueSize )
continue
for FieldName in FieldList :
IsArray = _IsFieldValueAnArray ( FieldList [ FieldName ] [ 0 ] )
if IsArray :
try :
FieldList [ FieldName ] [ 0 ] = ValueExpressionEx ( FieldList [ FieldName ] [ 0 ] , TAB_VOID , self . _GuidDict ) ( True )
except BadExpression :
EdkLogger . error ( ' Build ' , FORMAT_INVALID , " Invalid value format for %s . From %s Line %d " %
( " . " . join ( ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , FieldName ) ) , FieldList [ FieldName ] [ 1 ] , FieldList [ FieldName ] [ 2 ] ) )
except :
print ( " error " )
try :
Value , ValueSize = ParseFieldValue ( FieldList [ FieldName ] [ 0 ] )
except Exception :
EdkLogger . error ( ' Build ' , FORMAT_INVALID , " Invalid value format for %s . From %s Line %d " % ( " . " . join ( ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , FieldName ) ) , FieldList [ FieldName ] [ 1 ] , FieldList [ FieldName ] [ 2 ] ) )
if isinstance ( Value , str ) :
CApp = CApp + ' Pcd-> %s = %s ; // From %s Line %d Value %s \n ' % ( FieldName , Value , FieldList [ FieldName ] [ 1 ] , FieldList [ FieldName ] [ 2 ] , FieldList [ FieldName ] [ 0 ] )
elif IsArray :
#
# Use memcpy() to copy value into field
#
CApp = CApp + ' FieldSize = __FIELD_SIZE( %s , %s ); \n ' % ( Pcd . BaseDatumType , FieldName )
CApp = CApp + ' Value = %s ; // From %s Line %d Value %s \n ' % ( DscBuildData . IntToCString ( Value , ValueSize ) , FieldList [ FieldName ] [ 1 ] , FieldList [ FieldName ] [ 2 ] , FieldList [ FieldName ] [ 0 ] )
CApp = CApp + ' __STATIC_ASSERT((__FIELD_SIZE( %s , %s ) >= %d ) || (__FIELD_SIZE( %s , %s ) == 0), " Input buffer exceeds the buffer array " ); // From %s Line %d Value %s \n ' % ( Pcd . BaseDatumType , FieldName , ValueSize , Pcd . BaseDatumType , FieldName , FieldList [ FieldName ] [ 1 ] , FieldList [ FieldName ] [ 2 ] , FieldList [ FieldName ] [ 0 ] )
CApp = CApp + ' memcpy (&Pcd-> %s , Value, (FieldSize > 0 && FieldSize < %d ) ? FieldSize : %d ); \n ' % ( FieldName , ValueSize , ValueSize )
else :
if ' [ ' in FieldName and ' ] ' in FieldName :
Index = int ( FieldName . split ( ' [ ' ) [ 1 ] . split ( ' ] ' ) [ 0 ] )
CApp = CApp + ' __STATIC_ASSERT(( %d < __ARRAY_SIZE(Pcd-> %s )) || (__ARRAY_SIZE(Pcd-> %s ) == 0), " array index exceeds the array number " ); // From %s Line %d Index of %s \n ' % ( Index , FieldName . split ( ' [ ' ) [ 0 ] , FieldName . split ( ' [ ' ) [ 0 ] , FieldList [ FieldName ] [ 1 ] , FieldList [ FieldName ] [ 2 ] , FieldName )
if ValueSize > 4 :
CApp = CApp + ' Pcd-> %s = %d ULL; // From %s Line %d Value %s \n ' % ( FieldName , Value , FieldList [ FieldName ] [ 1 ] , FieldList [ FieldName ] [ 2 ] , FieldList [ FieldName ] [ 0 ] )
else :
CApp = CApp + ' Pcd-> %s = %d ; // From %s Line %d Value %s \n ' % ( FieldName , Value , FieldList [ FieldName ] [ 1 ] , FieldList [ FieldName ] [ 2 ] , FieldList [ FieldName ] [ 0 ] )
CApp = CApp + " } \n "
return CApp
@staticmethod
def GenerateCommandLineValueStatement ( Pcd ) :
CApp = ' Assign_ %s _ %s _CommandLine_Value(Pcd); \n ' % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName )
return CApp
def GenerateFdfValue ( self , Pcd ) :
CApp = " // Value in Fdf \n "
CApp = CApp + " void Assign_ %s _ %s _Fdf_Value( %s *Pcd) { \n " % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , Pcd . BaseDatumType )
CApp = CApp + ' UINT32 FieldSize; \n '
CApp = CApp + ' CHAR8 *Value; \n '
pcddefaultvalue = Pcd . PcdValueFromFdf
for FieldList in [ pcddefaultvalue , Pcd . PcdFieldValueFromFdf ] :
if not FieldList :
continue
if pcddefaultvalue and FieldList == pcddefaultvalue :
IsArray = _IsFieldValueAnArray ( FieldList )
if IsArray :
try :
FieldList = ValueExpressionEx ( FieldList , TAB_VOID ) ( True )
except BadExpression :
EdkLogger . error ( " Build " , FORMAT_INVALID , " Invalid value format for %s . %s , from Fdf: %s " %
( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , FieldList ) )
Value , ValueSize = ParseFieldValue ( FieldList )
if isinstance ( Value , str ) :
CApp = CApp + ' Pcd = %s ; // From Fdf \n ' % ( Value )
elif IsArray :
#
# Use memcpy() to copy value into field
#
CApp = CApp + ' Value = %s ; // From Fdf . \n ' % ( DscBuildData . IntToCString ( Value , ValueSize ) )
CApp = CApp + ' memcpy (Pcd, Value, %d ); \n ' % ( ValueSize )
continue
for FieldName in FieldList :
IsArray = _IsFieldValueAnArray ( FieldList [ FieldName ] [ 0 ] )
if IsArray :
try :
FieldList [ FieldName ] [ 0 ] = ValueExpressionEx ( FieldList [ FieldName ] [ 0 ] , TAB_VOID , self . _GuidDict ) ( True )
except BadExpression :
EdkLogger . error ( ' Build ' , FORMAT_INVALID , " Invalid value format for %s . From %s Line %d " %
( " . " . join ( ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , FieldName ) ) , FieldList [ FieldName ] [ 1 ] , FieldList [ FieldName ] [ 2 ] ) )
except :
print ( " error " )
try :
Value , ValueSize = ParseFieldValue ( FieldList [ FieldName ] [ 0 ] )
except Exception :
EdkLogger . error ( ' Build ' , FORMAT_INVALID , " Invalid value format for %s . From %s Line %d " % ( " . " . join ( ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , FieldName ) ) , FieldList [ FieldName ] [ 1 ] , FieldList [ FieldName ] [ 2 ] ) )
if isinstance ( Value , str ) :
CApp = CApp + ' Pcd-> %s = %s ; // From %s Line %d Value %s \n ' % ( FieldName , Value , FieldList [ FieldName ] [ 1 ] , FieldList [ FieldName ] [ 2 ] , FieldList [ FieldName ] [ 0 ] )
elif IsArray :
#
# Use memcpy() to copy value into field
#
CApp = CApp + ' FieldSize = __FIELD_SIZE( %s , %s ); \n ' % ( Pcd . BaseDatumType , FieldName )
CApp = CApp + ' Value = %s ; // From %s Line %d Value %s \n ' % ( DscBuildData . IntToCString ( Value , ValueSize ) , FieldList [ FieldName ] [ 1 ] , FieldList [ FieldName ] [ 2 ] , FieldList [ FieldName ] [ 0 ] )
CApp = CApp + ' __STATIC_ASSERT((__FIELD_SIZE( %s , %s ) >= %d ) || (__FIELD_SIZE( %s , %s ) == 0), " Input buffer exceeds the buffer array " ); // From %s Line %d Value %s \n ' % ( Pcd . BaseDatumType , FieldName , ValueSize , Pcd . BaseDatumType , FieldName , FieldList [ FieldName ] [ 1 ] , FieldList [ FieldName ] [ 2 ] , FieldList [ FieldName ] [ 0 ] )
CApp = CApp + ' memcpy (&Pcd-> %s , Value, (FieldSize > 0 && FieldSize < %d ) ? FieldSize : %d ); \n ' % ( FieldName , ValueSize , ValueSize )
else :
if ' [ ' in FieldName and ' ] ' in FieldName :
Index = int ( FieldName . split ( ' [ ' ) [ 1 ] . split ( ' ] ' ) [ 0 ] )
CApp = CApp + ' __STATIC_ASSERT(( %d < __ARRAY_SIZE(Pcd-> %s )) || (__ARRAY_SIZE(Pcd-> %s ) == 0), " array index exceeds the array number " ); // From %s Line %d Index of %s \n ' % ( Index , FieldName . split ( ' [ ' ) [ 0 ] , FieldName . split ( ' [ ' ) [ 0 ] , FieldList [ FieldName ] [ 1 ] , FieldList [ FieldName ] [ 2 ] , FieldName )
if ValueSize > 4 :
CApp = CApp + ' Pcd-> %s = %d ULL; // From %s Line %d Value %s \n ' % ( FieldName , Value , FieldList [ FieldName ] [ 1 ] , FieldList [ FieldName ] [ 2 ] , FieldList [ FieldName ] [ 0 ] )
else :
CApp = CApp + ' Pcd-> %s = %d ; // From %s Line %s Value %s \n ' % ( FieldName , Value , FieldList [ FieldName ] [ 1 ] , FieldList [ FieldName ] [ 2 ] , FieldList [ FieldName ] [ 0 ] )
CApp = CApp + " } \n "
return CApp
@staticmethod
def GenerateFdfValueStatement ( Pcd ) :
CApp = ' Assign_ %s _ %s _Fdf_Value(Pcd); \n ' % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName )
return CApp
def GenerateInitializeFunc ( self , SkuName , DefaultStore , Pcd , InitByteValue , CApp ) :
OverrideValues = { DefaultStore : { } }
if Pcd . SkuOverrideValues :
OverrideValues = Pcd . SkuOverrideValues [ SkuName ]
if not OverrideValues :
OverrideValues = { TAB_DEFAULT_STORES_DEFAULT : Pcd . DefaultValues }
for DefaultStoreName in OverrideValues :
CApp = CApp + ' void \n '
CApp = CApp + ' Initialize_ %s _ %s _ %s _ %s ( \n ' % ( SkuName , DefaultStoreName , Pcd . TokenSpaceGuidCName , Pcd . TokenCName )
CApp = CApp + ' void \n '
CApp = CApp + ' ) \n '
CApp = CApp + ' { \n '
CApp = CApp + ' UINT32 Size; \n '
CApp = CApp + ' UINT32 FieldSize; \n '
CApp = CApp + ' CHAR8 *Value; \n '
CApp = CApp + ' UINT32 OriginalSize; \n '
CApp = CApp + ' VOID *OriginalPcd; \n '
CApp = CApp + ' %s *Pcd; // From %s Line %d \n ' % ( Pcd . BaseDatumType , Pcd . PkgPath , Pcd . PcdDefineLineNo )
CApp = CApp + ' \n '
PcdDefaultValue = StringToArray ( Pcd . DefaultValueFromDec . strip ( ) )
InitByteValue + = ' %s . %s . %s . %s | %s | %s \n ' % ( SkuName , DefaultStoreName , Pcd . TokenSpaceGuidCName , Pcd . TokenCName , Pcd . DatumType , PcdDefaultValue )
#
# Get current PCD value and size
#
CApp = CApp + ' OriginalPcd = PcdGetPtr ( %s , %s , %s , %s , &OriginalSize); \n ' % ( SkuName , DefaultStoreName , Pcd . TokenSpaceGuidCName , Pcd . TokenCName )
#
# Determine the size of the PCD. For simple structures, sizeof(TYPE) provides
# the correct value. For structures with a flexible array member, the flexible
# array member is detected, and the size is based on the highest index used with
# the flexible array member. The flexible array member must be the last field
# in a structure. The size formula for this case is:
# OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1)
#
CApp = CApp + DscBuildData . GenerateSizeStatments ( Pcd , SkuName , DefaultStoreName )
if Pcd . IsArray ( ) and Pcd . Capacity [ - 1 ] != " -1 " :
CApp = CApp + ' OriginalSize = OriginalSize < sizeof( %s ) * %d ? OriginalSize:sizeof( %s ) * %d ; \n ' % ( Pcd . BaseDatumType , Pcd . PcdArraySize ( ) , Pcd . BaseDatumType , Pcd . PcdArraySize ( ) )
CApp = CApp + ' Size = sizeof( %s ) * %d ; \n ' % ( Pcd . BaseDatumType , Pcd . PcdArraySize ( ) )
#
# Allocate and zero buffer for the PCD
# Must handle cases where current value is smaller, larger, or same size
# Always keep that larger one as the current size
#
CApp = CApp + ' Size = (OriginalSize > Size ? OriginalSize : Size); \n '
CApp = CApp + ' Pcd = ( %s *)malloc (Size); \n ' % ( Pcd . BaseDatumType , )
CApp = CApp + ' memset (Pcd, 0, Size); \n '
#
# Copy current PCD value into allocated buffer.
#
CApp = CApp + ' memcpy (Pcd, OriginalPcd, OriginalSize); \n '
#
# Assign field values in PCD
#
CApp = CApp + DscBuildData . GenerateDefaultValueAssignStatement ( Pcd )
if Pcd . Type not in [ self . _PCD_TYPE_STRING_ [ MODEL_PCD_FIXED_AT_BUILD ] ,
self . _PCD_TYPE_STRING_ [ MODEL_PCD_PATCHABLE_IN_MODULE ] ] :
for skuname in self . SkuIdMgr . GetSkuChain ( SkuName ) :
storeset = [ DefaultStoreName ] if DefaultStoreName == TAB_DEFAULT_STORES_DEFAULT else [ TAB_DEFAULT_STORES_DEFAULT , DefaultStoreName ]
for defaultstorenameitem in storeset :
CApp = CApp + " // SkuName: %s , DefaultStoreName: %s \n " % ( skuname , defaultstorenameitem )
CApp = CApp + DscBuildData . GenerateInitValueStatement ( Pcd , skuname , defaultstorenameitem )
if skuname == SkuName :
break
else :
CApp = CApp + " // SkuName: %s , DefaultStoreName: STANDARD \n " % self . SkuIdMgr . SystemSkuId
CApp = CApp + DscBuildData . GenerateInitValueStatement ( Pcd , self . SkuIdMgr . SystemSkuId , TAB_DEFAULT_STORES_DEFAULT )
CApp = CApp + DscBuildData . GenerateFdfValueStatement ( Pcd )
CApp = CApp + DscBuildData . GenerateCommandLineValueStatement ( Pcd )
#
# Set new PCD value and size
#
CApp = CApp + ' PcdSetPtr ( %s , %s , %s , %s , Size, (void *)Pcd); \n ' % ( SkuName , DefaultStoreName , Pcd . TokenSpaceGuidCName , Pcd . TokenCName )
#
# Free PCD
#
CApp = CApp + ' free (Pcd); \n '
CApp = CApp + ' } \n '
CApp = CApp + ' \n '
return InitByteValue , CApp
def GenerateArrayAssignment ( self , Pcd ) :
CApp = " "
if not Pcd :
return CApp
Demesion = " "
for d in Pcd . Capacity :
Demesion + = " [] "
Value = Pcd . DefaultValueFromDec
if " { CODE( " in Pcd . DefaultValueFromDec :
realvalue = Pcd . DefaultValueFromDec . strip ( ) [ 6 : - 2 ] # "{CODE(").rstrip(")}"
CApp + = " static %s %s _ %s _INIT_Value %s = %s ; \n " % ( Pcd . BaseDatumType , Pcd . TokenSpaceGuidCName , Pcd . TokenCName , Demesion , realvalue )
if Pcd . Type in PCD_DYNAMIC_TYPE_SET | PCD_DYNAMIC_EX_TYPE_SET :
for skuname in Pcd . SkuInfoList :
skuinfo = Pcd . SkuInfoList [ skuname ]
if skuinfo . VariableName :
for defaultstore in skuinfo . DefaultStoreDict :
pcddscrawdefaultvalue = self . GetPcdDscRawDefaultValue ( Pcd , skuname , defaultstore )
if pcddscrawdefaultvalue :
Value = skuinfo . DefaultStoreDict [ defaultstore ]
if " { CODE( " in Value :
realvalue = Value . strip ( ) [ 6 : - 2 ] # "{CODE(").rstrip(")}"
CApp + = " static %s %s _ %s _ %s _ %s _Value %s = %s ; \n " % ( Pcd . BaseDatumType , Pcd . TokenSpaceGuidCName , Pcd . TokenCName , skuname , defaultstore , Demesion , realvalue )
else :
pcddscrawdefaultvalue = self . GetPcdDscRawDefaultValue ( Pcd , skuname , TAB_DEFAULT_STORES_DEFAULT )
if pcddscrawdefaultvalue :
Value = skuinfo . DefaultValue
if " { CODE( " in Value :
realvalue = Value . strip ( ) [ 6 : - 2 ] # "{CODE(").rstrip(")}"
CApp + = " static %s %s _ %s _ %s _ %s _Value %s = %s ; \n " % ( Pcd . BaseDatumType , Pcd . TokenSpaceGuidCName , Pcd . TokenCName , skuname , TAB_DEFAULT_STORES_DEFAULT , Demesion , realvalue )
else :
pcddscrawdefaultvalue = self . GetPcdDscRawDefaultValue ( Pcd , TAB_DEFAULT , TAB_DEFAULT_STORES_DEFAULT )
if pcddscrawdefaultvalue :
if " { CODE( " in Pcd . DefaultValue :
realvalue = Pcd . DefaultValue . strip ( ) [ 6 : - 2 ] # "{CODE(").rstrip(")}"
CApp + = " static %s %s _ %s _DEFAULT_STANDARD_Value %s = %s ; \n " % ( Pcd . BaseDatumType , Pcd . TokenSpaceGuidCName , Pcd . TokenCName , Demesion , realvalue )
return CApp
def SkuOverrideValuesEmpty ( self , OverrideValues ) :
if not OverrideValues :
return True
for key in OverrideValues :
if OverrideValues [ key ] :
return False
return True
def ParseCCFlags ( self , ccflag ) :
ccflags = set ( )
ccflaglist = ccflag . split ( " " )
i = 0
while i < len ( ccflaglist ) :
item = ccflaglist [ i ] . strip ( )
if item in ( r " /D " , r " /U " , " -D " , " -U " ) :
ccflags . add ( " " . join ( ( ccflaglist [ i ] , ccflaglist [ i + 1 ] ) ) )
i = i + 1
elif item . startswith ( ( r " /D " , r " /U " , " -D " , " -U " ) ) :
ccflags . add ( item )
i + = 1
return ccflags
def GenerateByteArrayValue ( self , StructuredPcds ) :
#
# Generate/Compile/Run C application to determine if there are any flexible array members
#
if not StructuredPcds :
return
InitByteValue = " "
CApp = PcdMainCHeader
IncludeFiles = set ( )
for PcdName in StructuredPcds :
Pcd = StructuredPcds [ PcdName ]
for IncludeFile in Pcd . StructuredPcdIncludeFile :
if IncludeFile not in IncludeFiles :
IncludeFiles . add ( IncludeFile )
CApp = CApp + ' #include < %s > \n ' % ( IncludeFile )
CApp = CApp + ' \n '
for Pcd in StructuredPcds . values ( ) :
CApp = CApp + self . GenerateArrayAssignment ( Pcd )
for PcdName in StructuredPcds :
Pcd = StructuredPcds [ PcdName ]
CApp = CApp + self . GenerateSizeFunction ( Pcd )
CApp = CApp + self . GenerateDefaultValueAssignFunction ( Pcd )
CApp = CApp + self . GenerateFdfValue ( Pcd )
CApp = CApp + self . GenerateCommandLineValue ( Pcd )
if self . SkuOverrideValuesEmpty ( Pcd . SkuOverrideValues ) or Pcd . Type in [ self . _PCD_TYPE_STRING_ [ MODEL_PCD_FIXED_AT_BUILD ] ,
self . _PCD_TYPE_STRING_ [ MODEL_PCD_PATCHABLE_IN_MODULE ] ] :
CApp = CApp + self . GenerateInitValueFunction ( Pcd , self . SkuIdMgr . SystemSkuId , TAB_DEFAULT_STORES_DEFAULT )
else :
for SkuName in self . SkuIdMgr . SkuOverrideOrder ( ) :
if SkuName not in Pcd . SkuOverrideValues :
continue
for DefaultStoreName in Pcd . SkuOverrideValues [ SkuName ] :
CApp = CApp + self . GenerateInitValueFunction ( Pcd , SkuName , DefaultStoreName )
if self . SkuOverrideValuesEmpty ( Pcd . SkuOverrideValues ) or Pcd . Type in [ self . _PCD_TYPE_STRING_ [ MODEL_PCD_FIXED_AT_BUILD ] ,
self . _PCD_TYPE_STRING_ [ MODEL_PCD_PATCHABLE_IN_MODULE ] ] :
InitByteValue , CApp = self . GenerateInitializeFunc ( self . SkuIdMgr . SystemSkuId , TAB_DEFAULT_STORES_DEFAULT , Pcd , InitByteValue , CApp )
else :
for SkuName in self . SkuIdMgr . SkuOverrideOrder ( ) :
if SkuName not in Pcd . SkuOverrideValues :
continue
for DefaultStoreName in Pcd . DefaultStoreName :
Pcd = StructuredPcds [ PcdName ]
InitByteValue , CApp = self . GenerateInitializeFunc ( SkuName , DefaultStoreName , Pcd , InitByteValue , CApp )
CApp = CApp + ' VOID \n '
CApp = CApp + ' PcdEntryPoint( \n '
CApp = CApp + ' VOID \n '
CApp = CApp + ' ) \n '
CApp = CApp + ' { \n '
for Pcd in StructuredPcds . values ( ) :
if self . SkuOverrideValuesEmpty ( Pcd . SkuOverrideValues ) or Pcd . Type in [ self . _PCD_TYPE_STRING_ [ MODEL_PCD_FIXED_AT_BUILD ] , self . _PCD_TYPE_STRING_ [ MODEL_PCD_PATCHABLE_IN_MODULE ] ] :
CApp = CApp + ' Initialize_ %s _ %s _ %s _ %s (); \n ' % ( self . SkuIdMgr . SystemSkuId , TAB_DEFAULT_STORES_DEFAULT , Pcd . TokenSpaceGuidCName , Pcd . TokenCName )
else :
for SkuName in self . SkuIdMgr . SkuOverrideOrder ( ) :
if SkuName not in self . SkuIdMgr . AvailableSkuIdSet :
continue
for DefaultStoreName in Pcd . SkuOverrideValues [ SkuName ] :
CApp = CApp + ' Initialize_ %s _ %s _ %s _ %s (); \n ' % ( SkuName , DefaultStoreName , Pcd . TokenSpaceGuidCName , Pcd . TokenCName )
CApp = CApp + ' } \n '
CApp = CApp + PcdMainCEntry + ' \n '
if not os . path . exists ( self . OutputPath ) :
os . makedirs ( self . OutputPath )
CAppBaseFileName = os . path . join ( self . OutputPath , PcdValueInitName )
SaveFileOnChange ( CAppBaseFileName + ' .c ' , CApp , False )
MakeApp = PcdMakefileHeader
if sys . platform == " win32 " :
MakeApp = MakeApp + ' APPFILE = %s \ %s .exe \n ' % ( self . OutputPath , PcdValueInitName ) + ' APPNAME = %s \n ' % ( PcdValueInitName ) + ' OBJECTS = %s \ %s .obj \n ' % ( self . OutputPath , PcdValueInitName ) + ' INC = '
else :
MakeApp = MakeApp + PcdGccMakefile
MakeApp = MakeApp + ' APPFILE = %s / %s \n ' % ( self . OutputPath , PcdValueInitName ) + ' APPNAME = %s \n ' % ( PcdValueInitName ) + ' OBJECTS = %s / %s .o \n ' % ( self . OutputPath , PcdValueInitName ) + \
' include $(MAKEROOT)/Makefiles/app.makefile \n ' + ' INCLUDE += '
IncSearchList = [ ]
PlatformInc = OrderedDict ( )
for Cache in self . _Bdb . _CACHE_ . values ( ) :
if Cache . MetaFile . Ext . lower ( ) != ' .dec ' :
continue
if Cache . Includes :
if str ( Cache . MetaFile . Path ) not in PlatformInc :
PlatformInc [ str ( Cache . MetaFile . Path ) ] = [ ]
PlatformInc [ str ( Cache . MetaFile . Path ) ] . append ( os . path . dirname ( Cache . MetaFile . Path ) )
PlatformInc [ str ( Cache . MetaFile . Path ) ] . extend ( Cache . CommonIncludes )
PcdDependDEC = [ ]
for Pcd in StructuredPcds . values ( ) :
for PackageDec in Pcd . PackageDecs :
Package = os . path . normpath ( mws . join ( GlobalData . gWorkspace , PackageDec ) )
if not os . path . exists ( Package ) :
EdkLogger . error ( ' Build ' , RESOURCE_NOT_AVAILABLE , " The dependent Package %s of PCD %s . %s is not exist. " % ( PackageDec , Pcd . TokenSpaceGuidCName , Pcd . TokenCName ) )
if Package not in PcdDependDEC :
PcdDependDEC . append ( Package )
if PlatformInc and PcdDependDEC :
for pkg in PcdDependDEC :
if pkg in PlatformInc :
for inc in PlatformInc [ pkg ] :
MakeApp + = ' -I ' + str ( inc ) + ' '
IncSearchList . append ( inc )
MakeApp = MakeApp + ' \n '
CC_FLAGS = LinuxCFLAGS
if sys . platform == " win32 " :
CC_FLAGS = WindowsCFLAGS
BuildOptions = OrderedDict ( )
for Options in self . BuildOptions :
if Options [ 2 ] != EDKII_NAME :
continue
Family = Options [ 0 ]
if Family and Family != self . ToolChainFamily :
continue
Target , Tag , Arch , Tool , Attr = Options [ 1 ] . split ( " _ " )
if Tool != ' CC ' :
continue
if Attr != " FLAGS " :
continue
if Target == TAB_STAR or Target == self . _Target :
if Tag == TAB_STAR or Tag == self . _Toolchain :
if ' COMMON ' not in BuildOptions :
BuildOptions [ ' COMMON ' ] = set ( )
if Arch == TAB_STAR :
BuildOptions [ ' COMMON ' ] | = self . ParseCCFlags ( self . BuildOptions [ Options ] )
if Arch in self . SupArchList :
if Arch not in BuildOptions :
BuildOptions [ Arch ] = set ( )
BuildOptions [ Arch ] | = self . ParseCCFlags ( self . BuildOptions [ Options ] )
if BuildOptions :
ArchBuildOptions = { arch : flags for arch , flags in BuildOptions . items ( ) if arch != ' COMMON ' }
if len ( ArchBuildOptions . keys ( ) ) == 1 :
BuildOptions [ ' COMMON ' ] | = ( list ( ArchBuildOptions . values ( ) ) [ 0 ] )
elif len ( ArchBuildOptions . keys ( ) ) > 1 :
CommonBuildOptions = reduce ( lambda x , y : x & y , ArchBuildOptions . values ( ) )
BuildOptions [ ' COMMON ' ] | = CommonBuildOptions
ValueList = [ item for item in BuildOptions [ ' COMMON ' ] if item . startswith ( ( r " /U " , " -U " ) ) ]
ValueList . extend ( [ item for item in BuildOptions [ ' COMMON ' ] if item . startswith ( ( r " /D " , " -D " ) ) ] )
CC_FLAGS + = " " . join ( ValueList )
MakeApp + = CC_FLAGS
if sys . platform == " win32 " :
MakeApp = MakeApp + PcdMakefileEnd
MakeApp = MakeApp + AppTarget % ( """ \t copy $(APPLICATION) $(APPFILE) /y """ )
else :
MakeApp = MakeApp + AppTarget % ( """ \t cp $(APPLICATION) $(APPFILE) """ )
MakeApp = MakeApp + ' \n '
IncludeFileFullPaths = [ ]
for includefile in IncludeFiles :
for includepath in IncSearchList :
includefullpath = os . path . join ( str ( includepath ) , includefile )
if os . path . exists ( includefullpath ) :
IncludeFileFullPaths . append ( os . path . normpath ( includefullpath ) )
break
SearchPathList = [ ]
SearchPathList . append ( os . path . normpath ( mws . join ( GlobalData . gWorkspace , " BaseTools/Source/C/Include " ) ) )
SearchPathList . append ( os . path . normpath ( mws . join ( GlobalData . gWorkspace , " BaseTools/Source/C/Common " ) ) )
SearchPathList . extend ( str ( item ) for item in IncSearchList )
IncFileList = GetDependencyList ( IncludeFileFullPaths , SearchPathList )
for include_file in IncFileList :
MakeApp + = " $(OBJECTS) : %s \n " % include_file
MakeFileName = os . path . join ( self . OutputPath , ' Makefile ' )
MakeApp + = " $(OBJECTS) : %s \n " % MakeFileName
SaveFileOnChange ( MakeFileName , MakeApp , False )
InputValueFile = os . path . join ( self . OutputPath , ' Input.txt ' )
OutputValueFile = os . path . join ( self . OutputPath , ' Output.txt ' )
SaveFileOnChange ( InputValueFile , InitByteValue , False )
Dest_PcdValueInitExe = PcdValueInitName
if not sys . platform == " win32 " :
Dest_PcdValueInitExe = os . path . join ( self . OutputPath , PcdValueInitName )
else :
Dest_PcdValueInitExe = os . path . join ( self . OutputPath , PcdValueInitName ) + " .exe "
Messages = ' '
if sys . platform == " win32 " :
MakeCommand = ' nmake -f %s ' % ( MakeFileName )
returncode , StdOut , StdErr = DscBuildData . ExecuteCommand ( MakeCommand )
Messages = StdOut
else :
MakeCommand = ' make -f %s ' % ( MakeFileName )
returncode , StdOut , StdErr = DscBuildData . ExecuteCommand ( MakeCommand )
Messages = StdErr
Messages = Messages . split ( ' \n ' )
MessageGroup = [ ]
if returncode != 0 :
CAppBaseFileName = os . path . join ( self . OutputPath , PcdValueInitName )
File = open ( CAppBaseFileName + ' .c ' , ' r ' )
FileData = File . readlines ( )
File . close ( )
for Message in Messages :
if " error " in Message or " warning " in Message :
FileInfo = Message . strip ( ) . split ( ' ( ' )
if len ( FileInfo ) > 1 :
FileName = FileInfo [ 0 ]
FileLine = FileInfo [ 1 ] . split ( ' ) ' ) [ 0 ]
else :
FileInfo = Message . strip ( ) . split ( ' : ' )
if len ( FileInfo ) < 2 :
continue
FileName = FileInfo [ 0 ]
FileLine = FileInfo [ 1 ]
if FileLine . isdigit ( ) :
error_line = FileData [ int ( FileLine ) - 1 ]
if r " // " in error_line :
c_line , dsc_line = error_line . split ( r " // " )
else :
dsc_line = error_line
message_itmes = Message . split ( " : " )
Index = 0
if " PcdValueInit.c " not in Message :
if not MessageGroup :
MessageGroup . append ( Message )
break
else :
for item in message_itmes :
if " PcdValueInit.c " in item :
Index = message_itmes . index ( item )
message_itmes [ Index ] = dsc_line . strip ( )
break
MessageGroup . append ( " : " . join ( message_itmes [ Index : ] ) . strip ( ) )
continue
else :
MessageGroup . append ( Message )
if MessageGroup :
EdkLogger . error ( " build " , PCD_STRUCTURE_PCD_ERROR , " \n " . join ( MessageGroup ) )
else :
EdkLogger . error ( ' Build ' , COMMAND_FAILURE , ' Can not execute command: %s ' % MakeCommand )
if DscBuildData . NeedUpdateOutput ( OutputValueFile , Dest_PcdValueInitExe , InputValueFile ) :
Command = Dest_PcdValueInitExe + ' -i %s -o %s ' % ( InputValueFile , OutputValueFile )
returncode , StdOut , StdErr = DscBuildData . ExecuteCommand ( Command )
if returncode != 0 :
EdkLogger . warn ( ' Build ' , COMMAND_FAILURE , ' Can not collect output from command: %s ' % Command )
File = open ( OutputValueFile , ' r ' )
FileBuffer = File . readlines ( )
File . close ( )
StructurePcdSet = [ ]
for Pcd in FileBuffer :
PcdValue = Pcd . split ( ' | ' )
PcdInfo = PcdValue [ 0 ] . split ( ' . ' )
StructurePcdSet . append ( ( PcdInfo [ 0 ] , PcdInfo [ 1 ] , PcdInfo [ 2 ] , PcdInfo [ 3 ] , PcdValue [ 2 ] . strip ( ) ) )
return StructurePcdSet
@staticmethod
def NeedUpdateOutput ( OutputFile , ValueCFile , StructureInput ) :
if not os . path . exists ( OutputFile ) :
return True
if os . stat ( OutputFile ) . st_mtime < = os . stat ( ValueCFile ) . st_mtime :
return True
if os . stat ( OutputFile ) . st_mtime < = os . stat ( StructureInput ) . st_mtime :
return True
return False
## Retrieve dynamic PCD settings
#
# @param Type PCD type
#
# @retval a dict object contains settings of given PCD type
#
def _GetDynamicPcd ( self , Type ) :
Pcds = OrderedDict ( )
#
# tdict is a special dict kind of type, used for selecting correct
# PCD settings for certain ARCH and SKU
#
PcdDict = tdict ( True , 4 )
PcdList = [ ]
# Find out all possible PCD candidates for self._Arch
RecordList = self . _RawData [ Type , self . _Arch ]
AvailableSkuIdSet = copy . copy ( self . SkuIds )
for TokenSpaceGuid , PcdCName , Setting , Arch , SkuName , Dummy3 , Dummy4 , Dummy5 in RecordList :
SkuName = SkuName . upper ( )
SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
if SkuName not in AvailableSkuIdSet :
EdkLogger . error ( ' build ' , PARAMETER_INVALID , ' Sku %s is not defined in [SkuIds] section ' % SkuName ,
File = self . MetaFile , Line = Dummy5 )
if " . " not in TokenSpaceGuid and " [ " not in PcdCName and ( PcdCName , TokenSpaceGuid , SkuName , Dummy5 ) not in PcdList :
PcdList . append ( ( PcdCName , TokenSpaceGuid , SkuName , Dummy5 ) )
PcdDict [ Arch , SkuName , PcdCName , TokenSpaceGuid ] = Setting
# Remove redundant PCD candidates, per the ARCH and SKU
for PcdCName , TokenSpaceGuid , SkuName , Dummy4 in PcdList :
Setting = PcdDict [ self . _Arch , SkuName , PcdCName , TokenSpaceGuid ]
if Setting is None :
continue
PcdValue , DatumType , MaxDatumSize = self . _ValidatePcd ( PcdCName , TokenSpaceGuid , Setting , Type , Dummy4 )
if MaxDatumSize :
if int ( MaxDatumSize , 0 ) > 0xFFFF :
EdkLogger . error ( ' build ' , FORMAT_INVALID , " The size value must not exceed the maximum value of 0xFFFF (UINT16) for %s . " % " . " . join ( ( TokenSpaceGuid , PcdCName ) ) ,
File = self . MetaFile , Line = Dummy4 )
if int ( MaxDatumSize , 0 ) < 0 :
EdkLogger . error ( ' build ' , FORMAT_INVALID , " The size value can ' t be set to negative value for %s . " % " . " . join ( ( TokenSpaceGuid , PcdCName ) ) ,
File = self . MetaFile , Line = Dummy4 )
SkuInfo = SkuInfoClass ( SkuName , self . SkuIds [ SkuName ] [ 0 ] , ' ' , ' ' , ' ' , ' ' , ' ' , PcdValue )
if ( PcdCName , TokenSpaceGuid ) in Pcds :
pcdObject = Pcds [ PcdCName , TokenSpaceGuid ]
pcdObject . SkuInfoList [ SkuName ] = SkuInfo
if MaxDatumSize . strip ( ) :
CurrentMaxSize = int ( MaxDatumSize . strip ( ) , 0 )
else :
CurrentMaxSize = 0
if pcdObject . MaxDatumSize :
PcdMaxSize = int ( pcdObject . MaxDatumSize , 0 )
else :
PcdMaxSize = 0
if CurrentMaxSize > PcdMaxSize :
pcdObject . MaxDatumSize = str ( CurrentMaxSize )
else :
Pcds [ PcdCName , TokenSpaceGuid ] = PcdClassObject (
PcdCName ,
TokenSpaceGuid ,
self . _PCD_TYPE_STRING_ [ Type ] ,
DatumType ,
PcdValue ,
' ' ,
MaxDatumSize ,
OrderedDict ( { SkuName : SkuInfo } ) ,
False ,
None ,
IsDsc = True )
if SkuName not in Pcds [ PcdCName , TokenSpaceGuid ] . DscRawValue :
Pcds [ PcdCName , TokenSpaceGuid ] . DscRawValue [ SkuName ] = { }
Pcds [ PcdCName , TokenSpaceGuid ] . DscRawValueInfo [ SkuName ] = { }
Pcds [ PcdCName , TokenSpaceGuid ] . DscRawValue [ SkuName ] [ TAB_DEFAULT_STORES_DEFAULT ] = PcdValue
Pcds [ PcdCName , TokenSpaceGuid ] . DscRawValueInfo [ SkuName ] [ TAB_DEFAULT_STORES_DEFAULT ] = ( self . MetaFile . File , Dummy4 )
for pcd in Pcds . values ( ) :
pcdDecObject = self . _DecPcds [ pcd . TokenCName , pcd . TokenSpaceGuidCName ]
# Only fix the value while no value provided in DSC file.
for sku in pcd . SkuInfoList . values ( ) :
if not sku . DefaultValue :
sku . DefaultValue = pcdDecObject . DefaultValue
if TAB_DEFAULT not in pcd . SkuInfoList and TAB_COMMON not in pcd . SkuInfoList :
valuefromDec = pcdDecObject . DefaultValue
SkuInfo = SkuInfoClass ( TAB_DEFAULT , ' 0 ' , ' ' , ' ' , ' ' , ' ' , ' ' , valuefromDec )
pcd . SkuInfoList [ TAB_DEFAULT ] = SkuInfo
elif TAB_DEFAULT not in pcd . SkuInfoList and TAB_COMMON in pcd . SkuInfoList :
pcd . SkuInfoList [ TAB_DEFAULT ] = pcd . SkuInfoList [ TAB_COMMON ]
del pcd . SkuInfoList [ TAB_COMMON ]
elif TAB_DEFAULT in pcd . SkuInfoList and TAB_COMMON in pcd . SkuInfoList :
del pcd . SkuInfoList [ TAB_COMMON ]
list ( map ( self . FilterSkuSettings , Pcds . values ( ) ) )
return Pcds
def FilterSkuSettings ( self , PcdObj ) :
if self . SkuIdMgr . SkuUsageType == self . SkuIdMgr . SINGLE :
if TAB_DEFAULT in PcdObj . SkuInfoList and self . SkuIdMgr . SystemSkuId not in PcdObj . SkuInfoList :
PcdObj . SkuInfoList [ self . SkuIdMgr . SystemSkuId ] = PcdObj . SkuInfoList [ TAB_DEFAULT ]
PcdObj . SkuInfoList = { TAB_DEFAULT : PcdObj . SkuInfoList [ self . SkuIdMgr . SystemSkuId ] }
PcdObj . SkuInfoList [ TAB_DEFAULT ] . SkuIdName = TAB_DEFAULT
PcdObj . SkuInfoList [ TAB_DEFAULT ] . SkuId = ' 0 '
elif self . SkuIdMgr . SkuUsageType == self . SkuIdMgr . DEFAULT :
PcdObj . SkuInfoList = { TAB_DEFAULT : PcdObj . SkuInfoList [ TAB_DEFAULT ] }
return PcdObj
@staticmethod
def CompareVarAttr ( Attr1 , Attr2 ) :
if not Attr1 or not Attr2 : # for empty string
return True
Attr1s = [ attr . strip ( ) for attr in Attr1 . split ( " , " ) ]
Attr1Set = set ( Attr1s )
Attr2s = [ attr . strip ( ) for attr in Attr2 . split ( " , " ) ]
Attr2Set = set ( Attr2s )
if Attr2Set == Attr1Set :
return True
else :
return False
def CompletePcdValues ( self , PcdSet ) :
Pcds = OrderedDict ( )
DefaultStoreObj = DefaultStore ( self . _GetDefaultStores ( ) )
SkuIds = { skuname : skuid for skuname , skuid in self . SkuIdMgr . AvailableSkuIdSet . items ( ) if skuname != TAB_COMMON }
DefaultStores = set ( storename for pcdobj in PcdSet . values ( ) for skuobj in pcdobj . SkuInfoList . values ( ) for storename in skuobj . DefaultStoreDict )
for PcdCName , TokenSpaceGuid in PcdSet :
PcdObj = PcdSet [ ( PcdCName , TokenSpaceGuid ) ]
if PcdObj . Type not in [ self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_DEFAULT ] ,
self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_HII ] ,
self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_VPD ] ,
self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_EX_DEFAULT ] ,
self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_EX_HII ] ,
self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_EX_VPD ] ] :
Pcds [ PcdCName , TokenSpaceGuid ] = PcdObj
continue
PcdType = PcdObj . Type
if PcdType in [ self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_HII ] , self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_EX_HII ] ] :
for skuid in PcdObj . SkuInfoList :
skuobj = PcdObj . SkuInfoList [ skuid ]
mindefaultstorename = DefaultStoreObj . GetMin ( set ( defaultstorename for defaultstorename in skuobj . DefaultStoreDict ) )
for defaultstorename in DefaultStores :
if defaultstorename not in skuobj . DefaultStoreDict :
skuobj . DefaultStoreDict [ defaultstorename ] = skuobj . DefaultStoreDict [ mindefaultstorename ]
skuobj . HiiDefaultValue = skuobj . DefaultStoreDict [ mindefaultstorename ]
for skuname , skuid in SkuIds . items ( ) :
if skuname not in PcdObj . SkuInfoList :
nextskuid = self . SkuIdMgr . GetNextSkuId ( skuname )
while nextskuid not in PcdObj . SkuInfoList :
nextskuid = self . SkuIdMgr . GetNextSkuId ( nextskuid )
PcdObj . SkuInfoList [ skuname ] = copy . deepcopy ( PcdObj . SkuInfoList [ nextskuid ] )
PcdObj . SkuInfoList [ skuname ] . SkuId = skuid
PcdObj . SkuInfoList [ skuname ] . SkuIdName = skuname
if PcdType in [ self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_HII ] , self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_EX_HII ] ] :
PcdObj . DefaultValue = list ( PcdObj . SkuInfoList . values ( ) ) [ 0 ] . HiiDefaultValue if self . SkuIdMgr . SkuUsageType == self . SkuIdMgr . SINGLE else PcdObj . SkuInfoList [ TAB_DEFAULT ] . HiiDefaultValue
Pcds [ PcdCName , TokenSpaceGuid ] = PcdObj
return Pcds
## Retrieve dynamic HII PCD settings
#
# @param Type PCD type
#
# @retval a dict object contains settings of given PCD type
#
def _GetDynamicHiiPcd ( self , Type ) :
VariableAttrs = { }
Pcds = OrderedDict ( )
UserDefinedDefaultStores = [ ]
#
# tdict is a special dict kind of type, used for selecting correct
# PCD settings for certain ARCH and SKU
#
PcdDict = tdict ( True , 5 )
PcdList = [ ]
RecordList = self . _RawData [ Type , self . _Arch ]
# Find out all possible PCD candidates for self._Arch
AvailableSkuIdSet = copy . copy ( self . SkuIds )
DefaultStoresDefine = self . _GetDefaultStores ( )
for TokenSpaceGuid , PcdCName , Setting , Arch , SkuName , DefaultStore , Dummy4 , Dummy5 in RecordList :
SkuName = SkuName . upper ( )
SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
DefaultStore = DefaultStore . upper ( )
if DefaultStore == TAB_COMMON :
DefaultStore = TAB_DEFAULT_STORES_DEFAULT
else :
#The end user define [DefaultStores] and [SKUID_IDENTIFIER.Menufacturing] in DSC
UserDefinedDefaultStores . append ( ( PcdCName , TokenSpaceGuid ) )
if SkuName not in AvailableSkuIdSet :
EdkLogger . error ( ' build ' , PARAMETER_INVALID , ' Sku %s is not defined in [SkuIds] section ' % SkuName ,
File = self . MetaFile , Line = Dummy5 )
if DefaultStore not in DefaultStoresDefine :
EdkLogger . error ( ' build ' , PARAMETER_INVALID , ' DefaultStores %s is not defined in [DefaultStores] section ' % DefaultStore ,
File = self . MetaFile , Line = Dummy5 )
if " . " not in TokenSpaceGuid and " [ " not in PcdCName and ( PcdCName , TokenSpaceGuid , SkuName , DefaultStore , Dummy5 ) not in PcdList :
PcdList . append ( ( PcdCName , TokenSpaceGuid , SkuName , DefaultStore , Dummy5 ) )
PcdDict [ Arch , SkuName , PcdCName , TokenSpaceGuid , DefaultStore ] = Setting
# Remove redundant PCD candidates, per the ARCH and SKU
2019-09-20 06:56:20 +02:00
for index , ( PcdCName , TokenSpaceGuid , SkuName , DefaultStore , Dummy4 ) in enumerate ( PcdList ) :
2019-09-03 11:58:42 +02:00
Setting = PcdDict [ self . _Arch , SkuName , PcdCName , TokenSpaceGuid , DefaultStore ]
if Setting is None :
continue
VariableName , VariableGuid , VariableOffset , DefaultValue , VarAttribute = self . _ValidatePcd ( PcdCName , TokenSpaceGuid , Setting , Type , Dummy4 )
rt , Msg = VariableAttributes . ValidateVarAttributes ( VarAttribute )
if not rt :
EdkLogger . error ( " build " , PCD_VARIABLE_ATTRIBUTES_ERROR , " Variable attributes settings for %s is incorrect. \n %s " % ( " . " . join ( ( TokenSpaceGuid , PcdCName ) ) , Msg ) ,
ExtraData = " [ %s ] " % VarAttribute )
ExceedMax = False
FormatCorrect = True
if VariableOffset . isdigit ( ) :
if int ( VariableOffset , 10 ) > 0xFFFF :
ExceedMax = True
elif variablePattern . match ( VariableOffset ) :
if int ( VariableOffset , 16 ) > 0xFFFF :
ExceedMax = True
# For Offset written in "A.B"
elif VariableOffset . find ( ' . ' ) > - 1 :
VariableOffsetList = VariableOffset . split ( " . " )
if not ( len ( VariableOffsetList ) == 2
and IsValidWord ( VariableOffsetList [ 0 ] )
and IsValidWord ( VariableOffsetList [ 1 ] ) ) :
FormatCorrect = False
else :
FormatCorrect = False
if not FormatCorrect :
EdkLogger . error ( ' Build ' , FORMAT_INVALID , " Invalid syntax or format of the variable offset value is incorrect for %s . " % " . " . join ( ( TokenSpaceGuid , PcdCName ) ) )
if ExceedMax :
EdkLogger . error ( ' Build ' , OPTION_VALUE_INVALID , " The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s . " % " . " . join ( ( TokenSpaceGuid , PcdCName ) ) )
if ( VariableName , VariableGuid ) not in VariableAttrs :
VariableAttrs [ ( VariableName , VariableGuid ) ] = VarAttribute
else :
if not DscBuildData . CompareVarAttr ( VariableAttrs [ ( VariableName , VariableGuid ) ] , VarAttribute ) :
EdkLogger . error ( ' Build ' , PCD_VARIABLE_ATTRIBUTES_CONFLICT_ERROR , " The variable %s . %s for DynamicHii PCDs has conflicting attributes [ %s ] and [ %s ] " % ( VariableGuid , VariableName , VarAttribute , VariableAttrs [ ( VariableName , VariableGuid ) ] ) )
pcdDecObject = self . _DecPcds [ PcdCName , TokenSpaceGuid ]
if ( PcdCName , TokenSpaceGuid ) in Pcds :
pcdObject = Pcds [ PcdCName , TokenSpaceGuid ]
if SkuName in pcdObject . SkuInfoList :
Skuitem = pcdObject . SkuInfoList [ SkuName ]
Skuitem . DefaultStoreDict . update ( { DefaultStore : DefaultValue } )
else :
SkuInfo = SkuInfoClass ( SkuName , self . SkuIds [ SkuName ] [ 0 ] , VariableName , VariableGuid , VariableOffset , DefaultValue , VariableAttribute = VarAttribute , DefaultStore = { DefaultStore : DefaultValue } )
pcdObject . SkuInfoList [ SkuName ] = SkuInfo
else :
SkuInfo = SkuInfoClass ( SkuName , self . SkuIds [ SkuName ] [ 0 ] , VariableName , VariableGuid , VariableOffset , DefaultValue , VariableAttribute = VarAttribute , DefaultStore = { DefaultStore : DefaultValue } )
PcdClassObj = PcdClassObject (
PcdCName ,
TokenSpaceGuid ,
self . _PCD_TYPE_STRING_ [ Type ] ,
' ' ,
DefaultValue ,
' ' ,
' ' ,
OrderedDict ( { SkuName : SkuInfo } ) ,
False ,
None ,
pcdDecObject . validateranges ,
pcdDecObject . validlists ,
pcdDecObject . expressions ,
IsDsc = True )
if ( PcdCName , TokenSpaceGuid ) in UserDefinedDefaultStores :
PcdClassObj . UserDefinedDefaultStoresFlag = True
Pcds [ PcdCName , TokenSpaceGuid ] = PcdClassObj
2019-09-20 06:56:20 +02:00
Pcds [ PcdCName , TokenSpaceGuid ] . CustomAttribute [ ' DscPosition ' ] = index
2019-09-03 11:58:42 +02:00
if SkuName not in Pcds [ PcdCName , TokenSpaceGuid ] . DscRawValue :
Pcds [ PcdCName , TokenSpaceGuid ] . DscRawValue [ SkuName ] = { }
Pcds [ PcdCName , TokenSpaceGuid ] . DscRawValueInfo [ SkuName ] = { }
Pcds [ PcdCName , TokenSpaceGuid ] . DscRawValue [ SkuName ] [ DefaultStore ] = DefaultValue
Pcds [ PcdCName , TokenSpaceGuid ] . DscRawValueInfo [ SkuName ] [ DefaultStore ] = ( self . MetaFile . File , Dummy4 )
for pcd in Pcds . values ( ) :
pcdDecObject = self . _DecPcds [ pcd . TokenCName , pcd . TokenSpaceGuidCName ]
pcd . DatumType = pcdDecObject . DatumType
# Only fix the value while no value provided in DSC file.
for sku in pcd . SkuInfoList . values ( ) :
if ( sku . HiiDefaultValue == " " or sku . HiiDefaultValue is None ) :
sku . HiiDefaultValue = pcdDecObject . DefaultValue
for default_store in sku . DefaultStoreDict :
sku . DefaultStoreDict [ default_store ] = pcdDecObject . DefaultValue
pcd . DefaultValue = pcdDecObject . DefaultValue
if TAB_DEFAULT not in pcd . SkuInfoList and TAB_COMMON not in pcd . SkuInfoList :
SkuInfoObj = list ( pcd . SkuInfoList . values ( ) ) [ 0 ]
valuefromDec = pcdDecObject . DefaultValue
SkuInfo = SkuInfoClass ( TAB_DEFAULT , ' 0 ' , SkuInfoObj . VariableName , SkuInfoObj . VariableGuid , SkuInfoObj . VariableOffset , valuefromDec , VariableAttribute = SkuInfoObj . VariableAttribute , DefaultStore = { DefaultStore : valuefromDec } )
pcd . SkuInfoList [ TAB_DEFAULT ] = SkuInfo
elif TAB_DEFAULT not in pcd . SkuInfoList and TAB_COMMON in pcd . SkuInfoList :
pcd . SkuInfoList [ TAB_DEFAULT ] = pcd . SkuInfoList [ TAB_COMMON ]
del pcd . SkuInfoList [ TAB_COMMON ]
elif TAB_DEFAULT in pcd . SkuInfoList and TAB_COMMON in pcd . SkuInfoList :
del pcd . SkuInfoList [ TAB_COMMON ]
if pcd . MaxDatumSize . strip ( ) :
MaxSize = int ( pcd . MaxDatumSize , 0 )
else :
MaxSize = 0
if pcd . DatumType not in TAB_PCD_NUMERIC_TYPES :
for ( _ , skuobj ) in pcd . SkuInfoList . items ( ) :
datalen = 0
skuobj . HiiDefaultValue = StringToArray ( skuobj . HiiDefaultValue )
datalen = len ( skuobj . HiiDefaultValue . split ( " , " ) )
if datalen > MaxSize :
MaxSize = datalen
for defaultst in skuobj . DefaultStoreDict :
skuobj . DefaultStoreDict [ defaultst ] = StringToArray ( skuobj . DefaultStoreDict [ defaultst ] )
pcd . DefaultValue = StringToArray ( pcd . DefaultValue )
pcd . MaxDatumSize = str ( MaxSize )
rt , invalidhii = DscBuildData . CheckVariableNameAssignment ( Pcds )
if not rt :
invalidpcd = " , " . join ( invalidhii )
EdkLogger . error ( ' build ' , PCD_VARIABLE_INFO_ERROR , Message = ' The same HII PCD must map to the same EFI variable for all SKUs ' , File = self . MetaFile , ExtraData = invalidpcd )
list ( map ( self . FilterSkuSettings , Pcds . values ( ) ) )
return Pcds
@staticmethod
def CheckVariableNameAssignment ( Pcds ) :
invalidhii = [ ]
for pcdname in Pcds :
pcd = Pcds [ pcdname ]
varnameset = set ( sku . VariableName for ( skuid , sku ) in pcd . SkuInfoList . items ( ) )
if len ( varnameset ) > 1 :
invalidhii . append ( " . " . join ( ( pcdname [ 1 ] , pcdname [ 0 ] ) ) )
if len ( invalidhii ) :
return False , invalidhii
else :
return True , [ ]
## Retrieve dynamic VPD PCD settings
#
# @param Type PCD type
#
# @retval a dict object contains settings of given PCD type
#
def _GetDynamicVpdPcd ( self , Type ) :
Pcds = OrderedDict ( )
#
# tdict is a special dict kind of type, used for selecting correct
# PCD settings for certain ARCH and SKU
#
PcdDict = tdict ( True , 4 )
PcdList = [ ]
# Find out all possible PCD candidates for self._Arch
RecordList = self . _RawData [ Type , self . _Arch ]
AvailableSkuIdSet = copy . copy ( self . SkuIds )
for TokenSpaceGuid , PcdCName , Setting , Arch , SkuName , Dummy3 , Dummy4 , Dummy5 in RecordList :
SkuName = SkuName . upper ( )
SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
if SkuName not in AvailableSkuIdSet :
EdkLogger . error ( ' build ' , PARAMETER_INVALID , ' Sku %s is not defined in [SkuIds] section ' % SkuName ,
File = self . MetaFile , Line = Dummy5 )
if " . " not in TokenSpaceGuid and " [ " not in PcdCName and ( PcdCName , TokenSpaceGuid , SkuName , Dummy5 ) not in PcdList :
PcdList . append ( ( PcdCName , TokenSpaceGuid , SkuName , Dummy5 ) )
PcdDict [ Arch , SkuName , PcdCName , TokenSpaceGuid ] = Setting
# Remove redundant PCD candidates, per the ARCH and SKU
for PcdCName , TokenSpaceGuid , SkuName , Dummy4 in PcdList :
Setting = PcdDict [ self . _Arch , SkuName , PcdCName , TokenSpaceGuid ]
if Setting is None :
continue
#
# For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
# For the Integer & Boolean type, the optional data can only be InitialValue.
# At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
# until the DEC parser has been called.
#
VpdOffset , MaxDatumSize , InitialValue = self . _ValidatePcd ( PcdCName , TokenSpaceGuid , Setting , Type , Dummy4 )
if MaxDatumSize :
if int ( MaxDatumSize , 0 ) > 0xFFFF :
EdkLogger . error ( ' build ' , FORMAT_INVALID , " The size value must not exceed the maximum value of 0xFFFF (UINT16) for %s . " % " . " . join ( ( TokenSpaceGuid , PcdCName ) ) ,
File = self . MetaFile , Line = Dummy4 )
if int ( MaxDatumSize , 0 ) < 0 :
EdkLogger . error ( ' build ' , FORMAT_INVALID , " The size value can ' t be set to negative value for %s . " % " . " . join ( ( TokenSpaceGuid , PcdCName ) ) ,
File = self . MetaFile , Line = Dummy4 )
SkuInfo = SkuInfoClass ( SkuName , self . SkuIds [ SkuName ] [ 0 ] , ' ' , ' ' , ' ' , ' ' , VpdOffset , InitialValue )
if ( PcdCName , TokenSpaceGuid ) in Pcds :
pcdObject = Pcds [ PcdCName , TokenSpaceGuid ]
pcdObject . SkuInfoList [ SkuName ] = SkuInfo
if MaxDatumSize . strip ( ) :
CurrentMaxSize = int ( MaxDatumSize . strip ( ) , 0 )
else :
CurrentMaxSize = 0
if pcdObject . MaxDatumSize :
PcdMaxSize = int ( pcdObject . MaxDatumSize , 0 )
else :
PcdMaxSize = 0
if CurrentMaxSize > PcdMaxSize :
pcdObject . MaxDatumSize = str ( CurrentMaxSize )
else :
Pcds [ PcdCName , TokenSpaceGuid ] = PcdClassObject (
PcdCName ,
TokenSpaceGuid ,
self . _PCD_TYPE_STRING_ [ Type ] ,
' ' ,
InitialValue ,
' ' ,
MaxDatumSize ,
OrderedDict ( { SkuName : SkuInfo } ) ,
False ,
None ,
IsDsc = True )
if SkuName not in Pcds [ PcdCName , TokenSpaceGuid ] . DscRawValue :
Pcds [ PcdCName , TokenSpaceGuid ] . DscRawValue [ SkuName ] = { }
Pcds [ PcdCName , TokenSpaceGuid ] . DscRawValueInfo [ SkuName ] = { }
Pcds [ PcdCName , TokenSpaceGuid ] . DscRawValue [ SkuName ] [ TAB_DEFAULT_STORES_DEFAULT ] = InitialValue
Pcds [ PcdCName , TokenSpaceGuid ] . DscRawValueInfo [ SkuName ] [ TAB_DEFAULT_STORES_DEFAULT ] = ( self . MetaFile . File , Dummy4 )
for pcd in Pcds . values ( ) :
pcdDecObject = self . _DecPcds [ pcd . TokenCName , pcd . TokenSpaceGuidCName ]
pcd . DatumType = pcdDecObject . DatumType
# Only fix the value while no value provided in DSC file.
for sku in pcd . SkuInfoList . values ( ) :
if not sku . DefaultValue :
sku . DefaultValue = pcdDecObject . DefaultValue
if TAB_DEFAULT not in pcd . SkuInfoList and TAB_COMMON not in pcd . SkuInfoList :
SkuInfoObj = list ( pcd . SkuInfoList . values ( ) ) [ 0 ]
valuefromDec = pcdDecObject . DefaultValue
SkuInfo = SkuInfoClass ( TAB_DEFAULT , ' 0 ' , ' ' , ' ' , ' ' , ' ' , SkuInfoObj . VpdOffset , valuefromDec )
pcd . SkuInfoList [ TAB_DEFAULT ] = SkuInfo
elif TAB_DEFAULT not in pcd . SkuInfoList and TAB_COMMON in pcd . SkuInfoList :
pcd . SkuInfoList [ TAB_DEFAULT ] = pcd . SkuInfoList [ TAB_COMMON ]
del pcd . SkuInfoList [ TAB_COMMON ]
elif TAB_DEFAULT in pcd . SkuInfoList and TAB_COMMON in pcd . SkuInfoList :
del pcd . SkuInfoList [ TAB_COMMON ]
#For the same one VOID* pcd, if the default value type of one SKU is "Unicode string",
#the other SKUs are "OtherVOID*"(ASCII string or byte array),Then convert "Unicode string" to "byte array".
for pcd in Pcds . values ( ) :
PcdValueTypeSet = set ( )
for sku in pcd . SkuInfoList . values ( ) :
PcdValueTypeSet . add ( " UnicodeString " if sku . DefaultValue . startswith ( ( ' L " ' , " L ' " ) ) else " OtherVOID* " )
if len ( PcdValueTypeSet ) > 1 :
for sku in pcd . SkuInfoList . values ( ) :
sku . DefaultValue = StringToArray ( sku . DefaultValue ) if sku . DefaultValue . startswith ( ( ' L " ' , " L ' " ) ) else sku . DefaultValue
list ( map ( self . FilterSkuSettings , Pcds . values ( ) ) )
return Pcds
## Add external modules
#
# The external modules are mostly those listed in FDF file, which don't
# need "build".
#
# @param FilePath The path of module description file
#
def AddModule ( self , FilePath ) :
FilePath = NormPath ( FilePath )
if FilePath not in self . Modules :
Module = ModuleBuildClassObject ( )
Module . MetaFile = FilePath
self . Modules . append ( Module )
@property
def ToolChainFamily ( self ) :
self . _ToolChainFamily = TAB_COMPILER_MSFT
BuildConfigurationFile = os . path . normpath ( os . path . join ( GlobalData . gConfDirectory , " target.txt " ) )
if os . path . isfile ( BuildConfigurationFile ) == True :
ToolDefinitionFile = TargetTxt . TargetTxtDictionary [ DataType . TAB_TAT_DEFINES_TOOL_CHAIN_CONF ]
if ToolDefinitionFile == ' ' :
ToolDefinitionFile = " tools_def.txt "
ToolDefinitionFile = os . path . normpath ( mws . join ( self . WorkspaceDir , ' Conf ' , ToolDefinitionFile ) )
if os . path . isfile ( ToolDefinitionFile ) == True :
ToolDefinition = ToolDef . ToolsDefTxtDatabase
if TAB_TOD_DEFINES_FAMILY not in ToolDefinition \
or self . _Toolchain not in ToolDefinition [ TAB_TOD_DEFINES_FAMILY ] \
or not ToolDefinition [ TAB_TOD_DEFINES_FAMILY ] [ self . _Toolchain ] :
self . _ToolChainFamily = TAB_COMPILER_MSFT
else :
self . _ToolChainFamily = ToolDefinition [ TAB_TOD_DEFINES_FAMILY ] [ self . _Toolchain ]
return self . _ToolChainFamily
## Add external PCDs
#
# The external PCDs are mostly those listed in FDF file to specify address
# or offset information.
#
# @param Name Name of the PCD
# @param Guid Token space guid of the PCD
# @param Value Value of the PCD
#
def AddPcd ( self , Name , Guid , Value ) :
if ( Name , Guid ) not in self . Pcds :
self . Pcds [ Name , Guid ] = PcdClassObject ( Name , Guid , ' ' , ' ' , ' ' , ' ' , ' ' , { } , False , None )
self . Pcds [ Name , Guid ] . DefaultValue = Value
@property
def DecPcds ( self ) :
if self . _DecPcds is None :
FdfInfList = [ ]
if GlobalData . gFdfParser :
FdfInfList = GlobalData . gFdfParser . Profile . InfList
PkgSet = set ( )
for Inf in FdfInfList :
ModuleFile = PathClass ( NormPath ( Inf ) , GlobalData . gWorkspace , Arch = self . _Arch )
if ModuleFile in self . _Modules :
continue
ModuleData = self . _Bdb [ ModuleFile , self . _Arch , self . _Target , self . _Toolchain ]
PkgSet . update ( ModuleData . Packages )
self . _DecPcds , self . _GuidDict = GetDeclaredPcd ( self , self . _Bdb , self . _Arch , self . _Target , self . _Toolchain , PkgSet )
self . _GuidDict . update ( GlobalData . gPlatformPcds )
return self . _DecPcds