X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=BaseTools%2FSource%2FPython%2FWorkspace%2FDscBuildData.py;h=517385a32262cf15b99f6ff7cb20bfa9b2bf28f1;hp=302de724b1615a771c3180ea22a2e17bfbda858b;hb=34d808add3dc23aaa37e1c9edb2fcc2b50118367;hpb=ae7b6df816e913394a7f11264f24953658ff34ba diff --git a/BaseTools/Source/Python/Workspace/DscBuildData.py b/BaseTools/Source/Python/Workspace/DscBuildData.py index 302de724b1..517385a322 100644 --- a/BaseTools/Source/Python/Workspace/DscBuildData.py +++ b/BaseTools/Source/Python/Workspace/DscBuildData.py @@ -1,7 +1,7 @@ ## @file # This file is used to create a database used by build tool # -# Copyright (c) 2017, Intel Corporation. All rights reserved.
+# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.
# (C) Copyright 2016 Hewlett Packard Enterprise Development LP
# This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License @@ -21,9 +21,10 @@ from Common.String 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 * +from Common.ToolDefClassObject import * from MetaDataTable import * from MetaFileTable import * from MetaFileParser import * @@ -36,7 +37,9 @@ from Common.Parsing import IsValidWord from Common.VariableAttributes import VariableAttributes import Common.GlobalData as GlobalData import subprocess +from Common.Misc import SaveFileOnChange from Workspace.BuildClassObject import PlatformBuildClassObject, StructurePcd, PcdClassObject, ModuleBuildClassObject +from collections import OrderedDict # # Treat CHAR16 as a synonym for UINT16. CHAR16 support is required for VFR C structs @@ -77,22 +80,82 @@ PcdMakefileHeader = ''' ''' +WindowsCFLAGS = 'CFLAGS = $(CFLAGS) /wd4200 /wd4034 /wd4101 ' +LinuxCFLAGS = 'BUILD_CFLAGS += -Wno-pointer-to-int-cast -Wno-unused-variable ' PcdMakefileEnd = ''' !INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.common -CFLAGS = $(CFLAGS) /wd4200 /wd4034 /wd4101 - LIBS = $(LIB_PATH)\Common.lib !INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.app ''' PcdGccMakefile = ''' -ARCH ?= IA32 MAKEROOT ?= $(EDK_TOOLS_PATH)/Source/C LIBS = -lCommon ''' +## Regular expression for finding header file inclusions +from AutoGen.GenMake import gIncludePattern + +## Find dependencies for one source file +# +# By searching recursively "#include" directive in file, find out all the +# files needed by given source file. The dependecies will be only searched +# in given search path list. +# +# @param SearchPathList The list of search path +# +# @retval list The list of files the given source file depends on +# +def GetDependencyList(FileStack,SearchPathList): + DepDb = dict() + DependencySet = set(FileStack) + while len(FileStack) > 0: + F = FileStack.pop() + FullPathDependList = [] + CurrentFileDependencyList = [] + if F in DepDb: + CurrentFileDependencyList = DepDb[F] + else: + try: + Fd = open(F, 'r') + FileContent = Fd.read() + except BaseException, X: + EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=F + "\n\t" + str(X)) + finally: + if "Fd" in dir(locals()): + Fd.close() + + if len(FileContent) == 0: + continue + + if FileContent[0] == 0xff or FileContent[0] == 0xfe: + FileContent = unicode(FileContent, "utf-16") + IncludedFileList = gIncludePattern.findall(FileContent) + + for Inc in IncludedFileList: + Inc = Inc.strip() + Inc = os.path.normpath(Inc) + CurrentFileDependencyList.append(Inc) + DepDb[F] = CurrentFileDependencyList + + CurrentFilePath = os.path.dirname(F) + PathList = [CurrentFilePath] + SearchPathList + for Inc in CurrentFileDependencyList: + for SearchPath in PathList: + FilePath = os.path.join(SearchPath, Inc) + if not os.path.exists(FilePath): + continue + if FilePath not in DependencySet: + FileStack.append(FilePath) + FullPathDependList.append(FilePath) + break + DependencySet.update(FullPathDependList) + DependencyList = list(DependencySet) # remove duplicate ones + + return DependencyList + class DscBuildData(PlatformBuildClassObject): # dict used to convert PCD type in database to string used by build tool _PCD_TYPE_STRING_ = { @@ -152,12 +215,18 @@ class DscBuildData(PlatformBuildClassObject): self._Arch = Arch self._Target = Target self._Toolchain = Toolchain + self._ToolChainFamily = None self._Clear() self._HandleOverridePath() + self.WorkspaceDir = os.getenv("WORKSPACE") if os.getenv("WORKSPACE") else "" + self.DefaultStores = None + self.SkuIdMgr = SkuClass(self.SkuName, self.SkuIds) + @property + def OutputPath(self): if os.getenv("WORKSPACE"): - self.OutputPath = os.path.join(os.getenv("WORKSPACE"), 'Build', PcdValueInitName) + return os.path.join(os.getenv("WORKSPACE"), self.OutputDirectory, self._Target + "_" + self._Toolchain,PcdValueInitName) else: - self.OutputPath = os.path.dirname(self.DscFile) + return os.path.dirname(self.DscFile) ## XXX[key] = value def __setitem__(self, key, value): @@ -182,8 +251,6 @@ class DscBuildData(PlatformBuildClassObject): self._SupArchList = None self._BuildTargets = None self._SkuName = None - self._SkuIdentifier = None - self._AvilableSkuIds = None self._PcdInfoFlag = None self._VarCheckFlag = None self._FlashDefinition = None @@ -206,6 +273,7 @@ class DscBuildData(PlatformBuildClassObject): self._ISOLanguages = None self._VpdToolGuid = None self.__Macros = None + self.DefaultStores = None ## handle Override Path of Module @@ -214,8 +282,8 @@ class DscBuildData(PlatformBuildClassObject): Macros = self._Macros Macros["EDK_SOURCE"] = GlobalData.gEcpSource for Record in RecordList: - ModuleId = Record[5] - LineNo = Record[6] + ModuleId = Record[6] + LineNo = Record[7] ModuleFile = PathClass(NormPath(Record[0]), GlobalData.gWorkspace, Arch=self._Arch) RecordList = self._RawData[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH, self._Arch, None, ModuleId] if RecordList != []: @@ -302,8 +370,8 @@ class DscBuildData(PlatformBuildClassObject): elif Name == TAB_DSC_DEFINES_SKUID_IDENTIFIER: if self._SkuName == None: self._SkuName = Record[2] - self._SkuIdentifier = Record[2] - self._AvilableSkuIds = 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: @@ -434,30 +502,19 @@ class DscBuildData(PlatformBuildClassObject): return True else: return False - def _GetAviableSkuIds(self): - if self._AvilableSkuIds: - return self._AvilableSkuIds - return self.SkuIdentifier - def _GetSkuIdentifier(self): - if self._SkuName: - return self._SkuName - if self._SkuIdentifier == None: - if self._Header == None: - self._GetHeaderInfo() - return self._SkuIdentifier - ## Retrieve SKUID_IDENTIFIER + + # # Retrieve SKUID_IDENTIFIER def _GetSkuName(self): if self._SkuName == None: if self._Header == None: self._GetHeaderInfo() - if (self._SkuName == None or self._SkuName not in self.SkuIds): + if self._SkuName == None: self._SkuName = 'DEFAULT' return self._SkuName ## Override SKUID_IDENTIFIER def _SetSkuName(self, Value): self._SkuName = Value - self._Pcds = None def _GetFdfFile(self): if self._FlashDefinition == None: @@ -587,12 +644,48 @@ class DscBuildData(PlatformBuildClassObject): if Record[1] in [None, '']: EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID name', File=self.MetaFile, Line=Record[-1]) - self._SkuIds[Record[1]] = Record[0] + Pattern = re.compile('^[1-9]\d*|0$') + HexPattern = re.compile(r'0[xX][0-9a-fA-F]+$') + if Pattern.match(Record[0]) == None and HexPattern.match(Record[0]) == None: + 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 IsValidWord(Record[1]): + EdkLogger.error('build', FORMAT_INVALID, "The format of the Sku ID name is invalid. The correct format is '(a-zA-Z0-9_)(a-zA-Z0-9_-.)*'", + File=self.MetaFile, Line=Record[-1]) + self._SkuIds[Record[1].upper()] = (str(self.ToInt(Record[0])), Record[1].upper(), Record[2].upper()) if 'DEFAULT' not in self._SkuIds: - self._SkuIds['DEFAULT'] = '0' + self._SkuIds['DEFAULT'] = ("0","DEFAULT","DEFAULT") if 'COMMON' not in self._SkuIds: - self._SkuIds['COMMON'] = '0' + self._SkuIds['COMMON'] = ("0","DEFAULT","DEFAULT") return self._SkuIds + def ToInt(self,intstr): + return int(intstr,16) if intstr.upper().startswith("0X") else int(intstr) + def _GetDefaultStores(self): + if self.DefaultStores == None: + self.DefaultStores = sdict() + RecordList = self._RawData[MODEL_EFI_DEFAULT_STORES, self._Arch] + for Record in RecordList: + if Record[0] in [None, '']: + EdkLogger.error('build', FORMAT_INVALID, 'No DefaultStores ID number', + File=self.MetaFile, Line=Record[-1]) + if Record[1] in [None, '']: + EdkLogger.error('build', FORMAT_INVALID, 'No DefaultStores ID name', + File=self.MetaFile, Line=Record[-1]) + Pattern = re.compile('^[1-9]\d*|0$') + HexPattern = re.compile(r'0[xX][0-9a-fA-F]+$') + if Pattern.match(Record[0]) == None and HexPattern.match(Record[0]) == None: + 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()] = (self.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 = self.DefaultStores.keys() + if GlobalData.gDefaultStores: + GlobalData.gDefaultStores.sort() + return self.DefaultStores ## Retrieve [Components] section information def _GetModules(self): @@ -607,8 +700,8 @@ class DscBuildData(PlatformBuildClassObject): DuplicatedFile = False ModuleFile = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch) - ModuleId = Record[5] - LineNo = Record[6] + ModuleId = Record[6] + LineNo = Record[7] # check the file validation ErrorCode, ErrorInfo = ModuleFile.Validate('.inf') @@ -648,11 +741,12 @@ class DscBuildData(PlatformBuildClassObject): 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 in RecordList: + for TokenSpaceGuid, PcdCName, Setting, Dummy1, Dummy2, Dummy3, Dummy4,Dummy5 in RecordList: TokenList = GetSplitValueList(Setting) DefaultValue = TokenList[0] - if len(TokenList) > 1: - MaxDatumSize = TokenList[1] + # the format is PcdName| Value | VOID* | MaxDatumSize + if len(TokenList) > 2: + MaxDatumSize = TokenList[2] else: MaxDatumSize = '' TypeString = self._PCD_TYPE_STRING_[Type] @@ -672,7 +766,7 @@ class DscBuildData(PlatformBuildClassObject): # 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 in RecordList: + for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4,Dummy5 in RecordList: if (ToolChainFamily, ToolChain) not in Module.BuildOptions: Module.BuildOptions[ToolChainFamily, ToolChain] = Option else: @@ -712,7 +806,7 @@ class DscBuildData(PlatformBuildClassObject): RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, -1] Macros = self._Macros for Record in RecordList: - LibraryClass, LibraryInstance, Dummy, Arch, ModuleType, Dummy, LineNo = Record + LibraryClass, LibraryInstance, Dummy, Arch, ModuleType, Dummy,Dummy, LineNo = Record if LibraryClass == '' or LibraryClass == 'NULL': self._NullLibraryNumber += 1 LibraryClass = 'NULL%d' % self._NullLibraryNumber @@ -766,7 +860,7 @@ class DscBuildData(PlatformBuildClassObject): def _ValidatePcd(self, PcdCName, TokenSpaceGuid, Setting, PcdType, LineNo): if self._DecPcds == None: - self._DecPcds = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain) + FdfInfList = [] if GlobalData.gFdfParser: FdfInfList = GlobalData.gFdfParser.Profile.InfList @@ -778,25 +872,31 @@ class DscBuildData(PlatformBuildClassObject): continue ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain] PkgSet.update(ModuleData.Packages) - DecPcds = {} - for Pkg in PkgSet: - for Pcd in Pkg.Pcds: - DecPcds[Pcd[0], Pcd[1]] = Pkg.Pcds[Pcd] - self._DecPcds.update(DecPcds) - if (PcdCName, TokenSpaceGuid) not in self._DecPcds and "." in TokenSpaceGuid and (TokenSpaceGuid.split(".")[1], TokenSpaceGuid.split(".")[0]) not in self._DecPcds: + 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. 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 and 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)) - if ValueList[Index] and PcdType not in [MODEL_PCD_FEATURE_FLAG, MODEL_PCD_FIXED_AT_BUILD]: + 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 try: - ValueList[Index] = ValueExpression(ValueList[Index], GlobalData.gPlatformPcds)(True) - except WrnExpression, Value: - ValueList[Index] = Value.result + ValueList[Index] = ValueExpressionEx(ValueList[Index], DatumType, self._GuidDict)(True) + except BadExpression, Value: + EdkLogger.error('Parser', FORMAT_INVALID, Value, File=self.MetaFile, Line=LineNo, + ExtraData="PCD [%s.%s] Value \"%s\" " % ( + TokenSpaceGuid, PcdCName, ValueList[Index])) except EvaluationException, Excpt: if hasattr(Excpt, 'Pcd'): if Excpt.Pcd in GlobalData.gPlatformOtherPcds: @@ -810,21 +910,220 @@ class DscBuildData(PlatformBuildClassObject): else: EdkLogger.error('Parser', FORMAT_INVALID, "Invalid expression: %s" % str(Excpt), File=self.MetaFile, Line=LineNo) - if ValueList[Index] == 'True': - ValueList[Index] = '1' - elif ValueList[Index] == 'False': - ValueList[Index] = '0' + if ValueList[Index]: Valid, ErrStr = CheckPcdDatum(self._DecPcds[PcdCName, TokenSpaceGuid].DatumType, ValueList[Index]) if not Valid: EdkLogger.error('build', FORMAT_INVALID, ErrStr, File=self.MetaFile, Line=LineNo, ExtraData="%s.%s" % (TokenSpaceGuid, PcdCName)) + if PcdType in (MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_EX_DEFAULT): + if self._DecPcds[PcdCName, TokenSpaceGuid].DatumType.strip() != ValueList[1].strip(): + EdkLogger.error('build', FORMAT_INVALID, "Pcd datumtype used in DSC file is not the same as its declaration in DEC file." , File=self.MetaFile, Line=LineNo, + ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting)) + if (TokenSpaceGuid + '.' + PcdCName) in GlobalData.gPlatformPcds: + if GlobalData.gPlatformPcds[TokenSpaceGuid + '.' + PcdCName] != ValueList[Index]: + GlobalData.gPlatformPcds[TokenSpaceGuid + '.' + PcdCName] = ValueList[Index] return ValueList + def _FilterPcdBySkuUsage(self,Pcds): + available_sku = self.SkuIdMgr.AvailableSkuIdSet + sku_usage = self.SkuIdMgr.SkuUsageType + if sku_usage == SkuClass.SINGLE: + for pcdname in Pcds: + pcd = Pcds[pcdname] + Pcds[pcdname].SkuInfoList = {"DEFAULT":pcd.SkuInfoList[skuid] for skuid in pcd.SkuInfoList if skuid in available_sku} + if type(pcd) is StructurePcd and pcd.SkuOverrideValues: + Pcds[pcdname].SkuOverrideValues = {"DEFAULT":pcd.SkuOverrideValues[skuid] for skuid in pcd.SkuOverrideValues if skuid in available_sku} + 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 type(pcd) is 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 "STANDARD" not in skuobj.DefaultStoreDict: + PcdDefaultStoreSet = set([defaultstorename for defaultstorename in skuobj.DefaultStoreDict]) + mindefaultstorename = DefaultStoreMgr.GetMin(PcdDefaultStoreSet) + skuobj.DefaultStoreDict['STANDARD'] = copy.deepcopy(skuobj.DefaultStoreDict[mindefaultstorename]) + return Pcds + + 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("DEFAULT").HiiDefaultValue + else: + pcd.PcdValueFromComm = pcd.SkuInfoList.get("DEFAULT").DefaultValue + for pcd in self._Pcds: + if isinstance(self._Pcds[pcd],StructurePcd) and (self._Pcds[pcd].PcdValueFromComm or self._Pcds[pcd].PcdFieldValueFromComm): + UpdateCommandLineValue(self._Pcds[pcd]) + + def __ParsePcdFromCommandLine(self): + if GlobalData.BuildOptionPcd: + for i, pcd in enumerate(GlobalData.BuildOptionPcd): + if type(pcd) is tuple: + continue + (pcdname, pcdvalue) = pcd.split('=') + if not pcdvalue: + EdkLogger.error('build', AUTOGEN_ERROR, "No Value specified for the PCD %s." % (pcdname)) + if '.' in pcdname: + (Name1, Name2) = pcdname.split('.',1) + if "." in Name2: + (Name3, FieldName) = Name2.split(".",1) + if ((Name3,Name1)) in self.DecPcds: + HasTokenSpace = True + TokenCName = Name3 + TokenSpaceGuidCName = Name1 + else: + FieldName = Name2 + TokenCName = Name1 + TokenSpaceGuidCName = '' + HasTokenSpace = False + else: + if ((Name2,Name1)) in self.DecPcds: + HasTokenSpace = True + TokenCName = Name2 + TokenSpaceGuidCName = Name1 + FieldName ="" + else: + FieldName = Name2 + TokenCName = Name1 + TokenSpaceGuidCName = '' + HasTokenSpace = False + else: + FieldName = "" + TokenCName = pcdname + TokenSpaceGuidCName = '' + HasTokenSpace = False + TokenSpaceGuidCNameList = [] + FoundFlag = False + PcdDatumType = '' + 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 = self.HandleFlexiblePcd(TokenSpaceGuidCName, TokenCName, pcdvalue, PcdDatumType, self._GuidDict, FieldName) + else: + pcdvalue = self.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)) + + for BuildData in self._Bdb._CACHE_.values(): + if BuildData.MetaFile.Ext == '.dec' or BuildData.MetaFile.Ext == '.dsc': + continue + for key in BuildData.Pcds: + PcdItem = BuildData.Pcds[key] + if (TokenSpaceGuidCName, TokenCName) == (PcdItem.TokenSpaceGuidCName, PcdItem.TokenCName) and FieldName =="": + PcdItem.DefaultValue = pcdvalue + + def HandleFlexiblePcd(self, TokenSpaceGuidCName, TokenCName, PcdValue, PcdDatumType, GuidDict, FieldName=''): + if FieldName: + IsArray = False + TokenCName += '.' + FieldName + if PcdValue.startswith('H'): + if FieldName and IsFieldValueAnArray(PcdValue[1:]): + PcdDatumType = 'VOID*' + IsArray = True + if FieldName and not IsArray: + return PcdValue + try: + PcdValue = ValueExpressionEx(PcdValue[1:], PcdDatumType, GuidDict)(True) + except BadExpression, Value: + EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' % + (TokenSpaceGuidCName, TokenCName, PcdValue, Value)) + elif PcdValue.startswith("L'") or PcdValue.startswith("'"): + if FieldName and IsFieldValueAnArray(PcdValue): + PcdDatumType = 'VOID*' + IsArray = True + if FieldName and not IsArray: + return PcdValue + try: + PcdValue = ValueExpressionEx(PcdValue, PcdDatumType, GuidDict)(True) + except BadExpression, Value: + EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' % + (TokenSpaceGuidCName, TokenCName, PcdValue, Value)) + elif PcdValue.startswith('L'): + PcdValue = 'L"' + PcdValue[1:] + '"' + if FieldName and IsFieldValueAnArray(PcdValue): + PcdDatumType = 'VOID*' + IsArray = True + if FieldName and not IsArray: + return PcdValue + try: + PcdValue = ValueExpressionEx(PcdValue, PcdDatumType, GuidDict)(True) + except BadExpression, Value: + EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' % + (TokenSpaceGuidCName, TokenCName, PcdValue, Value)) + else: + if PcdValue.upper() == 'FALSE': + PcdValue = str(0) + if PcdValue.upper() == 'TRUE': + PcdValue = str(1) + if not FieldName: + if PcdDatumType not in ['UINT8','UINT16','UINT32','UINT64','BOOLEAN']: + PcdValue = '"' + PcdValue + '"' + else: + IsArray = False + Base = 10 + if PcdValue.upper().startswith('0X'): + Base = 16 + try: + Num = int(PcdValue, Base) + except: + PcdValue = '"' + PcdValue + '"' + if IsFieldValueAnArray(PcdValue): + PcdDatumType = 'VOID*' + IsArray = True + if not IsArray: + return PcdValue + try: + PcdValue = ValueExpressionEx(PcdValue, PcdDatumType, GuidDict)(True) + except BadExpression, Value: + EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' % + (TokenSpaceGuidCName, TokenCName, PcdValue, Value)) + return PcdValue + ## Retrieve all PCD settings in platform def _GetPcds(self): if self._Pcds == None: self._Pcds = sdict() + 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)) @@ -835,9 +1134,26 @@ class DscBuildData(PlatformBuildClassObject): 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.OverrideByFdfCommOverAll(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 + def _dumpPcdInfo(self,Pcds): + for pcd in Pcds: + pcdobj = Pcds[pcd] + if not pcdobj.TokenCName.startswith("Test"): + continue + for skuid in pcdobj.SkuInfoList: + if pcdobj.Type in (self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]): + for storename in pcdobj.SkuInfoList[skuid].DefaultStoreDict: + print "PcdCName: %s, SkuName: %s, StoreName: %s, Value: %s" % (".".join((pcdobj.TokenSpaceGuidCName, pcdobj.TokenCName)), skuid,storename,str(pcdobj.SkuInfoList[skuid].DefaultStoreDict[storename])) + else: + print "PcdCName: %s, SkuName: %s, Value: %s" % (".".join((pcdobj.TokenSpaceGuidCName, pcdobj.TokenCName)), skuid,str(pcdobj.SkuInfoList[skuid].DefaultValue)) ## Retrieve [BuildOptions] def _GetBuildOptions(self): if self._BuildOptions == None: @@ -847,7 +1163,9 @@ class DscBuildData(PlatformBuildClassObject): # 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 in RecordList: + for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4,Dummy5 in RecordList: + if Dummy3.upper() != 'COMMON': + continue CurKey = (ToolChainFamily, ToolChain, CodeBase) # # Only flags can be appended @@ -855,7 +1173,8 @@ class DscBuildData(PlatformBuildClassObject): if CurKey not in self._BuildOptions or not ToolChain.endswith('_FLAGS') or Option.startswith('='): self._BuildOptions[CurKey] = Option else: - self._BuildOptions[CurKey] += ' ' + Option + if ' ' + Option not in self._BuildOptions[CurKey]: + self._BuildOptions[CurKey] += ' ' + Option return self._BuildOptions def GetBuildOptionsByModuleType(self, Edk, ModuleType): @@ -866,59 +1185,158 @@ class DscBuildData(PlatformBuildClassObject): self._ModuleTypeOptions[Edk, ModuleType] = options DriverType = '%s.%s' % (Edk, ModuleType) CommonDriverType = '%s.%s' % ('COMMON', ModuleType) - RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, DriverType] - for ToolChainFamily, ToolChain, Option, Arch, Type, Dummy3, Dummy4 in RecordList: - if Type == DriverType or Type == CommonDriverType: + 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: - options[Key] += ' ' + Option + if ' ' + Option not in options[Key]: + options[Key] += ' ' + Option return self._ModuleTypeOptions[Edk, ModuleType] def GetStructurePcdInfo(self, PcdSet): structure_pcd_data = {} for item in PcdSet: - if item[1] not in structure_pcd_data: - structure_pcd_data[item[1]] = [] - structure_pcd_data[item[1]].append(item) + if (item[0],item[1]) not in structure_pcd_data: + structure_pcd_data[(item[0],item[1])] = [] + structure_pcd_data[(item[0],item[1])].append(item) return structure_pcd_data + def OverrideByFdfComm(self,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 = set([(item[0],item[1]) for item in StructurePcdInCom.keys()]) + 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 OverrideByFdfCommOverAll(self,AllPcds): + def CheckStructureInComm(commpcds): + if not commpcds: + return False + if len(commpcds[0]) == 5: + return True + return False + if CheckStructureInComm(GlobalData.BuildOptionPcd): + StructurePcdInCom = {(item[0],item[1],item[2] ):(item[3],item[4]) for item in GlobalData.BuildOptionPcd } if GlobalData.BuildOptionPcd else {} + NoFiledValues = {(item[0],item[1]):StructurePcdInCom[item] for item in StructurePcdInCom if not item[2]} + else: + NoFiledValues = {(item[0],item[1]):[item[2]] for item in GlobalData.BuildOptionPcd} + for Guid,Name in NoFiledValues: + if (Name,Guid) in AllPcds: + Pcd = AllPcds.get((Name,Guid)) + 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.DatumType == "VOID*": + if Pcd.MaxDatumSize is None: + Pcd.MaxDatumSize = '0' + MaxSize = int(Pcd.MaxDatumSize,10) + if Pcd.DefaultValue.startswith("{") and Pcd.DefaultValue.endswith("}"): + MaxSize = max([len(Pcd.DefaultValue.split(",")),MaxSize]) + elif Pcd.DefaultValue.startswith("\"") or Pcd.DefaultValue.startswith("\'"): + MaxSize = max([len(Pcd.DefaultValue)-2+1,MaxSize]) + elif Pcd.DefaultValue.startswith("L\""): + MaxSize = max([2*(len(Pcd.DefaultValue)-3+1),MaxSize]) + else: + MaxSize = max([len(Pcd.DefaultValue),MaxSize]) + 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.Pcds[Name, Guid] = copy.deepcopy(PcdInDec) + self.Pcds[Name, Guid].DefaultValue = NoFiledValues[( Guid,Name)][0] + return AllPcds 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 - SkuObj = SkuClass(self.SkuIdentifier, self.SkuIds) + DefaultStoreMgr = DefaultStore(self.DefaultStores) + SkuIds = self.SkuIdMgr.AvailableSkuIdSet + SkuIds.update({'DEFAULT':0}) + DefaultStores = set([storename for pcdobj in AllPcds.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict.keys()]) 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, Dummy3, Dummy4 in RecordList: + for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, default_store, Dummy4,Dummy5 in RecordList: + SkuName = SkuName.upper() + default_store = default_store.upper() SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName - if SkuName in SkuObj.SkuIdSet and "." in TokenSpaceGuid: - S_PcdSet.append((PcdCName, TokenSpaceGuid, SkuName, Dummy4, AnalyzePcdExpression(Setting)[0])) + if SkuName not in SkuIds: + continue + + if SkuName in SkuIds and "." in TokenSpaceGuid: + S_PcdSet.append([ TokenSpaceGuid.split(".")[0],TokenSpaceGuid.split(".")[1], PcdCName,SkuName, default_store,Dummy5, AnalyzePcdExpression(Setting)[0]]) # handle pcd value override StrPcdSet = self.GetStructurePcdInfo(S_PcdSet) - S_pcd_set = {} + S_pcd_set = OrderedDict() for str_pcd in StrPcdSet: - str_pcd_obj = Pcds.get((str_pcd.split(".")[1], str_pcd.split(".")[0]), None) - str_pcd_dec = self._DecPcds.get((str_pcd.split(".")[1], str_pcd.split(".")[0]), None) + 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) + if not isinstance (str_pcd_dec, StructurePcd): + EdkLogger.error('build', PARSER_ERROR, + "Pcd (%s.%s) is not declared as Structure PCD in DEC files. Arch: ['%s']" % (str_pcd[0], str_pcd[1], self._Arch), + File=self.MetaFile,Line = StrPcdSet[str_pcd][0][5]) if str_pcd_dec: str_pcd_obj_str = StructurePcd() str_pcd_obj_str.copy(str_pcd_dec) if str_pcd_obj: str_pcd_obj_str.copy(str_pcd_obj) - if str_pcd_obj.DefaultValue: - str_pcd_obj_str.DefaultFromDSC = str_pcd_obj.DefaultValue + 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[2] in SkuObj.SkuIdSet: - str_pcd_obj_str.AddOverrideValue(str_pcd_data[0], str(str_pcd_data[4]), 'DEFAULT' if str_pcd_data[2] == 'COMMON' else str_pcd_data[2],self.MetaFile.File,LineNo=str_pcd_data[3]) - S_pcd_set[str_pcd.split(".")[1], str_pcd.split(".")[0]] = str_pcd_obj_str + if str_pcd_data[3] in SkuIds: + str_pcd_obj_str.AddOverrideValue(str_pcd_data[2], str(str_pcd_data[6]), 'DEFAULT' if str_pcd_data[3] == 'COMMON' else str_pcd_data[3],'STANDARD' if str_pcd_data[4] == 'COMMON' else str_pcd_data[4], self.MetaFile.File if self.WorkspaceDir not in self.MetaFile.File else self.MetaFile.File[len(self.WorkspaceDir) if self.WorkspaceDir.endswith(os.path.sep) else len(self.WorkspaceDir)+1:],LineNo=str_pcd_data[5]) + S_pcd_set[str_pcd[1], str_pcd[0]] = str_pcd_obj_str + else: + EdkLogger.error('build', PARSER_ERROR, + "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (str_pcd[0], str_pcd[1], self._Arch), + File=self.MetaFile,Line = StrPcdSet[str_pcd][0][5]) # Add the Structure PCD that only defined in DEC, don't have override in DSC file - for Pcd in self._DecPcds: + for Pcd in self.DecPcds: if type (self._DecPcds[Pcd]) is StructurePcd: if Pcd not in S_pcd_set: str_pcd_obj_str = StructurePcd() @@ -926,37 +1344,103 @@ class DscBuildData(PlatformBuildClassObject): str_pcd_obj = Pcds.get(Pcd, None) if str_pcd_obj: str_pcd_obj_str.copy(str_pcd_obj) - if str_pcd_obj.DefaultValue: - str_pcd_obj_str.DefaultFromDSC = str_pcd_obj.DefaultValue + 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 + 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 == "DEFAULT": + NoDefault = True + break + nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid) + stru_pcd.SkuOverrideValues[skuid] = copy.deepcopy(stru_pcd.SkuOverrideValues[nextskuid]) if not NoDefault else copy.deepcopy({defaultstorename: stru_pcd.DefaultValues for defaultstorename in DefaultStores} if DefaultStores else {'STANDARD':stru_pcd.DefaultValues}) + if not NoDefault: + stru_pcd.ValueChain[(skuid,'')]= (nextskuid,'') + 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 == "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] = copy.deepcopy(stru_pcd.SkuOverrideValues[nextskuid][mindefaultstorename]) + stru_pcd.ValueChain[(skuid,defaultstoreid)]= (nextskuid,mindefaultstorename) + S_pcd_set = self.OverrideByFdfComm(S_pcd_set) Str_Pcd_Values = self.GenerateByteArrayValue(S_pcd_set) if Str_Pcd_Values: - for item in Str_Pcd_Values: - str_pcd_obj = S_pcd_set.get((item[2], item[1])) + 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 item[0] not in str_pcd_obj.SkuInfoList: - str_pcd_obj.SkuInfoList[item[0]] = SkuInfoClass(SkuIdName=item[0], SkuId=self.SkuIds[item[0]], HiiDefaultValue=item[3]) + 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[item[0]].HiiDefaultValue = item[3] + 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 item[0] in (SkuObj.SystemSkuId, 'DEFAULT', 'COMMON'): - str_pcd_obj.DefaultValue = item[3] + if skuname in (self.SkuIdMgr.SystemSkuId, 'DEFAULT', 'COMMON'): + str_pcd_obj.DefaultValue = PcdValue else: - if item[0] not in str_pcd_obj.SkuInfoList: - str_pcd_obj.SkuInfoList[item[0]] = SkuInfoClass(SkuIdName=item[0], SkuId=self.SkuIds[item[0]], DefaultValue=item[3]) + 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 == "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[item[0]].DefaultValue = item[3] + 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 = self.GetStructurePcdMaxSize(str_pcd_obj) Pcds[str_pcd_obj.TokenCName, str_pcd_obj.TokenSpaceGuidCName] = str_pcd_obj + for pcdkey in Pcds: + pcd = Pcds[pcdkey] + if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys(): + pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON'] + del(pcd.SkuInfoList['COMMON']) + elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys(): + del(pcd.SkuInfoList['COMMON']) + + map(self.FilterSkuSettings,[Pcds[pcdkey] for pcdkey in Pcds if Pcds[pcdkey].Type in DynamicPcdType]) return Pcds ## Retrieve non-dynamic PCD settings @@ -971,32 +1455,23 @@ class DscBuildData(PlatformBuildClassObject): # tdict is a special dict kind of type, used for selecting correct # PCD settings for certain ARCH # - - SkuObj = SkuClass(self.SkuIdentifier, self.SkuIds) + AvailableSkuIdSet = copy.copy(self.SkuIds) PcdDict = tdict(True, 3) PcdSet = set() # Find out all possible PCD candidates for self._Arch RecordList = self._RawData[Type, self._Arch] - AvailableSkuIdSet = SkuObj.AvailableSkuIdSet.copy() - AvailableSkuIdSet.update({'DEFAULT':0, 'COMMON':0}) PcdValueDict = sdict() - for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList: + for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4,Dummy5 in RecordList: + SkuName = SkuName.upper() + SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName if SkuName not in AvailableSkuIdSet: - EdkLogger.error('Build', OPTION_VALUE_INVALID, "The SKUID name %s is not supported by the platform." % SkuName) - if "." not in TokenSpaceGuid: - PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, Dummy4)) + 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, 'DEFAULT', 'COMMON'): + if "." not in TokenSpaceGuid: + PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, Dummy5)) PcdDict[Arch, PcdCName, TokenSpaceGuid, SkuName] = Setting - else: - TokenSpaceGuid, PcdCName = TokenSpaceGuid.split('.') - Flag = True - for PcdItem in RecordList: - if (TokenSpaceGuid, PcdCName) == (PcdItem[0], PcdItem[1]): - Flag = False - break - if Flag: - PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, 0)) - PcdDict[Arch, PcdCName, TokenSpaceGuid, SkuName] = '' for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdSet: Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid, SkuName] @@ -1019,8 +1494,8 @@ class DscBuildData(PlatformBuildClassObject): PcdValue, DatumType, MaxDatumSize = PcdSetting['COMMON'] if 'DEFAULT' in PcdSetting: PcdValue, DatumType, MaxDatumSize = PcdSetting['DEFAULT'] - if SkuObj.SystemSkuId in PcdSetting: - PcdValue, DatumType, MaxDatumSize = PcdSetting[SkuObj.SystemSkuId] + if self.SkuIdMgr.SystemSkuId in PcdSetting: + PcdValue, DatumType, MaxDatumSize = PcdSetting[self.SkuIdMgr.SystemSkuId] Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject( PcdCName, @@ -1038,6 +1513,26 @@ class DscBuildData(PlatformBuildClassObject): return Pcds + def __UNICODE2OCTList(self,Value): + Value = Value.strip() + Value = Value[2:-1] + List = [] + for Item in Value: + Temp = '%04X' % ord(Item) + List.append('0x' + Temp[2:4]) + List.append('0x' + Temp[0:2]) + List.append('0x00') + List.append('0x00') + return List + def __STRING2OCTList(self,Value): + OCTList = [] + Value = Value.strip('"') + for char in Value: + Temp = '%02X' % ord(char) + OCTList.append('0x' + Temp) + OCTList.append('0x00') + return OCTList + def GetStructurePcdMaxSize(self, str_pcd): pcd_default_value = str_pcd.DefaultValue sku_values = [skuobj.HiiDefaultValue if str_pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]] else skuobj.DefaultValue for skuobj in str_pcd.SkuInfoList.values()] @@ -1045,50 +1540,30 @@ class DscBuildData(PlatformBuildClassObject): def get_length(value): Value = value.strip() - if Value.startswith('GUID') and Value.endswith(')'): - return 16 - if Value.startswith('L"') and Value.endswith('"'): - return len(Value[2:-1]) - if Value[0] == '"' and Value[-1] == '"': - return len(Value) - 2 - if Value[0] == '{' and Value[-1] == '}': - return len(Value.split(",")) - if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1: - return len(list(Value[2:-1])) - if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1: - return len(Value) - 2 + if len(value) > 1: + if Value.startswith('GUID') and Value.endswith(')'): + return 16 + if Value.startswith('L"') and Value.endswith('"'): + return len(Value[2:-1]) + if Value[0] == '"' and Value[-1] == '"': + return len(Value) - 2 + if Value[0] == '{' and Value[-1] == '}': + return len(Value.split(",")) + if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1: + return len(list(Value[2:-1])) + if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1: + return len(Value) - 2 return len(Value) return str(max([pcd_size for pcd_size in [get_length(item) for item in sku_values]])) - def IsFieldValueAnArray (self, Value): - Value = Value.strip() - if Value.startswith('GUID') and Value.endswith(')'): - return True - if Value.startswith('L"') and Value.endswith('"') and len(list(Value[2:-1])) > 1: - return True - if Value[0] == '"' and Value[-1] == '"' and len(list(Value[1:-1])) > 1: - return True - if Value[0] == '{' and Value[-1] == '}': - return True - if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1: - print 'foo = ', list(Value[2:-1]) - return True - if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1: - print 'bar = ', list(Value[1:-1]) - return True - return False - def ExecuteCommand (self, Command): try: Process = subprocess.Popen(Command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) except: - print 'ERROR: Can not execute command:', Command - sys.exit(1) + EdkLogger.error('Build', COMMAND_FAILURE, 'Can not execute command: %s' % Command) Result = Process.communicate() - if Process.returncode <> 0: - print 'ERROR: Can not collect output from command:', Command - return Result[0], Result[1] + return Process.returncode, Result[0], Result[1] def IntToCString(self, Value, ValueSize): Result = '"' @@ -1099,49 +1574,47 @@ class DscBuildData(PlatformBuildClassObject): Result = Result + '"' return Result - def GenerateInitializeFunc(self, SkuName, DefaultStoreName, Pcd, InitByteValue, CApp): - OverrideValues = None - if Pcd.SkuOverrideValues: - OverrideValues = Pcd.SkuOverrideValues[SkuName] - 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 + ' UINT8 *Value;\n' - CApp = CApp + ' UINT32 OriginalSize;\n' - CApp = CApp + ' VOID *OriginalPcd;\n' - CApp = CApp + ' %s *Pcd;\n' % (Pcd.DatumType) - CApp = CApp + '\n' - InitByteValue += '%s.%s.%s.%s|%s|%s\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType, Pcd.DefaultValue) - - # - # 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 + ' Size = sizeof(%s);\n' % (Pcd.DatumType) - for FieldList in [Pcd.DefaultValues, OverrideValues]: + def GetPcdMaxSize(self,Pcd): + MaxSize = int(Pcd.MaxDatumSize,10) if Pcd.MaxDatumSize else 0 + if Pcd.DatumType not in ['BOOLEAN','UINT8','UINT16','UINT32','UINT64']: + if Pcd.PcdValueFromComm: + if Pcd.PcdValueFromComm.startswith("{") and Pcd.PcdValueFromComm.endswith("}"): + MaxSize = max([len(Pcd.PcdValueFromComm.split(",")),MaxSize]) + elif Pcd.PcdValueFromComm.startswith("\"") or Pcd.PcdValueFromComm.startswith("\'"): + MaxSize = max([len(Pcd.PcdValueFromComm)-2+1,MaxSize]) + elif Pcd.PcdValueFromComm.startswith("L\""): + MaxSize = max([2*(len(Pcd.PcdValueFromComm)-3+1),MaxSize]) + else: + MaxSize = max([len(Pcd.PcdValueFromComm),MaxSize]) + elif Pcd.DatumType not in ['BOOLEAN','UINT8']: + MaxSize = 1 + elif Pcd.DatumType == 'UINT16': + MaxSize = 2 + elif Pcd.DatumType == 'UINT32': + MaxSize = 4 + elif Pcd.DatumType == 'UINT64': + MaxSize = 8 + return MaxSize + def GenerateSizeFunction(self,Pcd): + CApp = "// Default Value in Dec \n" + CApp = CApp + "void Cal_%s_%s_Size(UINT32 *Size){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) + for FieldList in [Pcd.DefaultValues]: if not FieldList: continue for FieldName in FieldList: FieldName = "." + FieldName - IsArray = self.IsFieldValueAnArray(FieldList[FieldName.strip(".")][0]) - if IsArray: - Value, ValueSize = ParseFieldValue (FieldList[FieldName.strip(".")][0]) - CApp = CApp + ' __FLEXIBLE_SIZE(Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0));\n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip(".")) + 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], "VOID*", self._GuidDict)(True) + except BadExpression: + EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % + (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2])) + Value, ValueSize = ParseFieldValue(Value) + CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0)); // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2], FieldList[FieldName.strip(".")][0]); else: NewFieldName = '' + FieldName_ori = FieldName.strip('.') while '[' in FieldName: NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]' ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0]) @@ -1149,71 +1622,350 @@ class DscBuildData(PlatformBuildClassObject): FieldName = NewFieldName + FieldName while '[' in FieldName: FieldName = FieldName.rsplit('[', 1)[0] - CApp = CApp + ' __FLEXIBLE_SIZE(Size, %s, %s, %d);\n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1) - + CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2], FieldList[FieldName_ori][0]) + for skuname in Pcd.SkuOverrideValues: + if skuname == "COMMON": + continue + for defaultstorenameitem in Pcd.SkuOverrideValues[skuname]: + CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % (skuname, defaultstorenameitem) + for FieldList in [Pcd.SkuOverrideValues[skuname].get(defaultstorenameitem)]: + if not FieldList: + continue + for FieldName in FieldList: + FieldName = "." + FieldName + 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], "VOID*", self._GuidDict)(True) + except BadExpression: + EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % + (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2])) + Value, ValueSize = ParseFieldValue(Value) + CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0)); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2], FieldList[FieldName.strip(".")][0]); + else: + NewFieldName = '' + FieldName_ori = FieldName.strip('.') + while '[' in FieldName: + NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]' + ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0]) + FieldName = FieldName.split(']', 1)[1] + FieldName = NewFieldName + FieldName + while '[' in FieldName: + FieldName = FieldName.rsplit('[', 1)[0] + CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2], FieldList[FieldName_ori][0]) + 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], "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) + 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]' + ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0]) + FieldName = FieldName.split(']', 1)[1] + FieldName = NewFieldName + FieldName + while '[' in FieldName: + FieldName = FieldName.rsplit('[', 1)[0] + CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1, Pcd.PcdFieldValueFromComm[FieldName_ori][1], Pcd.PcdFieldValueFromComm[FieldName_ori][2], Pcd.PcdFieldValueFromComm[FieldName_ori][0]) + CApp = CApp + " *Size = (%d > *Size ? %d : *Size); // The Pcd maxsize is %d \n" % (self.GetPcdMaxSize(Pcd),self.GetPcdMaxSize(Pcd),self.GetPcdMaxSize(Pcd)) + CApp = CApp + "}\n" + return CApp + def GenerateSizeStatments(self,Pcd): + CApp = ' Size = sizeof(%s);\n' % (Pcd.DatumType) + CApp = CApp + ' Cal_%s_%s_Size(&Size);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) + return CApp + def GenerateDefaultValueAssignFunction(self,Pcd): + CApp = "// Default value in Dec \n" + CApp = CApp + "void Assign_%s_%s_Default_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType) + CApp = CApp + ' UINT32 FieldSize;\n' + CApp = CApp + ' CHAR8 *Value;\n' + DefaultValueFromDec = Pcd.DefaultValueFromDec + IsArray = IsFieldValueAnArray(Pcd.DefaultValueFromDec) + if IsArray: + try: + DefaultValueFromDec = ValueExpressionEx(Pcd.DefaultValueFromDec, "VOID*")(True) + except BadExpression: + EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DEC: %s" % + (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, DefaultValueFromDec)) + DefaultValueFromDec = StringToArray(DefaultValueFromDec) + Value, ValueSize = ParseFieldValue (DefaultValueFromDec) + if isinstance(Value, str): + CApp = CApp + ' Pcd = %s; // From DEC Default Value %s\n' % (Value, Pcd.DefaultValueFromDec) + elif IsArray: # - # 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 + # Use memcpy() to copy value into field # - CApp = CApp + ' Size = (OriginalSize > Size ? OriginalSize : Size);\n' - CApp = CApp + ' Pcd = (%s *)malloc (Size);\n' % (Pcd.DatumType) - CApp = CApp + ' memset (Pcd, 0, Size);\n' + CApp = CApp + ' Value = %s; // From DEC Default Value %s\n' % (self.IntToCString(Value, ValueSize), Pcd.DefaultValueFromDec) + CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize) + for FieldList in [Pcd.DefaultValues]: + if not FieldList: + continue + for FieldName in FieldList: + IsArray = IsFieldValueAnArray(FieldList[FieldName][0]) + if IsArray: + try: + FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], "VOID*", self._GuidDict)(True) + except BadExpression: + EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % + (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1],FieldList[FieldName][2])) - # - # Copy current PCD value into allocated buffer. - # - CApp = CApp + ' memcpy (Pcd, OriginalPcd, OriginalSize);\n' - CApp = CApp + ' free (OriginalPcd);\n' + try: + Value, ValueSize = ParseFieldValue (FieldList[FieldName][0]) + except Exception: + EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName,FieldName)),FieldList[FieldName][1], FieldList[FieldName][2])) + if isinstance(Value, str): + CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) + elif IsArray: + # + # Use memcpy() to copy value into field + # + CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName) + CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (self.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) + CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize) + else: + 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 GenerateDefaultValueAssignStatement(self,Pcd): + CApp = ' Assign_%s_%s_Default_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) + return CApp + def GenerateInitValueFunction(self,Pcd,SkuName,DefaultStoreName): + CApp = "// Value in Dsc for Sku: %s, DefaultStore %s\n" % (SkuName,DefaultStoreName) + CApp = CApp + "void Assign_%s_%s_%s_%s_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName,DefaultStoreName,Pcd.DatumType) + CApp = CApp + ' UINT32 FieldSize;\n' + CApp = CApp + ' CHAR8 *Value;\n' - # - # Assign field values in PCD - # - for FieldList in [Pcd.DefaultValues, Pcd.DefaultFromDSC, OverrideValues]: + CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % ('DEFAULT', 'STANDARD') + inherit_OverrideValues = Pcd.SkuOverrideValues[SkuName] + if (SkuName,DefaultStoreName) == ('DEFAULT','STANDARD'): + pcddefaultvalue = Pcd.DefaultFromDSC.get('DEFAULT',{}).get('STANDARD', Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue + else: + if not Pcd.DscRawValue: + # handle the case that structure pcd is not appear in DSC + self.CopyDscRawValue(Pcd) + pcddefaultvalue = Pcd.DscRawValue.get(SkuName,{}).get(DefaultStoreName) + for FieldList in [pcddefaultvalue,inherit_OverrideValues.get(DefaultStoreName)]: if not FieldList: continue - if Pcd.DefaultFromDSC and FieldList == Pcd.DefaultFromDSC: - IsArray = self.IsFieldValueAnArray(FieldList) + if pcddefaultvalue and FieldList == pcddefaultvalue: + IsArray = IsFieldValueAnArray(FieldList) + if IsArray: + try: + FieldList = ValueExpressionEx(FieldList, "VOID*")(True) + except BadExpression: + EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DSC: %s" % + (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList)) Value, ValueSize = ParseFieldValue (FieldList) - if isinstance(Value, str): - CApp = CApp + ' Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DefaultFromDSC) - elif IsArray: + + if (SkuName,DefaultStoreName) == ('DEFAULT','STANDARD'): + if isinstance(Value, str): + CApp = CApp + ' Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DefaultFromDSC.get('DEFAULT',{}).get('STANDARD', Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue) + elif IsArray: # # Use memcpy() to copy value into field # - CApp = CApp + ' Value = %s; // From DSC Default Value %s\n' % (self.IntToCString(Value, ValueSize), Pcd.DefaultFromDSC) - CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize) + CApp = CApp + ' Value = %s; // From DSC Default Value %s\n' % (self.IntToCString(Value, ValueSize), Pcd.DefaultFromDSC.get('DEFAULT',{}).get('STANDARD', Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue) + CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize) + else: + if isinstance(Value, str): + CApp = CApp + ' Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DscRawValue.get(SkuName,{}).get(DefaultStoreName)) + elif IsArray: + # + # Use memcpy() to copy value into field + # + CApp = CApp + ' Value = %s; // From DSC Default Value %s\n' % (self.IntToCString(Value, ValueSize), Pcd.DscRawValue.get(SkuName,{}).get(DefaultStoreName)) + CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize) + continue + if (SkuName,DefaultStoreName) == ('DEFAULT','STANDARD') or (( (SkuName,'') not in Pcd.ValueChain) and ( (SkuName,DefaultStoreName) not in Pcd.ValueChain )): + for FieldName in FieldList: + IsArray = IsFieldValueAnArray(FieldList[FieldName][0]) + if IsArray: + try: + FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], "VOID*", self._GuidDict)(True) + except BadExpression: + EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % + (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2])) + try: + Value, ValueSize = ParseFieldValue (FieldList[FieldName][0]) + except Exception: + EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName,FieldName)),FieldList[FieldName][1], FieldList[FieldName][2])) + if isinstance(Value, str): + CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) + elif IsArray: + # + # Use memcpy() to copy value into field + # + CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName) + CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (self.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) + CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize) + else: + 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 GenerateInitValueStatement(self,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.DatumType) + CApp = CApp + ' UINT32 FieldSize;\n' + CApp = CApp + ' CHAR8 *Value;\n' + + pcddefaultvalue = Pcd.PcdValueFromComm + for FieldList in [pcddefaultvalue,Pcd.PcdFieldValueFromComm]: + if not FieldList: continue + if pcddefaultvalue and FieldList == pcddefaultvalue: + IsArray = IsFieldValueAnArray(FieldList) + if IsArray: + try: + FieldList = ValueExpressionEx(FieldList, "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' % (self.IntToCString(Value, ValueSize)) + CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize) + continue for FieldName in FieldList: - IsArray = self.IsFieldValueAnArray(FieldList[FieldName][0]) - Value, ValueSize = ParseFieldValue (FieldList[FieldName][0]) + IsArray = IsFieldValueAnArray(FieldList[FieldName][0]) + if IsArray: + try: + FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], "VOID*", self._GuidDict)(True) + except BadExpression: + EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % + (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2])) + except: + print "error" + try: + Value, ValueSize = ParseFieldValue (FieldList[FieldName][0]) + except Exception: + EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName,FieldName)),FieldList[FieldName][1], FieldList[FieldName][2])) if isinstance(Value, str): CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) elif IsArray: - # - # Use memcpy() to copy value into field - # + # + # Use memcpy() to copy value into field + # CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName) CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (self.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) - CApp = CApp + ' memcpy (&Pcd->%s[0], Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize) + CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize) else: 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 GenerateCommandLineValueStatement(self,Pcd): + CApp = ' Assign_%s_%s_CommandLine_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) + return CApp + def GenerateInitializeFunc(self, SkuName, DefaultStore, Pcd, InitByteValue, CApp): + OverrideValues = {DefaultStore:""} + if Pcd.SkuOverrideValues: + OverrideValues = Pcd.SkuOverrideValues[SkuName] + for DefaultStoreName in OverrideValues.keys(): + CApp = CApp + 'void\n' + CApp = CApp + 'Initialize_%s_%s_%s_%s(\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName) + CApp = CApp + ' void\n' + CApp = CApp + ' )\n' + CApp = CApp + '{\n' + CApp = CApp + ' UINT32 Size;\n' + CApp = CApp + ' UINT32 FieldSize;\n' + 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.DatumType, Pcd.PkgPath, Pcd.PcdDefineLineNo) + CApp = CApp + '\n' + + if SkuName in Pcd.SkuInfoList: + DefaultValue = Pcd.SkuInfoList[SkuName].DefaultStoreDict.get(DefaultStoreName,Pcd.SkuInfoList[SkuName].HiiDefaultValue if Pcd.SkuInfoList[SkuName].HiiDefaultValue else Pcd.SkuInfoList[SkuName].DefaultValue) + else: + DefaultValue = Pcd.DefaultValue + PcdDefaultValue = StringToArray(DefaultValue.strip()) - # - # Set new PCD value and size - # - CApp = CApp + ' PcdSetPtr (%s, %s, %s, %s, Size, (UINT8 *)Pcd);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName) + InitByteValue += '%s.%s.%s.%s|%s|%s\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType, PcdDefaultValue) - # - # Free PCD - # - CApp = CApp + ' free (Pcd);\n' - CApp = CApp + '}\n' - CApp = CApp + '\n' + # + # 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 + self.GenerateSizeStatments(Pcd) + + # + # Allocate and zero buffer for the PCD + # Must handle cases where current value is smaller, larger, or same size + # Always keep that larger one as the current size + # + CApp = CApp + ' Size = (OriginalSize > Size ? OriginalSize : Size);\n' + CApp = CApp + ' Pcd = (%s *)malloc (Size);\n' % (Pcd.DatumType) + CApp = CApp + ' memset (Pcd, 0, Size);\n' + + # + # Copy current PCD value into allocated buffer. + # + CApp = CApp + ' memcpy (Pcd, OriginalPcd, OriginalSize);\n' + + # + # Assign field values in PCD + # + CApp = CApp + self.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 == 'STANDARD' else ['STANDARD', DefaultStoreName] + for defaultstorenameitem in storeset: + CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % (skuname, defaultstorenameitem) + CApp = CApp + self.GenerateInitValueStatement(Pcd,skuname,defaultstorenameitem) + if skuname == SkuName: + break + else: + CApp = CApp + "// SkuName: %s, DefaultStoreName: STANDARD \n" % self.SkuIdMgr.SystemSkuId + CApp = CApp + self.GenerateInitValueStatement(Pcd,self.SkuIdMgr.SystemSkuId,"STANDARD") + CApp = CApp + self.GenerateCommandLineValueStatement(Pcd) + # + # Set new PCD value and size + # + CApp = CApp + ' PcdSetPtr (%s, %s, %s, %s, Size, (UINT8 *)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 GenerateByteArrayValue (self, StructuredPcds): @@ -1227,20 +1979,36 @@ class DscBuildData(PlatformBuildClassObject): CApp = PcdMainCHeader Includes = {} + IncludeFiles = set() for PcdName in StructuredPcds: Pcd = StructuredPcds[PcdName] - IncludeFile = Pcd.StructuredPcdIncludeFile - if IncludeFile not in Includes: - Includes[IncludeFile] = True - CApp = CApp + '#include <%s>\n' % (IncludeFile) + for IncludeFile in Pcd.StructuredPcdIncludeFile: + if IncludeFile not in Includes: + Includes[IncludeFile] = True + IncludeFiles.add(IncludeFile) + CApp = CApp + '#include <%s>\n' % (IncludeFile) CApp = CApp + '\n' - for PcdName in StructuredPcds: Pcd = StructuredPcds[PcdName] - if not Pcd.SkuOverrideValues: - InitByteValue, CApp = self.GenerateInitializeFunc('DEFAULT', 'STANDARD', Pcd, InitByteValue, CApp) + CApp = CApp + self.GenerateSizeFunction(Pcd) + CApp = CApp + self.GenerateDefaultValueAssignFunction(Pcd) + CApp = CApp + self.GenerateCommandLineValue(Pcd) + if not Pcd.SkuOverrideValues or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD], + self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]: + CApp = CApp + self.GenerateInitValueFunction(Pcd,self.SkuIdMgr.SystemSkuId, 'STANDARD') else: - for SkuName in Pcd.SkuOverrideValues: + 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) + if not Pcd.SkuOverrideValues or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD], + self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]: + InitByteValue, CApp = self.GenerateInitializeFunc(self.SkuIdMgr.SystemSkuId, 'STANDARD', 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) @@ -1251,11 +2019,13 @@ class DscBuildData(PlatformBuildClassObject): CApp = CApp + ' )\n' CApp = CApp + '{\n' for Pcd in StructuredPcds.values(): - if not Pcd.SkuOverrideValues: - CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % ('DEFAULT', 'STANDARD', Pcd.TokenSpaceGuidCName, Pcd.TokenCName) + if not Pcd.SkuOverrideValues or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]: + CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (self.SkuIdMgr.SystemSkuId, 'STANDARD', Pcd.TokenSpaceGuidCName, Pcd.TokenCName) else: - for SkuName in Pcd.SkuOverrideValues: - for DefaultStoreName in Pcd.DefaultStoreName: + for SkuName in self.SkuIdMgr.SkuOverrideOrder(): + if SkuName not in Pcd.SkuOverrideValues: + continue + for DefaultStoreName in Pcd.SkuOverrideValues[SkuName]: CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName) CApp = CApp + '}\n' @@ -1264,25 +2034,24 @@ class DscBuildData(PlatformBuildClassObject): if not os.path.exists(self.OutputPath): os.makedirs(self.OutputPath) CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName) - File = open (CAppBaseFileName + '.c', 'w') - File.write(CApp) - File.close() + SaveFileOnChange(CAppBaseFileName + '.c', CApp, False) MakeApp = PcdMakefileHeader if sys.platform == "win32": - MakeApp = MakeApp + 'ARCH = IA32\nAPPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s\%s.obj\n' % (self.OutputPath, PcdValueInitName) + 'INC = ' + MakeApp = MakeApp + 'APPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s\%s.obj\n' % (self.OutputPath, PcdValueInitName) + 'INC = ' else: MakeApp = MakeApp + PcdGccMakefile MakeApp = MakeApp + 'APPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s/%s.o\n' % (self.OutputPath, PcdValueInitName) + \ - 'include $(MAKEROOT)/Makefiles/app.makefile\n' + 'BUILD_CFLAGS += -Wno-error\n' + 'INCLUDE +=' + 'include $(MAKEROOT)/Makefiles/app.makefile\n' + 'INCLUDE +=' + IncSearchList = [] PlatformInc = {} for Cache in self._Bdb._CACHE_.values(): if Cache.MetaFile.Ext.lower() != '.dec': continue if Cache.Includes: if str(Cache.MetaFile.Path) not in PlatformInc: - PlatformInc[str(Cache.MetaFile.Path)] = Cache.Includes + PlatformInc[str(Cache.MetaFile.Path)] = Cache.CommonIncludes PcdDependDEC = [] for Pcd in StructuredPcds.values(): @@ -1298,57 +2067,142 @@ class DscBuildData(PlatformBuildClassObject): if pkg in PlatformInc: for inc in PlatformInc[pkg]: MakeApp += '-I' + str(inc) + ' ' + IncSearchList.append(inc) MakeApp = MakeApp + '\n' + + CC_FLAGS = LinuxCFLAGS + if sys.platform == "win32": + CC_FLAGS = WindowsCFLAGS + BuildOptions = {} + for Options in self.BuildOptions: + if Options[2] != EDKII_NAME: + continue + Family = Options[0] + if Family and Family != self.ToolChainFamily: + continue + Target, Tag, Arch, Tool, Attr = Options[1].split("_") + if Tool != 'CC': + continue + + if Target == "*" or Target == self._Target: + if Tag == "*" or Tag == self._Toolchain: + if Arch == "*" or Arch == self.Arch: + if Tool not in BuildOptions: + BuildOptions[Tool] = {} + if Attr != "FLAGS" or Attr not in BuildOptions[Tool] or self.BuildOptions[Options].startswith('='): + BuildOptions[Tool][Attr] = self.BuildOptions[Options] + else: + # append options for the same tool except PATH + if Attr != 'PATH': + BuildOptions[Tool][Attr] += " " + self.BuildOptions[Options] + else: + BuildOptions[Tool][Attr] = self.BuildOptions[Options] + if BuildOptions: + for Tool in BuildOptions: + for Attr in BuildOptions[Tool]: + if Attr == "FLAGS": + Value = BuildOptions[Tool][Attr] + ValueList = Value.split() + if ValueList: + for Id, Item in enumerate(ValueList): + if Item == '-D' or Item == '/D': + CC_FLAGS += ' ' + Item + if Id + 1 < len(ValueList): + CC_FLAGS += ' ' + ValueList[Id + 1] + elif Item.startswith('/D') or Item.startswith('-D'): + CC_FLAGS += ' ' + Item + MakeApp += CC_FLAGS + if sys.platform == "win32": MakeApp = MakeApp + PcdMakefileEnd + MakeApp = MakeApp + '\n' + IncludeFileFullPaths = [] + for includefile in IncludeFiles: + for includepath in IncSearchList: + includefullpath = os.path.join(str(includepath),includefile) + if os.path.exists(includefullpath): + IncludeFileFullPaths.append(os.path.normpath(includefullpath)) + break + SearchPathList = [] + SearchPathList.append(os.path.normpath(mws.join(GlobalData.gWorkspace, "BaseTools/Source/C/Include"))) + SearchPathList.append(os.path.normpath(mws.join(GlobalData.gWorkspace, "BaseTools/Source/C/Common"))) + SearchPathList.extend([str(item) for item in IncSearchList]) + IncFileList = GetDependencyList(IncludeFileFullPaths,SearchPathList) + for include_file in IncFileList: + MakeApp += "$(OBJECTS) : %s\n" % include_file MakeFileName = os.path.join(self.OutputPath, 'Makefile') - File = open (MakeFileName, 'w') - File.write(MakeApp) - File.close() + MakeApp += "$(OBJECTS) : %s\n" % MakeFileName + SaveFileOnChange(MakeFileName, MakeApp, False) InputValueFile = os.path.join(self.OutputPath, 'Input.txt') OutputValueFile = os.path.join(self.OutputPath, 'Output.txt') - File = open (InputValueFile, 'w') - File.write(InitByteValue) - File.close() - - if sys.platform == "win32": - StdOut, StdErr = self.ExecuteCommand ('nmake clean & nmake -f %s' % (MakeFileName)) - else: - StdOut, StdErr = self.ExecuteCommand ('make clean & make -f %s' % (MakeFileName)) - Messages = StdOut.split('\r') - for Message in Messages: - if " error " in Message: - FileInfo = Message.strip().split('(') - if len (FileInfo) > 0: - FileName = FileInfo [0] - FileLine = FileInfo [1].split (')')[0] - else: - FileInfo = Message.strip().split(':') - FileName = FileInfo [0] - FileLine = FileInfo [1] - - File = open (FileName, 'r') - FileData = File.readlines() - File.close() - error_line = FileData[int (FileLine) - 1] - if r"//" in error_line: - c_line,dsc_line = error_line.split(r"//") - else: - dsc_line = error_line - - message_itmes = Message.split(":") - for item in message_itmes: - if "PcdValueInit.c" in item: - message_itmes[message_itmes.index(item)] = dsc_line.strip() - - EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, ":".join(message_itmes[1:])) + SaveFileOnChange(InputValueFile, InitByteValue, False) PcdValueInitExe = PcdValueInitName if not sys.platform == "win32": PcdValueInitExe = os.path.join(os.getenv("EDK_TOOLS_PATH"), 'Source', 'C', 'bin', PcdValueInitName) + else: + PcdValueInitExe = os.path.join(os.getenv("EDK_TOOLS_PATH"), 'Bin', 'Win32', PcdValueInitName) +".exe" + + Messages = '' + if sys.platform == "win32": + MakeCommand = 'nmake -f %s' % (MakeFileName) + returncode, StdOut, StdErr = self.ExecuteCommand (MakeCommand) + Messages = StdOut + else: + MakeCommand = 'make -f %s' % (MakeFileName) + returncode, StdOut, StdErr = self.ExecuteCommand (MakeCommand) + Messages = StdErr + Messages = Messages.split('\n') + MessageGroup = [] + if returncode <>0: + CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName) + File = open (CAppBaseFileName + '.c', 'r') + FileData = File.readlines() + File.close() + for Message in Messages: + if " error" in Message or "warning" in Message: + FileInfo = Message.strip().split('(') + if len (FileInfo) > 1: + FileName = FileInfo [0] + FileLine = FileInfo [1].split (')')[0] + else: + FileInfo = Message.strip().split(':') + FileName = FileInfo [0] + FileLine = FileInfo [1] + if FileLine.isdigit(): + error_line = FileData[int (FileLine) - 1] + if r"//" in error_line: + c_line,dsc_line = error_line.split(r"//") + 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' % MakeCommand) + + if self.NeedUpdateOutput(OutputValueFile, PcdValueInitExe ,InputValueFile): + Command = PcdValueInitExe + ' -i %s -o %s' % (InputValueFile, OutputValueFile) + returncode, StdOut, StdErr = self.ExecuteCommand (Command) + if returncode <> 0: + EdkLogger.warn('Build', COMMAND_FAILURE, 'Can not collect output from command: %s' % Command) - StdOut, StdErr = self.ExecuteCommand (PcdValueInitExe + ' -i %s -o %s' % (InputValueFile, OutputValueFile)) File = open (OutputValueFile, 'r') FileBuffer = File.readlines() File.close() @@ -1357,9 +2211,18 @@ class DscBuildData(PlatformBuildClassObject): for Pcd in FileBuffer: PcdValue = Pcd.split ('|') PcdInfo = PcdValue[0].split ('.') - StructurePcdSet.append((PcdInfo[0], PcdInfo[2], PcdInfo[3], PcdValue[2].strip())) + StructurePcdSet.append((PcdInfo[0],PcdInfo[1], PcdInfo[2], PcdInfo[3], PcdValue[2].strip())) return StructurePcdSet + def NeedUpdateOutput(self,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 @@ -1368,7 +2231,6 @@ class DscBuildData(PlatformBuildClassObject): # def _GetDynamicPcd(self, Type): - SkuObj = SkuClass(self.SkuIdentifier, self.SkuIds) Pcds = sdict() # @@ -1379,15 +2241,17 @@ class DscBuildData(PlatformBuildClassObject): PcdList = [] # Find out all possible PCD candidates for self._Arch RecordList = self._RawData[Type, self._Arch] - AvailableSkuIdSet = SkuObj.AvailableSkuIdSet.copy() + AvailableSkuIdSet = copy.copy(self.SkuIds) - AvailableSkuIdSet.update({'DEFAULT':0, 'COMMON':0}) - for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList: + for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4,Dummy5 in RecordList: + SkuName = SkuName.upper() + SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName if SkuName not in AvailableSkuIdSet: - EdkLogger.error('Build', OPTION_VALUE_INVALID, "The SKUID name %s is not supported by the platform." % SkuName) + EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName, + File=self.MetaFile, Line=Dummy5) if "." not in TokenSpaceGuid: - PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy4)) + PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy5)) PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting # Remove redundant PCD candidates, per the ARCH and SKU @@ -1398,7 +2262,7 @@ class DscBuildData(PlatformBuildClassObject): continue PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4) - SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], '', '', '', '', '', PcdValue) + SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', '', PcdValue) if (PcdCName, TokenSpaceGuid) in Pcds.keys(): pcdObject = Pcds[PcdCName, TokenSpaceGuid] pcdObject.SkuInfoList[SkuName] = SkuInfo @@ -1428,6 +2292,10 @@ class DscBuildData(PlatformBuildClassObject): 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 (sku.DefaultValue == "" or sku.DefaultValue==None): + sku.DefaultValue = pcdDecObject.DefaultValue if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys(): valuefromDec = pcdDecObject.DefaultValue SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec) @@ -1437,13 +2305,26 @@ class DscBuildData(PlatformBuildClassObject): del(pcd.SkuInfoList['COMMON']) elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys(): del(pcd.SkuInfoList['COMMON']) - if SkuObj.SkuUsageType == SkuObj.SINGLE: - if 'DEFAULT' in pcd.SkuInfoList.keys() and SkuObj.SystemSkuId not in pcd.SkuInfoList.keys(): - pcd.SkuInfoList[SkuObj.SystemSkuId] = pcd.SkuInfoList['DEFAULT'] - del(pcd.SkuInfoList['DEFAULT']) + + map(self.FilterSkuSettings,Pcds.values()) return Pcds + def FilterSkuSettings(self, PcdObj): + + if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE: + if 'DEFAULT' in PcdObj.SkuInfoList.keys() and self.SkuIdMgr.SystemSkuId not in PcdObj.SkuInfoList.keys(): + PcdObj.SkuInfoList[self.SkuIdMgr.SystemSkuId] = PcdObj.SkuInfoList['DEFAULT'] + PcdObj.SkuInfoList = {'DEFAULT':PcdObj.SkuInfoList[self.SkuIdMgr.SystemSkuId]} + PcdObj.SkuInfoList['DEFAULT'].SkuIdName = 'DEFAULT' + PcdObj.SkuInfoList['DEFAULT'].SkuId = '0' + + elif self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.DEFAULT: + PcdObj.SkuInfoList = {'DEFAULT':PcdObj.SkuInfoList['DEFAULT']} + + return PcdObj + + def CompareVarAttr(self, Attr1, Attr2): if not Attr1 or not Attr2: # for empty string return True @@ -1455,6 +2336,57 @@ class DscBuildData(PlatformBuildClassObject): return True else: return False + def CopyDscRawValue(self,Pcd): + if Pcd.DscRawValue is None: + Pcd.DscRawValue = dict() + if Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD], self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]: + if self.SkuIdMgr.SystemSkuId not in Pcd.DscRawValue: + Pcd.DscRawValue[self.SkuIdMgr.SystemSkuId] = {} + Pcd.DscRawValue[self.SkuIdMgr.SystemSkuId]['STANDARD'] = Pcd.DefaultValue + for skuname in Pcd.SkuInfoList: + Pcd.DscRawValue[skuname] = {} + if Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]: + for defaultstore in Pcd.SkuInfoList[skuname].DefaultStoreDict: + Pcd.DscRawValue[skuname][defaultstore] = Pcd.SkuInfoList[skuname].DefaultStoreDict[defaultstore] + else: + Pcd.DscRawValue[skuname]['STANDARD'] = Pcd.SkuInfoList[skuname].DefaultValue + def CompletePcdValues(self,PcdSet): + Pcds = {} + DefaultStoreObj = DefaultStore(self._GetDefaultStores()) + SkuIds = {skuname:skuid for skuname,skuid in self.SkuIdMgr.AvailableSkuIdSet.items() if skuname !='COMMON'} + DefaultStores = set([storename for pcdobj in PcdSet.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict.keys()]) + for PcdCName, TokenSpaceGuid in PcdSet: + PcdObj = PcdSet[(PcdCName, TokenSpaceGuid)] + self.CopyDscRawValue(PcdObj) + 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] = copy.deepcopy(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 = PcdObj.SkuInfoList.values()[0].HiiDefaultValue if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE else PcdObj.SkuInfoList["DEFAULT"].HiiDefaultValue + Pcds[PcdCName, TokenSpaceGuid]= PcdObj + return Pcds ## Retrieve dynamic HII PCD settings # # @param Type PCD type @@ -1463,7 +2395,6 @@ class DscBuildData(PlatformBuildClassObject): # def _GetDynamicHiiPcd(self, Type): - SkuObj = SkuClass(self.SkuIdentifier, self.SkuIds) VariableAttrs = {} Pcds = sdict() @@ -1471,25 +2402,34 @@ class DscBuildData(PlatformBuildClassObject): # tdict is a special dict kind of type, used for selecting correct # PCD settings for certain ARCH and SKU # - PcdDict = tdict(True, 4) + PcdDict = tdict(True, 5) PcdSet = set() RecordList = self._RawData[Type, self._Arch] # Find out all possible PCD candidates for self._Arch - AvailableSkuIdSet = SkuObj.AvailableSkuIdSet.copy() + AvailableSkuIdSet = copy.copy(self.SkuIds) + DefaultStoresDefine = self._GetDefaultStores() - AvailableSkuIdSet.update({'DEFAULT':0, 'COMMON':0}) - for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList: + for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, DefaultStore, Dummy4,Dummy5 in RecordList: + SkuName = SkuName.upper() + SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName + DefaultStore = DefaultStore.upper() + if DefaultStore == "COMMON": + DefaultStore = "STANDARD" if SkuName not in AvailableSkuIdSet: - EdkLogger.error('Build', OPTION_VALUE_INVALID, "The SKUID name %s is not supported by the platform." % SkuName) + 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: - PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, Dummy4)) - PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting + PcdSet.add((PcdCName, TokenSpaceGuid, SkuName,DefaultStore, Dummy5)) + PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid,DefaultStore] = Setting # Remove redundant PCD candidates, per the ARCH and SKU - for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdSet: + for PcdCName, TokenSpaceGuid, SkuName,DefaultStore, Dummy4 in PcdSet: - Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid] + Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid,DefaultStore] if Setting == None: continue VariableName, VariableGuid, VariableOffset, DefaultValue, VarAttribute = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4) @@ -1526,12 +2466,17 @@ class DscBuildData(PlatformBuildClassObject): if not self.CompareVarAttr(VariableAttrs[(VariableName, VariableGuid)], VarAttribute): EdkLogger.error('Build', PCD_VARIABLE_ATTRIBUTES_CONFLICT_ERROR, "The variable %s.%s for DynamicHii PCDs has conflicting attributes [%s] and [%s] " % (VariableGuid, VariableName, VarAttribute, VariableAttrs[(VariableName, VariableGuid)])) - SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute) pcdDecObject = self._DecPcds[PcdCName, TokenSpaceGuid] if (PcdCName, TokenSpaceGuid) in Pcds.keys(): pcdObject = Pcds[PcdCName, TokenSpaceGuid] - pcdObject.SkuInfoList[SkuName] = SkuInfo + 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}) Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject( PcdCName, TokenSpaceGuid, @@ -1552,13 +2497,17 @@ class DscBuildData(PlatformBuildClassObject): for pcd in Pcds.values(): SkuInfoObj = pcd.SkuInfoList.values()[0] 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 == None): sku.HiiDefaultValue = pcdDecObject.DefaultValue + for default_store in sku.DefaultStoreDict: + sku.DefaultStoreDict[default_store]=pcdDecObject.DefaultValue + pcd.DefaultValue = pcdDecObject.DefaultValue if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys(): valuefromDec = pcdDecObject.DefaultValue - SkuInfo = SkuInfoClass('DEFAULT', '0', SkuInfoObj.VariableName, SkuInfoObj.VariableGuid, SkuInfoObj.VariableOffset, valuefromDec) + SkuInfo = SkuInfoClass('DEFAULT', '0', SkuInfoObj.VariableName, SkuInfoObj.VariableGuid, SkuInfoObj.VariableOffset, valuefromDec,VariableAttribute=SkuInfoObj.VariableAttribute,DefaultStore={DefaultStore:valuefromDec}) pcd.SkuInfoList['DEFAULT'] = SkuInfo elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys(): pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON'] @@ -1566,30 +2515,41 @@ class DscBuildData(PlatformBuildClassObject): elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys(): del(pcd.SkuInfoList['COMMON']) - if SkuObj.SkuUsageType == SkuObj.SINGLE: - if 'DEFAULT' in pcd.SkuInfoList.keys() and SkuObj.SystemSkuId not in pcd.SkuInfoList.keys(): - pcd.SkuInfoList[SkuObj.SystemSkuId] = pcd.SkuInfoList['DEFAULT'] - del(pcd.SkuInfoList['DEFAULT']) - if pcd.MaxDatumSize.strip(): MaxSize = int(pcd.MaxDatumSize, 0) else: MaxSize = 0 - if pcdDecObject.DatumType == 'VOID*': - for (skuname, skuobj) in pcd.SkuInfoList.items(): + if pcd.DatumType not in ['BOOLEAN','UINT8','UINT16','UINT32','UINT64']: + for (_, skuobj) in pcd.SkuInfoList.items(): datalen = 0 - if skuobj.HiiDefaultValue.startswith("L"): - datalen = (len(skuobj.HiiDefaultValue) - 3 + 1) * 2 - elif skuobj.HiiDefaultValue.startswith("{"): - datalen = len(skuobj.HiiDefaultValue.split(",")) - else: - datalen = len(skuobj.HiiDefaultValue) - 2 + 1 + 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) - return Pcds + rt, invalidhii = self.CheckVariableNameAssignment(Pcds) + if not rt: + invalidpcd = ",".join(invalidhii) + EdkLogger.error('build', PCD_VARIABLE_INFO_ERROR, Message='The same HII PCD must map to the same EFI variable for all SKUs', File=self.MetaFile, ExtraData=invalidpcd) + map(self.FilterSkuSettings,Pcds.values()) + return Pcds + + def CheckVariableNameAssignment(self,Pcds): + invalidhii = [] + for pcdname in Pcds: + pcd = Pcds[pcdname] + varnameset = set([sku.VariableName for (skuid,sku) in pcd.SkuInfoList.items()]) + if len(varnameset) > 1: + invalidhii.append(".".join((pcdname[1],pcdname[0]))) + if len(invalidhii): + return False,invalidhii + else: + return True, [] ## Retrieve dynamic VPD PCD settings # # @param Type PCD type @@ -1598,7 +2558,6 @@ class DscBuildData(PlatformBuildClassObject): # def _GetDynamicVpdPcd(self, Type): - SkuObj = SkuClass(self.SkuIdentifier, self.SkuIds) Pcds = sdict() # @@ -1610,14 +2569,16 @@ class DscBuildData(PlatformBuildClassObject): # Find out all possible PCD candidates for self._Arch RecordList = self._RawData[Type, self._Arch] - AvailableSkuIdSet = SkuObj.AvailableSkuIdSet.copy() + AvailableSkuIdSet = copy.copy(self.SkuIds) - AvailableSkuIdSet.update({'DEFAULT':0, 'COMMON':0}) - for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList: + for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4,Dummy5 in RecordList: + SkuName = SkuName.upper() + SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName if SkuName not in AvailableSkuIdSet: - EdkLogger.error('Build', OPTION_VALUE_INVALID, "The SKUID name %s is not supported by the platform." % SkuName) + EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName, + File=self.MetaFile, Line=Dummy5) if "." not in TokenSpaceGuid: - PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy4)) + PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy5)) PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting # Remove redundant PCD candidates, per the ARCH and SKU @@ -1632,7 +2593,7 @@ class DscBuildData(PlatformBuildClassObject): # until the DEC parser has been called. # VpdOffset, MaxDatumSize, InitialValue = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4) - SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], '', '', '', '', VpdOffset, InitialValue) + SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', VpdOffset, InitialValue) if (PcdCName, TokenSpaceGuid) in Pcds.keys(): pcdObject = Pcds[PcdCName, TokenSpaceGuid] pcdObject.SkuInfoList[SkuName] = SkuInfo @@ -1662,6 +2623,11 @@ class DscBuildData(PlatformBuildClassObject): for pcd in Pcds.values(): SkuInfoObj = pcd.SkuInfoList.values()[0] 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.DefaultValue == "" or sku.DefaultValue==None): + sku.DefaultValue = pcdDecObject.DefaultValue if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys(): valuefromDec = pcdDecObject.DefaultValue SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '', '', SkuInfoObj.VpdOffset, valuefromDec) @@ -1671,11 +2637,9 @@ class DscBuildData(PlatformBuildClassObject): del(pcd.SkuInfoList['COMMON']) elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys(): del(pcd.SkuInfoList['COMMON']) - if SkuObj.SkuUsageType == SkuObj.SINGLE: - if 'DEFAULT' in pcd.SkuInfoList.keys() and SkuObj.SystemSkuId not in pcd.SkuInfoList.keys(): - pcd.SkuInfoList[SkuObj.SystemSkuId] = pcd.SkuInfoList['DEFAULT'] - del(pcd.SkuInfoList['DEFAULT']) + + map(self.FilterSkuSettings,Pcds.values()) return Pcds ## Add external modules @@ -1692,6 +2656,28 @@ class DscBuildData(PlatformBuildClassObject): Module.MetaFile = FilePath self.Modules.append(Module) + def _GetToolChainFamily(self): + self._ToolChainFamily = "MSFT" + BuildConfigurationFile = os.path.normpath(os.path.join(GlobalData.gConfDirectory, "target.txt")) + if os.path.isfile(BuildConfigurationFile) == True: + TargetTxt = TargetTxtClassObject() + TargetTxt.LoadTargetTxtFile(BuildConfigurationFile) + ToolDefinitionFile = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF] + if ToolDefinitionFile == '': + ToolDefinitionFile = "tools_def.txt" + ToolDefinitionFile = os.path.normpath(mws.join(self.WorkspaceDir, 'Conf', ToolDefinitionFile)) + if os.path.isfile(ToolDefinitionFile) == True: + ToolDef = ToolDefClassObject() + ToolDef.LoadToolDefFile(ToolDefinitionFile) + ToolDefinition = ToolDef.ToolsDefTxtDatabase + if TAB_TOD_DEFINES_FAMILY not in ToolDefinition \ + or self._Toolchain not in ToolDefinition[TAB_TOD_DEFINES_FAMILY] \ + or not ToolDefinition[TAB_TOD_DEFINES_FAMILY][self._Toolchain]: + self._ToolChainFamily = "MSFT" + else: + self._ToolChainFamily = ToolDefinition[TAB_TOD_DEFINES_FAMILY][self._Toolchain] + return self._ToolChainFamily + ## Add external PCDs # # The external PCDs are mostly those listed in FDF file to specify address @@ -1705,7 +2691,21 @@ class DscBuildData(PlatformBuildClassObject): 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 == None: + FdfInfList = [] + if GlobalData.gFdfParser: + FdfInfList = GlobalData.gFdfParser.Profile.InfList + PkgSet = set() + for Inf in FdfInfList: + ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch) + if ModuleFile in self._Modules: + continue + ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain] + PkgSet.update(ModuleData.Packages) + self._DecPcds, self._GuidDict = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain,PkgSet) + return self._DecPcds _Macros = property(_GetMacros) Arch = property(_GetArch, _SetArch) Platform = property(_GetPlatformName) @@ -1717,8 +2717,6 @@ class DscBuildData(PlatformBuildClassObject): SupArchList = property(_GetSupArch) BuildTargets = property(_GetBuildTarget) SkuName = property(_GetSkuName, _SetSkuName) - SkuIdentifier = property(_GetSkuIdentifier) - AvilableSkuIds = property(_GetAviableSkuIds) PcdInfoFlag = property(_GetPcdInfoFlag) VarCheckFlag = property(_GetVarCheckFlag) FlashDefinition = property(_GetFdfFile) @@ -1738,3 +2736,4 @@ class DscBuildData(PlatformBuildClassObject): LibraryClasses = property(_GetLibraryClasses) Pcds = property(_GetPcds) BuildOptions = property(_GetBuildOptions) + ToolChainFamily = property(_GetToolChainFamily)