diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-11 08:17:27 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-11 08:17:27 +0000 |
commit | f215e02bf85f68d3a6106c2a1f4f7f063f819064 (patch) | |
tree | 6bb5b92c046312c4e95ac2620b10ddf482d3fa8b /src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Workspace/DscBuildData.py | |
parent | Initial commit. (diff) | |
download | virtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.tar.xz virtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.zip |
Adding upstream version 7.0.14-dfsg.upstream/7.0.14-dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Workspace/DscBuildData.py')
-rwxr-xr-x | src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Workspace/DscBuildData.py | 3588 |
1 files changed, 3588 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Workspace/DscBuildData.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Workspace/DscBuildData.py new file mode 100755 index 00000000..eeefc9f5 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Workspace/DscBuildData.py @@ -0,0 +1,3588 @@ +## @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 +from Common.ToolDefClassObject import ToolDefDict +from .MetaDataTable import * +from .MetaFileTable import * +from .MetaFileParser import * + +from .WorkspaceCommon import GetDeclaredPcd +from Common.Misc import AnalyzeDscPcd +from Common.Misc import ProcessDuplicatedInf,RemoveCComments,ArrayIndex +import re +from Common.Parsing import IsValidWord +from Common.VariableAttributes import VariableAttributes +import Common.GlobalData as GlobalData +import subprocess +from functools import reduce +from Common.Misc import SaveFileOnChange +from Workspace.BuildClassObject import PlatformBuildClassObject, StructurePcd, PcdClassObject, ModuleBuildClassObject +from collections import OrderedDict, defaultdict + +def _IsFieldValueAnArray (Value): + Value = Value.strip() + if Value.startswith(TAB_GUID) and Value.endswith(')'): + return True + if Value.startswith('L"') and Value.endswith('"') and len(list(Value[2:-1])) > 1: + return True + if Value[0] == '"' and Value[-1] == '"' and len(list(Value[1:-1])) > 1: + return True + if Value[0] == '{' and Value[-1] == '}': + return True + if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1: + return True + if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1: + return True + return False + +PcdValueInitName = 'PcdValueInit' +PcdValueCommonName = 'PcdValueCommon' + +PcdMainCHeader = ''' +/** + DO NOT EDIT + FILE auto-generated +**/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <PcdValueCommon.h> +''' + +PcdMainCEntry = ''' +int +main ( + int argc, + char *argv[] + ) +{ + return PcdValueMain (argc, argv); +} +''' + +PcdMakefileHeader = ''' +# +# DO NOT EDIT +# This file is auto-generated by build utility +# + +''' + +WindowsCFLAGS = 'CFLAGS = $(CFLAGS) /wd4200 /wd4034 /wd4101 ' +LinuxCFLAGS = 'BUILD_CFLAGS += -Wno-pointer-to-int-cast -Wno-unused-variable ' +PcdMakefileEnd = ''' +!INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.common +!INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.app +''' + +AppTarget = ''' +all: $(APPFILE) +$(APPFILE): $(OBJECTS) +%s +''' + +PcdGccMakefile = ''' +MAKEROOT ?= $(EDK_TOOLS_PATH)/Source/C +LIBS = -lCommon +''' + +variablePattern = re.compile(r'[\t\s]*0[xX][a-fA-F0-9]+$') +SkuIdPattern = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_]*$') +## regular expressions for finding decimal and hex numbers +Pattern = re.compile('^[1-9]\d*|0$') +HexPattern = re.compile(r'0[xX][0-9a-fA-F]+$') +## Regular expression for finding header file inclusions +from AutoGen.GenMake import gIncludePattern + +## Find dependencies for one source file +# +# By searching recursively "#include" directive in file, find out all the +# files needed by given source file. The dependecies will be only searched +# in given search path list. +# +# @param SearchPathList The list of search path +# +# @retval list The list of files the given source file depends on +# +def GetDependencyList(FileStack, SearchPathList): + DepDb = dict() + DependencySet = set(FileStack) + while len(FileStack) > 0: + F = FileStack.pop() + FullPathDependList = [] + CurrentFileDependencyList = [] + if F in DepDb: + CurrentFileDependencyList = DepDb[F] + else: + try: + Fd = open(F, 'r') + FileContent = Fd.read() + except BaseException as X: + EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=F + "\n\t" + str(X)) + finally: + if "Fd" in dir(locals()): + Fd.close() + + if len(FileContent) == 0: + continue + + try: + if FileContent[0] == 0xff or FileContent[0] == 0xfe: + FileContent = FileContent.decode('utf-16') + else: + FileContent = FileContent.decode() + except: + # The file is not txt file. for example .mcb file + continue + IncludedFileList = gIncludePattern.findall(FileContent) + + for Inc in IncludedFileList: + Inc = Inc.strip() + Inc = os.path.normpath(Inc) + CurrentFileDependencyList.append(Inc) + DepDb[F] = CurrentFileDependencyList + + CurrentFilePath = os.path.dirname(F) + PathList = [CurrentFilePath] + SearchPathList + for Inc in CurrentFileDependencyList: + for SearchPath in PathList: + FilePath = os.path.join(SearchPath, Inc) + if not os.path.exists(FilePath): + continue + if FilePath not in DependencySet: + FileStack.append(FilePath) + FullPathDependList.append(FilePath) + break + DependencySet.update(FullPathDependList) + DependencyList = list(DependencySet) # remove duplicate ones + + return DependencyList + +class DscBuildData(PlatformBuildClassObject): + # dict used to convert PCD type in database to string used by build tool + _PCD_TYPE_STRING_ = { + MODEL_PCD_FIXED_AT_BUILD : TAB_PCDS_FIXED_AT_BUILD, + MODEL_PCD_PATCHABLE_IN_MODULE : TAB_PCDS_PATCHABLE_IN_MODULE, + MODEL_PCD_FEATURE_FLAG : TAB_PCDS_FEATURE_FLAG, + MODEL_PCD_DYNAMIC : TAB_PCDS_DYNAMIC, + MODEL_PCD_DYNAMIC_DEFAULT : TAB_PCDS_DYNAMIC, + MODEL_PCD_DYNAMIC_HII : TAB_PCDS_DYNAMIC_HII, + MODEL_PCD_DYNAMIC_VPD : TAB_PCDS_DYNAMIC_VPD, + MODEL_PCD_DYNAMIC_EX : TAB_PCDS_DYNAMIC_EX, + MODEL_PCD_DYNAMIC_EX_DEFAULT : TAB_PCDS_DYNAMIC_EX, + MODEL_PCD_DYNAMIC_EX_HII : TAB_PCDS_DYNAMIC_EX_HII, + MODEL_PCD_DYNAMIC_EX_VPD : TAB_PCDS_DYNAMIC_EX_VPD, + } + + # dict used to convert part of [Defines] to members of DscBuildData directly + _PROPERTY_ = { + # + # Required Fields + # + TAB_DSC_DEFINES_PLATFORM_NAME : "_PlatformName", + TAB_DSC_DEFINES_PLATFORM_GUID : "_Guid", + TAB_DSC_DEFINES_PLATFORM_VERSION : "_Version", + TAB_DSC_DEFINES_DSC_SPECIFICATION : "_DscSpecification", + # TAB_DSC_DEFINES_OUTPUT_DIRECTORY : "_OutputDirectory", + # TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : "_SupArchList", + # TAB_DSC_DEFINES_BUILD_TARGETS : "_BuildTargets", + TAB_DSC_DEFINES_SKUID_IDENTIFIER : "_SkuName", + # TAB_DSC_DEFINES_FLASH_DEFINITION : "_FlashDefinition", + TAB_DSC_DEFINES_BUILD_NUMBER : "_BuildNumber", + TAB_DSC_DEFINES_MAKEFILE_NAME : "_MakefileName", + TAB_DSC_DEFINES_BS_BASE_ADDRESS : "_BsBaseAddress", + TAB_DSC_DEFINES_RT_BASE_ADDRESS : "_RtBaseAddress", + # TAB_DSC_DEFINES_RFC_LANGUAGES : "_RFCLanguages", + # TAB_DSC_DEFINES_ISO_LANGUAGES : "_ISOLanguages", + } + + # used to compose dummy library class name for those forced library instances + _NullLibraryNumber = 0 + + ## Constructor of DscBuildData + # + # Initialize object of DscBuildData + # + # @param FilePath The path of platform description file + # @param RawData The raw data of DSC file + # @param BuildDataBase Database used to retrieve module/package information + # @param Arch The target architecture + # @param Platform (not used for DscBuildData) + # @param Macros Macros used for replacement in DSC file + # + def __init__(self, FilePath, RawData, BuildDataBase, Arch=TAB_ARCH_COMMON, Target=None, Toolchain=None): + self.MetaFile = FilePath + self._RawData = RawData + self._Bdb = BuildDataBase + self._Arch = Arch + self._Target = Target + self._Toolchain = Toolchain + self._ToolChainFamily = None + self._Clear() + self.WorkspaceDir = os.getenv("WORKSPACE") if os.getenv("WORKSPACE") else "" + self.DefaultStores = None + self.SkuIdMgr = SkuClass(self.SkuName, self.SkuIds) + + @property + def OutputPath(self): + if os.getenv("WORKSPACE"): + return os.path.join(os.getenv("WORKSPACE"), self.OutputDirectory, self._Target + "_" + self._Toolchain, PcdValueInitName) + else: + return os.path.dirname(self.DscFile) + + ## XXX[key] = value + def __setitem__(self, key, value): + self.__dict__[self._PROPERTY_[key]] = value + + ## value = XXX[key] + def __getitem__(self, key): + return self.__dict__[self._PROPERTY_[key]] + + ## "in" test support + def __contains__(self, key): + return key in self._PROPERTY_ + + ## Set all internal used members of DscBuildData to None + def _Clear(self): + self._Header = None + self._PlatformName = None + self._Guid = None + self._Version = None + self._DscSpecification = None + self._OutputDirectory = None + self._SupArchList = None + self._BuildTargets = None + self._SkuName = None + self._PcdInfoFlag = None + self._VarCheckFlag = None + self._FlashDefinition = None + self._Prebuild = None + self._Postbuild = None + self._BuildNumber = None + self._MakefileName = None + self._BsBaseAddress = None + self._RtBaseAddress = None + self._SkuIds = None + self._Modules = None + self._LibraryInstances = None + self._LibraryClasses = None + self._Pcds = None + self._DecPcds = None + self._BuildOptions = None + self._ModuleTypeOptions = None + self._LoadFixAddress = None + self._RFCLanguages = None + self._ISOLanguages = None + self._VpdToolGuid = None + self._MacroDict = None + self.DefaultStores = None + + ## Get current effective macros + @property + def _Macros(self): + if self._MacroDict is None: + self._MacroDict = {} + self._MacroDict.update(GlobalData.gPlatformDefines) + self._MacroDict.update(GlobalData.gGlobalDefines) + self._MacroDict.update(GlobalData.gCommandLineDefines) + return self._MacroDict + + ## Get architecture + @property + def Arch(self): + return self._Arch + @property + def Dir(self): + return self.MetaFile.Dir + + ## Retrieve all information in [Defines] section + # + # (Retrieving all [Defines] information in one-shot is just to save time.) + # + def _GetHeaderInfo(self): + RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch] + for Record in RecordList: + Name = Record[1] + # items defined _PROPERTY_ don't need additional processing + + # some special items in [Defines] section need special treatment + if Name == TAB_DSC_DEFINES_OUTPUT_DIRECTORY: + self._OutputDirectory = NormPath(Record[2], self._Macros) + if ' ' in self._OutputDirectory: + EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "No space is allowed in OUTPUT_DIRECTORY", + File=self.MetaFile, Line=Record[-1], + ExtraData=self._OutputDirectory) + elif Name == TAB_DSC_DEFINES_FLASH_DEFINITION: + self._FlashDefinition = PathClass(NormPath(Record[2], self._Macros), GlobalData.gWorkspace) + ErrorCode, ErrorInfo = self._FlashDefinition.Validate('.fdf') + if ErrorCode != 0: + EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=Record[-1], + ExtraData=ErrorInfo) + elif Name == TAB_DSC_PREBUILD: + PrebuildValue = Record[2] + if Record[2][0] == '"': + if Record[2][-1] != '"': + EdkLogger.error('build', FORMAT_INVALID, 'Missing double quotes in the end of %s statement.' % TAB_DSC_PREBUILD, + File=self.MetaFile, Line=Record[-1]) + PrebuildValue = Record[2][1:-1] + self._Prebuild = PrebuildValue + elif Name == TAB_DSC_POSTBUILD: + PostbuildValue = Record[2] + if Record[2][0] == '"': + if Record[2][-1] != '"': + EdkLogger.error('build', FORMAT_INVALID, 'Missing double quotes in the end of %s statement.' % TAB_DSC_POSTBUILD, + File=self.MetaFile, Line=Record[-1]) + PostbuildValue = Record[2][1:-1] + self._Postbuild = PostbuildValue + elif Name == TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES: + self._SupArchList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT) + elif Name == TAB_DSC_DEFINES_BUILD_TARGETS: + self._BuildTargets = GetSplitValueList(Record[2]) + elif Name == TAB_DSC_DEFINES_SKUID_IDENTIFIER: + if self._SkuName is None: + self._SkuName = Record[2] + if GlobalData.gSKUID_CMD: + self._SkuName = GlobalData.gSKUID_CMD + elif Name == TAB_DSC_DEFINES_PCD_INFO_GENERATION: + self._PcdInfoFlag = Record[2] + elif Name == TAB_DSC_DEFINES_PCD_VAR_CHECK_GENERATION: + self._VarCheckFlag = Record[2] + elif Name == TAB_FIX_LOAD_TOP_MEMORY_ADDRESS: + try: + self._LoadFixAddress = int (Record[2], 0) + except: + EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (Record[2])) + elif Name == TAB_DSC_DEFINES_RFC_LANGUAGES: + if not Record[2] or Record[2][0] != '"' or Record[2][-1] != '"' or len(Record[2]) == 1: + EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'language code for RFC_LANGUAGES must have double quotes around it, for example: RFC_LANGUAGES = "en-us;zh-hans"', + File=self.MetaFile, Line=Record[-1]) + LanguageCodes = Record[2][1:-1] + if not LanguageCodes: + EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement', + File=self.MetaFile, Line=Record[-1]) + LanguageList = GetSplitValueList(LanguageCodes, TAB_SEMI_COLON_SPLIT) + # check whether there is empty entries in the list + if None in LanguageList: + EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more empty language code is in RFC_LANGUAGES statement', + File=self.MetaFile, Line=Record[-1]) + self._RFCLanguages = LanguageList + elif Name == TAB_DSC_DEFINES_ISO_LANGUAGES: + if not Record[2] or Record[2][0] != '"' or Record[2][-1] != '"' or len(Record[2]) == 1: + EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = "engchn"', + File=self.MetaFile, Line=Record[-1]) + LanguageCodes = Record[2][1:-1] + if not LanguageCodes: + EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement', + File=self.MetaFile, Line=Record[-1]) + if len(LanguageCodes) % 3: + EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'bad ISO639-2 format for ISO_LANGUAGES', + File=self.MetaFile, Line=Record[-1]) + LanguageList = [] + for i in range(0, len(LanguageCodes), 3): + LanguageList.append(LanguageCodes[i:i + 3]) + self._ISOLanguages = LanguageList + elif Name == TAB_DSC_DEFINES_VPD_TOOL_GUID: + # + # try to convert GUID to a real UUID value to see whether the GUID is format + # for VPD_TOOL_GUID is correct. + # + try: + uuid.UUID(Record[2]) + except: + EdkLogger.error("build", FORMAT_INVALID, "Invalid GUID format for VPD_TOOL_GUID", File=self.MetaFile) + self._VpdToolGuid = Record[2] + elif Name in self: + self[Name] = Record[2] + # set _Header to non-None in order to avoid database re-querying + self._Header = 'DUMMY' + + ## Retrieve platform name + @property + def PlatformName(self): + if self._PlatformName is None: + if self._Header is None: + self._GetHeaderInfo() + if self._PlatformName is None: + EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_NAME", File=self.MetaFile) + return self._PlatformName + + @property + def Platform(self): + return self.PlatformName + + ## Retrieve file guid + @property + def Guid(self): + if self._Guid is None: + if self._Header is None: + self._GetHeaderInfo() + if self._Guid is None: + EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_GUID", File=self.MetaFile) + return self._Guid + + ## Retrieve platform version + @property + def Version(self): + if self._Version is None: + if self._Header is None: + self._GetHeaderInfo() + if self._Version is None: + EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_VERSION", File=self.MetaFile) + return self._Version + + ## Retrieve platform description file version + @property + def DscSpecification(self): + if self._DscSpecification is None: + if self._Header is None: + self._GetHeaderInfo() + if self._DscSpecification is None: + EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No DSC_SPECIFICATION", File=self.MetaFile) + return self._DscSpecification + + ## Retrieve OUTPUT_DIRECTORY + @property + def OutputDirectory(self): + if self._OutputDirectory is None: + if self._Header is None: + self._GetHeaderInfo() + if self._OutputDirectory is None: + self._OutputDirectory = os.path.join("Build", self._PlatformName) + return self._OutputDirectory + + ## Retrieve SUPPORTED_ARCHITECTURES + @property + def SupArchList(self): + if self._SupArchList is None: + if self._Header is None: + self._GetHeaderInfo() + if self._SupArchList is None: + EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No SUPPORTED_ARCHITECTURES", File=self.MetaFile) + return self._SupArchList + + ## Retrieve BUILD_TARGETS + @property + def BuildTargets(self): + if self._BuildTargets is None: + if self._Header is None: + self._GetHeaderInfo() + if self._BuildTargets is None: + EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No BUILD_TARGETS", File=self.MetaFile) + return self._BuildTargets + + @property + def PcdInfoFlag(self): + if self._PcdInfoFlag is None or self._PcdInfoFlag.upper() == 'FALSE': + return False + elif self._PcdInfoFlag.upper() == 'TRUE': + return True + else: + return False + + @property + def VarCheckFlag(self): + if self._VarCheckFlag is None or self._VarCheckFlag.upper() == 'FALSE': + return False + elif self._VarCheckFlag.upper() == 'TRUE': + return True + else: + return False + + # # Retrieve SKUID_IDENTIFIER + @property + def SkuName(self): + if self._SkuName is None: + if self._Header is None: + self._GetHeaderInfo() + if self._SkuName is None: + self._SkuName = TAB_DEFAULT + return self._SkuName + + ## Override SKUID_IDENTIFIER + @SkuName.setter + def SkuName(self, Value): + self._SkuName = Value + + @property + def FlashDefinition(self): + if self._FlashDefinition is None: + if self._Header is None: + self._GetHeaderInfo() + if self._FlashDefinition is None: + self._FlashDefinition = '' + return self._FlashDefinition + + @property + def Prebuild(self): + if self._Prebuild is None: + if self._Header is None: + self._GetHeaderInfo() + if self._Prebuild is None: + self._Prebuild = '' + return self._Prebuild + + @property + def Postbuild(self): + if self._Postbuild is None: + if self._Header is None: + self._GetHeaderInfo() + if self._Postbuild is None: + self._Postbuild = '' + return self._Postbuild + + ## Retrieve FLASH_DEFINITION + @property + def BuildNumber(self): + if self._BuildNumber is None: + if self._Header is None: + self._GetHeaderInfo() + if self._BuildNumber is None: + self._BuildNumber = '' + return self._BuildNumber + + ## Retrieve MAKEFILE_NAME + @property + def MakefileName(self): + if self._MakefileName is None: + if self._Header is None: + self._GetHeaderInfo() + if self._MakefileName is None: + self._MakefileName = '' + return self._MakefileName + + ## Retrieve BsBaseAddress + @property + def BsBaseAddress(self): + if self._BsBaseAddress is None: + if self._Header is None: + self._GetHeaderInfo() + if self._BsBaseAddress is None: + self._BsBaseAddress = '' + return self._BsBaseAddress + + ## Retrieve RtBaseAddress + @property + def RtBaseAddress(self): + if self._RtBaseAddress is None: + if self._Header is None: + self._GetHeaderInfo() + if self._RtBaseAddress is None: + self._RtBaseAddress = '' + return self._RtBaseAddress + + ## Retrieve the top address for the load fix address + @property + def LoadFixAddress(self): + if self._LoadFixAddress is None: + if self._Header is None: + self._GetHeaderInfo() + + if self._LoadFixAddress is None: + self._LoadFixAddress = self._Macros.get(TAB_FIX_LOAD_TOP_MEMORY_ADDRESS, '0') + + try: + self._LoadFixAddress = int (self._LoadFixAddress, 0) + except: + EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (self._LoadFixAddress)) + + # + # If command line defined, should override the value in DSC file. + # + if 'FIX_LOAD_TOP_MEMORY_ADDRESS' in GlobalData.gCommandLineDefines: + try: + self._LoadFixAddress = int(GlobalData.gCommandLineDefines['FIX_LOAD_TOP_MEMORY_ADDRESS'], 0) + except: + EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (GlobalData.gCommandLineDefines['FIX_LOAD_TOP_MEMORY_ADDRESS'])) + + if self._LoadFixAddress < 0: + EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value 0x%x" % (self._LoadFixAddress)) + if self._LoadFixAddress != 0xFFFFFFFFFFFFFFFF and self._LoadFixAddress % 0x1000 != 0: + EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value 0x%x" % (self._LoadFixAddress)) + + return self._LoadFixAddress + + ## Retrieve RFCLanguage filter + @property + def RFCLanguages(self): + if self._RFCLanguages is None: + if self._Header is None: + self._GetHeaderInfo() + if self._RFCLanguages is None: + self._RFCLanguages = [] + return self._RFCLanguages + + ## Retrieve ISOLanguage filter + @property + def ISOLanguages(self): + if self._ISOLanguages is None: + if self._Header is None: + self._GetHeaderInfo() + if self._ISOLanguages is None: + self._ISOLanguages = [] + return self._ISOLanguages + + ## Retrieve the GUID string for VPD tool + @property + def VpdToolGuid(self): + if self._VpdToolGuid is None: + if self._Header is None: + self._GetHeaderInfo() + if self._VpdToolGuid is None: + self._VpdToolGuid = '' + return self._VpdToolGuid + + ## Retrieve [SkuIds] section information + @property + def SkuIds(self): + if self._SkuIds is None: + self._SkuIds = OrderedDict() + RecordList = self._RawData[MODEL_EFI_SKU_ID, self._Arch] + for Record in RecordList: + if not Record[0]: + EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID number', + File=self.MetaFile, Line=Record[-1]) + if not Record[1]: + EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID name', + File=self.MetaFile, Line=Record[-1]) + if not Pattern.match(Record[0]) and not HexPattern.match(Record[0]): + EdkLogger.error('build', FORMAT_INVALID, "The format of the Sku ID number is invalid. It only support Integer and HexNumber", + File=self.MetaFile, Line=Record[-1]) + if not SkuIdPattern.match(Record[1]) or (Record[2] and not SkuIdPattern.match(Record[2])): + EdkLogger.error('build', FORMAT_INVALID, "The format of the Sku ID name is invalid. The correct format is '(a-zA-Z_)(a-zA-Z0-9_)*'", + File=self.MetaFile, Line=Record[-1]) + self._SkuIds[Record[1].upper()] = (str(DscBuildData.ToInt(Record[0])), Record[1].upper(), Record[2].upper()) + if TAB_DEFAULT not in self._SkuIds: + self._SkuIds[TAB_DEFAULT] = ("0", TAB_DEFAULT, TAB_DEFAULT) + if TAB_COMMON not in self._SkuIds: + self._SkuIds[TAB_COMMON] = ("0", TAB_DEFAULT, TAB_DEFAULT) + return self._SkuIds + + @staticmethod + def ToInt(intstr): + return int(intstr, 16) if intstr.upper().startswith("0X") else int(intstr) + + def _GetDefaultStores(self): + if self.DefaultStores is None: + self.DefaultStores = OrderedDict() + RecordList = self._RawData[MODEL_EFI_DEFAULT_STORES, self._Arch] + for Record in RecordList: + if not Record[0]: + EdkLogger.error('build', FORMAT_INVALID, 'No DefaultStores ID number', + File=self.MetaFile, Line=Record[-1]) + if not Record[1]: + EdkLogger.error('build', FORMAT_INVALID, 'No DefaultStores ID name', + File=self.MetaFile, Line=Record[-1]) + if not Pattern.match(Record[0]) and not HexPattern.match(Record[0]): + EdkLogger.error('build', FORMAT_INVALID, "The format of the DefaultStores ID number is invalid. It only support Integer and HexNumber", + File=self.MetaFile, Line=Record[-1]) + if not IsValidWord(Record[1]): + EdkLogger.error('build', FORMAT_INVALID, "The format of the DefaultStores ID name is invalid. The correct format is '(a-zA-Z0-9_)(a-zA-Z0-9_-.)*'", + File=self.MetaFile, Line=Record[-1]) + self.DefaultStores[Record[1].upper()] = (DscBuildData.ToInt(Record[0]), Record[1].upper()) + if TAB_DEFAULT_STORES_DEFAULT not in self.DefaultStores: + self.DefaultStores[TAB_DEFAULT_STORES_DEFAULT] = (0, TAB_DEFAULT_STORES_DEFAULT) + GlobalData.gDefaultStores = sorted(self.DefaultStores.keys()) + return self.DefaultStores + + def OverrideDuplicateModule(self): + RecordList = self._RawData[MODEL_META_DATA_COMPONENT, self._Arch] + Macros = self._Macros + Components = {} + for Record in RecordList: + ModuleId = Record[6] + file_guid = self._RawData[MODEL_META_DATA_HEADER, self._Arch, None, ModuleId] + file_guid_str = file_guid[0][2] if file_guid else "NULL" + ModuleFile = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch) + if self._Arch != TAB_ARCH_COMMON and (file_guid_str,str(ModuleFile)) in Components: + self._RawData.DisableOverrideComponent(Components[(file_guid_str,str(ModuleFile))]) + Components[(file_guid_str,str(ModuleFile))] = ModuleId + self._RawData._PostProcessed = False + + ## Retrieve 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] + 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]) + for skuname in Pcd.SkuOverrideValues: + if skuname == TAB_COMMON: + continue + for defaultstorenameitem in Pcd.SkuOverrideValues[skuname]: + CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % (skuname, defaultstorenameitem) + for index in Pcd.SkuOverrideValues[skuname][defaultstorenameitem]: + if index: + ActualCap.append(index) + for FieldList in [Pcd.SkuOverrideValues[skuname][defaultstorenameitem][index]]: + if not FieldList: + continue + for FieldName in FieldList: + FieldName = "." + FieldName + IsArray = _IsFieldValueAnArray(FieldList[FieldName.strip(".")][0]) + if IsArray and not (FieldList[FieldName.strip(".")][0].startswith('{GUID') and FieldList[FieldName.strip(".")][0].endswith('}')): + try: + Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], TAB_VOID, self._GuidDict)(True) + except BadExpression: + EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % + (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2])) + Value, ValueSize = ParseFieldValue(Value) + if not Pcd.IsArray(): + CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0)); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2], FieldList[FieldName.strip(".")][0]); + else: + NewFieldName = '' + FieldName_ori = FieldName.strip('.') + while '[' in FieldName: + NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]' + Array_Index = int(FieldName.split('[', 1)[1].split(']', 1)[0]) + FieldName = FieldName.split(']', 1)[1] + FieldName = NewFieldName + FieldName + while '[' in FieldName and not Pcd.IsArray(): + FieldName = FieldName.rsplit('[', 1)[0] + CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), Array_Index + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2], FieldList[FieldName_ori][0]) + if Pcd.PcdFieldValueFromFdf: + CApp = CApp + "// From fdf \n" + for FieldName in Pcd.PcdFieldValueFromFdf: + FieldName = "." + FieldName + IsArray = _IsFieldValueAnArray(Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0]) + if IsArray and not (Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0].startswith('{GUID') and Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0].endswith('}')): + try: + Value = ValueExpressionEx(Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0], TAB_VOID, self._GuidDict)(True) + except BadExpression: + EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % + (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][1], Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][2])) + Value, ValueSize = ParseFieldValue(Value) + if not Pcd.IsArray(): + CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0)); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][1], Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][2], Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0]); + else: + NewFieldName = '' + FieldName_ori = FieldName.strip('.') + while '[' in FieldName: + NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]' + Array_Index = int(FieldName.split('[', 1)[1].split(']', 1)[0]) + FieldName = FieldName.split(']', 1)[1] + FieldName = NewFieldName + FieldName + while '[' in FieldName: + FieldName = FieldName.rsplit('[', 1)[0] + CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %s Value %s \n' % (Pcd.DatumType, FieldName.strip("."), Array_Index + 1, Pcd.PcdFieldValueFromFdf[FieldName_ori][1], Pcd.PcdFieldValueFromFdf[FieldName_ori][2], Pcd.PcdFieldValueFromFdf[FieldName_ori][0]) + if Pcd.PcdFieldValueFromComm: + CApp = CApp + "// From Command Line \n" + for FieldName in Pcd.PcdFieldValueFromComm: + FieldName = "." + FieldName + IsArray = _IsFieldValueAnArray(Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0]) + if IsArray and not (Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0].startswith('{GUID') and Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0].endswith('}')): + try: + Value = ValueExpressionEx(Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0], TAB_VOID, self._GuidDict)(True) + except BadExpression: + EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % + (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), Pcd.PcdFieldValueFromComm[FieldName.strip(".")][1], Pcd.PcdFieldValueFromComm[FieldName.strip(".")][2])) + Value, ValueSize = ParseFieldValue(Value) + if not Pcd.IsArray(): + CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0)); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), Pcd.PcdFieldValueFromComm[FieldName.strip(".")][1], Pcd.PcdFieldValueFromComm[FieldName.strip(".")][2], Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0]); + else: + NewFieldName = '' + FieldName_ori = FieldName.strip('.') + while '[' in FieldName: + NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]' + Array_Index = int(FieldName.split('[', 1)[1].split(']', 1)[0]) + FieldName = FieldName.split(']', 1)[1] + FieldName = NewFieldName + FieldName + while '[' in FieldName and not Pcd.IsArray(): + FieldName = FieldName.rsplit('[', 1)[0] + CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), Array_Index + 1, Pcd.PcdFieldValueFromComm[FieldName_ori][1], Pcd.PcdFieldValueFromComm[FieldName_ori][2], Pcd.PcdFieldValueFromComm[FieldName_ori][0]) + if Pcd.GetPcdMaxSize(): + CApp = CApp + " *Size = (%d > *Size ? %d : *Size); // The Pcd maxsize is %d \n" % (Pcd.GetPcdMaxSize(), Pcd.GetPcdMaxSize(), Pcd.GetPcdMaxSize()) + ArraySizeByAssign = self.CalculateActualCap(ActualCap) + if ArraySizeByAssign > 1: + CApp = CApp + " *Size = (%d > *Size ? %d : *Size); \n" % (ArraySizeByAssign, ArraySizeByAssign) + CApp = CApp + "}\n" + return CApp + def CalculateActualCap(self,ActualCap): + if not ActualCap: + return 1 + maxsize = 1 + for item in ActualCap: + index_elements = ArrayIndex.findall(item) + rt = 1 + for index_e in index_elements: + index_num = index_e.lstrip("[").rstrip("]").strip() + if not index_num: + # Not support flexiable pcd array assignment + return 1 + index_num = int(index_num,16) if index_num.startswith(("0x","0X")) else int(index_num) + rt = rt * (index_num+1) + if rt >maxsize: + maxsize = rt + + return maxsize + + @staticmethod + def GenerateSizeStatments(Pcd,skuname,defaultstorename): + if Pcd.IsArray(): + r_datatype = [Pcd.BaseDatumType] + lastoneisEmpty = False + for dem in Pcd.Capacity: + if lastoneisEmpty: + EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. " % + (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName)))) + if dem == '0' or dem == "-1": + r_datatype.append("[1]") + lastoneisEmpty = True + else: + r_datatype.append("[" + dem + "]") + + if Pcd.Type in [MODEL_PCD_DYNAMIC_EX_HII, MODEL_PCD_DYNAMIC_HII]: + PcdDefValue = Pcd.SkuInfoList.get(skuname).DefaultStoreDict.get(defaultstorename) + elif Pcd.Type in [MODEL_PCD_DYNAMIC_EX_DEFAULT,MODEL_PCD_DYNAMIC_VPD,MODEL_PCD_DYNAMIC_DEFAULT,MODEL_PCD_DYNAMIC_EX_VPD]: + PcdDefValue = Pcd.SkuInfoList.get(skuname).DefaultValue + else: + PcdDefValue = Pcd.DefaultValue + if lastoneisEmpty: + if "{CODE(" not in PcdDefValue: + sizebasevalue_plus = "(%s / sizeof(%s) + 1)" % ((DscBuildData.GetStructurePcdMaxSize(Pcd), Pcd.BaseDatumType)) + sizebasevalue = "(%s / sizeof(%s))" % ((DscBuildData.GetStructurePcdMaxSize(Pcd), Pcd.BaseDatumType)) + sizeof = "sizeof(%s)" % Pcd.BaseDatumType + CApp = ' int ArraySize = %s %% %s ? %s : %s ;\n' % ( (DscBuildData.GetStructurePcdMaxSize(Pcd), sizeof, sizebasevalue_plus, sizebasevalue)) + CApp += ' Size = ArraySize * sizeof(%s); \n' % Pcd.BaseDatumType + else: + CApp = " Size = 0;\n" + else: + CApp = ' Size = sizeof(%s);\n' % ("".join(r_datatype) ) + else: + CApp = ' Size = sizeof(%s);\n' % (Pcd.DatumType) + CApp = CApp + ' Cal_%s_%s_Size(&Size);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) + return CApp + + def GetIndicator(self,index,FieldName,Pcd): + def cleanupindex(indexstr): + return indexstr.strip("[").strip("]").strip() + index_elements = ArrayIndex.findall(index) + pcd_capacity = Pcd.Capacity + if index: + indicator = "(Pcd" + if len(pcd_capacity)>2: + for i in range(0,len(index_elements)): + index_ele = index_elements[i] + index_num = index_ele.strip("[").strip("]").strip() + if i == len(index_elements) -2: + indicator += "+ %d*Size/sizeof(%s)/%d + %s)" %(int(cleanupindex(index_elements[i+1])),Pcd.BaseDatumType,reduce(lambda x,y: int(x)*int(y),pcd_capacity[:-1]), cleanupindex(index_elements[i])) + break + else: + indicator += " + %d*%s*Size/sizeof(%s)/%d" %(int(cleanupindex(index_elements[i])),reduce(lambda x,y: int(x)*int(y),pcd_capacity[i+1:-1]),Pcd.BaseDatumType,reduce(lambda x,y: int(x)*int(y),pcd_capacity[:-1])) + elif len(pcd_capacity) == 2: + indicator += "+ %d*Size/sizeof(%s)/%d + %s)" %(int(cleanupindex(index_elements[0])),Pcd.BaseDatumType,int(pcd_capacity[0]), index_elements[1].strip("[").strip("]").strip()) + elif len(pcd_capacity) == 1: + index_ele = index_elements[0] + index_num = index_ele.strip("[").strip("]").strip() + indicator += " + %s)" % (index_num) + else: + indicator = "Pcd" + if FieldName: + indicator += "->" + FieldName + return indicator + + def GetStarNum(self,Pcd): + if not Pcd.IsArray(): + return 1 + elif Pcd.IsSimpleTypeArray(): + return len(Pcd.Capacity) + else: + return len(Pcd.Capacity) + 1 + def GenerateDefaultValueAssignFunction(self, Pcd): + CApp = "// Default value in Dec \n" + CApp = CApp + "void Assign_%s_%s_Default_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.BaseDatumType) + CApp = CApp + ' UINT32 FieldSize;\n' + CApp = CApp + ' CHAR8 *Value;\n' + CApp = CApp + ' UINT32 PcdArraySize;\n' + DefaultValueFromDec = Pcd.DefaultValueFromDec + IsArray = _IsFieldValueAnArray(Pcd.DefaultValueFromDec) + if IsArray: + try: + DefaultValueFromDec = ValueExpressionEx(Pcd.DefaultValueFromDec, TAB_VOID)(True) + except BadExpression: + EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DEC: %s" % + (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, DefaultValueFromDec)) + DefaultValueFromDec = StringToArray(DefaultValueFromDec) + Value, ValueSize = ParseFieldValue (DefaultValueFromDec) + if IsArray: + # + # Use memcpy() to copy value into field + # + if Pcd.IsArray(): + pcdarraysize = Pcd.PcdArraySize() + if "{CODE(" in Pcd.DefaultValueFromDec: + if Pcd.Capacity[-1] != "-1": + CApp = CApp + '__STATIC_ASSERT(sizeof(%s_%s_INIT_Value) < %d * sizeof(%s), "Pcd %s.%s Value in Dec exceed the array capability %s"); // From %s Line %s \n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,Pcd.DefaultValueFromDecInfo[0],Pcd.DefaultValueFromDecInfo[1]) + CApp = CApp + ' PcdArraySize = sizeof(%s_%s_INIT_Value);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) + CApp = CApp + ' memcpy (Pcd, %s_%s_INIT_Value,PcdArraySize);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) + else: + if Pcd.Capacity[-1] != "-1": + CApp = CApp + '__STATIC_ASSERT(%d < %d * sizeof(%s), "Pcd %s.%s Value in Dec exceed the array capability %s"); // From %s Line %s \n' % (ValueSize,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,Pcd.DefaultValueFromDecInfo[0],Pcd.DefaultValueFromDecInfo[1]) + CApp = CApp + ' PcdArraySize = %d;\n' % ValueSize + CApp = CApp + ' Value = %s; // From DEC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DefaultValueFromDec) + CApp = CApp + ' memcpy (Pcd, Value, PcdArraySize);\n' + else: + if "{CODE(" in Pcd.DefaultValueFromDec: + CApp = CApp + ' PcdArraySize = sizeof(%s_%s_INIT_Value);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) + CApp = CApp + ' memcpy (Pcd, &%s_%s_INIT_Value,PcdArraySize);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) + else: + CApp = CApp + ' Value = %s; // From DEC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DefaultValueFromDec) + CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize) + elif isinstance(Value, str): + CApp = CApp + ' Pcd = %s; // From DEC Default Value %s\n' % (Value, Pcd.DefaultValueFromDec) + for index in Pcd.DefaultValues: + FieldList = Pcd.DefaultValues[index] + if not FieldList: + continue + for FieldName in FieldList: + IsArray = _IsFieldValueAnArray(FieldList[FieldName][0]) + if IsArray: + try: + FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], TAB_VOID, self._GuidDict)(True) + except BadExpression: + EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % + (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2])) + + try: + Value, ValueSize = ParseFieldValue (FieldList[FieldName][0]) + except Exception: + EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2])) + + indicator = self.GetIndicator(index, FieldName,Pcd) + if IsArray: + # + # Use memcpy() to copy value into field + # + CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.BaseDatumType, FieldName) + CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) + CApp = CApp + ' __STATIC_ASSERT((__FIELD_SIZE(%s, %s) >= %d) || (__FIELD_SIZE(%s, %s) == 0), "Input buffer exceeds the buffer array"); // From %s Line %d Value %s\n' % (Pcd.BaseDatumType, FieldName, ValueSize, Pcd.BaseDatumType, FieldName, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) + CApp = CApp + ' memcpy (&%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (indicator, ValueSize, ValueSize) + elif isinstance(Value, str): + CApp = CApp + ' %s = %s; // From %s Line %d Value %s\n' % (indicator, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) + else: + if '[' in FieldName and ']' in FieldName: + Index = int(FieldName.split('[')[1].split(']')[0]) + CApp = CApp + ' __STATIC_ASSERT((%d < __ARRAY_SIZE(Pcd->%s)) || (__ARRAY_SIZE(Pcd->%s) == 0), "array index exceeds the array number"); // From %s Line %d Index of %s\n' % (Index, FieldName.split('[')[0], FieldName.split('[')[0], FieldList[FieldName][1], FieldList[FieldName][2], FieldName) + if ValueSize > 4: + CApp = CApp + ' %s = %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 GenerateByteArrayValue (self, StructuredPcds): + # + # Generate/Compile/Run C application to determine if there are any flexible array members + # + if not StructuredPcds: + return + + InitByteValue = "" + CApp = PcdMainCHeader + + IncludeFiles = set() + for PcdName in StructuredPcds: + Pcd = StructuredPcds[PcdName] + for IncludeFile in Pcd.StructuredPcdIncludeFile: + if IncludeFile not in IncludeFiles: + IncludeFiles.add(IncludeFile) + CApp = CApp + '#include <%s>\n' % (IncludeFile) + CApp = CApp + '\n' + for Pcd in StructuredPcds.values(): + CApp = CApp + self.GenerateArrayAssignment(Pcd) + for PcdName in 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' + + if not os.path.exists(self.OutputPath): + os.makedirs(self.OutputPath) + 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' + + CC_FLAGS = LinuxCFLAGS + if sys.platform == "win32": + CC_FLAGS = WindowsCFLAGS + BuildOptions = OrderedDict() + for Options in self.BuildOptions: + if Options[2] != EDKII_NAME: + continue + Family = Options[0] + if Family and Family != self.ToolChainFamily: + continue + Target, Tag, Arch, Tool, Attr = Options[1].split("_") + if Tool != 'CC': + continue + if Attr != "FLAGS": + continue + if Target == TAB_STAR or Target == self._Target: + if Tag == TAB_STAR or Tag == self._Toolchain: + if 'COMMON' not in BuildOptions: + BuildOptions['COMMON'] = set() + if Arch == TAB_STAR: + BuildOptions['COMMON']|= self.ParseCCFlags(self.BuildOptions[Options]) + if Arch in self.SupArchList: + if Arch not in BuildOptions: + BuildOptions[Arch] = set() + BuildOptions[Arch] |= self.ParseCCFlags(self.BuildOptions[Options]) + + if BuildOptions: + ArchBuildOptions = {arch:flags for arch,flags in BuildOptions.items() if arch != 'COMMON'} + if len(ArchBuildOptions.keys()) == 1: + BuildOptions['COMMON'] |= (list(ArchBuildOptions.values())[0]) + elif len(ArchBuildOptions.keys()) > 1: + CommonBuildOptions = reduce(lambda x,y: x&y, ArchBuildOptions.values()) + BuildOptions['COMMON'] |= CommonBuildOptions + ValueList = [item for item in BuildOptions['COMMON'] if item.startswith((r"/U","-U"))] + ValueList.extend([item for item in BuildOptions['COMMON'] if item.startswith((r"/D", "-D"))]) + CC_FLAGS += " ".join(ValueList) + MakeApp += CC_FLAGS + + if sys.platform == "win32": + MakeApp = MakeApp + PcdMakefileEnd + MakeApp = MakeApp + AppTarget % ("""\tcopy $(APPLICATION) $(APPFILE) /y """) + else: + MakeApp = MakeApp + AppTarget % ("""\tcp $(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) + for include_file in IncFileList: + 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 -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' % (Command, StdOut, StdErr)) + + #start update structure pcd final value + File = open (OutputValueFile, 'r') + FileBuffer = File.readlines() + File.close() + + StructurePcdSet = [] + for Pcd in FileBuffer: + PcdValue = Pcd.split ('|') + PcdInfo = PcdValue[0].split ('.') + StructurePcdSet.append((PcdInfo[0], PcdInfo[1], PcdInfo[2], PcdInfo[3], PcdValue[2].strip())) + return StructurePcdSet + + @staticmethod + def NeedUpdateOutput(OutputFile, ValueCFile, StructureInput): + if not os.path.exists(OutputFile): + return True + if os.stat(OutputFile).st_mtime <= os.stat(ValueCFile).st_mtime: + return True + if os.stat(OutputFile).st_mtime <= os.stat(StructureInput).st_mtime: + return True + return False + + ## Retrieve dynamic PCD settings + # + # @param Type PCD type + # + # @retval a dict object contains settings of given PCD type + # + def _GetDynamicPcd(self, Type): + + + Pcds = OrderedDict() + # + # tdict is a special dict kind of type, used for selecting correct + # PCD settings for certain ARCH and SKU + # + PcdDict = tdict(True, 4) + PcdList = [] + # Find out all possible PCD candidates for self._Arch + RecordList = self._RawData[Type, self._Arch] + AvailableSkuIdSet = copy.copy(self.SkuIds) + + + for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4, Dummy5 in RecordList: + SkuName = SkuName.upper() + SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName + if SkuName not in AvailableSkuIdSet: + EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName, + File=self.MetaFile, Line=Dummy5) + if "." not in TokenSpaceGuid and "[" not in PcdCName and (PcdCName, TokenSpaceGuid, SkuName, Dummy5) not in PcdList: + PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy5)) + PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting + + # Remove redundant PCD candidates, per the ARCH and SKU + for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList: + + Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid] + if Setting is None: + continue + + PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4) + if MaxDatumSize: + if int(MaxDatumSize, 0) > 0xFFFF: + EdkLogger.error('build', FORMAT_INVALID, "The size value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)), + File=self.MetaFile, Line=Dummy4) + if int(MaxDatumSize, 0) < 0: + EdkLogger.error('build', FORMAT_INVALID, "The size value can't be set to negative value for %s." % ".".join((TokenSpaceGuid, PcdCName)), + File=self.MetaFile, Line=Dummy4) + SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', '', PcdValue) + if (PcdCName, TokenSpaceGuid) in Pcds: + pcdObject = Pcds[PcdCName, TokenSpaceGuid] + pcdObject.SkuInfoList[SkuName] = SkuInfo + if MaxDatumSize.strip(): + CurrentMaxSize = int(MaxDatumSize.strip(), 0) + else: + CurrentMaxSize = 0 + if pcdObject.MaxDatumSize: + PcdMaxSize = int(pcdObject.MaxDatumSize, 0) + else: + PcdMaxSize = 0 + if CurrentMaxSize > PcdMaxSize: + pcdObject.MaxDatumSize = str(CurrentMaxSize) + else: + Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject( + PcdCName, + TokenSpaceGuid, + self._PCD_TYPE_STRING_[Type], + DatumType, + PcdValue, + '', + MaxDatumSize, + OrderedDict({SkuName : SkuInfo}), + False, + None, + IsDsc=True) + + if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue: + Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {} + Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName] = {} + Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][TAB_DEFAULT_STORES_DEFAULT] = PcdValue + Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName][TAB_DEFAULT_STORES_DEFAULT] = (self.MetaFile.File,Dummy4) + + for pcd in Pcds.values(): + pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName] + # Only fix the value while no value provided in DSC file. + for sku in pcd.SkuInfoList.values(): + if not sku.DefaultValue: + sku.DefaultValue = pcdDecObject.DefaultValue + if TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON not in pcd.SkuInfoList: + valuefromDec = pcdDecObject.DefaultValue + SkuInfo = SkuInfoClass(TAB_DEFAULT, '0', '', '', '', '', '', valuefromDec) + pcd.SkuInfoList[TAB_DEFAULT] = SkuInfo + elif TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList: + pcd.SkuInfoList[TAB_DEFAULT] = pcd.SkuInfoList[TAB_COMMON] + del pcd.SkuInfoList[TAB_COMMON] + elif TAB_DEFAULT in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList: + del pcd.SkuInfoList[TAB_COMMON] + + list(map(self.FilterSkuSettings, Pcds.values())) + + return Pcds + + def FilterSkuSettings(self, PcdObj): + + if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE: + if TAB_DEFAULT in PcdObj.SkuInfoList and self.SkuIdMgr.SystemSkuId not in PcdObj.SkuInfoList: + PcdObj.SkuInfoList[self.SkuIdMgr.SystemSkuId] = PcdObj.SkuInfoList[TAB_DEFAULT] + PcdObj.SkuInfoList = {TAB_DEFAULT:PcdObj.SkuInfoList[self.SkuIdMgr.SystemSkuId]} + PcdObj.SkuInfoList[TAB_DEFAULT].SkuIdName = TAB_DEFAULT + PcdObj.SkuInfoList[TAB_DEFAULT].SkuId = '0' + + elif self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.DEFAULT: + PcdObj.SkuInfoList = {TAB_DEFAULT:PcdObj.SkuInfoList[TAB_DEFAULT]} + + return PcdObj + + @staticmethod + def CompareVarAttr(Attr1, Attr2): + if not Attr1 or not Attr2: # for empty string + return True + Attr1s = [attr.strip() for attr in Attr1.split(",")] + Attr1Set = set(Attr1s) + Attr2s = [attr.strip() for attr in Attr2.split(",")] + Attr2Set = set(Attr2s) + if Attr2Set == Attr1Set: + return True + else: + return False + + def CompletePcdValues(self, PcdSet): + Pcds = OrderedDict() + DefaultStoreObj = DefaultStore(self._GetDefaultStores()) + SkuIds = {skuname:skuid for skuname, skuid in self.SkuIdMgr.AvailableSkuIdSet.items() if skuname != TAB_COMMON} + DefaultStores = set(storename for pcdobj in PcdSet.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict) + for PcdCName, TokenSpaceGuid in PcdSet: + PcdObj = PcdSet[(PcdCName, TokenSpaceGuid)] + + if PcdObj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT], + self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], + self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD], + self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_DEFAULT], + self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII], + self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]: + Pcds[PcdCName, TokenSpaceGuid]= PcdObj + continue + PcdType = PcdObj.Type + if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]: + for skuid in PcdObj.SkuInfoList: + skuobj = PcdObj.SkuInfoList[skuid] + mindefaultstorename = DefaultStoreObj.GetMin(set(defaultstorename for defaultstorename in skuobj.DefaultStoreDict)) + for defaultstorename in DefaultStores: + if defaultstorename not in skuobj.DefaultStoreDict: + skuobj.DefaultStoreDict[defaultstorename] = skuobj.DefaultStoreDict[mindefaultstorename] + skuobj.HiiDefaultValue = skuobj.DefaultStoreDict[mindefaultstorename] + for skuname, skuid in SkuIds.items(): + if skuname not in PcdObj.SkuInfoList: + nextskuid = self.SkuIdMgr.GetNextSkuId(skuname) + while nextskuid not in PcdObj.SkuInfoList: + nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid) + PcdObj.SkuInfoList[skuname] = copy.deepcopy(PcdObj.SkuInfoList[nextskuid]) + PcdObj.SkuInfoList[skuname].SkuId = skuid + PcdObj.SkuInfoList[skuname].SkuIdName = skuname + if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]: + PcdObj.DefaultValue = list(PcdObj.SkuInfoList.values())[0].HiiDefaultValue if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE else PcdObj.SkuInfoList[TAB_DEFAULT].HiiDefaultValue + Pcds[PcdCName, TokenSpaceGuid]= PcdObj + return Pcds + ## Retrieve dynamic HII PCD settings + # + # @param Type PCD type + # + # @retval a dict object contains settings of given PCD type + # + def _GetDynamicHiiPcd(self, Type): + + VariableAttrs = {} + + Pcds = OrderedDict() + UserDefinedDefaultStores = [] + # + # tdict is a special dict kind of type, used for selecting correct + # PCD settings for certain ARCH and SKU + # + PcdDict = tdict(True, 5) + PcdList = [] + RecordList = self._RawData[Type, self._Arch] + # Find out all possible PCD candidates for self._Arch + AvailableSkuIdSet = copy.copy(self.SkuIds) + DefaultStoresDefine = self._GetDefaultStores() + + for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, DefaultStore, Dummy4, Dummy5 in RecordList: + SkuName = SkuName.upper() + SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName + DefaultStore = DefaultStore.upper() + if DefaultStore == TAB_COMMON: + DefaultStore = TAB_DEFAULT_STORES_DEFAULT + else: + #The end user define [DefaultStores] and [SKUID_IDENTIFIER.Menufacturing] in DSC + UserDefinedDefaultStores.append((PcdCName, TokenSpaceGuid)) + if SkuName not in AvailableSkuIdSet: + EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName, + File=self.MetaFile, Line=Dummy5) + if DefaultStore not in DefaultStoresDefine: + EdkLogger.error('build', PARAMETER_INVALID, 'DefaultStores %s is not defined in [DefaultStores] section' % DefaultStore, + File=self.MetaFile, Line=Dummy5) + if "." not in TokenSpaceGuid and "[" not in PcdCName and (PcdCName, TokenSpaceGuid, SkuName, DefaultStore, Dummy5) not in PcdList: + PcdList.append((PcdCName, TokenSpaceGuid, SkuName, DefaultStore, Dummy5)) + PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid, DefaultStore] = Setting + + + # Remove redundant PCD candidates, per the ARCH and SKU + 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, "target.txt")) + if os.path.isfile(BuildConfigurationFile) == True: + ToolDefinitionFile = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF] + if ToolDefinitionFile == '': + ToolDefinitionFile = "tools_def.txt" + ToolDefinitionFile = os.path.normpath(mws.join(self.WorkspaceDir, 'Conf', ToolDefinitionFile)) + if os.path.isfile(ToolDefinitionFile) == True: + 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 |