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