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