2017-11-24 07:30:11 +01:00
## @file
# This file is used to create a database used by build tool
#
2018-01-22 06:38:39 +01:00
# Copyright (c) 2008 - 2018, 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 *
2018-03-07 07:14:43 +01:00
from Common . Expression import *
2017-11-24 07:30:11 +01:00
from CommonDataClass . CommonClass import SkuInfoClass
2017-12-26 06:16:17 +01:00
from Common . TargetTxtClassObject import *
from Common . ToolDefClassObject import *
2017-11-24 07:30:11 +01:00
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
2018-02-28 06:59:19 +01:00
from Common . Misc import SaveFileOnChange
2017-11-24 07:30:11 +01:00
from Workspace . BuildClassObject import PlatformBuildClassObject , StructurePcd , PcdClassObject , ModuleBuildClassObject
2018-02-28 06:59:20 +01:00
from collections import OrderedDict
2017-11-24 07:30:11 +01:00
#
# 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
#
'''
2017-12-26 06:16:17 +01:00
WindowsCFLAGS = ' CFLAGS = $(CFLAGS) /wd4200 /wd4034 /wd4101 '
LinuxCFLAGS = ' BUILD_CFLAGS += -Wno-pointer-to-int-cast -Wno-unused-variable '
2017-11-24 07:30:11 +01:00
PcdMakefileEnd = '''
! INCLUDE $ ( BASE_TOOLS_PATH ) \Source \C \Makefiles \ms . common
LIBS = $ ( LIB_PATH ) \Common . lib
! INCLUDE $ ( BASE_TOOLS_PATH ) \Source \C \Makefiles \ms . app
'''
PcdGccMakefile = '''
MAKEROOT ? = $ ( EDK_TOOLS_PATH ) / Source / C
LIBS = - lCommon
'''
2018-04-13 22:51:31 +02:00
## 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]+$ ' )
2018-03-16 10:40:00 +01:00
## 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 , 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
if FileContent [ 0 ] == 0xff or FileContent [ 0 ] == 0xfe :
FileContent = unicode ( FileContent , " utf-16 " )
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
2017-11-24 07:30:11 +01:00
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
2017-12-26 06:16:17 +01:00
self . _ToolChainFamily = None
2017-11-24 07:30:11 +01:00
self . _Clear ( )
self . _HandleOverridePath ( )
2018-02-28 06:59:19 +01:00
self . WorkspaceDir = os . getenv ( " WORKSPACE " ) if os . getenv ( " WORKSPACE " ) else " "
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 )
2018-02-28 06:59:19 +01:00
@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 )
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 ]
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 ) :
2018-03-26 22:25:43 +02:00
if self . __Macros is None :
2017-11-24 07:30:11 +01:00
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 :
2018-03-26 22:25:43 +02:00
if self . _SkuName is None :
2017-11-24 07:30:11 +01:00
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 ) :
2018-03-26 22:25:43 +02:00
if self . _PlatformName is None :
if self . _Header is None :
2017-11-24 07:30:11 +01:00
self . _GetHeaderInfo ( )
2018-03-26 22:25:43 +02:00
if self . _PlatformName is None :
2017-11-24 07:30:11 +01:00
EdkLogger . error ( ' build ' , ATTRIBUTE_NOT_AVAILABLE , " No PLATFORM_NAME " , File = self . MetaFile )
return self . _PlatformName
## Retrieve file guid
def _GetFileGuid ( self ) :
2018-03-26 22:25:43 +02:00
if self . _Guid is None :
if self . _Header is None :
2017-11-24 07:30:11 +01:00
self . _GetHeaderInfo ( )
2018-03-26 22:25:43 +02:00
if self . _Guid is None :
2017-11-24 07:30:11 +01:00
EdkLogger . error ( ' build ' , ATTRIBUTE_NOT_AVAILABLE , " No PLATFORM_GUID " , File = self . MetaFile )
return self . _Guid
## Retrieve platform version
def _GetVersion ( self ) :
2018-03-26 22:25:43 +02:00
if self . _Version is None :
if self . _Header is None :
2017-11-24 07:30:11 +01:00
self . _GetHeaderInfo ( )
2018-03-26 22:25:43 +02:00
if self . _Version is None :
2017-11-24 07:30:11 +01:00
EdkLogger . error ( ' build ' , ATTRIBUTE_NOT_AVAILABLE , " No PLATFORM_VERSION " , File = self . MetaFile )
return self . _Version
## Retrieve platform description file version
def _GetDscSpec ( self ) :
2018-03-26 22:25:43 +02:00
if self . _DscSpecification is None :
if self . _Header is None :
2017-11-24 07:30:11 +01:00
self . _GetHeaderInfo ( )
2018-03-26 22:25:43 +02:00
if self . _DscSpecification is None :
2017-11-24 07:30:11 +01:00
EdkLogger . error ( ' build ' , ATTRIBUTE_NOT_AVAILABLE , " No DSC_SPECIFICATION " , File = self . MetaFile )
return self . _DscSpecification
## Retrieve OUTPUT_DIRECTORY
def _GetOutpuDir ( self ) :
2018-03-26 22:25:43 +02:00
if self . _OutputDirectory is None :
if self . _Header is None :
2017-11-24 07:30:11 +01:00
self . _GetHeaderInfo ( )
2018-03-26 22:25:43 +02:00
if self . _OutputDirectory is None :
2017-11-24 07:30:11 +01:00
self . _OutputDirectory = os . path . join ( " Build " , self . _PlatformName )
return self . _OutputDirectory
## Retrieve SUPPORTED_ARCHITECTURES
def _GetSupArch ( self ) :
2018-03-26 22:25:43 +02:00
if self . _SupArchList is None :
if self . _Header is None :
2017-11-24 07:30:11 +01:00
self . _GetHeaderInfo ( )
2018-03-26 22:25:43 +02:00
if self . _SupArchList is None :
2017-11-24 07:30:11 +01:00
EdkLogger . error ( ' build ' , ATTRIBUTE_NOT_AVAILABLE , " No SUPPORTED_ARCHITECTURES " , File = self . MetaFile )
return self . _SupArchList
## Retrieve BUILD_TARGETS
def _GetBuildTarget ( self ) :
2018-03-26 22:25:43 +02:00
if self . _BuildTargets is None :
if self . _Header is None :
2017-11-24 07:30:11 +01:00
self . _GetHeaderInfo ( )
2018-03-26 22:25:43 +02:00
if self . _BuildTargets is None :
2017-11-24 07:30:11 +01:00
EdkLogger . error ( ' build ' , ATTRIBUTE_NOT_AVAILABLE , " No BUILD_TARGETS " , File = self . MetaFile )
return self . _BuildTargets
def _GetPcdInfoFlag ( self ) :
2018-03-26 22:25:43 +02:00
if self . _PcdInfoFlag is None or self . _PcdInfoFlag . upper ( ) == ' FALSE ' :
2017-11-24 07:30:11 +01:00
return False
elif self . _PcdInfoFlag . upper ( ) == ' TRUE ' :
return True
else :
return False
def _GetVarCheckFlag ( self ) :
2018-03-26 22:25:43 +02:00
if self . _VarCheckFlag is None or self . _VarCheckFlag . upper ( ) == ' FALSE ' :
2017-11-24 07:30:11 +01:00
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 ) :
2018-03-26 22:25:43 +02:00
if self . _SkuName is None :
if self . _Header is None :
2017-11-24 07:30:11 +01:00
self . _GetHeaderInfo ( )
2018-03-26 22:25:43 +02:00
if self . _SkuName is 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
def _GetFdfFile ( self ) :
2018-03-26 22:25:43 +02:00
if self . _FlashDefinition is None :
if self . _Header is None :
2017-11-24 07:30:11 +01:00
self . _GetHeaderInfo ( )
2018-03-26 22:25:43 +02:00
if self . _FlashDefinition is None :
2017-11-24 07:30:11 +01:00
self . _FlashDefinition = ' '
return self . _FlashDefinition
def _GetPrebuild ( self ) :
2018-03-26 22:25:43 +02:00
if self . _Prebuild is None :
if self . _Header is None :
2017-11-24 07:30:11 +01:00
self . _GetHeaderInfo ( )
2018-03-26 22:25:43 +02:00
if self . _Prebuild is None :
2017-11-24 07:30:11 +01:00
self . _Prebuild = ' '
return self . _Prebuild
def _GetPostbuild ( self ) :
2018-03-26 22:25:43 +02:00
if self . _Postbuild is None :
if self . _Header is None :
2017-11-24 07:30:11 +01:00
self . _GetHeaderInfo ( )
2018-03-26 22:25:43 +02:00
if self . _Postbuild is None :
2017-11-24 07:30:11 +01:00
self . _Postbuild = ' '
return self . _Postbuild
## Retrieve FLASH_DEFINITION
def _GetBuildNumber ( self ) :
2018-03-26 22:25:43 +02:00
if self . _BuildNumber is None :
if self . _Header is None :
2017-11-24 07:30:11 +01:00
self . _GetHeaderInfo ( )
2018-03-26 22:25:43 +02:00
if self . _BuildNumber is None :
2017-11-24 07:30:11 +01:00
self . _BuildNumber = ' '
return self . _BuildNumber
## Retrieve MAKEFILE_NAME
def _GetMakefileName ( self ) :
2018-03-26 22:25:43 +02:00
if self . _MakefileName is None :
if self . _Header is None :
2017-11-24 07:30:11 +01:00
self . _GetHeaderInfo ( )
2018-03-26 22:25:43 +02:00
if self . _MakefileName is None :
2017-11-24 07:30:11 +01:00
self . _MakefileName = ' '
return self . _MakefileName
## Retrieve BsBaseAddress
def _GetBsBaseAddress ( self ) :
2018-03-26 22:25:43 +02:00
if self . _BsBaseAddress is None :
if self . _Header is None :
2017-11-24 07:30:11 +01:00
self . _GetHeaderInfo ( )
2018-03-26 22:25:43 +02:00
if self . _BsBaseAddress is None :
2017-11-24 07:30:11 +01:00
self . _BsBaseAddress = ' '
return self . _BsBaseAddress
## Retrieve RtBaseAddress
def _GetRtBaseAddress ( self ) :
2018-03-26 22:25:43 +02:00
if self . _RtBaseAddress is None :
if self . _Header is None :
2017-11-24 07:30:11 +01:00
self . _GetHeaderInfo ( )
2018-03-26 22:25:43 +02:00
if self . _RtBaseAddress is None :
2017-11-24 07:30:11 +01:00
self . _RtBaseAddress = ' '
return self . _RtBaseAddress
## Retrieve the top address for the load fix address
def _GetLoadFixAddress ( self ) :
2018-03-26 22:25:43 +02:00
if self . _LoadFixAddress is None :
if self . _Header is None :
2017-11-24 07:30:11 +01:00
self . _GetHeaderInfo ( )
2018-03-26 22:25:43 +02:00
if self . _LoadFixAddress is None :
2017-11-24 07:30:11 +01:00
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 ) :
2018-03-26 22:25:43 +02:00
if self . _RFCLanguages is None :
if self . _Header is None :
2017-11-24 07:30:11 +01:00
self . _GetHeaderInfo ( )
2018-03-26 22:25:43 +02:00
if self . _RFCLanguages is None :
2017-11-24 07:30:11 +01:00
self . _RFCLanguages = [ ]
return self . _RFCLanguages
## Retrieve ISOLanguage filter
def _GetISOLanguages ( self ) :
2018-03-26 22:25:43 +02:00
if self . _ISOLanguages is None :
if self . _Header is None :
2017-11-24 07:30:11 +01:00
self . _GetHeaderInfo ( )
2018-03-26 22:25:43 +02:00
if self . _ISOLanguages is None :
2017-11-24 07:30:11 +01:00
self . _ISOLanguages = [ ]
return self . _ISOLanguages
## Retrieve the GUID string for VPD tool
def _GetVpdToolGuid ( self ) :
2018-03-26 22:25:43 +02:00
if self . _VpdToolGuid is None :
if self . _Header is None :
2017-11-24 07:30:11 +01:00
self . _GetHeaderInfo ( )
2018-03-26 22:25:43 +02:00
if self . _VpdToolGuid is None :
2017-11-24 07:30:11 +01:00
self . _VpdToolGuid = ' '
return self . _VpdToolGuid
## Retrieve [SkuIds] section information
def _GetSkuIds ( self ) :
2018-03-26 22:25:43 +02:00
if self . _SkuIds is None :
2018-04-03 23:03:09 +02:00
self . _SkuIds = OrderedDict ( )
2017-11-24 07:30:11 +01:00
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 ] )
2018-04-13 22:51:31 +02:00
if not Pattern . match ( Record [ 0 ] ) and not HexPattern . match ( Record [ 0 ] ) :
2018-01-22 06:38:39 +01:00
EdkLogger . error ( ' build ' , FORMAT_INVALID , " The format of the Sku ID number is invalid. It only support Integer and HexNumber " ,
2017-12-22 13:46:15 +01:00
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 ] )
2018-04-13 22:51:29 +02:00
self . _SkuIds [ Record [ 1 ] . upper ( ) ] = ( str ( DscBuildData . ToInt ( 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
2018-04-13 22:51:29 +02:00
@staticmethod
def ToInt ( intstr ) :
2017-12-22 13:46:15 +01:00
return int ( intstr , 16 ) if intstr . upper ( ) . startswith ( " 0X " ) else int ( intstr )
2018-04-13 22:51:29 +02:00
2017-12-22 13:46:15 +01:00
def _GetDefaultStores ( self ) :
2018-03-26 22:25:43 +02:00
if self . DefaultStores is None :
2018-04-03 23:03:09 +02:00
self . DefaultStores = OrderedDict ( )
2017-12-22 13:46:15 +01:00
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 ] )
2018-04-13 22:51:31 +02:00
if not Pattern . match ( Record [ 0 ] ) and not HexPattern . match ( Record [ 0 ] ) :
2018-01-22 06:46:52 +01:00
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 ] )
2018-04-13 22:51:29 +02:00
self . DefaultStores [ Record [ 1 ] . upper ( ) ] = ( DscBuildData . 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 ) :
2018-03-26 22:25:43 +02:00
if self . _Modules is not None :
2017-11-24 07:30:11 +01:00
return self . _Modules
2018-04-03 23:03:09 +02:00
self . _Modules = OrderedDict ( )
2017-11-24 07:30:11 +01:00
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 ]
2018-02-26 08:36:47 +01:00
# the format is PcdName| Value | VOID* | MaxDatumSize
if len ( TokenList ) > 2 :
MaxDatumSize = TokenList [ 2 ]
2017-11-24 07:30:11 +01:00
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 ) :
2018-03-26 22:25:43 +02:00
if self . _LibraryInstances is None :
2017-11-24 07:30:11 +01:00
self . _GetLibraryClasses ( )
return self . _LibraryInstances
## Retrieve [LibraryClasses] information
def _GetLibraryClasses ( self ) :
2018-03-26 22:25:43 +02:00
if self . _LibraryClasses is None :
2017-11-24 07:30:11 +01:00
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 ]
2018-03-26 22:25:43 +02:00
if LibraryInstance is None :
2017-11-24 07:30:11 +01:00
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 ) :
2018-03-26 22:25:43 +02:00
if self . _DecPcds is 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-26 09:17:13 +01:00
self . _DecPcds , self . _GuidDict = GetDeclaredPcd ( self , self . _Bdb , self . _Arch , self . _Target , self . _Toolchain , PkgSet )
2018-02-07 14:37:26 +01:00
self . _GuidDict . update ( GlobalData . gPlatformPcds )
2017-12-22 13:04:04 +01:00
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 ) )
2018-01-26 17:28:05 +01:00
if ValueList [ Index ] :
DatumType = self . _DecPcds [ PcdCName , TokenSpaceGuid ] . DatumType
2017-11-24 07:30:11 +01:00
try :
2018-01-26 17:28:05 +01:00
ValueList [ Index ] = ValueExpressionEx ( ValueList [ Index ] , DatumType , self . _GuidDict ) ( True )
2017-12-26 09:17:13 +01:00
except BadExpression , Value :
2018-01-26 17:28:05 +01:00
EdkLogger . error ( ' Parser ' , FORMAT_INVALID , Value , File = self . MetaFile , Line = LineNo ,
ExtraData = " PCD [ %s . %s ] Value \" %s \" " % (
TokenSpaceGuid , PcdCName , ValueList [ Index ] ) )
2017-11-24 07:30:11 +01:00
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 )
2018-01-26 17:28:05 +01:00
2017-11-24 07:30:11 +01:00
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 ( ) :
2018-01-31 10:32:01 +01:00
EdkLogger . error ( ' build ' , FORMAT_INVALID , " Pcd datumtype used in DSC file is not the same as its declaration in DEC file. " , File = self . MetaFile , Line = LineNo ,
2017-12-01 07:15:59 +01:00
ExtraData = " %s . %s | %s " % ( TokenSpaceGuid , PcdCName , Setting ) )
2018-01-26 17:28:05 +01:00
if ( TokenSpaceGuid + ' . ' + PcdCName ) in GlobalData . gPlatformPcds :
if GlobalData . gPlatformPcds [ TokenSpaceGuid + ' . ' + PcdCName ] != ValueList [ Index ] :
GlobalData . gPlatformPcds [ TokenSpaceGuid + ' . ' + PcdCName ] = ValueList [ Index ]
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 )
2018-04-11 01:17:20 +02:00
if TAB_DEFAULT_STORES_DEFAULT not in skuobj . DefaultStoreDict :
2017-12-22 13:04:04 +01:00
PcdDefaultStoreSet = set ( [ defaultstorename for defaultstorename in skuobj . DefaultStoreDict ] )
mindefaultstorename = DefaultStoreMgr . GetMin ( PcdDefaultStoreSet )
2018-04-11 01:17:20 +02:00
skuobj . DefaultStoreDict [ TAB_DEFAULT_STORES_DEFAULT ] = copy . deepcopy ( skuobj . DefaultStoreDict [ mindefaultstorename ] )
2017-12-22 13:04:04 +01:00
return Pcds
2018-01-31 09:49:14 +01:00
def RecoverCommandLinePcd ( self ) :
2018-03-08 06:56:21 +01:00
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 ( " DEFAULT " ) . HiiDefaultValue
else :
pcd . PcdValueFromComm = pcd . SkuInfoList . get ( " 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 ] )
2018-01-31 09:49:14 +01:00
def __ParsePcdFromCommandLine ( self ) :
if GlobalData . BuildOptionPcd :
for i , pcd in enumerate ( GlobalData . BuildOptionPcd ) :
if type ( pcd ) is 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 = ' '
2018-03-07 07:14:43 +01:00
DisplayName = TokenCName
if FieldName :
DisplayName = TokenCName + ' . ' + FieldName
2018-01-31 09:49:14 +01:00
if not HasTokenSpace :
for key in self . DecPcds :
2018-03-07 07:14:43 +01:00
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 ] )
)
2018-01-31 09:49:14 +01:00
else :
if ( TokenCName , TokenSpaceGuidCName ) in self . DecPcds :
2018-03-12 08:09:03 +01:00
PcdDatumType = self . DecPcds [ ( TokenCName , TokenSpaceGuidCName ) ] . DatumType
2018-01-31 09:49:14 +01:00
FoundFlag = True
if not FoundFlag :
if HasTokenSpace :
2018-03-07 07:14:43 +01:00
EdkLogger . error ( ' build ' , AUTOGEN_ERROR , " The Pcd %s . %s is not found in the DEC file. " % ( TokenSpaceGuidCName , DisplayName ) )
2018-01-31 09:49:14 +01:00
else :
2018-03-07 07:14:43 +01:00
EdkLogger . error ( ' build ' , AUTOGEN_ERROR , " The Pcd %s is not found in the DEC file. " % ( DisplayName ) )
pcdvalue = pcdvalue . replace ( " \\ \\ \\ ' " , ' \\ \\ \\ " ' ) . replace ( ' \\ \' ' , ' \' ' ) . replace ( ' \\ \\ \\ " ' , " \\ ' " )
if FieldName :
2018-04-13 22:51:29 +02:00
pcdvalue = DscBuildData . HandleFlexiblePcd ( TokenSpaceGuidCName , TokenCName , pcdvalue , PcdDatumType , self . _GuidDict , FieldName )
2018-03-07 07:14:43 +01:00
else :
2018-04-13 22:51:29 +02:00
pcdvalue = DscBuildData . HandleFlexiblePcd ( TokenSpaceGuidCName , TokenCName , pcdvalue , PcdDatumType , self . _GuidDict )
2018-03-07 07:14:43 +01:00
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 ) )
2018-01-31 09:49:14 +01:00
for BuildData in self . _Bdb . _CACHE_ . values ( ) :
if BuildData . MetaFile . Ext == ' .dec ' or BuildData . MetaFile . Ext == ' .dsc ' :
continue
for key in BuildData . Pcds :
PcdItem = BuildData . Pcds [ key ]
if ( TokenSpaceGuidCName , TokenCName ) == ( PcdItem . TokenSpaceGuidCName , PcdItem . TokenCName ) and FieldName == " " :
2018-03-07 07:14:43 +01:00
PcdItem . DefaultValue = pcdvalue
2018-04-13 22:51:29 +02:00
@staticmethod
def HandleFlexiblePcd ( TokenSpaceGuidCName , TokenCName , PcdValue , PcdDatumType , GuidDict , FieldName = ' ' ) :
2018-03-07 07:14:43 +01:00
if FieldName :
IsArray = False
TokenCName + = ' . ' + FieldName
if PcdValue . startswith ( ' H ' ) :
if FieldName and IsFieldValueAnArray ( PcdValue [ 1 : ] ) :
PcdDatumType = ' VOID* '
IsArray = True
if FieldName and not IsArray :
return PcdValue
try :
PcdValue = ValueExpressionEx ( PcdValue [ 1 : ] , PcdDatumType , GuidDict ) ( True )
except BadExpression , 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 = ' VOID* '
IsArray = True
if FieldName and not IsArray :
return PcdValue
try :
PcdValue = ValueExpressionEx ( PcdValue , PcdDatumType , GuidDict ) ( True )
except BadExpression , 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 = ' VOID* '
IsArray = True
if FieldName and not IsArray :
return PcdValue
try :
PcdValue = ValueExpressionEx ( PcdValue , PcdDatumType , GuidDict ) ( True )
except BadExpression , 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 [ ' UINT8 ' , ' UINT16 ' , ' UINT32 ' , ' UINT64 ' , ' BOOLEAN ' ] :
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 = ' VOID* '
IsArray = True
if not IsArray :
return PcdValue
try :
PcdValue = ValueExpressionEx ( PcdValue , PcdDatumType , GuidDict ) ( True )
except BadExpression , Value :
EdkLogger . error ( ' Parser ' , FORMAT_INVALID , ' PCD [ %s . %s ] Value " %s " , %s ' %
( TokenSpaceGuidCName , TokenCName , PcdValue , Value ) )
return PcdValue
2017-11-24 07:30:11 +01:00
## Retrieve all PCD settings in platform
def _GetPcds ( self ) :
2018-03-26 22:25:43 +02:00
if self . _Pcds is None :
2018-04-03 23:03:09 +02:00
self . _Pcds = OrderedDict ( )
2018-01-31 09:49:14 +01:00
self . __ParsePcdFromCommandLine ( )
2017-11-24 07:30:11 +01:00
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 )
2018-03-02 11:11:13 +01:00
self . _Pcds = self . OverrideByFdfCommOverAll ( 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 )
2018-03-02 11:11:13 +01:00
2018-01-31 09:49:14 +01:00
self . RecoverCommandLinePcd ( )
2017-11-24 07:30:11 +01:00
return self . _Pcds
## Retrieve [BuildOptions]
def _GetBuildOptions ( self ) :
2018-03-26 22:25:43 +02:00
if self . _BuildOptions is None :
2018-04-03 23:03:09 +02:00
self . _BuildOptions = OrderedDict ( )
2017-11-24 07:30:11 +01:00
#
# 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 ) :
2018-03-26 22:25:43 +02:00
if self . _ModuleTypeOptions is None :
2018-04-03 23:03:09 +02:00
self . _ModuleTypeOptions = OrderedDict ( )
2017-11-24 07:30:11 +01:00
if ( Edk , ModuleType ) not in self . _ModuleTypeOptions :
2018-04-03 23:03:09 +02:00
options = OrderedDict ( )
2017-11-24 07:30:11 +01:00
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
2018-04-13 22:51:29 +02:00
@staticmethod
def OverrideByFdfComm ( StruPcds ) :
2018-03-02 11:11:13 +01:00
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 ] )
2018-01-31 09:49:14 +01:00
GlobalPcds = set ( [ ( item [ 0 ] , item [ 1 ] ) for item in StructurePcdInCom . keys ( ) ] )
for Pcd in StruPcds . values ( ) :
if ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName ) not in GlobalPcds :
continue
2018-03-02 11:11:13 +01:00
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 ]
2018-01-31 09:49:14 +01:00
return StruPcds
2018-04-13 22:51:29 +02:00
2018-01-31 09:49:14 +01:00
def OverrideByFdfCommOverAll ( self , AllPcds ) :
def CheckStructureInComm ( commpcds ) :
if not commpcds :
return False
if len ( commpcds [ 0 ] ) == 5 :
return True
return False
2017-11-24 07:30:11 +01:00
2018-01-31 09:49:14 +01:00
if CheckStructureInComm ( GlobalData . BuildOptionPcd ) :
StructurePcdInCom = { ( item [ 0 ] , item [ 1 ] , item [ 2 ] ) : ( item [ 3 ] , item [ 4 ] ) for item in GlobalData . BuildOptionPcd } if GlobalData . BuildOptionPcd else { }
NoFiledValues = { ( item [ 0 ] , item [ 1 ] ) : StructurePcdInCom [ item ] for item in StructurePcdInCom if not item [ 2 ] }
else :
NoFiledValues = { ( item [ 0 ] , item [ 1 ] ) : [ item [ 2 ] ] for item in GlobalData . BuildOptionPcd }
for Guid , Name in NoFiledValues :
if ( Name , Guid ) in AllPcds :
Pcd = AllPcds . get ( ( Name , Guid ) )
2018-03-02 11:11:13 +01:00
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 :
2018-03-08 06:56:21 +01:00
Pcd . PcdValueFromComm = NoFiledValues [ ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName ) ] [ 0 ]
2018-03-02 11:11:13 +01:00
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 ]
2018-03-21 03:36:59 +01:00
if Pcd . Type in [ self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_EX_HII ] , self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_HII ] ] :
if Pcd . DatumType == " 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 )
2018-01-31 09:49:14 +01:00
else :
PcdInDec = self . DecPcds . get ( ( Name , Guid ) )
if PcdInDec :
2018-03-08 06:56:21 +01:00
PcdInDec . PcdValueFromComm = NoFiledValues [ ( Guid , Name ) ] [ 0 ]
2018-01-31 09:49:14 +01:00
if PcdInDec . Type in [ self . _PCD_TYPE_STRING_ [ MODEL_PCD_FIXED_AT_BUILD ] ,
2018-03-20 07:57:04 +01:00
self . _PCD_TYPE_STRING_ [ MODEL_PCD_PATCHABLE_IN_MODULE ] ,
self . _PCD_TYPE_STRING_ [ MODEL_PCD_FEATURE_FLAG ] ] :
2018-01-31 09:49:14 +01:00
self . Pcds [ Name , Guid ] = copy . deepcopy ( PcdInDec )
self . Pcds [ Name , Guid ] . DefaultValue = NoFiledValues [ ( Guid , Name ) ] [ 0 ]
return AllPcds
2017-11-24 07:30:11 +01:00
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 :
2018-01-31 09:49:14 +01:00
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 )
2018-02-28 06:59:20 +01:00
S_pcd_set = OrderedDict ( )
2017-11-24 07:30:11 +01:00
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 )
2018-01-31 10:32:01 +01:00
if not isinstance ( str_pcd_dec , StructurePcd ) :
EdkLogger . error ( ' build ' , PARSER_ERROR ,
" Pcd ( %s . %s ) is not declared as Structure PCD 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
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 )
2018-03-02 11:11:14 +01:00
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 }
2017-11-24 07:30:11 +01:00
for str_pcd_data in StrPcdSet [ str_pcd ] :
2017-12-22 13:46:15 +01:00
if str_pcd_data [ 3 ] in SkuIds :
2018-04-11 01:17:20 +02:00
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 ] , TAB_DEFAULT_STORES_DEFAULT if str_pcd_data [ 4 ] == ' COMMON ' else str_pcd_data [ 4 ] , 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 [ 5 ] )
2017-12-22 13:46:15 +01:00
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 )
2018-02-07 05:10:29 +01:00
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 }
2017-11-24 07:30:11 +01:00
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
2018-02-28 06:59:21 +01:00
if skuid not in stru_pcd . SkuOverrideValues :
while nextskuid not in stru_pcd . SkuOverrideValues :
if nextskuid == " DEFAULT " :
NoDefault = True
break
nextskuid = self . SkuIdMgr . GetNextSkuId ( nextskuid )
2018-04-11 01:17:20 +02:00
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 } )
2018-02-28 06:59:21 +01:00
if not NoDefault :
stru_pcd . ValueChain [ ( skuid , ' ' ) ] = ( nextskuid , ' ' )
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 ] )
2018-02-28 06:59:21 +01:00
stru_pcd . ValueChain [ ( skuid , defaultstoreid ) ] = ( nextskuid , mindefaultstorename )
2018-04-13 22:51:29 +02:00
S_pcd_set = DscBuildData . OverrideByFdfComm ( S_pcd_set )
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 ) :
2018-04-03 23:03:09 +02:00
Pcds = OrderedDict ( )
2017-11-24 07:30:11 +01:00
#
# 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 ]
2018-04-03 23:03:09 +02:00
PcdValueDict = OrderedDict ( )
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 :
2018-01-31 10:32:01 +01:00
PcdSet . add ( ( PcdCName , TokenSpaceGuid , SkuName , Dummy5 ) )
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 ]
2018-03-26 22:25:43 +02:00
if Setting is None :
2017-11-24 07:30:11 +01:00
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
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 ] ] ) )
2018-04-13 22:51:29 +02:00
@staticmethod
def ExecuteCommand ( Command ) :
2017-11-24 07:30:11 +01:00
try :
Process = subprocess . Popen ( Command , stdout = subprocess . PIPE , stderr = subprocess . PIPE , shell = True )
except :
2018-01-31 10:32:01 +01:00
EdkLogger . error ( ' Build ' , COMMAND_FAILURE , ' Can not execute command: %s ' % Command )
2017-11-24 07:30:11 +01:00
Result = Process . communicate ( )
2018-01-31 10:32:01 +01:00
return Process . returncode , Result [ 0 ] , Result [ 1 ]
2017-11-24 07:30:11 +01:00
2018-04-13 22:51:29 +02:00
@staticmethod
def IntToCString ( Value , ValueSize ) :
2017-11-24 07:30:11 +01:00
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
2018-04-13 22:51:29 +02:00
@staticmethod
def GetPcdMaxSize ( Pcd ) :
2018-03-02 11:11:13 +01:00
MaxSize = int ( Pcd . MaxDatumSize , 10 ) if Pcd . MaxDatumSize else 0
if Pcd . DatumType not in [ ' BOOLEAN ' , ' UINT8 ' , ' UINT16 ' , ' UINT32 ' , ' UINT64 ' ] :
if Pcd . PcdValueFromComm :
if Pcd . PcdValueFromComm . startswith ( " { " ) and Pcd . PcdValueFromComm . endswith ( " } " ) :
MaxSize = max ( [ len ( Pcd . PcdValueFromComm . split ( " , " ) ) , MaxSize ] )
elif Pcd . PcdValueFromComm . startswith ( " \" " ) or Pcd . PcdValueFromComm . startswith ( " \' " ) :
MaxSize = max ( [ len ( Pcd . PcdValueFromComm ) - 2 + 1 , MaxSize ] )
elif Pcd . PcdValueFromComm . startswith ( " L \" " ) :
MaxSize = max ( [ 2 * ( len ( Pcd . PcdValueFromComm ) - 3 + 1 ) , MaxSize ] )
else :
MaxSize = max ( [ len ( Pcd . PcdValueFromComm ) , MaxSize ] )
elif Pcd . DatumType not in [ ' BOOLEAN ' , ' UINT8 ' ] :
MaxSize = 1
elif Pcd . DatumType == ' UINT16 ' :
MaxSize = 2
elif Pcd . DatumType == ' UINT32 ' :
MaxSize = 4
elif Pcd . DatumType == ' UINT64 ' :
MaxSize = 8
return MaxSize
2018-04-13 22:51:29 +02:00
2018-02-28 06:59:20 +01:00
def GenerateSizeFunction ( self , Pcd ) :
CApp = " // Default Value in Dec \n "
CApp = CApp + " void Cal_ %s _ %s _Size(UINT32 *Size) { \n " % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName )
for FieldList in [ Pcd . DefaultValues ] :
if not FieldList :
continue
for FieldName in FieldList :
FieldName = " . " + FieldName
2018-03-07 07:14:43 +01:00
IsArray = IsFieldValueAnArray ( FieldList [ FieldName . strip ( " . " ) ] [ 0 ] )
2018-02-28 06:59:20 +01:00
if IsArray and not ( FieldList [ FieldName . strip ( " . " ) ] [ 0 ] . startswith ( ' { GUID ' ) and FieldList [ FieldName . strip ( " . " ) ] [ 0 ] . endswith ( ' } ' ) ) :
try :
Value = ValueExpressionEx ( FieldList [ FieldName . strip ( " . " ) ] [ 0 ] , " 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 )
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] '
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 ); // From %s Line %d Value %s \n ' % ( Pcd . DatumType , FieldName . strip ( " . " ) , ArrayIndex + 1 , FieldList [ FieldName_ori ] [ 1 ] , FieldList [ FieldName_ori ] [ 2 ] , FieldList [ FieldName_ori ] [ 0 ] )
for skuname in Pcd . SkuOverrideValues :
if skuname == " COMMON " :
continue
for defaultstorenameitem in Pcd . SkuOverrideValues [ skuname ] :
CApp = CApp + " // SkuName: %s , DefaultStoreName: %s \n " % ( skuname , defaultstorenameitem )
for FieldList in [ Pcd . SkuOverrideValues [ skuname ] . get ( defaultstorenameitem ) ] :
if not FieldList :
continue
for FieldName in FieldList :
FieldName = " . " + FieldName
2018-03-07 07:14:43 +01:00
IsArray = IsFieldValueAnArray ( FieldList [ FieldName . strip ( " . " ) ] [ 0 ] )
2018-02-28 06:59:20 +01:00
if IsArray and not ( FieldList [ FieldName . strip ( " . " ) ] [ 0 ] . startswith ( ' { GUID ' ) and FieldList [ FieldName . strip ( " . " ) ] [ 0 ] . endswith ( ' } ' ) ) :
try :
Value = ValueExpressionEx ( FieldList [ FieldName . strip ( " . " ) ] [ 0 ] , " 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 )
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] '
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 ); // From %s Line %d Value %s \n ' % ( Pcd . DatumType , FieldName . strip ( " . " ) , ArrayIndex + 1 , FieldList [ FieldName_ori ] [ 1 ] , FieldList [ FieldName_ori ] [ 2 ] , FieldList [ FieldName_ori ] [ 0 ] )
2018-03-02 11:11:13 +01:00
if Pcd . PcdFieldValueFromComm :
CApp = CApp + " // From Command Line \n "
for FieldName in Pcd . PcdFieldValueFromComm :
FieldName = " . " + FieldName
2018-03-07 07:14:43 +01:00
IsArray = IsFieldValueAnArray ( Pcd . PcdFieldValueFromComm [ FieldName . strip ( " . " ) ] [ 0 ] )
2018-03-02 16:51:56 +01:00
if IsArray and not ( Pcd . PcdFieldValueFromComm [ FieldName . strip ( " . " ) ] [ 0 ] . startswith ( ' { GUID ' ) and Pcd . PcdFieldValueFromComm [ FieldName . strip ( " . " ) ] [ 0 ] . endswith ( ' } ' ) ) :
2018-03-02 11:11:13 +01:00
try :
2018-03-02 16:51:56 +01:00
Value = ValueExpressionEx ( Pcd . PcdFieldValueFromComm [ FieldName . strip ( " . " ) ] [ 0 ] , " VOID* " , self . _GuidDict ) ( True )
2018-03-02 11:11:13 +01:00
except BadExpression :
EdkLogger . error ( ' Build ' , FORMAT_INVALID , " Invalid value format for %s . From %s Line %d " %
2018-03-02 16:51:56 +01:00
( " . " . join ( ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , FieldName . strip ( ' . ' ) ) ) , Pcd . PcdFieldValueFromComm [ FieldName . strip ( " . " ) ] [ 1 ] , Pcd . PcdFieldValueFromComm [ FieldName . strip ( " . " ) ] [ 2 ] ) )
2018-03-02 11:11:13 +01:00
Value , ValueSize = ParseFieldValue ( Value )
2018-03-02 16:51:56 +01:00
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 ] ) ;
2018-03-02 11:11:13 +01:00
else :
NewFieldName = ' '
FieldName_ori = FieldName . strip ( ' . ' )
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 ]
2018-03-02 16:51:56 +01:00
CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s , %s , %d ); // From %s Line %d Value %s \n ' % ( Pcd . DatumType , FieldName . strip ( " . " ) , ArrayIndex + 1 , Pcd . PcdFieldValueFromComm [ FieldName_ori ] [ 1 ] , Pcd . PcdFieldValueFromComm [ FieldName_ori ] [ 2 ] , Pcd . PcdFieldValueFromComm [ FieldName_ori ] [ 0 ] )
2018-04-13 22:51:29 +02:00
CApp = CApp + " *Size = ( %d > *Size ? %d : *Size); // The Pcd maxsize is %d \n " % ( DscBuildData . GetPcdMaxSize ( Pcd ) , DscBuildData . GetPcdMaxSize ( Pcd ) , DscBuildData . GetPcdMaxSize ( Pcd ) )
2018-02-28 06:59:20 +01:00
CApp = CApp + " } \n "
return CApp
2018-04-13 22:51:29 +02:00
@staticmethod
def GenerateSizeStatments ( Pcd ) :
2018-02-28 06:59:20 +01:00
CApp = ' Size = sizeof( %s ); \n ' % ( Pcd . DatumType )
CApp = CApp + ' Cal_ %s _ %s _Size(&Size); \n ' % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName )
return CApp
2018-04-13 22:51:29 +02:00
2018-02-28 06:59:20 +01:00
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 . DatumType )
CApp = CApp + ' UINT32 FieldSize; \n '
CApp = CApp + ' CHAR8 *Value; \n '
DefaultValueFromDec = Pcd . DefaultValueFromDec
2018-03-07 07:14:43 +01:00
IsArray = IsFieldValueAnArray ( Pcd . DefaultValueFromDec )
2018-02-28 06:59:20 +01:00
if IsArray :
try :
DefaultValueFromDec = ValueExpressionEx ( Pcd . DefaultValueFromDec , " VOID* " ) ( True )
except BadExpression :
EdkLogger . error ( " Build " , FORMAT_INVALID , " Invalid value format for %s . %s , from DEC: %s " %
( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , DefaultValueFromDec ) )
2018-03-08 06:56:21 +01:00
DefaultValueFromDec = StringToArray ( DefaultValueFromDec )
2018-02-28 06:59:20 +01:00
Value , ValueSize = ParseFieldValue ( DefaultValueFromDec )
if isinstance ( Value , str ) :
CApp = CApp + ' Pcd = %s ; // From DEC Default Value %s \n ' % ( Value , Pcd . DefaultValueFromDec )
elif IsArray :
#
# Use memcpy() to copy value into field
#
2018-04-13 22:51:29 +02:00
CApp = CApp + ' Value = %s ; // From DEC Default Value %s \n ' % ( DscBuildData . IntToCString ( Value , ValueSize ) , Pcd . DefaultValueFromDec )
2018-02-28 06:59:20 +01:00
CApp = CApp + ' memcpy (Pcd, Value, %d ); \n ' % ( ValueSize )
for FieldList in [ Pcd . DefaultValues ] :
if not FieldList :
continue
for FieldName in FieldList :
2018-03-07 07:14:43 +01:00
IsArray = IsFieldValueAnArray ( FieldList [ FieldName ] [ 0 ] )
2018-02-28 06:59:20 +01:00
if IsArray :
try :
FieldList [ FieldName ] [ 0 ] = ValueExpressionEx ( FieldList [ FieldName ] [ 0 ] , " 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 . DatumType , FieldName )
2018-04-13 22:51:29 +02:00
CApp = CApp + ' Value = %s ; // From %s Line %d Value %s \n ' % ( DscBuildData . IntToCString ( Value , ValueSize ) , FieldList [ FieldName ] [ 1 ] , FieldList [ FieldName ] [ 2 ] , FieldList [ FieldName ] [ 0 ] )
2018-02-28 06:59:20 +01:00
CApp = CApp + ' memcpy (&Pcd-> %s , Value, (FieldSize > 0 && FieldSize < %d ) ? FieldSize : %d ); \n ' % ( FieldName , ValueSize , ValueSize )
else :
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 ] )
2018-02-28 06:59:21 +01:00
CApp = CApp + " } \n "
return CApp
2018-04-13 22:51:29 +02:00
@staticmethod
def GenerateDefaultValueAssignStatement ( Pcd ) :
2018-02-28 06:59:21 +01:00
CApp = ' Assign_ %s _ %s _Default_Value(Pcd); \n ' % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName )
return CApp
2018-04-13 22:51:29 +02:00
2018-02-28 06:59:21 +01:00
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 . DatumType )
CApp = CApp + ' UINT32 FieldSize; \n '
CApp = CApp + ' CHAR8 *Value; \n '
2018-04-11 01:17:20 +02:00
CApp = CApp + " // SkuName: %s , DefaultStoreName: %s \n " % ( ' DEFAULT ' , TAB_DEFAULT_STORES_DEFAULT )
2018-02-28 06:59:21 +01:00
inherit_OverrideValues = Pcd . SkuOverrideValues [ SkuName ]
2018-04-11 01:17:20 +02:00
if ( SkuName , DefaultStoreName ) == ( ' DEFAULT ' , TAB_DEFAULT_STORES_DEFAULT ) :
pcddefaultvalue = Pcd . DefaultFromDSC . get ( ' DEFAULT ' , { } ) . get ( TAB_DEFAULT_STORES_DEFAULT , Pcd . DefaultValue ) if Pcd . DefaultFromDSC else Pcd . DefaultValue
2018-02-28 06:59:21 +01:00
else :
2018-03-02 11:11:14 +01:00
if not Pcd . DscRawValue :
# handle the case that structure pcd is not appear in DSC
self . CopyDscRawValue ( Pcd )
2018-02-28 06:59:21 +01:00
pcddefaultvalue = Pcd . DscRawValue . get ( SkuName , { } ) . get ( DefaultStoreName )
for FieldList in [ pcddefaultvalue , inherit_OverrideValues . get ( DefaultStoreName ) ] :
2018-02-28 06:59:20 +01:00
if not FieldList :
continue
if pcddefaultvalue and FieldList == pcddefaultvalue :
2018-03-07 07:14:43 +01:00
IsArray = IsFieldValueAnArray ( FieldList )
2018-02-28 06:59:20 +01:00
if IsArray :
try :
FieldList = ValueExpressionEx ( FieldList , " 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 )
2018-02-28 06:59:21 +01:00
2018-04-11 01:17:20 +02:00
if ( SkuName , DefaultStoreName ) == ( ' DEFAULT ' , TAB_DEFAULT_STORES_DEFAULT ) :
2018-02-28 06:59:21 +01:00
if isinstance ( Value , str ) :
2018-04-11 01:17:20 +02:00
CApp = CApp + ' Pcd = %s ; // From DSC Default Value %s \n ' % ( Value , Pcd . DefaultFromDSC . get ( ' DEFAULT ' , { } ) . get ( TAB_DEFAULT_STORES_DEFAULT , Pcd . DefaultValue ) if Pcd . DefaultFromDSC else Pcd . DefaultValue )
2018-02-28 06:59:21 +01:00
elif IsArray :
#
# Use memcpy() to copy value into field
#
2018-04-13 22:51:29 +02:00
CApp = CApp + ' Value = %s ; // From DSC Default Value %s \n ' % ( DscBuildData . IntToCString ( Value , ValueSize ) , Pcd . DefaultFromDSC . get ( ' DEFAULT ' , { } ) . get ( TAB_DEFAULT_STORES_DEFAULT , Pcd . DefaultValue ) if Pcd . DefaultFromDSC else Pcd . DefaultValue )
2018-02-28 06:59:21 +01:00
CApp = CApp + ' memcpy (Pcd, Value, %d ); \n ' % ( ValueSize )
else :
if isinstance ( Value , str ) :
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
#
2018-04-13 22:51:29 +02:00
CApp = CApp + ' Value = %s ; // From DSC Default Value %s \n ' % ( DscBuildData . IntToCString ( Value , ValueSize ) , Pcd . DscRawValue . get ( SkuName , { } ) . get ( DefaultStoreName ) )
2018-02-28 06:59:21 +01:00
CApp = CApp + ' memcpy (Pcd, Value, %d ); \n ' % ( ValueSize )
2018-02-28 06:59:20 +01:00
continue
2018-04-11 01:17:20 +02:00
if ( SkuName , DefaultStoreName ) == ( ' DEFAULT ' , TAB_DEFAULT_STORES_DEFAULT ) or ( ( ( SkuName , ' ' ) not in Pcd . ValueChain ) and ( ( SkuName , DefaultStoreName ) not in Pcd . ValueChain ) ) :
2018-02-28 06:59:21 +01:00
for FieldName in FieldList :
2018-03-07 07:14:43 +01:00
IsArray = IsFieldValueAnArray ( FieldList [ FieldName ] [ 0 ] )
2018-02-28 06:59:21 +01:00
if IsArray :
try :
FieldList [ FieldName ] [ 0 ] = ValueExpressionEx ( FieldList [ FieldName ] [ 0 ] , " 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 ] ) )
2018-02-28 06:59:20 +01:00
try :
2018-02-28 06:59:21 +01:00
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 . DatumType , FieldName )
2018-04-13 22:51:29 +02:00
CApp = CApp + ' Value = %s ; // From %s Line %d Value %s \n ' % ( DscBuildData . IntToCString ( Value , ValueSize ) , FieldList [ FieldName ] [ 1 ] , FieldList [ FieldName ] [ 2 ] , FieldList [ FieldName ] [ 0 ] )
2018-02-28 06:59:21 +01:00
CApp = CApp + ' memcpy (&Pcd-> %s , Value, (FieldSize > 0 && FieldSize < %d ) ? FieldSize : %d ); \n ' % ( FieldName , ValueSize , ValueSize )
2018-02-28 06:59:20 +01:00
else :
2018-02-28 06:59:21 +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 ] )
2018-02-28 06:59:20 +01:00
CApp = CApp + " } \n "
return CApp
2018-04-13 22:51:29 +02:00
@staticmethod
def GenerateInitValueStatement ( Pcd , SkuName , DefaultStoreName ) :
2018-02-28 06:59:21 +01:00
CApp = ' Assign_ %s _ %s _ %s _ %s _Value(Pcd); \n ' % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName , SkuName , DefaultStoreName )
2018-02-28 06:59:20 +01:00
return CApp
2018-04-13 22:51:29 +02:00
2018-03-02 11:11:13 +01:00
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 . DatumType )
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 :
2018-03-07 07:14:43 +01:00
IsArray = IsFieldValueAnArray ( FieldList )
2018-03-02 11:11:13 +01:00
if IsArray :
try :
FieldList = ValueExpressionEx ( FieldList , " VOID* " ) ( True )
except BadExpression :
2018-03-08 06:56:21 +01:00
EdkLogger . error ( " Build " , FORMAT_INVALID , " Invalid value format for %s . %s , from Command: %s " %
2018-03-02 11:11:13 +01:00
( 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
#
2018-04-13 22:51:29 +02:00
CApp = CApp + ' Value = %s ; // From Command Line. \n ' % ( DscBuildData . IntToCString ( Value , ValueSize ) )
2018-03-02 11:11:13 +01:00
CApp = CApp + ' memcpy (Pcd, Value, %d ); \n ' % ( ValueSize )
continue
for FieldName in FieldList :
2018-03-07 07:14:43 +01:00
IsArray = IsFieldValueAnArray ( FieldList [ FieldName ] [ 0 ] )
2018-03-02 11:11:13 +01:00
if IsArray :
try :
FieldList [ FieldName ] [ 0 ] = ValueExpressionEx ( FieldList [ FieldName ] [ 0 ] , " 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 . DatumType , FieldName )
2018-04-13 22:51:29 +02:00
CApp = CApp + ' Value = %s ; // From %s Line %d Value %s \n ' % ( DscBuildData . IntToCString ( Value , ValueSize ) , FieldList [ FieldName ] [ 1 ] , FieldList [ FieldName ] [ 2 ] , FieldList [ FieldName ] [ 0 ] )
2018-03-02 11:11:13 +01:00
CApp = CApp + ' memcpy (&Pcd-> %s , Value, (FieldSize > 0 && FieldSize < %d ) ? FieldSize : %d ); \n ' % ( FieldName , ValueSize , ValueSize )
else :
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
2018-04-13 22:51:29 +02:00
@staticmethod
def GenerateCommandLineValueStatement ( Pcd ) :
2018-03-02 11:11:13 +01:00
CApp = ' Assign_ %s _ %s _CommandLine_Value(Pcd); \n ' % ( Pcd . TokenSpaceGuidCName , Pcd . TokenCName )
return CApp
2018-04-13 22:51:29 +02:00
2018-02-28 06:59:21 +01:00
def GenerateInitializeFunc ( self , SkuName , DefaultStore , Pcd , InitByteValue , CApp ) :
OverrideValues = { DefaultStore : " " }
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 '
2018-01-23 04:03:05 +01:00
CApp = CApp + ' %s *Pcd; // From %s Line %d \n ' % ( Pcd . DatumType , Pcd . PkgPath , Pcd . PcdDefineLineNo )
2017-12-22 13:46:15 +01:00
CApp = CApp + ' \n '
2017-12-22 13:14:29 +01:00
2018-01-23 04:34:45 +01:00
if SkuName in Pcd . SkuInfoList :
2018-02-28 06:59:21 +01:00
DefaultValue = Pcd . SkuInfoList [ SkuName ] . DefaultStoreDict . get ( DefaultStoreName , Pcd . SkuInfoList [ SkuName ] . HiiDefaultValue if Pcd . SkuInfoList [ SkuName ] . HiiDefaultValue else Pcd . SkuInfoList [ SkuName ] . DefaultValue )
2018-01-23 04:34:45 +01:00
else :
DefaultValue = Pcd . DefaultValue
PcdDefaultValue = StringToArray ( DefaultValue . strip ( ) )
2017-12-22 13:14:29 +01:00
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)
#
2018-04-13 22:51:29 +02:00
CApp = CApp + DscBuildData . GenerateSizeStatments ( Pcd )
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
#
2018-04-13 22:51:29 +02:00
CApp = CApp + DscBuildData . GenerateDefaultValueAssignStatement ( Pcd )
2018-02-28 06:59:21 +01:00
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 ) :
2018-04-11 01:17:20 +02:00
storeset = [ DefaultStoreName ] if DefaultStoreName == TAB_DEFAULT_STORES_DEFAULT else [ TAB_DEFAULT_STORES_DEFAULT , DefaultStoreName ]
2018-02-28 06:59:21 +01:00
for defaultstorenameitem in storeset :
CApp = CApp + " // SkuName: %s , DefaultStoreName: %s \n " % ( skuname , defaultstorenameitem )
2018-04-13 22:51:29 +02:00
CApp = CApp + DscBuildData . GenerateInitValueStatement ( Pcd , skuname , defaultstorenameitem )
2018-02-28 06:59:21 +01:00
if skuname == SkuName :
break
else :
2018-03-02 11:11:14 +01:00
CApp = CApp + " // SkuName: %s , DefaultStoreName: STANDARD \n " % self . SkuIdMgr . SystemSkuId
2018-04-13 22:51:29 +02:00
CApp = CApp + DscBuildData . GenerateInitValueStatement ( Pcd , self . SkuIdMgr . SystemSkuId , TAB_DEFAULT_STORES_DEFAULT )
CApp = CApp + DscBuildData . GenerateCommandLineValueStatement ( Pcd )
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 = { }
2018-03-16 10:40:00 +01:00
IncludeFiles = set ( )
2017-11-24 07:30:11 +01:00
for PcdName in StructuredPcds :
Pcd = StructuredPcds [ PcdName ]
2018-01-29 07:09:36 +01:00
for IncludeFile in Pcd . StructuredPcdIncludeFile :
if IncludeFile not in Includes :
Includes [ IncludeFile ] = True
2018-03-16 10:40:00 +01:00
IncludeFiles . add ( IncludeFile )
2018-01-29 07:09:36 +01:00
CApp = CApp + ' #include < %s > \n ' % ( IncludeFile )
2017-11-24 07:30:11 +01:00
CApp = CApp + ' \n '
for PcdName in StructuredPcds :
Pcd = StructuredPcds [ PcdName ]
2018-02-28 06:59:20 +01:00
CApp = CApp + self . GenerateSizeFunction ( Pcd )
CApp = CApp + self . GenerateDefaultValueAssignFunction ( Pcd )
2018-03-02 11:11:13 +01:00
CApp = CApp + self . GenerateCommandLineValue ( Pcd )
2018-02-28 06:59:21 +01:00
if not Pcd . SkuOverrideValues or Pcd . Type in [ self . _PCD_TYPE_STRING_ [ MODEL_PCD_FIXED_AT_BUILD ] ,
self . _PCD_TYPE_STRING_ [ MODEL_PCD_PATCHABLE_IN_MODULE ] ] :
2018-04-11 01:17:20 +02:00
CApp = CApp + self . GenerateInitValueFunction ( Pcd , self . SkuIdMgr . SystemSkuId , TAB_DEFAULT_STORES_DEFAULT )
2018-02-28 06:59:21 +01:00
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 )
2018-02-28 06:59:19 +01:00
if not Pcd . SkuOverrideValues or Pcd . Type in [ self . _PCD_TYPE_STRING_ [ MODEL_PCD_FIXED_AT_BUILD ] ,
self . _PCD_TYPE_STRING_ [ MODEL_PCD_PATCHABLE_IN_MODULE ] ] :
2018-04-11 01:17:20 +02:00
InitByteValue , CApp = self . GenerateInitializeFunc ( self . SkuIdMgr . SystemSkuId , TAB_DEFAULT_STORES_DEFAULT , 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 ( ) :
2018-02-28 06:59:19 +01:00
if not Pcd . SkuOverrideValues or Pcd . Type in [ self . _PCD_TYPE_STRING_ [ MODEL_PCD_FIXED_AT_BUILD ] , self . _PCD_TYPE_STRING_ [ MODEL_PCD_PATCHABLE_IN_MODULE ] ] :
2018-04-11 01:17:20 +02:00
CApp = CApp + ' Initialize_ %s _ %s _ %s _ %s (); \n ' % ( self . SkuIdMgr . SystemSkuId , TAB_DEFAULT_STORES_DEFAULT , 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 )
2018-02-28 06:59:19 +01:00
SaveFileOnChange ( CAppBaseFileName + ' .c ' , CApp , False )
2017-11-24 07:30:11 +01:00
MakeApp = PcdMakefileHeader
if sys . platform == " win32 " :
2018-02-28 06:59:19 +01:00
MakeApp = MakeApp + ' APPNAME = %s \n ' % ( PcdValueInitName ) + ' OBJECTS = %s \ %s .obj \n ' % ( self . OutputPath , PcdValueInitName ) + ' INC = '
2017-11-24 07:30:11 +01:00
else :
MakeApp = MakeApp + PcdGccMakefile
MakeApp = MakeApp + ' APPNAME = %s \n ' % ( PcdValueInitName ) + ' OBJECTS = %s / %s .o \n ' % ( self . OutputPath , PcdValueInitName ) + \
2017-12-26 06:16:17 +01:00
' include $(MAKEROOT)/Makefiles/app.makefile \n ' + ' INCLUDE += '
2017-11-24 07:30:11 +01:00
2018-03-16 10:40:00 +01:00
IncSearchList = [ ]
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 :
2018-03-22 16:22:06 +01:00
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 )
2017-11-24 07:30:11 +01:00
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 ) + ' '
2018-03-16 10:40:00 +01:00
IncSearchList . append ( inc )
2017-11-24 07:30:11 +01:00
MakeApp = MakeApp + ' \n '
2017-12-26 06:16:17 +01:00
CC_FLAGS = LinuxCFLAGS
if sys . platform == " win32 " :
CC_FLAGS = WindowsCFLAGS
BuildOptions = { }
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 Target == " * " or Target == self . _Target :
if Tag == " * " or Tag == self . _Toolchain :
if Arch == " * " or Arch == self . Arch :
if Tool not in BuildOptions :
BuildOptions [ Tool ] = { }
if Attr != " FLAGS " or Attr not in BuildOptions [ Tool ] or self . BuildOptions [ Options ] . startswith ( ' = ' ) :
BuildOptions [ Tool ] [ Attr ] = self . BuildOptions [ Options ]
else :
# append options for the same tool except PATH
if Attr != ' PATH ' :
BuildOptions [ Tool ] [ Attr ] + = " " + self . BuildOptions [ Options ]
else :
BuildOptions [ Tool ] [ Attr ] = self . BuildOptions [ Options ]
if BuildOptions :
for Tool in BuildOptions :
for Attr in BuildOptions [ Tool ] :
if Attr == " FLAGS " :
Value = BuildOptions [ Tool ] [ Attr ]
ValueList = Value . split ( )
if ValueList :
for Id , Item in enumerate ( ValueList ) :
if Item == ' -D ' or Item == ' /D ' :
CC_FLAGS + = ' ' + Item
if Id + 1 < len ( ValueList ) :
CC_FLAGS + = ' ' + ValueList [ Id + 1 ]
elif Item . startswith ( ' /D ' ) or Item . startswith ( ' -D ' ) :
CC_FLAGS + = ' ' + Item
MakeApp + = CC_FLAGS
2017-11-24 07:30:11 +01:00
if sys . platform == " win32 " :
MakeApp = MakeApp + PcdMakefileEnd
2018-03-16 10:40:00 +01:00
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
2017-11-24 07:30:11 +01:00
MakeFileName = os . path . join ( self . OutputPath , ' Makefile ' )
2018-03-16 10:40:00 +01:00
MakeApp + = " $(OBJECTS) : %s \n " % MakeFileName
2018-02-28 06:59:19 +01:00
SaveFileOnChange ( MakeFileName , MakeApp , False )
2017-11-24 07:30:11 +01:00
InputValueFile = os . path . join ( self . OutputPath , ' Input.txt ' )
OutputValueFile = os . path . join ( self . OutputPath , ' Output.txt ' )
2018-02-28 06:59:19 +01:00
SaveFileOnChange ( InputValueFile , InitByteValue , False )
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 )
2018-01-31 10:32:01 +01:00
else :
2018-02-28 06:59:19 +01:00
PcdValueInitExe = os . path . join ( os . getenv ( " EDK_TOOLS_PATH " ) , ' Bin ' , ' Win32 ' , PcdValueInitName ) + " .exe "
2018-03-16 10:40:00 +01:00
Messages = ' '
if sys . platform == " win32 " :
MakeCommand = ' nmake -f %s ' % ( MakeFileName )
2018-04-13 22:51:29 +02:00
returncode , StdOut , StdErr = DscBuildData . ExecuteCommand ( MakeCommand )
2018-03-16 10:40:00 +01:00
Messages = StdOut
else :
MakeCommand = ' make -f %s ' % ( MakeFileName )
2018-04-13 22:51:29 +02:00
returncode , StdOut , StdErr = DscBuildData . ExecuteCommand ( MakeCommand )
2018-03-16 10:40:00 +01:00
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 ( ' : ' )
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 " // " )
2018-02-28 06:59:19 +01:00
else :
2018-03-16 10:40:00 +01:00
dsc_line = error_line
message_itmes = Message . split ( " : " )
Index = 0
if " PcdValueInit.c " not in Message :
if not MessageGroup :
MessageGroup . append ( Message )
break
2018-02-28 06:59:19 +01:00
else :
2018-03-16 10:40:00 +01:00
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 )
2018-04-13 22:51:29 +02:00
if DscBuildData . NeedUpdateOutput ( OutputValueFile , PcdValueInitExe , InputValueFile ) :
2018-02-28 06:59:19 +01:00
Command = PcdValueInitExe + ' -i %s -o %s ' % ( InputValueFile , OutputValueFile )
2018-04-13 22:51:29 +02:00
returncode , StdOut , StdErr = DscBuildData . ExecuteCommand ( Command )
2018-02-28 06:59:19 +01:00
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 ( )
2017-11-24 07:30:11 +01:00
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
2018-04-13 22:51:29 +02:00
@staticmethod
def NeedUpdateOutput ( OutputFile , ValueCFile , StructureInput ) :
2018-02-28 06:59:19 +01:00
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
2017-11-24 07:30:11 +01:00
## Retrieve dynamic PCD settings
#
# @param Type PCD type
#
# @retval a dict object contains settings of given PCD type
#
def _GetDynamicPcd ( self , Type ) :
2018-04-03 23:03:09 +02:00
Pcds = OrderedDict ( )
2017-11-24 07:30:11 +01:00
#
# 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 :
2018-01-31 10:32:01 +01:00
PcdList . append ( ( PcdCName , TokenSpaceGuid , SkuName , Dummy5 ) )
2017-11-24 07:30:11 +01:00
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 ]
2018-03-26 22:25:43 +02:00
if Setting is None :
2017-11-24 07:30:11 +01:00
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 ( ) :
2018-04-13 02:02:10 +02:00
if not sku . DefaultValue :
2017-12-22 13:07:54 +01:00
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
2018-04-13 22:51:29 +02:00
@staticmethod
def CompareVarAttr ( Attr1 , Attr2 ) :
2017-11-24 07:30:11 +01:00
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
2018-04-13 22:51:29 +02:00
2018-02-28 06:59:21 +01:00
def CopyDscRawValue ( self , Pcd ) :
if Pcd . DscRawValue is None :
Pcd . DscRawValue = dict ( )
2018-03-02 11:11:14 +01:00
if Pcd . Type in [ self . _PCD_TYPE_STRING_ [ MODEL_PCD_FIXED_AT_BUILD ] , self . _PCD_TYPE_STRING_ [ MODEL_PCD_PATCHABLE_IN_MODULE ] ] :
if self . SkuIdMgr . SystemSkuId not in Pcd . DscRawValue :
Pcd . DscRawValue [ self . SkuIdMgr . SystemSkuId ] = { }
2018-04-11 01:17:20 +02:00
Pcd . DscRawValue [ self . SkuIdMgr . SystemSkuId ] [ TAB_DEFAULT_STORES_DEFAULT ] = Pcd . DefaultValue
2018-02-28 06:59:21 +01:00
for skuname in Pcd . SkuInfoList :
Pcd . DscRawValue [ skuname ] = { }
if Pcd . Type in [ self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_HII ] , self . _PCD_TYPE_STRING_ [ MODEL_PCD_DYNAMIC_EX_HII ] ] :
for defaultstore in Pcd . SkuInfoList [ skuname ] . DefaultStoreDict :
Pcd . DscRawValue [ skuname ] [ defaultstore ] = Pcd . SkuInfoList [ skuname ] . DefaultStoreDict [ defaultstore ]
else :
2018-04-11 01:17:20 +02:00
Pcd . DscRawValue [ skuname ] [ TAB_DEFAULT_STORES_DEFAULT ] = Pcd . SkuInfoList [ skuname ] . DefaultValue
2017-12-22 13:46:15 +01:00
def CompletePcdValues ( self , PcdSet ) :
Pcds = { }
DefaultStoreObj = DefaultStore ( self . _GetDefaultStores ( ) )
2017-12-27 07:03:35 +01:00
SkuIds = { skuname : skuid for skuname , skuid in self . SkuIdMgr . AvailableSkuIdSet . items ( ) if skuname != ' COMMON ' }
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 ) ]
2018-03-02 11:11:14 +01:00
self . CopyDscRawValue ( PcdObj )
2017-12-22 13:46:15 +01:00
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 = { }
2018-04-03 23:03:09 +02:00
Pcds = OrderedDict ( )
2017-11-24 07:30:11 +01:00
#
# 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 " :
2018-04-11 01:17:20 +02:00
DefaultStore = TAB_DEFAULT_STORES_DEFAULT
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 :
2018-01-31 10:32:01 +01:00
PcdSet . add ( ( PcdCName , TokenSpaceGuid , SkuName , DefaultStore , Dummy5 ) )
2017-12-22 13:46:15 +01:00
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 ]
2018-03-26 22:25:43 +02:00
if Setting is None :
2017-11-24 07:30:11 +01:00
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 :
2018-04-13 22:51:29 +02:00
if not DscBuildData . CompareVarAttr ( VariableAttrs [ ( VariableName , VariableGuid ) ] , VarAttribute ) :
2017-11-24 07:30:11 +01:00
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 ]
2018-02-06 08:20:46 +01:00
pcd . DatumType = pcdDecObject . DatumType
2017-11-24 07:30:11 +01:00
# Only fix the value while no value provided in DSC file.
for sku in pcd . SkuInfoList . values ( ) :
2018-03-26 22:25:43 +02:00
if ( sku . HiiDefaultValue == " " or sku . HiiDefaultValue is None ) :
2017-11-24 07:30:11 +01:00
sku . HiiDefaultValue = pcdDecObject . DefaultValue
2018-02-06 08:20:46 +01:00
for default_store in sku . DefaultStoreDict :
sku . DefaultStoreDict [ default_store ] = pcdDecObject . DefaultValue
pcd . 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
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
2018-03-02 11:11:13 +01:00
if pcd . DatumType not in [ ' BOOLEAN ' , ' UINT8 ' , ' UINT16 ' , ' UINT32 ' , ' UINT64 ' ] :
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 )
2018-04-13 22:51:29 +02:00
rt , invalidhii = DscBuildData . CheckVariableNameAssignment ( Pcds )
2017-12-22 13:04:04 +01:00
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
2018-04-13 22:51:29 +02:00
@staticmethod
def CheckVariableNameAssignment ( Pcds ) :
2017-12-22 13:04:04 +01:00
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 ) :
2018-04-03 23:03:09 +02:00
Pcds = OrderedDict ( )
2017-11-24 07:30:11 +01:00
#
# 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 :
2018-01-31 10:32:01 +01:00
PcdList . append ( ( PcdCName , TokenSpaceGuid , SkuName , Dummy5 ) )
2017-11-24 07:30:11 +01:00
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 ]
2018-03-26 22:25:43 +02:00
if Setting is None :
2017-11-24 07:30:11 +01:00
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 ]
2018-02-07 03:01:59 +01:00
pcd . DatumType = pcdDecObject . DatumType
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 ( ) :
2018-04-13 02:02:10 +02:00
if not sku . DefaultValue :
2017-12-22 13:07:54 +01:00
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 )
2017-12-26 06:16:17 +01:00
def _GetToolChainFamily ( self ) :
self . _ToolChainFamily = " MSFT "
BuildConfigurationFile = os . path . normpath ( os . path . join ( GlobalData . gConfDirectory , " target.txt " ) )
if os . path . isfile ( BuildConfigurationFile ) == True :
TargetTxt = TargetTxtClassObject ( )
TargetTxt . LoadTargetTxtFile ( BuildConfigurationFile )
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 :
ToolDef = ToolDefClassObject ( )
ToolDef . LoadToolDefFile ( ToolDefinitionFile )
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 = " MSFT "
else :
self . _ToolChainFamily = ToolDefinition [ TAB_TOD_DEFINES_FAMILY ] [ self . _Toolchain ]
return self . _ToolChainFamily
2017-11-24 07:30:11 +01:00
## 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 ) :
2018-03-26 22:25:43 +02:00
if self . _DecPcds is None :
2017-12-26 04:33:33 +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-26 09:17:13 +01:00
self . _DecPcds , self . _GuidDict = GetDeclaredPcd ( self , self . _Bdb , self . _Arch , self . _Target , self . _Toolchain , PkgSet )
2017-12-26 04:33:33 +01:00
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 )
2017-12-26 06:16:17 +01:00
ToolChainFamily = property ( _GetToolChainFamily )