2017-11-24 07:30:11 +01:00
## @file
# This file is used to create a database used by build tool
#
2017-12-26 06:24:20 +01:00
# Copyright (c) 2008 - 2017, Intel Corporation. All rights reserved.<BR>
2017-11-24 07:30:11 +01:00
# (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
## 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 Common . String import *
from Common . DataType import *
from Common . Misc import *
from types import *
from CommonDataClass . CommonClass import SkuInfoClass
from MetaDataTable import *
from MetaFileTable import *
from MetaFileParser import *
from WorkspaceCommon import GetDeclaredPcd
from Common . Misc import AnalyzeDscPcd
from Common . Misc import ProcessDuplicatedInf
import re
from Common . Parsing import IsValidWord
from Common . VariableAttributes import VariableAttributes
import Common . GlobalData as GlobalData
import subprocess
from Workspace . BuildClassObject import PlatformBuildClassObject , StructurePcd , PcdClassObject , ModuleBuildClassObject
#
# Treat CHAR16 as a synonym for UINT16. CHAR16 support is required for VFR C structs
#
PcdValueInitName = ' PcdValueInit '
PcdSupportedBaseTypes = [ ' BOOLEAN ' , ' UINT8 ' , ' UINT16 ' , ' UINT32 ' , ' UINT64 ' , ' CHAR16 ' ]
PcdSupportedBaseTypeWidth = { ' BOOLEAN ' : 8 , ' UINT8 ' : 8 , ' UINT16 ' : 16 , ' UINT32 ' : 32 , ' UINT64 ' : 64 }
PcdUnsupportedBaseTypes = [ ' INT8 ' , ' INT16 ' , ' INT32 ' , ' INT64 ' , ' CHAR8 ' , ' UINTN ' , ' INTN ' , ' VOID ' ]
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
#
'''
PcdMakefileEnd = '''
! INCLUDE $ ( BASE_TOOLS_PATH ) \Source \C \Makefiles \ms . common
CFLAGS = $ ( CFLAGS ) / wd4200 / wd4034 / wd4101
LIBS = $ ( LIB_PATH ) \Common . lib
! INCLUDE $ ( BASE_TOOLS_PATH ) \Source \C \Makefiles \ms . app
'''
PcdGccMakefile = '''
ARCH ? = IA32
MAKEROOT ? = $ ( EDK_TOOLS_PATH ) / Source / C
LIBS = - lCommon
'''
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 : " FixedAtBuild " ,
MODEL_PCD_PATCHABLE_IN_MODULE : " PatchableInModule " ,
MODEL_PCD_FEATURE_FLAG : " FeatureFlag " ,
MODEL_PCD_DYNAMIC : " Dynamic " ,
MODEL_PCD_DYNAMIC_DEFAULT : " Dynamic " ,
MODEL_PCD_DYNAMIC_HII : " DynamicHii " ,
MODEL_PCD_DYNAMIC_VPD : " DynamicVpd " ,
MODEL_PCD_DYNAMIC_EX : " DynamicEx " ,
MODEL_PCD_DYNAMIC_EX_DEFAULT : " DynamicEx " ,
MODEL_PCD_DYNAMIC_EX_HII : " DynamicExHii " ,
MODEL_PCD_DYNAMIC_EX_VPD : " DynamicExVpd " ,
}
# 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 = ' COMMON ' , Target = None , Toolchain = None ) :
self . MetaFile = FilePath
self . _RawData = RawData
self . _Bdb = BuildDataBase
self . _Arch = Arch
self . _Target = Target
self . _Toolchain = Toolchain
self . _Clear ( )
self . _HandleOverridePath ( )
if os . getenv ( " WORKSPACE " ) :
self . OutputPath = os . path . join ( os . getenv ( " WORKSPACE " ) , ' Build ' , PcdValueInitName )
else :
self . OutputPath = os . path . dirname ( self . DscFile )
2017-12-22 13:46:15 +01:00
self . DefaultStores = None
2017-12-22 13:07:54 +01:00
self . SkuIdMgr = SkuClass ( self . SkuName , self . SkuIds )
2017-12-22 13:46:15 +01:00
arraystr = self . SkuIdMgr . DumpSkuIdArrary ( )
2017-11-24 07:30:11 +01:00
## 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 . __Macros = None
2017-12-22 13:46:15 +01:00
self . DefaultStores = None
2017-11-24 07:30:11 +01:00
## handle Override Path of Module
def _HandleOverridePath ( self ) :
RecordList = self . _RawData [ MODEL_META_DATA_COMPONENT , self . _Arch ]
Macros = self . _Macros
Macros [ " EDK_SOURCE " ] = GlobalData . gEcpSource
for Record in RecordList :
2017-12-22 13:46:15 +01:00
ModuleId = Record [ 6 ]
LineNo = Record [ 7 ]
2017-11-24 07:30:11 +01:00
ModuleFile = PathClass ( NormPath ( Record [ 0 ] ) , GlobalData . gWorkspace , Arch = self . _Arch )
RecordList = self . _RawData [ MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH , self . _Arch , None , ModuleId ]
if RecordList != [ ] :
SourceOverridePath = mws . join ( GlobalData . gWorkspace , NormPath ( RecordList [ 0 ] [ 0 ] ) )
# Check if the source override path exists
if not os . path . isdir ( SourceOverridePath ) :
EdkLogger . error ( ' build ' , FILE_NOT_FOUND , Message = ' Source override path does not exist: ' , File = self . MetaFile , ExtraData = SourceOverridePath , Line = LineNo )
# Add to GlobalData Variables
GlobalData . gOverrideDir [ ModuleFile . Key ] = SourceOverridePath
## Get current effective macros
def _GetMacros ( self ) :
if self . __Macros == None :
self . __Macros = { }
self . __Macros . update ( GlobalData . gPlatformDefines )
self . __Macros . update ( GlobalData . gGlobalDefines )
self . __Macros . update ( GlobalData . gCommandLineDefines )
return self . __Macros
## Get architecture
def _GetArch ( self ) :
return self . _Arch
## Set architecture
#
# Changing the default ARCH to another may affect all other information
# because all information in a platform may be ARCH-related. That's
# why we need to clear all internal used members, in order to cause all
# information to be re-retrieved.
#
# @param Value The value of ARCH
#
def _SetArch ( self , Value ) :
if self . _Arch == Value :
return
self . _Arch = Value
self . _Clear ( )
## Retrieve all information in [Defines] section
#
# (Retriving 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 == None :
self . _SkuName = Record [ 2 ]
2017-12-22 13:07:54 +01:00
if GlobalData . gSKUID_CMD :
self . _SkuName = GlobalData . gSKUID_CMD
2017-11-24 07:30:11 +01:00
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
def _GetPlatformName ( self ) :
if self . _PlatformName == None :
if self . _Header == None :
self . _GetHeaderInfo ( )
if self . _PlatformName == None :
EdkLogger . error ( ' build ' , ATTRIBUTE_NOT_AVAILABLE , " No PLATFORM_NAME " , File = self . MetaFile )
return self . _PlatformName
## Retrieve file guid
def _GetFileGuid ( self ) :
if self . _Guid == None :
if self . _Header == None :
self . _GetHeaderInfo ( )
if self . _Guid == None :
EdkLogger . error ( ' build ' , ATTRIBUTE_NOT_AVAILABLE , " No PLATFORM_GUID " , File = self . MetaFile )
return self . _Guid
## Retrieve platform version
def _GetVersion ( self ) :
if self . _Version == None :
if self . _Header == None :
self . _GetHeaderInfo ( )
if self . _Version == None :
EdkLogger . error ( ' build ' , ATTRIBUTE_NOT_AVAILABLE , " No PLATFORM_VERSION " , File = self . MetaFile )
return self . _Version
## Retrieve platform description file version
def _GetDscSpec ( self ) :
if self . _DscSpecification == None :
if self . _Header == None :
self . _GetHeaderInfo ( )
if self . _DscSpecification == None :
EdkLogger . error ( ' build ' , ATTRIBUTE_NOT_AVAILABLE , " No DSC_SPECIFICATION " , File = self . MetaFile )
return self . _DscSpecification
## Retrieve OUTPUT_DIRECTORY
def _GetOutpuDir ( self ) :
if self . _OutputDirectory == None :
if self . _Header == None :
self . _GetHeaderInfo ( )
if self . _OutputDirectory == None :
self . _OutputDirectory = os . path . join ( " Build " , self . _PlatformName )
return self . _OutputDirectory
## Retrieve SUPPORTED_ARCHITECTURES
def _GetSupArch ( self ) :
if self . _SupArchList == None :
if self . _Header == None :
self . _GetHeaderInfo ( )
if self . _SupArchList == None :
EdkLogger . error ( ' build ' , ATTRIBUTE_NOT_AVAILABLE , " No SUPPORTED_ARCHITECTURES " , File = self . MetaFile )
return self . _SupArchList
## Retrieve BUILD_TARGETS
def _GetBuildTarget ( self ) :
if self . _BuildTargets == None :
if self . _Header == None :
self . _GetHeaderInfo ( )
if self . _BuildTargets == None :
EdkLogger . error ( ' build ' , ATTRIBUTE_NOT_AVAILABLE , " No BUILD_TARGETS " , File = self . MetaFile )
return self . _BuildTargets
def _GetPcdInfoFlag ( self ) :
if self . _PcdInfoFlag == None or self . _PcdInfoFlag . upper ( ) == ' FALSE ' :
return False
elif self . _PcdInfoFlag . upper ( ) == ' TRUE ' :
return True
else :
return False
def _GetVarCheckFlag ( self ) :
if self . _VarCheckFlag == None or self . _VarCheckFlag . upper ( ) == ' FALSE ' :
return False
elif self . _VarCheckFlag . upper ( ) == ' TRUE ' :
return True
else :
return False
2017-12-22 13:07:54 +01:00
# # Retrieve SKUID_IDENTIFIER
2017-11-24 07:30:11 +01:00
def _GetSkuName ( self ) :
if self . _SkuName == None :
if self . _Header == None :
self . _GetHeaderInfo ( )
2017-12-22 13:07:54 +01:00
if self . _SkuName == None :
2017-11-24 07:30:11 +01:00
self . _SkuName = ' DEFAULT '
return self . _SkuName
## Override SKUID_IDENTIFIER
def _SetSkuName ( self , Value ) :
self . _SkuName = Value
self . _Pcds = None
def _GetFdfFile ( self ) :
if self . _FlashDefinition == None :
if self . _Header == None :
self . _GetHeaderInfo ( )
if self . _FlashDefinition == None :
self . _FlashDefinition = ' '
return self . _FlashDefinition
def _GetPrebuild ( self ) :
if self . _Prebuild == None :
if self . _Header == None :
self . _GetHeaderInfo ( )
if self . _Prebuild == None :
self . _Prebuild = ' '
return self . _Prebuild
def _GetPostbuild ( self ) :
if self . _Postbuild == None :
if self . _Header == None :
self . _GetHeaderInfo ( )
if self . _Postbuild == None :
self . _Postbuild = ' '
return self . _Postbuild
## Retrieve FLASH_DEFINITION
def _GetBuildNumber ( self ) :
if self . _BuildNumber == None :
if self . _Header == None :
self . _GetHeaderInfo ( )
if self . _BuildNumber == None :
self . _BuildNumber = ' '
return self . _BuildNumber
## Retrieve MAKEFILE_NAME
def _GetMakefileName ( self ) :
if self . _MakefileName == None :
if self . _Header == None :
self . _GetHeaderInfo ( )
if self . _MakefileName == None :
self . _MakefileName = ' '
return self . _MakefileName
## Retrieve BsBaseAddress
def _GetBsBaseAddress ( self ) :
if self . _BsBaseAddress == None :
if self . _Header == None :
self . _GetHeaderInfo ( )
if self . _BsBaseAddress == None :
self . _BsBaseAddress = ' '
return self . _BsBaseAddress
## Retrieve RtBaseAddress
def _GetRtBaseAddress ( self ) :
if self . _RtBaseAddress == None :
if self . _Header == None :
self . _GetHeaderInfo ( )
if self . _RtBaseAddress == None :
self . _RtBaseAddress = ' '
return self . _RtBaseAddress
## Retrieve the top address for the load fix address
def _GetLoadFixAddress ( self ) :
if self . _LoadFixAddress == None :
if self . _Header == None :
self . _GetHeaderInfo ( )
if self . _LoadFixAddress == 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 . keys ( ) :
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
def _GetRFCLanguages ( self ) :
if self . _RFCLanguages == None :
if self . _Header == None :
self . _GetHeaderInfo ( )
if self . _RFCLanguages == None :
self . _RFCLanguages = [ ]
return self . _RFCLanguages
## Retrieve ISOLanguage filter
def _GetISOLanguages ( self ) :
if self . _ISOLanguages == None :
if self . _Header == None :
self . _GetHeaderInfo ( )
if self . _ISOLanguages == None :
self . _ISOLanguages = [ ]
return self . _ISOLanguages
## Retrieve the GUID string for VPD tool
def _GetVpdToolGuid ( self ) :
if self . _VpdToolGuid == None :
if self . _Header == None :
self . _GetHeaderInfo ( )
if self . _VpdToolGuid == None :
self . _VpdToolGuid = ' '
return self . _VpdToolGuid
## Retrieve [SkuIds] section information
def _GetSkuIds ( self ) :
if self . _SkuIds == None :
self . _SkuIds = sdict ( )
RecordList = self . _RawData [ MODEL_EFI_SKU_ID , self . _Arch ]
for Record in RecordList :
if Record [ 0 ] in [ None , ' ' ] :
EdkLogger . error ( ' build ' , FORMAT_INVALID , ' No Sku ID number ' ,
File = self . MetaFile , Line = Record [ - 1 ] )
if Record [ 1 ] in [ None , ' ' ] :
EdkLogger . error ( ' build ' , FORMAT_INVALID , ' No Sku ID name ' ,
File = self . MetaFile , Line = Record [ - 1 ] )
2017-12-22 13:46:15 +01:00
Pattern = re . compile ( ' ^[1-9] \ d*|0$ ' )
if Pattern . match ( Record [ 0 ] ) == None :
EdkLogger . error ( ' build ' , FORMAT_INVALID , " The format of the Sku ID number is invalid. The correct format is ' { (0-9)} { (1-9)(0-9)+} ' " ,
File = self . MetaFile , Line = Record [ - 1 ] )
if not IsValidWord ( Record [ 1 ] ) :
EdkLogger . error ( ' build ' , FORMAT_INVALID , " The format of the Sku ID name is invalid. The correct format is ' (a-zA-Z0-9_)(a-zA-Z0-9_-.)* ' " ,
File = self . MetaFile , Line = Record [ - 1 ] )
2017-12-22 13:04:04 +01:00
self . _SkuIds [ Record [ 1 ] . upper ( ) ] = ( Record [ 0 ] , Record [ 1 ] . upper ( ) , Record [ 2 ] . upper ( ) )
2017-11-24 07:30:11 +01:00
if ' DEFAULT ' not in self . _SkuIds :
2017-12-22 13:46:15 +01:00
self . _SkuIds [ ' DEFAULT ' ] = ( " 0 " , " DEFAULT " , " DEFAULT " )
2017-11-24 07:30:11 +01:00
if ' COMMON ' not in self . _SkuIds :
2017-12-22 13:46:15 +01:00
self . _SkuIds [ ' COMMON ' ] = ( " 0 " , " DEFAULT " , " DEFAULT " )
2017-11-24 07:30:11 +01:00
return self . _SkuIds
2017-12-22 13:46:15 +01:00
def ToInt ( self , intstr ) :
return int ( intstr , 16 ) if intstr . upper ( ) . startswith ( " 0X " ) else int ( intstr )
def _GetDefaultStores ( self ) :
if self . DefaultStores == None :
self . DefaultStores = sdict ( )
RecordList = self . _RawData [ MODEL_EFI_DEFAULT_STORES , self . _Arch ]
for Record in RecordList :
if Record [ 0 ] in [ None , ' ' ] :
EdkLogger . error ( ' build ' , FORMAT_INVALID , ' No DefaultStores ID number ' ,
File = self . MetaFile , Line = Record [ - 1 ] )
if Record [ 1 ] in [ None , ' ' ] :
EdkLogger . error ( ' build ' , FORMAT_INVALID , ' No DefaultStores ID name ' ,
File = self . MetaFile , Line = Record [ - 1 ] )
2017-12-22 13:04:04 +01:00
self . DefaultStores [ Record [ 1 ] . upper ( ) ] = ( self . ToInt ( Record [ 0 ] ) , Record [ 1 ] . upper ( ) )
2017-12-22 13:46:15 +01:00
if TAB_DEFAULT_STORES_DEFAULT not in self . DefaultStores :
self . DefaultStores [ TAB_DEFAULT_STORES_DEFAULT ] = ( 0 , TAB_DEFAULT_STORES_DEFAULT )
2017-12-22 13:07:54 +01:00
GlobalData . gDefaultStores = self . DefaultStores . keys ( )
if GlobalData . gDefaultStores :
GlobalData . gDefaultStores . sort ( )
2017-12-22 13:46:15 +01:00
return self . DefaultStores
2017-11-24 07:30:11 +01:00
## Retrieve [Components] section information
def _GetModules ( self ) :
if self . _Modules != None :
return self . _Modules
self . _Modules = sdict ( )
RecordList = self . _RawData [ MODEL_META_DATA_COMPONENT , self . _Arch ]
Macros = self . _Macros
Macros [ " EDK_SOURCE " ] = GlobalData . gEcpSource
for Record in RecordList :
DuplicatedFile = False
ModuleFile = PathClass ( NormPath ( Record [ 0 ] , Macros ) , GlobalData . gWorkspace , Arch = self . _Arch )
2017-12-22 13:46:15 +01:00
ModuleId = Record [ 6 ]
LineNo = Record [ 7 ]
2017-11-24 07:30:11 +01:00
# check the file validation
ErrorCode , ErrorInfo = ModuleFile . Validate ( ' .inf ' )
if ErrorCode != 0 :
EdkLogger . error ( ' build ' , ErrorCode , File = self . MetaFile , Line = LineNo ,
ExtraData = ErrorInfo )
# Check duplication
# If arch is COMMON, no duplicate module is checked since all modules in all component sections are selected
if self . _Arch != ' COMMON ' and ModuleFile in self . _Modules :
DuplicatedFile = True
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 ]
2017-12-22 13:46:15 +01:00
for TokenSpaceGuid , PcdCName , Setting , Dummy1 , Dummy2 , Dummy3 , Dummy4 , Dummy5 in RecordList :
2017-11-24 07:30:11 +01:00
TokenList = GetSplitValueList ( Setting )
DefaultValue = TokenList [ 0 ]
if len ( TokenList ) > 1 :
MaxDatumSize = TokenList [ 1 ]
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 ]
2017-12-22 13:46:15 +01:00
for ToolChainFamily , ToolChain , Option , Dummy1 , Dummy2 , Dummy3 , Dummy4 , Dummy5 in RecordList :
2017-11-24 07:30:11 +01:00
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 DuplicatedFile and not RecordList :
EdkLogger . error ( ' build ' , FILE_DUPLICATED , File = self . MetaFile , ExtraData = str ( ModuleFile ) , Line = LineNo )
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
def _GetLibraryInstances ( self ) :
if self . _LibraryInstances == None :
self . _GetLibraryClasses ( )
return self . _LibraryInstances
## Retrieve [LibraryClasses] information
def _GetLibraryClasses ( self ) :
if self . _LibraryClasses == 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 :
2017-12-22 13:46:15 +01:00
LibraryClass , LibraryInstance , Dummy , Arch , ModuleType , Dummy , Dummy , LineNo = Record
2017-11-24 07:30:11 +01:00
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 != ' 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 == None :
continue
self . _LibraryClasses [ LibraryClass , ModuleType ] = LibraryInstance
# for Edk style library instances, which are listed in different section
Macros [ " EDK_SOURCE " ] = GlobalData . gEcpSource
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 self . _DecPcds == None :
2017-12-22 13:04:04 +01:00
2017-11-24 07:30:11 +01:00
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 )
2017-12-22 13:04:04 +01:00
self . _DecPcds = GetDeclaredPcd ( self , self . _Bdb , self . _Arch , self . _Target , self . _Toolchain , PkgSet )
if ( PcdCName , TokenSpaceGuid ) not in self . _DecPcds :
2017-11-24 07:30:11 +01:00
EdkLogger . error ( ' build ' , PARSER_ERROR ,
" Pcd ( %s . %s ) defined in DSC is not declared in DEC files. Arch: [ ' %s ' ] " % ( TokenSpaceGuid , PcdCName , self . _Arch ) ,
File = self . MetaFile , Line = LineNo )
ValueList , IsValid , Index = AnalyzeDscPcd ( Setting , PcdType , self . _DecPcds [ PcdCName , TokenSpaceGuid ] . DatumType )
2017-12-01 07:15:59 +01:00
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 ) )
2017-11-24 07:30:11 +01:00
if ValueList [ Index ] and PcdType not in [ MODEL_PCD_FEATURE_FLAG , MODEL_PCD_FIXED_AT_BUILD ] :
try :
ValueList [ Index ] = ValueExpression ( ValueList [ Index ] , GlobalData . gPlatformPcds ) ( True )
except WrnExpression , Value :
ValueList [ Index ] = Value . result
except EvaluationException , 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 ] == ' True ' :
ValueList [ Index ] = ' 1 '
elif ValueList [ Index ] == ' False ' :
ValueList [ Index ] = ' 0 '
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 ) )
2017-12-01 07:15:59 +01:00
if PcdType in ( MODEL_PCD_DYNAMIC_DEFAULT , MODEL_PCD_DYNAMIC_EX_DEFAULT ) :
if self . _DecPcds [ PcdCName , TokenSpaceGuid ] . DatumType . strip ( ) != ValueList [ 1 ] . strip ( ) :
EdkLogger . error ( ' build ' , FORMAT_INVALID , ErrStr , File = self . MetaFile , Line = LineNo ,
ExtraData = " %s . %s | %s " % ( TokenSpaceGuid , PcdCName , Setting ) )
2017-11-24 07:30:11 +01:00
return ValueList
2017-12-22 13:46:15 +01:00
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 = { " DEFAULT " : pcd . SkuInfoList [ skuid ] for skuid in pcd . SkuInfoList if skuid in available_sku }
2017-12-01 15:00:07 +01:00
if type ( pcd ) is StructurePcd and pcd . SkuOverrideValues :
Pcds [ pcdname ] . SkuOverrideValues = { " DEFAULT " : pcd . SkuOverrideValues [ skuid ] for skuid in pcd . SkuOverrideValues if skuid in available_sku }
2017-12-22 13:46:15 +01:00
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 }
2017-12-01 15:00:07 +01:00
if type ( pcd ) is StructurePcd and pcd . SkuOverrideValues :
Pcds [ pcdname ] . SkuOverrideValues = { skuid : pcd . SkuOverrideValues [ skuid ] for skuid in pcd . SkuOverrideValues if skuid in available_sku }
2017-12-22 13:46:15 +01:00
return Pcds
2017-12-22 13:04:04 +01:00
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 " STANDARD " not in skuobj . DefaultStoreDict :
PcdDefaultStoreSet = set ( [ defaultstorename for defaultstorename in skuobj . DefaultStoreDict ] )
mindefaultstorename = DefaultStoreMgr . GetMin ( PcdDefaultStoreSet )
skuobj . DefaultStoreDict [ ' STANDARD ' ] = copy . deepcopy ( skuobj . DefaultStoreDict [ mindefaultstorename ] )
return Pcds
2017-11-24 07:30:11 +01:00
## Retrieve all PCD settings in platform
def _GetPcds ( self ) :
if self . _Pcds == None :
self . _Pcds = sdict ( )
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 ) )
2017-12-22 13:46:15 +01:00
self . _Pcds = self . CompletePcdValues ( self . _Pcds )
2017-11-24 07:30:11 +01:00
self . _Pcds = self . UpdateStructuredPcds ( MODEL_PCD_TYPE_LIST , self . _Pcds )
2017-12-22 13:04:04 +01:00
self . _Pcds = self . CompleteHiiPcdsDefaultStores ( self . _Pcds )
2017-12-22 13:46:15 +01:00
self . _Pcds = self . _FilterPcdBySkuUsage ( self . _Pcds )
2017-11-24 07:30:11 +01:00
return self . _Pcds
2017-12-22 13:46:15 +01:00
def _dumpPcdInfo ( self , Pcds ) :
for pcd in Pcds :
pcdobj = Pcds [ pcd ]
if not pcdobj . TokenCName . startswith ( " Test " ) :
continue
for skuid in pcdobj . SkuInfoList :
if pcdobj . Type in ( self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_HII ] , self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_EX_HII ] ) :
for storename in pcdobj . SkuInfoList [ skuid ] . DefaultStoreDict :
print " PcdCName: %s , SkuName: %s , StoreName: %s , Value: %s " % ( " . " . join ( ( pcdobj . TokenSpaceGuidCName , pcdobj . TokenCName ) ) , skuid , storename , str ( pcdobj . SkuInfoList [ skuid ] . DefaultStoreDict [ storename ] ) )
else :
print " PcdCName: %s , SkuName: %s , Value: %s " % ( " . " . join ( ( pcdobj . TokenSpaceGuidCName , pcdobj . TokenCName ) ) , skuid , str ( pcdobj . SkuInfoList [ skuid ] . DefaultValue ) )
2017-11-24 07:30:11 +01:00
## Retrieve [BuildOptions]
def _GetBuildOptions ( self ) :
if self . _BuildOptions == None :
self . _BuildOptions = sdict ( )
#
# 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 ]
2017-12-22 13:46:15 +01:00
for ToolChainFamily , ToolChain , Option , Dummy1 , Dummy2 , Dummy3 , Dummy4 , Dummy5 in RecordList :
2017-12-22 13:53:01 +01:00
if Dummy3 . upper ( ) != ' COMMON ' :
continue
2017-11-24 07:30:11 +01:00
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 :
2017-12-22 13:53:01 +01:00
if ' ' + Option not in self . _BuildOptions [ CurKey ] :
self . _BuildOptions [ CurKey ] + = ' ' + Option
2017-11-24 07:30:11 +01:00
return self . _BuildOptions
def GetBuildOptionsByModuleType ( self , Edk , ModuleType ) :
if self . _ModuleTypeOptions == None :
self . _ModuleTypeOptions = sdict ( )
if ( Edk , ModuleType ) not in self . _ModuleTypeOptions :
options = sdict ( )
self . _ModuleTypeOptions [ Edk , ModuleType ] = options
DriverType = ' %s . %s ' % ( Edk , ModuleType )
CommonDriverType = ' %s . %s ' % ( ' COMMON ' , ModuleType )
2017-12-22 13:53:01 +01:00
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 ( ) :
2017-11-24 07:30:11 +01:00
Key = ( ToolChainFamily , ToolChain , Edk )
if Key not in options or not ToolChain . endswith ( ' _FLAGS ' ) or Option . startswith ( ' = ' ) :
options [ Key ] = Option
else :
2017-12-22 13:53:01 +01:00
if ' ' + Option not in options [ Key ] :
options [ Key ] + = ' ' + Option
2017-11-24 07:30:11 +01:00
return self . _ModuleTypeOptions [ Edk , ModuleType ]
def GetStructurePcdInfo ( self , PcdSet ) :
structure_pcd_data = { }
for item in PcdSet :
2017-12-22 13:46:15 +01:00
if ( item [ 0 ] , item [ 1 ] ) not in structure_pcd_data :
structure_pcd_data [ ( item [ 0 ] , item [ 1 ] ) ] = [ ]
structure_pcd_data [ ( item [ 0 ] , item [ 1 ] ) ] . append ( item )
2017-11-24 07:30:11 +01:00
return structure_pcd_data
def UpdateStructuredPcds ( self , TypeList , AllPcds ) :
2017-12-01 15:00:07 +01:00
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 ] ]
2017-11-24 07:30:11 +01:00
Pcds = AllPcds
2017-12-22 13:46:15 +01:00
DefaultStoreMgr = DefaultStore ( self . DefaultStores )
2017-12-01 15:00:07 +01:00
SkuIds = self . SkuIdMgr . AvailableSkuIdSet
SkuIds . update ( { ' DEFAULT ' : 0 } )
2017-12-22 13:46:15 +01:00
DefaultStores = set ( [ storename for pcdobj in AllPcds . values ( ) for skuobj in pcdobj . SkuInfoList . values ( ) for storename in skuobj . DefaultStoreDict . keys ( ) ] )
2017-11-24 07:30:11 +01:00
S_PcdSet = [ ]
# Find out all possible PCD candidates for self._Arch
RecordList = [ ]
2017-12-22 13:04:04 +01:00
2017-11-24 07:30:11 +01:00
for Type in TypeList :
RecordList . extend ( self . _RawData [ Type , self . _Arch ] )
2017-12-22 13:46:15 +01:00
for TokenSpaceGuid , PcdCName , Setting , Arch , SkuName , default_store , Dummy4 , Dummy5 in RecordList :
2017-12-22 13:04:04 +01:00
SkuName = SkuName . upper ( )
default_store = default_store . upper ( )
SkuName = ' DEFAULT ' if SkuName == ' COMMON ' else SkuName
2017-12-22 13:46:15 +01:00
if SkuName not in SkuIds :
continue
2017-12-22 13:04:04 +01:00
2017-12-22 13:46:15 +01:00
if SkuName in SkuIds and " . " in TokenSpaceGuid :
S_PcdSet . append ( ( TokenSpaceGuid . split ( " . " ) [ 0 ] , TokenSpaceGuid . split ( " . " ) [ 1 ] , PcdCName , SkuName , default_store , Dummy5 , AnalyzePcdExpression ( Setting ) [ 0 ] ) )
2017-11-24 07:30:11 +01:00
# handle pcd value override
StrPcdSet = self . GetStructurePcdInfo ( S_PcdSet )
S_pcd_set = { }
for str_pcd in StrPcdSet :
2017-12-22 13:46:15 +01:00
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 )
2017-11-24 07:30:11 +01:00
if str_pcd_dec :
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 . DefaultValue :
str_pcd_obj_str . DefaultFromDSC = str_pcd_obj . DefaultValue
for str_pcd_data in StrPcdSet [ str_pcd ] :
2017-12-22 13:46:15 +01:00
if str_pcd_data [ 3 ] in SkuIds :
str_pcd_obj_str . AddOverrideValue ( str_pcd_data [ 2 ] , str ( str_pcd_data [ 6 ] ) , ' DEFAULT ' if str_pcd_data [ 3 ] == ' COMMON ' else str_pcd_data [ 3 ] , ' STANDARD ' if str_pcd_data [ 4 ] == ' COMMON ' else str_pcd_data [ 4 ] , self . MetaFile . File , LineNo = str_pcd_data [ 5 ] )
S_pcd_set [ str_pcd [ 1 ] , str_pcd [ 0 ] ] = str_pcd_obj_str
2017-12-22 13:04:04 +01:00
else :
EdkLogger . error ( ' build ' , PARSER_ERROR ,
" Pcd ( %s . %s ) defined in DSC is not declared in DEC files. Arch: [ ' %s ' ] " % ( str_pcd [ 0 ] , str_pcd [ 1 ] , self . _Arch ) ,
File = self . MetaFile , Line = StrPcdSet [ str_pcd ] [ 0 ] [ 5 ] )
2017-11-24 07:30:11 +01:00
# Add the Structure PCD that only defined in DEC, don't have override in DSC file
2017-12-26 04:33:33 +01:00
for Pcd in self . DecPcds :
2017-11-24 07:30:11 +01:00
if type ( self . _DecPcds [ Pcd ] ) is 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 . DefaultValue :
str_pcd_obj_str . DefaultFromDSC = str_pcd_obj . DefaultValue
S_pcd_set [ Pcd ] = str_pcd_obj_str
if S_pcd_set :
GlobalData . gStructurePcd [ self . Arch ] = S_pcd_set
2017-12-22 13:46:15 +01:00
for stru_pcd in S_pcd_set . values ( ) :
2017-12-18 05:42:41 +01:00
for skuid in SkuIds :
if skuid in stru_pcd . SkuOverrideValues :
continue
nextskuid = self . SkuIdMgr . GetNextSkuId ( skuid )
NoDefault = False
while nextskuid not in stru_pcd . SkuOverrideValues :
if nextskuid == " 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 { ' STANDARD ' : stru_pcd . DefaultValues } )
2017-12-22 13:46:15 +01:00
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
2017-12-22 13:04:04 +01:00
NoDefault = False
2017-12-22 13:46:15 +01:00
if skuid not in stru_pcd . SkuOverrideValues :
while nextskuid not in stru_pcd . SkuOverrideValues :
2017-12-22 13:04:04 +01:00
if nextskuid == " DEFAULT " :
NoDefault = True
break
2017-12-22 13:46:15 +01:00
nextskuid = self . SkuIdMgr . GetNextSkuId ( nextskuid )
2017-12-22 13:04:04 +01:00
if NoDefault :
continue
PcdDefaultStoreSet = set ( [ defaultstorename for defaultstorename in stru_pcd . SkuOverrideValues [ nextskuid ] ] )
2017-12-22 13:46:15 +01:00
mindefaultstorename = DefaultStoreMgr . GetMin ( PcdDefaultStoreSet )
2017-12-22 13:04:04 +01:00
2017-12-22 13:46:15 +01:00
for defaultstoreid in DefaultStores :
if defaultstoreid not in stru_pcd . SkuOverrideValues [ skuid ] :
2017-12-22 13:04:04 +01:00
stru_pcd . SkuOverrideValues [ skuid ] [ defaultstoreid ] = copy . deepcopy ( stru_pcd . SkuOverrideValues [ nextskuid ] [ mindefaultstorename ] )
2017-12-01 15:00:07 +01:00
2017-11-24 07:30:11 +01:00
Str_Pcd_Values = self . GenerateByteArrayValue ( S_pcd_set )
if Str_Pcd_Values :
2017-12-22 13:46:15 +01:00
for ( skuname , StoreName , PcdGuid , PcdName , PcdValue ) in Str_Pcd_Values :
str_pcd_obj = S_pcd_set . get ( ( PcdName , PcdGuid ) )
2017-11-24 07:30:11 +01:00
if str_pcd_obj is None :
2017-12-18 05:42:41 +01:00
print PcdName , PcdGuid
2017-11-24 07:30:11 +01:00
raise
if str_pcd_obj . Type in [ self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_HII ] ,
self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_EX_HII ] ] :
2017-12-22 13:46:15 +01:00
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 } )
2017-11-24 07:30:11 +01:00
else :
2017-12-22 13:46:15 +01:00
str_pcd_obj . SkuInfoList [ skuname ] . HiiDefaultValue = PcdValue
str_pcd_obj . SkuInfoList [ skuname ] . DefaultStoreDict . update ( { StoreName : PcdValue } )
2017-11-24 07:30:11 +01:00
elif str_pcd_obj . Type in [ self . _PCD_TYPE_STRING_ [ MODEL_PCD_FIXED_AT_BUILD ] ,
self . _PCD_TYPE_STRING_ [ MODEL_PCD_PATCHABLE_IN_MODULE ] ] :
2017-12-22 13:46:15 +01:00
if skuname in ( self . SkuIdMgr . SystemSkuId , ' DEFAULT ' , ' COMMON ' ) :
str_pcd_obj . DefaultValue = PcdValue
2017-11-24 07:30:11 +01:00
else :
2017-12-22 13:46:15 +01:00
if skuname not in str_pcd_obj . SkuInfoList :
2017-12-01 15:00:07 +01:00
nextskuid = self . SkuIdMgr . GetNextSkuId ( skuname )
NoDefault = False
while nextskuid not in str_pcd_obj . SkuInfoList :
if nextskuid == " 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
2017-11-24 07:30:11 +01:00
else :
2017-12-22 13:46:15 +01:00
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 ]
2017-11-24 07:30:11 +01:00
for str_pcd_obj in S_pcd_set . values ( ) :
2017-12-22 13:04:04 +01:00
2017-11-24 07:30:11 +01:00
str_pcd_obj . MaxDatumSize = self . GetStructurePcdMaxSize ( str_pcd_obj )
Pcds [ str_pcd_obj . TokenCName , str_pcd_obj . TokenSpaceGuidCName ] = str_pcd_obj
2017-12-01 15:00:07 +01:00
for pcdkey in Pcds :
pcd = Pcds [ pcdkey ]
if ' DEFAULT ' not in pcd . SkuInfoList . keys ( ) and ' COMMON ' in pcd . SkuInfoList . keys ( ) :
pcd . SkuInfoList [ ' DEFAULT ' ] = pcd . SkuInfoList [ ' COMMON ' ]
del ( pcd . SkuInfoList [ ' COMMON ' ] )
elif ' DEFAULT ' in pcd . SkuInfoList . keys ( ) and ' COMMON ' in pcd . SkuInfoList . keys ( ) :
del ( pcd . SkuInfoList [ ' COMMON ' ] )
map ( self . FilterSkuSettings , [ Pcds [ pcdkey ] for pcdkey in Pcds if Pcds [ pcdkey ] . Type in DynamicPcdType ] )
2017-11-24 07:30:11 +01:00
return Pcds
## Retrieve non-dynamic PCD settings
#
# @param Type PCD type
#
# @retval a dict object contains settings of given PCD type
#
def _GetPcd ( self , Type ) :
Pcds = sdict ( )
#
# tdict is a special dict kind of type, used for selecting correct
# PCD settings for certain ARCH
#
2017-12-22 13:04:04 +01:00
AvailableSkuIdSet = copy . copy ( self . SkuIds )
2017-11-24 07:30:11 +01:00
PcdDict = tdict ( True , 3 )
PcdSet = set ( )
# Find out all possible PCD candidates for self._Arch
RecordList = self . _RawData [ Type , self . _Arch ]
PcdValueDict = sdict ( )
2017-12-22 13:46:15 +01:00
for TokenSpaceGuid , PcdCName , Setting , Arch , SkuName , Dummy3 , Dummy4 , Dummy5 in RecordList :
2017-12-22 13:04:04 +01:00
SkuName = SkuName . upper ( )
SkuName = ' DEFAULT ' if SkuName == ' 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 )
2017-12-22 13:46:15 +01:00
if SkuName in ( self . SkuIdMgr . SystemSkuId , ' DEFAULT ' , ' COMMON ' ) :
if " . " not in TokenSpaceGuid :
PcdSet . add ( ( PcdCName , TokenSpaceGuid , SkuName , Dummy4 ) )
2017-11-24 07:30:11 +01:00
PcdDict [ Arch , PcdCName , TokenSpaceGuid , SkuName ] = Setting
for PcdCName , TokenSpaceGuid , SkuName , Dummy4 in PcdSet :
Setting = PcdDict [ self . _Arch , PcdCName , TokenSpaceGuid , SkuName ]
if Setting == None :
continue
PcdValue , DatumType , MaxDatumSize = self . _ValidatePcd ( PcdCName , TokenSpaceGuid , Setting , Type , Dummy4 )
if ( PcdCName , TokenSpaceGuid ) in PcdValueDict :
PcdValueDict [ PcdCName , TokenSpaceGuid ] [ SkuName ] = ( PcdValue , DatumType , MaxDatumSize )
else :
PcdValueDict [ PcdCName , TokenSpaceGuid ] = { SkuName : ( PcdValue , DatumType , MaxDatumSize ) }
PcdsKeys = PcdValueDict . keys ( )
for PcdCName , TokenSpaceGuid in PcdsKeys :
PcdSetting = PcdValueDict [ PcdCName , TokenSpaceGuid ]
PcdValue = None
DatumType = None
MaxDatumSize = None
if ' COMMON ' in PcdSetting :
PcdValue , DatumType , MaxDatumSize = PcdSetting [ ' COMMON ' ]
if ' DEFAULT ' in PcdSetting :
PcdValue , DatumType , MaxDatumSize = PcdSetting [ ' DEFAULT ' ]
2017-12-22 13:46:15 +01:00
if self . SkuIdMgr . SystemSkuId in PcdSetting :
PcdValue , DatumType , MaxDatumSize = PcdSetting [ self . SkuIdMgr . SystemSkuId ]
2017-11-24 07:30:11 +01:00
Pcds [ PcdCName , TokenSpaceGuid ] = PcdClassObject (
PcdCName ,
TokenSpaceGuid ,
self . _PCD_TYPE_STRING_ [ Type ] ,
DatumType ,
PcdValue ,
' ' ,
MaxDatumSize ,
{ } ,
False ,
None ,
IsDsc = True )
return Pcds
2017-12-22 13:46:15 +01:00
def __UNICODE2OCTList ( self , Value ) :
Value = Value . strip ( )
Value = Value [ 2 : - 1 ]
List = [ ]
for Item in Value :
Temp = ' %04X ' % ord ( Item )
List . append ( ' 0x ' + Temp [ 2 : 4 ] )
List . append ( ' 0x ' + Temp [ 0 : 2 ] )
List . append ( ' 0x00 ' )
List . append ( ' 0x00 ' )
return List
def __STRING2OCTList ( self , Value ) :
OCTList = [ ]
Value = Value . strip ( ' " ' )
for char in Value :
Temp = ' %02X ' % ord ( char )
OCTList . append ( ' 0x ' + Temp )
OCTList . append ( ' 0x00 ' )
return OCTList
2017-11-24 07:30:11 +01:00
def GetStructurePcdMaxSize ( self , str_pcd ) :
pcd_default_value = str_pcd . DefaultValue
sku_values = [ skuobj . HiiDefaultValue if str_pcd . Type in [ self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_HII ] , self . _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 ( )
2017-12-19 09:01:38 +01:00
if len ( value ) > 1 :
if Value . startswith ( ' 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 [ 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
2017-11-24 07:30:11 +01:00
return len ( Value )
return str ( max ( [ pcd_size for pcd_size in [ get_length ( item ) for item in sku_values ] ] ) )
def IsFieldValueAnArray ( self , Value ) :
Value = Value . strip ( )
if Value . startswith ( ' 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 :
print ' foo = ' , list ( Value [ 2 : - 1 ] )
return True
if Value [ 0 ] == " ' " and Value [ - 1 ] == " ' " and len ( list ( Value [ 1 : - 1 ] ) ) > 1 :
print ' bar = ' , list ( Value [ 1 : - 1 ] )
return True
return False
def ExecuteCommand ( self , Command ) :
try :
Process = subprocess . Popen ( Command , stdout = subprocess . PIPE , stderr = subprocess . PIPE , shell = True )
except :
print ' ERROR: Can not execute command: ' , Command
sys . exit ( 1 )
Result = Process . communicate ( )
if Process . returncode < > 0 :
print ' ERROR: Can not collect output from command: ' , Command
return Result [ 0 ] , Result [ 1 ]
def IntToCString ( self , 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 GenerateInitializeFunc ( self , SkuName , DefaultStoreName , Pcd , InitByteValue , CApp ) :
2017-12-22 13:46:15 +01:00
OverrideValues = { DefaultStoreName : " " }
2017-11-24 07:30:11 +01:00
if Pcd . SkuOverrideValues :
OverrideValues = Pcd . SkuOverrideValues [ SkuName ]
2017-12-22 13:46:15 +01:00
for DefaultStoreName in OverrideValues . keys ( ) :
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 '
2017-12-15 05:12:58 +01:00
CApp = CApp + ' CHAR8 *Value; \n '
2017-12-22 13:46:15 +01:00
CApp = CApp + ' UINT32 OriginalSize; \n '
CApp = CApp + ' VOID *OriginalPcd; \n '
CApp = CApp + ' %s *Pcd; \n ' % ( Pcd . DatumType )
CApp = CApp + ' \n '
2017-12-22 13:14:29 +01:00
2017-12-22 13:46:15 +01:00
Pcd . DefaultValue = Pcd . DefaultValue . strip ( )
2017-12-22 13:14:29 +01:00
PcdDefaultValue = StringToArray ( Pcd . DefaultValue )
2017-12-22 13:46:15 +01:00
InitByteValue + = ' %s . %s . %s . %s | %s | %s \n ' % ( SkuName , DefaultStoreName , Pcd . TokenSpaceGuidCName , Pcd . TokenCName , Pcd . DatumType , PcdDefaultValue )
2017-11-24 07:30:11 +01:00
2017-12-22 13:46:15 +01:00
#
# Get current PCD value and size
#
CApp = CApp + ' OriginalPcd = PcdGetPtr ( %s , %s , %s , %s , &OriginalSize); \n ' % ( SkuName , DefaultStoreName , Pcd . TokenSpaceGuidCName , Pcd . TokenCName )
2017-11-24 07:30:11 +01:00
2017-12-22 13:46:15 +01:00
#
# 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 + ' Size = sizeof( %s ); \n ' % ( Pcd . DatumType )
2017-12-22 13:53:01 +01:00
for skuname in self . SkuIdMgr . SkuOverrideOrder ( ) :
inherit_OverrideValues = Pcd . SkuOverrideValues [ skuname ]
for FieldList in [ Pcd . DefaultValues , inherit_OverrideValues . get ( DefaultStoreName ) ] :
if not FieldList :
continue
for FieldName in FieldList :
FieldName = " . " + FieldName
IsArray = self . IsFieldValueAnArray ( FieldList [ FieldName . strip ( " . " ) ] [ 0 ] )
if IsArray :
Value , ValueSize = ParseFieldValue ( FieldList [ FieldName . strip ( " . " ) ] [ 0 ] )
CApp = CApp + ' __FLEXIBLE_SIZE(Size, %s , %s , %d / __ARRAY_ELEMENT_SIZE( %s , %s ) + (( %d %% __ARRAY_ELEMENT_SIZE( %s , %s )) ? 1 : 0)); \n ' % ( Pcd . DatumType , FieldName . strip ( " . " ) , ValueSize , Pcd . DatumType , FieldName . strip ( " . " ) , ValueSize , Pcd . DatumType , FieldName . strip ( " . " ) ) ;
else :
NewFieldName = ' '
while ' [ ' in FieldName :
NewFieldName = NewFieldName + FieldName . split ( ' [ ' , 1 ) [ 0 ] + ' [0] '
ArrayIndex = 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 ); \n ' % ( Pcd . DatumType , FieldName . strip ( " . " ) , ArrayIndex + 1 )
if skuname == SkuName :
break
2017-11-24 07:30:11 +01:00
2017-12-22 13:46:15 +01:00
#
# 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 . DatumType )
CApp = CApp + ' memset (Pcd, 0, Size); \n '
2017-11-24 07:30:11 +01:00
2017-12-22 13:46:15 +01:00
#
# Copy current PCD value into allocated buffer.
#
CApp = CApp + ' memcpy (Pcd, OriginalPcd, OriginalSize); \n '
2017-11-24 07:30:11 +01:00
2017-12-22 13:46:15 +01:00
#
# Assign field values in PCD
#
2017-12-22 13:53:01 +01:00
for skuname in self . SkuIdMgr . SkuOverrideOrder ( ) :
inherit_OverrideValues = Pcd . SkuOverrideValues [ skuname ]
for FieldList in [ Pcd . DefaultValues , Pcd . DefaultFromDSC , inherit_OverrideValues . get ( DefaultStoreName ) ] :
if not FieldList :
continue
if Pcd . DefaultFromDSC and FieldList == Pcd . DefaultFromDSC :
IsArray = self . IsFieldValueAnArray ( FieldList )
Value , ValueSize = ParseFieldValue ( FieldList )
if isinstance ( Value , str ) :
CApp = CApp + ' Pcd = %s ; // From DSC Default Value %s \n ' % ( Value , Pcd . DefaultFromDSC )
elif IsArray :
2017-12-22 13:46:15 +01:00
#
# Use memcpy() to copy value into field
#
2017-12-22 13:53:01 +01:00
CApp = CApp + ' Value = %s ; // From DSC Default Value %s \n ' % ( self . IntToCString ( Value , ValueSize ) , Pcd . DefaultFromDSC )
CApp = CApp + ' memcpy (Pcd, Value, %d ); \n ' % ( ValueSize )
continue
2017-11-24 07:30:11 +01:00
2017-12-22 13:53:01 +01:00
for FieldName in FieldList :
IsArray = self . IsFieldValueAnArray ( FieldList [ FieldName ] [ 0 ] )
try :
Value , ValueSize = ParseFieldValue ( FieldList [ FieldName ] [ 0 ] )
except Exception :
print FieldList [ FieldName ] [ 0 ]
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 :
2017-12-22 13:46:15 +01:00
#
# Use memcpy() to copy value into field
#
2017-12-22 13:53:01 +01:00
CApp = CApp + ' FieldSize = __FIELD_SIZE( %s , %s ); \n ' % ( Pcd . DatumType , FieldName )
CApp = CApp + ' Value = %s ; // From %s Line %d Value %s \n ' % ( self . IntToCString ( Value , ValueSize ) , FieldList [ FieldName ] [ 1 ] , FieldList [ FieldName ] [ 2 ] , FieldList [ FieldName ] [ 0 ] )
CApp = CApp + ' memcpy (&Pcd-> %s [0], Value, (FieldSize > 0 && FieldSize < %d ) ? FieldSize : %d ); \n ' % ( FieldName , ValueSize , ValueSize )
2017-12-22 13:46:15 +01:00
else :
2017-12-22 13:53:01 +01:00
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 ] )
if skuname == SkuName :
break
2017-12-22 13:46:15 +01:00
#
# Set new PCD value and size
#
CApp = CApp + ' PcdSetPtr ( %s , %s , %s , %s , Size, (UINT8 *)Pcd); \n ' % ( SkuName , DefaultStoreName , Pcd . TokenSpaceGuidCName , Pcd . TokenCName )
2017-11-24 07:30:11 +01:00
2017-12-22 13:46:15 +01:00
#
# Free PCD
#
CApp = CApp + ' free (Pcd); \n '
CApp = CApp + ' } \n '
CApp = CApp + ' \n '
2017-11-24 07:30:11 +01:00
return InitByteValue , CApp
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
Includes = { }
for PcdName in StructuredPcds :
Pcd = StructuredPcds [ PcdName ]
IncludeFile = Pcd . StructuredPcdIncludeFile
if IncludeFile not in Includes :
Includes [ IncludeFile ] = True
CApp = CApp + ' #include < %s > \n ' % ( IncludeFile )
CApp = CApp + ' \n '
for PcdName in StructuredPcds :
Pcd = StructuredPcds [ PcdName ]
if not Pcd . SkuOverrideValues :
2017-12-22 13:46:15 +01:00
InitByteValue , CApp = self . GenerateInitializeFunc ( self . SkuIdMgr . SystemSkuId , ' STANDARD ' , Pcd , InitByteValue , CApp )
2017-11-24 07:30:11 +01:00
else :
2017-12-22 13:53:01 +01:00
for SkuName in self . SkuIdMgr . SkuOverrideOrder ( ) :
if SkuName not in Pcd . SkuOverrideValues :
continue
2017-11-24 07:30:11 +01:00
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 not Pcd . SkuOverrideValues :
2017-12-22 13:46:15 +01:00
CApp = CApp + ' Initialize_ %s _ %s _ %s _ %s (); \n ' % ( self . SkuIdMgr . SystemSkuId , ' STANDARD ' , Pcd . TokenSpaceGuidCName , Pcd . TokenCName )
2017-11-24 07:30:11 +01:00
else :
2017-12-22 13:53:01 +01:00
for SkuName in self . SkuIdMgr . SkuOverrideOrder ( ) :
if SkuName not in Pcd . SkuOverrideValues :
continue
2017-12-22 13:46:15 +01:00
for DefaultStoreName in Pcd . SkuOverrideValues [ SkuName ] :
2017-11-24 07:30:11 +01:00
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 )
File = open ( CAppBaseFileName + ' .c ' , ' w ' )
File . write ( CApp )
File . close ( )
MakeApp = PcdMakefileHeader
if sys . platform == " win32 " :
MakeApp = MakeApp + ' ARCH = IA32 \n APPNAME = %s \n ' % ( PcdValueInitName ) + ' OBJECTS = %s \ %s .obj \n ' % ( self . OutputPath , PcdValueInitName ) + ' INC = '
else :
MakeApp = MakeApp + PcdGccMakefile
MakeApp = MakeApp + ' APPNAME = %s \n ' % ( PcdValueInitName ) + ' OBJECTS = %s / %s .o \n ' % ( self . OutputPath , PcdValueInitName ) + \
2017-12-15 05:12:58 +01:00
' include $(MAKEROOT)/Makefiles/app.makefile \n ' + ' BUILD_CFLAGS += -Wno-pointer-to-int-cast -Wno-unused-variable \n ' + ' INCLUDE += '
2017-11-24 07:30:11 +01:00
PlatformInc = { }
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 ) ] = Cache . Includes
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 ) + ' '
MakeApp = MakeApp + ' \n '
if sys . platform == " win32 " :
MakeApp = MakeApp + PcdMakefileEnd
MakeFileName = os . path . join ( self . OutputPath , ' Makefile ' )
File = open ( MakeFileName , ' w ' )
File . write ( MakeApp )
File . close ( )
InputValueFile = os . path . join ( self . OutputPath , ' Input.txt ' )
OutputValueFile = os . path . join ( self . OutputPath , ' Output.txt ' )
File = open ( InputValueFile , ' w ' )
File . write ( InitByteValue )
File . close ( )
2017-12-15 05:12:58 +01:00
Messages = ' '
2017-11-24 07:30:11 +01:00
if sys . platform == " win32 " :
StdOut , StdErr = self . ExecuteCommand ( ' nmake clean & nmake -f %s ' % ( MakeFileName ) )
2017-12-15 05:12:58 +01:00
Messages = StdOut
2017-11-24 07:30:11 +01:00
else :
StdOut , StdErr = self . ExecuteCommand ( ' make clean & make -f %s ' % ( MakeFileName ) )
2017-12-15 05:12:58 +01:00
Messages = StdErr
Messages = Messages . split ( ' \n ' )
for Message in Messages :
if " error " in Message :
FileInfo = Message . strip ( ) . split ( ' ( ' )
if len ( FileInfo ) > 1 :
FileName = FileInfo [ 0 ]
FileLine = FileInfo [ 1 ] . split ( ' ) ' ) [ 0 ]
else :
FileInfo = Message . strip ( ) . split ( ' : ' )
FileName = FileInfo [ 0 ]
FileLine = FileInfo [ 1 ]
File = open ( FileName , ' r ' )
FileData = File . readlines ( )
File . close ( )
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
for item in message_itmes :
if " PcdValueInit.c " in item :
Index = message_itmes . index ( item )
message_itmes [ Index ] = dsc_line . strip ( )
break
EdkLogger . error ( " build " , PCD_STRUCTURE_PCD_ERROR , " : " . join ( message_itmes [ Index : ] ) )
2017-11-24 07:30:11 +01:00
PcdValueInitExe = PcdValueInitName
if not sys . platform == " win32 " :
PcdValueInitExe = os . path . join ( os . getenv ( " EDK_TOOLS_PATH " ) , ' Source ' , ' C ' , ' bin ' , PcdValueInitName )
StdOut , StdErr = self . ExecuteCommand ( PcdValueInitExe + ' -i %s -o %s ' % ( InputValueFile , OutputValueFile ) )
File = open ( OutputValueFile , ' r ' )
FileBuffer = File . readlines ( )
File . close ( )
StructurePcdSet = [ ]
for Pcd in FileBuffer :
PcdValue = Pcd . split ( ' | ' )
PcdInfo = PcdValue [ 0 ] . split ( ' . ' )
2017-12-22 13:46:15 +01:00
StructurePcdSet . append ( ( PcdInfo [ 0 ] , PcdInfo [ 1 ] , PcdInfo [ 2 ] , PcdInfo [ 3 ] , PcdValue [ 2 ] . strip ( ) ) )
2017-11-24 07:30:11 +01:00
return StructurePcdSet
## Retrieve dynamic PCD settings
#
# @param Type PCD type
#
# @retval a dict object contains settings of given PCD type
#
def _GetDynamicPcd ( self , Type ) :
Pcds = sdict ( )
#
# 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 ]
2017-12-22 13:46:15 +01:00
AvailableSkuIdSet = copy . copy ( self . SkuIds )
2017-11-24 07:30:11 +01:00
2017-12-22 13:46:15 +01:00
for TokenSpaceGuid , PcdCName , Setting , Arch , SkuName , Dummy3 , Dummy4 , Dummy5 in RecordList :
2017-12-22 13:04:04 +01:00
SkuName = SkuName . upper ( )
SkuName = ' DEFAULT ' if SkuName == ' COMMON ' else SkuName
2017-11-24 07:30:11 +01:00
if SkuName not in AvailableSkuIdSet :
2017-12-22 13:04:04 +01:00
EdkLogger . error ( ' build ' , PARAMETER_INVALID , ' Sku %s is not defined in [SkuIds] section ' % SkuName ,
File = self . MetaFile , Line = Dummy5 )
2017-11-24 07:30:11 +01:00
if " . " not in TokenSpaceGuid :
PcdList . append ( ( PcdCName , TokenSpaceGuid , SkuName , Dummy4 ) )
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 == None :
continue
PcdValue , DatumType , MaxDatumSize = self . _ValidatePcd ( PcdCName , TokenSpaceGuid , Setting , Type , Dummy4 )
2017-12-22 13:46:15 +01:00
SkuInfo = SkuInfoClass ( SkuName , self . SkuIds [ SkuName ] [ 0 ] , ' ' , ' ' , ' ' , ' ' , ' ' , PcdValue )
2017-11-24 07:30:11 +01:00
if ( PcdCName , TokenSpaceGuid ) in Pcds . keys ( ) :
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 ,
{ SkuName : SkuInfo } ,
False ,
None ,
IsDsc = True )
for pcd in Pcds . values ( ) :
pcdDecObject = self . _DecPcds [ pcd . TokenCName , pcd . TokenSpaceGuidCName ]
2017-12-22 13:07:54 +01:00
# Only fix the value while no value provided in DSC file.
for sku in pcd . SkuInfoList . values ( ) :
if ( sku . DefaultValue == " " or sku . DefaultValue == None ) :
sku . DefaultValue = pcdDecObject . DefaultValue
2017-11-24 07:30:11 +01:00
if ' DEFAULT ' not in pcd . SkuInfoList . keys ( ) and ' COMMON ' not in pcd . SkuInfoList . keys ( ) :
valuefromDec = pcdDecObject . DefaultValue
SkuInfo = SkuInfoClass ( ' DEFAULT ' , ' 0 ' , ' ' , ' ' , ' ' , ' ' , ' ' , valuefromDec )
pcd . SkuInfoList [ ' DEFAULT ' ] = SkuInfo
elif ' DEFAULT ' not in pcd . SkuInfoList . keys ( ) and ' COMMON ' in pcd . SkuInfoList . keys ( ) :
pcd . SkuInfoList [ ' DEFAULT ' ] = pcd . SkuInfoList [ ' COMMON ' ]
del ( pcd . SkuInfoList [ ' COMMON ' ] )
elif ' DEFAULT ' in pcd . SkuInfoList . keys ( ) and ' COMMON ' in pcd . SkuInfoList . keys ( ) :
del ( pcd . SkuInfoList [ ' COMMON ' ] )
2017-12-01 15:00:07 +01:00
map ( self . FilterSkuSettings , Pcds . values ( ) )
2017-11-24 07:30:11 +01:00
return Pcds
2017-12-01 15:00:07 +01:00
def FilterSkuSettings ( self , PcdObj ) :
if self . SkuIdMgr . SkuUsageType == self . SkuIdMgr . SINGLE :
if ' DEFAULT ' in PcdObj . SkuInfoList . keys ( ) and self . SkuIdMgr . SystemSkuId not in PcdObj . SkuInfoList . keys ( ) :
PcdObj . SkuInfoList [ self . SkuIdMgr . SystemSkuId ] = PcdObj . SkuInfoList [ ' DEFAULT ' ]
PcdObj . SkuInfoList = { ' DEFAULT ' : PcdObj . SkuInfoList [ self . SkuIdMgr . SystemSkuId ] }
PcdObj . SkuInfoList [ ' DEFAULT ' ] . SkuIdName = ' DEFAULT '
PcdObj . SkuInfoList [ ' DEFAULT ' ] . SkuId = ' 0 '
elif self . SkuIdMgr . SkuUsageType == self . SkuIdMgr . DEFAULT :
PcdObj . SkuInfoList = { ' DEFAULT ' : PcdObj . SkuInfoList [ ' DEFAULT ' ] }
return PcdObj
2017-11-24 07:30:11 +01:00
def CompareVarAttr ( self , 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
2017-12-22 13:46:15 +01:00
def CompletePcdValues ( self , PcdSet ) :
Pcds = { }
DefaultStoreObj = DefaultStore ( self . _GetDefaultStores ( ) )
2017-12-22 13:04:04 +01:00
SkuIds = set ( [ ( skuid , skuobj . SkuId ) for pcdobj in PcdSet . values ( ) for skuid , skuobj in pcdobj . SkuInfoList . items ( ) ] )
2017-12-19 09:26:16 +01:00
SkuIds = self . SkuIdMgr . AvailableSkuIdSet
2017-12-22 13:46:15 +01:00
DefaultStores = set ( [ storename for pcdobj in PcdSet . values ( ) for skuobj in pcdobj . SkuInfoList . values ( ) for storename in skuobj . DefaultStoreDict . keys ( ) ] )
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 :
2017-12-22 13:04:04 +01:00
skuobj . DefaultStoreDict [ defaultstorename ] = copy . deepcopy ( skuobj . DefaultStoreDict [ mindefaultstorename ] )
2017-12-22 13:46:15 +01:00
skuobj . HiiDefaultValue = skuobj . DefaultStoreDict [ mindefaultstorename ]
2017-12-19 09:26:16 +01:00
for skuname , skuid in SkuIds . items ( ) :
2017-12-22 13:04:04 +01:00
if skuname not in PcdObj . SkuInfoList :
nextskuid = self . SkuIdMgr . GetNextSkuId ( skuname )
2017-12-22 13:46:15 +01:00
while nextskuid not in PcdObj . SkuInfoList :
nextskuid = self . SkuIdMgr . GetNextSkuId ( nextskuid )
2017-12-22 13:04:04 +01:00
PcdObj . SkuInfoList [ skuname ] = copy . deepcopy ( PcdObj . SkuInfoList [ nextskuid ] )
PcdObj . SkuInfoList [ skuname ] . SkuId = skuid
PcdObj . SkuInfoList [ skuname ] . SkuIdName = skuname
2017-12-22 13:46:15 +01:00
if PcdType in [ self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_HII ] , self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_EX_HII ] ] :
PcdObj . DefaultValue = PcdObj . SkuInfoList . values ( ) [ 0 ] . HiiDefaultValue if self . SkuIdMgr . SkuUsageType == self . SkuIdMgr . SINGLE else PcdObj . SkuInfoList [ " DEFAULT " ] . HiiDefaultValue
Pcds [ PcdCName , TokenSpaceGuid ] = PcdObj
return Pcds
2017-11-24 07:30:11 +01:00
## 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 = sdict ( )
#
# tdict is a special dict kind of type, used for selecting correct
# PCD settings for certain ARCH and SKU
#
2017-12-22 13:46:15 +01:00
PcdDict = tdict ( True , 5 )
2017-11-24 07:30:11 +01:00
PcdSet = set ( )
RecordList = self . _RawData [ Type , self . _Arch ]
# Find out all possible PCD candidates for self._Arch
2017-12-22 13:46:15 +01:00
AvailableSkuIdSet = copy . copy ( self . SkuIds )
2017-12-22 13:04:04 +01:00
DefaultStoresDefine = self . _GetDefaultStores ( )
2017-11-24 07:30:11 +01:00
2017-12-22 13:46:15 +01:00
for TokenSpaceGuid , PcdCName , Setting , Arch , SkuName , DefaultStore , Dummy4 , Dummy5 in RecordList :
2017-12-22 13:04:04 +01:00
SkuName = SkuName . upper ( )
SkuName = ' DEFAULT ' if SkuName == ' COMMON ' else SkuName
DefaultStore = DefaultStore . upper ( )
2017-12-22 13:46:15 +01:00
if DefaultStore == " COMMON " :
DefaultStore = " STANDARD "
2017-11-24 07:30:11 +01:00
if SkuName not in AvailableSkuIdSet :
2017-12-22 13:04:04 +01:00
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 )
2017-11-24 07:30:11 +01:00
if " . " not in TokenSpaceGuid :
2017-12-22 13:46:15 +01:00
PcdSet . add ( ( PcdCName , TokenSpaceGuid , SkuName , DefaultStore , Dummy4 ) )
PcdDict [ Arch , SkuName , PcdCName , TokenSpaceGuid , DefaultStore ] = Setting
2017-11-24 07:30:11 +01:00
# Remove redundant PCD candidates, per the ARCH and SKU
2017-12-22 13:46:15 +01:00
for PcdCName , TokenSpaceGuid , SkuName , DefaultStore , Dummy4 in PcdSet :
2017-11-24 07:30:11 +01:00
2017-12-22 13:46:15 +01:00
Setting = PcdDict [ self . _Arch , SkuName , PcdCName , TokenSpaceGuid , DefaultStore ]
2017-11-24 07:30:11 +01:00
if Setting == 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 re . match ( r ' [ \ t \ s]*0[xX][a-fA-F0-9]+$ ' , 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 self . 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 . keys ( ) :
pcdObject = Pcds [ PcdCName , TokenSpaceGuid ]
2017-12-22 13:46:15 +01:00
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
2017-11-24 07:30:11 +01:00
else :
2017-12-22 13:46:15 +01:00
SkuInfo = SkuInfoClass ( SkuName , self . SkuIds [ SkuName ] [ 0 ] , VariableName , VariableGuid , VariableOffset , DefaultValue , VariableAttribute = VarAttribute , DefaultStore = { DefaultStore : DefaultValue } )
2017-11-24 07:30:11 +01:00
Pcds [ PcdCName , TokenSpaceGuid ] = PcdClassObject (
PcdCName ,
TokenSpaceGuid ,
self . _PCD_TYPE_STRING_ [ Type ] ,
' ' ,
DefaultValue ,
' ' ,
' ' ,
{ SkuName : SkuInfo } ,
False ,
None ,
pcdDecObject . validateranges ,
pcdDecObject . validlists ,
pcdDecObject . expressions ,
IsDsc = True )
for pcd in Pcds . values ( ) :
SkuInfoObj = pcd . SkuInfoList . values ( ) [ 0 ]
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 ( sku . HiiDefaultValue == " " or sku . HiiDefaultValue == None ) :
sku . HiiDefaultValue = pcdDecObject . DefaultValue
if ' DEFAULT ' not in pcd . SkuInfoList . keys ( ) and ' COMMON ' not in pcd . SkuInfoList . keys ( ) :
valuefromDec = pcdDecObject . DefaultValue
2017-12-22 13:04:04 +01:00
SkuInfo = SkuInfoClass ( ' DEFAULT ' , ' 0 ' , SkuInfoObj . VariableName , SkuInfoObj . VariableGuid , SkuInfoObj . VariableOffset , valuefromDec , VariableAttribute = SkuInfoObj . VariableAttribute , DefaultStore = { DefaultStore : valuefromDec } )
2017-11-24 07:30:11 +01:00
pcd . SkuInfoList [ ' DEFAULT ' ] = SkuInfo
elif ' DEFAULT ' not in pcd . SkuInfoList . keys ( ) and ' COMMON ' in pcd . SkuInfoList . keys ( ) :
pcd . SkuInfoList [ ' DEFAULT ' ] = pcd . SkuInfoList [ ' COMMON ' ]
del ( pcd . SkuInfoList [ ' COMMON ' ] )
elif ' DEFAULT ' in pcd . SkuInfoList . keys ( ) and ' COMMON ' in pcd . SkuInfoList . keys ( ) :
del ( pcd . SkuInfoList [ ' COMMON ' ] )
if pcd . MaxDatumSize . strip ( ) :
MaxSize = int ( pcd . MaxDatumSize , 0 )
else :
MaxSize = 0
if pcdDecObject . DatumType == ' VOID* ' :
2017-12-22 13:04:04 +01:00
for ( _ , skuobj ) in pcd . SkuInfoList . items ( ) :
2017-11-24 07:30:11 +01:00
datalen = 0
2017-12-22 13:14:29 +01:00
skuobj . HiiDefaultValue = StringToArray ( skuobj . HiiDefaultValue )
datalen = len ( skuobj . HiiDefaultValue . split ( " , " ) )
2017-11-24 07:30:11 +01:00
if datalen > MaxSize :
MaxSize = datalen
2017-12-22 13:14:29 +01:00
for defaultst in skuobj . DefaultStoreDict :
skuobj . DefaultStoreDict [ defaultst ] = StringToArray ( skuobj . DefaultStoreDict [ defaultst ] )
pcd . DefaultValue = StringToArray ( pcd . DefaultValue )
2017-11-24 07:30:11 +01:00
pcd . MaxDatumSize = str ( MaxSize )
2017-12-22 13:04:04 +01:00
rt , invalidhii = self . 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 )
2017-12-01 15:00:07 +01:00
map ( self . FilterSkuSettings , Pcds . values ( ) )
2017-11-24 07:30:11 +01:00
return Pcds
2017-12-22 13:04:04 +01:00
def CheckVariableNameAssignment ( self , 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 , [ ]
2017-11-24 07:30:11 +01:00
## Retrieve dynamic VPD PCD settings
#
# @param Type PCD type
#
# @retval a dict object contains settings of given PCD type
#
def _GetDynamicVpdPcd ( self , Type ) :
Pcds = sdict ( )
#
# 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 ]
2017-12-22 13:46:15 +01:00
AvailableSkuIdSet = copy . copy ( self . SkuIds )
2017-11-24 07:30:11 +01:00
2017-12-22 13:46:15 +01:00
for TokenSpaceGuid , PcdCName , Setting , Arch , SkuName , Dummy3 , Dummy4 , Dummy5 in RecordList :
2017-12-22 13:04:04 +01:00
SkuName = SkuName . upper ( )
SkuName = ' DEFAULT ' if SkuName == ' COMMON ' else SkuName
2017-11-24 07:30:11 +01:00
if SkuName not in AvailableSkuIdSet :
2017-12-22 13:04:04 +01:00
EdkLogger . error ( ' build ' , PARAMETER_INVALID , ' Sku %s is not defined in [SkuIds] section ' % SkuName ,
File = self . MetaFile , Line = Dummy5 )
2017-11-24 07:30:11 +01:00
if " . " not in TokenSpaceGuid :
PcdList . append ( ( PcdCName , TokenSpaceGuid , SkuName , Dummy4 ) )
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 == 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 )
2017-12-22 13:46:15 +01:00
SkuInfo = SkuInfoClass ( SkuName , self . SkuIds [ SkuName ] [ 0 ] , ' ' , ' ' , ' ' , ' ' , VpdOffset , InitialValue )
2017-11-24 07:30:11 +01:00
if ( PcdCName , TokenSpaceGuid ) in Pcds . keys ( ) :
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 ,
{ SkuName : SkuInfo } ,
False ,
None ,
IsDsc = True )
for pcd in Pcds . values ( ) :
SkuInfoObj = pcd . SkuInfoList . values ( ) [ 0 ]
pcdDecObject = self . _DecPcds [ pcd . TokenCName , pcd . TokenSpaceGuidCName ]
2017-12-22 13:07:54 +01:00
# Only fix the value while no value provided in DSC file.
for sku in pcd . SkuInfoList . values ( ) :
if ( sku . DefaultValue == " " or sku . DefaultValue == None ) :
sku . DefaultValue = pcdDecObject . DefaultValue
2017-11-24 07:30:11 +01:00
if ' DEFAULT ' not in pcd . SkuInfoList . keys ( ) and ' COMMON ' not in pcd . SkuInfoList . keys ( ) :
valuefromDec = pcdDecObject . DefaultValue
SkuInfo = SkuInfoClass ( ' DEFAULT ' , ' 0 ' , ' ' , ' ' , ' ' , ' ' , SkuInfoObj . VpdOffset , valuefromDec )
pcd . SkuInfoList [ ' DEFAULT ' ] = SkuInfo
elif ' DEFAULT ' not in pcd . SkuInfoList . keys ( ) and ' COMMON ' in pcd . SkuInfoList . keys ( ) :
pcd . SkuInfoList [ ' DEFAULT ' ] = pcd . SkuInfoList [ ' COMMON ' ]
del ( pcd . SkuInfoList [ ' COMMON ' ] )
elif ' DEFAULT ' in pcd . SkuInfoList . keys ( ) and ' COMMON ' in pcd . SkuInfoList . keys ( ) :
del ( pcd . SkuInfoList [ ' COMMON ' ] )
2017-12-01 15:00:07 +01:00
map ( self . FilterSkuSettings , Pcds . values ( ) )
2017-11-24 07:30:11 +01:00
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 )
## 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
2017-12-26 04:33:33 +01:00
@property
def DecPcds ( self ) :
if self . _DecPcds == 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 = GetDeclaredPcd ( self , self . _Bdb , self . _Arch , self . _Target , self . _Toolchain , PkgSet )
return self . _DecPcds
2017-11-24 07:30:11 +01:00
_Macros = property ( _GetMacros )
Arch = property ( _GetArch , _SetArch )
Platform = property ( _GetPlatformName )
PlatformName = property ( _GetPlatformName )
Guid = property ( _GetFileGuid )
Version = property ( _GetVersion )
DscSpecification = property ( _GetDscSpec )
OutputDirectory = property ( _GetOutpuDir )
SupArchList = property ( _GetSupArch )
BuildTargets = property ( _GetBuildTarget )
SkuName = property ( _GetSkuName , _SetSkuName )
PcdInfoFlag = property ( _GetPcdInfoFlag )
VarCheckFlag = property ( _GetVarCheckFlag )
FlashDefinition = property ( _GetFdfFile )
Prebuild = property ( _GetPrebuild )
Postbuild = property ( _GetPostbuild )
BuildNumber = property ( _GetBuildNumber )
MakefileName = property ( _GetMakefileName )
BsBaseAddress = property ( _GetBsBaseAddress )
RtBaseAddress = property ( _GetRtBaseAddress )
LoadFixAddress = property ( _GetLoadFixAddress )
RFCLanguages = property ( _GetRFCLanguages )
ISOLanguages = property ( _GetISOLanguages )
VpdToolGuid = property ( _GetVpdToolGuid )
SkuIds = property ( _GetSkuIds )
Modules = property ( _GetModules )
LibraryInstances = property ( _GetLibraryInstances )
LibraryClasses = property ( _GetLibraryClasses )
Pcds = property ( _GetPcds )
BuildOptions = property ( _GetBuildOptions )