From 8518bf0b92a78938341a2752a0044f04336668cc Mon Sep 17 00:00:00 2001 From: Liming Gao Date: Fri, 22 Dec 2017 20:46:15 +0800 Subject: [PATCH] BaseTools: Support Structure PCD value inherit between the different SKUs https://bugzilla.tianocore.org/show_bug.cgi?id=543 Structure PCD field value can inherit between the different SKUIds. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Feng Bob C Reviewed-by: Liming Gao --- BaseTools/Source/Python/AutoGen/AutoGen.py | 33 +- BaseTools/Source/Python/AutoGen/GenC.py | 5 + BaseTools/Source/Python/AutoGen/GenPcdDb.py | 2 +- BaseTools/Source/Python/AutoGen/GenVar.py | 62 +- .../Source/Python/Common/BuildToolError.py | 3 +- BaseTools/Source/Python/Common/DataType.py | 2 + BaseTools/Source/Python/Common/Misc.py | 59 +- .../Python/CommonDataClass/CommonClass.py | 5 +- .../Python/CommonDataClass/DataClass.py | 1 + .../Python/Workspace/BuildClassObject.py | 17 +- .../Source/Python/Workspace/DscBuildData.py | 557 ++++++++++++------ .../Source/Python/Workspace/MetaFileParser.py | 56 +- .../Source/Python/Workspace/MetaFileTable.py | 11 +- 13 files changed, 533 insertions(+), 280 deletions(-) diff --git a/BaseTools/Source/Python/AutoGen/AutoGen.py b/BaseTools/Source/Python/AutoGen/AutoGen.py index 783305c7cc..be6fecd9f3 100644 --- a/BaseTools/Source/Python/AutoGen/AutoGen.py +++ b/BaseTools/Source/Python/AutoGen/AutoGen.py @@ -44,7 +44,7 @@ from Common.MultipleWorkspace import MultipleWorkspace as mws import InfSectionParser import datetime import hashlib -from GenVar import Variable,var_info +from GenVar import VariableMgr,var_info ## Regular expression for splitting Dependency Expression string into tokens gDepexTokenPattern = re.compile("(\(|\)|\w+| \S+\.inf)") @@ -1225,6 +1225,7 @@ class PlatformAutoGen(AutoGen): self.AllPcdList = [] # get the original module/package/platform objects self.BuildDatabase = Workspace.BuildDatabase + self.DscBuildDataObj = Workspace.Platform # flag indicating if the makefile/C-code file has been created or not self.IsMakeFileCreated = False @@ -1354,23 +1355,21 @@ class PlatformAutoGen(AutoGen): LibAuto.ConstPcd[key] = Pcd.DefaultValue def CollectVariables(self, DynamicPcdSet): - VariableInfo = Variable() + VariableInfo = VariableMgr(self.DscBuildDataObj._GetDefaultStores(),self.DscBuildDataObj._GetSkuIds()) Index = 0 for Pcd in DynamicPcdSet: - if not hasattr(Pcd,"DefaultStoreName"): - Pcd.DefaultStoreName = ['0'] - for StorageName in Pcd.DefaultStoreName: - pcdname = ".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName)) - for SkuName in Pcd.SkuInfoList: - Sku = Pcd.SkuInfoList[SkuName] - SkuId = Sku.SkuId - if SkuId == None or SkuId == '': - continue - if len(Sku.VariableName) > 0: - VariableGuidStructure = Sku.VariableGuidValue - VariableGuid = GuidStructureStringToGuidString(VariableGuidStructure) - if Pcd.Phase == "DXE": - VariableInfo.append_variable(var_info(Index,pcdname,StorageName,SkuId, StringToArray(Sku.VariableName),VariableGuid, Sku.VariableAttribute , Pcd.DefaultValue,Sku.HiiDefaultValue,Pcd.DatumType)) + pcdname = ".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName)) + for SkuName in Pcd.SkuInfoList: + Sku = Pcd.SkuInfoList[SkuName] + SkuId = Sku.SkuId + if SkuId == None or SkuId == '': + continue + if len(Sku.VariableName) > 0: + VariableGuidStructure = Sku.VariableGuidValue + VariableGuid = GuidStructureStringToGuidString(VariableGuidStructure) + if Pcd.Phase == "DXE": + for StorageName in Sku.DefaultStoreDict: + VariableInfo.append_variable(var_info(Index,pcdname,StorageName,SkuName, StringToArray(Sku.VariableName),VariableGuid, Sku.VariableAttribute , Pcd.DefaultValue,Sku.DefaultStoreDict[StorageName],Pcd.DatumType)) Index += 1 return VariableInfo ## Collect dynamic PCDs @@ -2383,7 +2382,7 @@ class PlatformAutoGen(AutoGen): else: SkuName = 'DEFAULT' ToPcd.SkuInfoList = { - SkuName : SkuInfoClass(SkuName, self.Platform.SkuIds[SkuName], '', '', '', '', '', ToPcd.DefaultValue) + SkuName : SkuInfoClass(SkuName, self.Platform.SkuIds[SkuName][0], '', '', '', '', '', ToPcd.DefaultValue) } ## Apply PCD setting defined platform to a module diff --git a/BaseTools/Source/Python/AutoGen/GenC.py b/BaseTools/Source/Python/AutoGen/GenC.py index 2bc4fbdb6e..6b95cd47c2 100644 --- a/BaseTools/Source/Python/AutoGen/GenC.py +++ b/BaseTools/Source/Python/AutoGen/GenC.py @@ -1677,6 +1677,9 @@ def CreatePcdCode(Info, AutoGenC, AutoGenH): if Pcd.Type in gDynamicExPcd and Pcd.TokenSpaceGuidCName not in TokenSpaceList: TokenSpaceList += [Pcd.TokenSpaceGuidCName] + SkuMgr = Info.Workspace.Platform.SkuIdMgr + AutoGenH.Append("\n// Definition of SkuId Array\n") + AutoGenH.Append("extern UINT64 _gPcd_SkuId_Array[];\n") # Add extern declarations to AutoGen.h if one or more Token Space GUIDs were found if TokenSpaceList <> []: AutoGenH.Append("\n// Definition of PCD Token Space GUIDs used in this module\n\n") @@ -1694,6 +1697,8 @@ def CreatePcdCode(Info, AutoGenC, AutoGenH): CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd) DynExPcdTokenNumberMapping (Info, AutoGenH) else: + AutoGenC.Append("\n// Definition of SkuId Array\n") + AutoGenC.Append("GLOBAL_REMOVE_IF_UNREFERENCED UINT64 _gPcd_SkuId_Array[] = %s;\n" % SkuMgr.DumpSkuIdArrary()) if Info.ModulePcdList: AutoGenH.Append("\n// Definition of PCDs used in this module\n") AutoGenC.Append("\n// Definition of PCDs used in this module\n") diff --git a/BaseTools/Source/Python/AutoGen/GenPcdDb.py b/BaseTools/Source/Python/AutoGen/GenPcdDb.py index 40743d1fd6..3d9bfd7666 100644 --- a/BaseTools/Source/Python/AutoGen/GenPcdDb.py +++ b/BaseTools/Source/Python/AutoGen/GenPcdDb.py @@ -1057,7 +1057,7 @@ def CreatePcdDatabasePhaseSpecificAutoGen (Platform, Phase): SkuObj = SkuClass(Platform.Platform.AvilableSkuIds, Platform.Platform.SkuIds) - Dict['SYSTEM_SKU_ID_VALUE'] = Platform.Platform.SkuIds[SkuObj.SystemSkuId] + Dict['SYSTEM_SKU_ID_VALUE'] = Platform.Platform.SkuIds[SkuObj.SystemSkuId][0] Dict['PCD_INFO_FLAG'] = Platform.Platform.PcdInfoFlag diff --git a/BaseTools/Source/Python/AutoGen/GenVar.py b/BaseTools/Source/Python/AutoGen/GenVar.py index 9b76078a07..98e1a4cdae 100644 --- a/BaseTools/Source/Python/AutoGen/GenVar.py +++ b/BaseTools/Source/Python/AutoGen/GenVar.py @@ -46,9 +46,11 @@ def PackGUID(Guid): ) return GuidBuffer -class Variable(object): - def __init__(self,): +class VariableMgr(object): + def __init__(self, DefaultStoreMap,SkuIdMap): self.VarInfo = [] + self.DefaultStoreMap = DefaultStoreMap + self.SkuIdMap = SkuIdMap def append_variable(self,uefi_var): self.VarInfo.append(uefi_var) @@ -61,7 +63,7 @@ class Variable(object): for item in self.VarInfo: if item.pcdindex not in indexedvarinfo: indexedvarinfo[item.pcdindex] = dict() - indexedvarinfo[item.pcdindex][(int(item.skuname),int(item.defaultstoragename))] = item + indexedvarinfo[item.pcdindex][(item.skuname,item.defaultstoragename)] = item for index in indexedvarinfo: sku_var_info = indexedvarinfo[index] @@ -69,7 +71,7 @@ class Variable(object): default_data_buffer = "" others_data_buffer = "" tail = None - default_sku_default = indexedvarinfo.get(index).get((0,0)) + default_sku_default = indexedvarinfo.get(index).get(("DEFAULT","STANDARD")) if default_sku_default.data_type not in ["UINT8","UINT16","UINT32","UINT64","BOOLEAN"]: var_max_len = max([len(var_item.default_value.split(",")) for var_item in sku_var_info.values()]) @@ -82,13 +84,13 @@ class Variable(object): for item in default_data_buffer: default_data_array += unpack("B",item) - if (0,0) not in var_data: - var_data[(0,0)] = collections.OrderedDict() - var_data[(0,0)][index] = (default_data_buffer,sku_var_info[(0,0)]) + if ("DEFAULT","STANDARD") not in var_data: + var_data[("DEFAULT","STANDARD")] = collections.OrderedDict() + var_data[("DEFAULT","STANDARD")][index] = (default_data_buffer,sku_var_info[("DEFAULT","STANDARD")]) for (skuid,defaultstoragename) in indexedvarinfo.get(index): tail = None - if (skuid,defaultstoragename) == (0,0): + if (skuid,defaultstoragename) == ("DEFAULT","STANDARD"): continue other_sku_other = indexedvarinfo.get(index).get((skuid,defaultstoragename)) @@ -113,7 +115,7 @@ class Variable(object): var_data = self.process_variable_data() - pcds_default_data = var_data.get((0,0)) + pcds_default_data = var_data.get(("DEFAULT","STANDARD")) NvStoreDataBuffer = "" var_data_offset = collections.OrderedDict() offset = NvStorageHeaderSize @@ -127,11 +129,6 @@ class Variable(object): else: var_attr_value = 0x07 - print "default var_name_buffer" - print self.format_data(var_name_buffer) - print "default var_buffer" - print self.format_data(default_data) - DataBuffer = self.AlignData(var_name_buffer + default_data) data_size = len(DataBuffer) @@ -139,20 +136,18 @@ class Variable(object): var_data_offset[default_info.pcdindex] = offset offset += data_size - len(default_info.var_name.split(",")) - var_header_buffer = self.PACK_VARIABLE_HEADER(var_attr_value, len(default_info.var_name.split(",")), data_size, vendorguid) + var_header_buffer = self.PACK_VARIABLE_HEADER(var_attr_value, len(default_info.var_name.split(",")), len (default_data), vendorguid) NvStoreDataBuffer += (var_header_buffer + DataBuffer) variable_storage_header_buffer = self.PACK_VARIABLE_STORE_HEADER(len(NvStoreDataBuffer) + 28) nv_default_part = self.AlignData(self.PACK_DEFAULT_DATA(0, 0, self.unpack_data(variable_storage_header_buffer+NvStoreDataBuffer))) - print "default whole data \n",self.format_data(nv_default_part) - data_delta_structure_buffer = "" - for skuid,defaultid in var_data: - if (skuid,defaultid) == (0,0): + for skuname,defaultstore in var_data: + if (skuname,defaultstore) == ("DEFAULT","STANDARD"): continue - pcds_sku_data = var_data.get((skuid,defaultid)) + pcds_sku_data = var_data.get((skuname,defaultstore)) delta_data_set = [] for pcdindex in pcds_sku_data: offset = var_data_offset[pcdindex] @@ -160,10 +155,7 @@ class Variable(object): delta_data = [(item[0] + offset, item[1]) for item in delta_data] delta_data_set.extend(delta_data) - data_delta_structure_buffer += self.AlignData(self.PACK_DELTA_DATA(defaultid,skuid,delta_data_set)) - print "delta data" - print delta_data_set - print self.format_data(self.AlignData(self.PACK_DELTA_DATA(defaultid,skuid,delta_data_set))) + data_delta_structure_buffer += self.AlignData(self.PACK_DELTA_DATA(skuname,defaultstore,delta_data_set)) return self.format_data(nv_default_part + data_delta_structure_buffer) @@ -179,8 +171,6 @@ class Variable(object): return final_data def calculate_delta(self, default, theother): - print "default data \n", default - print "other data \n",theother if len(default) - len(theother) != 0: EdkLogger.error("build", FORMAT_INVALID, 'The variable data length is not the same for the same PCD.') data_delta = [] @@ -258,7 +248,7 @@ class Variable(object): def PACK_DEFAULT_DATA(self, defaultstoragename,skuid,var_value): Buffer = "" - Buffer += pack("=H",6) + Buffer += pack("=L",8) Buffer += pack("=H",int(defaultstoragename)) Buffer += pack("=H",int(skuid)) @@ -269,11 +259,21 @@ class Variable(object): return Buffer - def PACK_DELTA_DATA(self,defaultstoragename,skuid,delta_list): + def GetSkuId(self,skuname): + if skuname not in self.SkuIdMap: + return None + return self.SkuIdMap.get(skuname)[0] + def GetDefaultStoreId(self,dname): + if dname not in self.DefaultStoreMap: + return None + return self.DefaultStoreMap.get(dname)[0] + def PACK_DELTA_DATA(self,skuname,defaultstoragename,delta_list): + skuid = self.GetSkuId(skuname) + defaultstorageid = self.GetDefaultStoreId(defaultstoragename) Buffer = "" - Buffer += pack("=H",6) - Buffer += pack("=H",int(defaultstoragename)) + Buffer += pack("=L",8) Buffer += pack("=H",int(skuid)) + Buffer += pack("=H",int(defaultstorageid)) for (delta_offset,value) in delta_list: Buffer += pack("=L",delta_offset) Buffer = Buffer[:-1] + pack("=B",value) @@ -294,4 +294,4 @@ class Variable(object): for name_char in var_name.strip("{").strip("}").split(","): Buffer += pack("=B",int(name_char,16)) - return Buffer \ No newline at end of file + return Buffer diff --git a/BaseTools/Source/Python/Common/BuildToolError.py b/BaseTools/Source/Python/Common/BuildToolError.py index 2ee899ac44..d3e5f9f167 100644 --- a/BaseTools/Source/Python/Common/BuildToolError.py +++ b/BaseTools/Source/Python/Common/BuildToolError.py @@ -86,7 +86,8 @@ MIGRATION_ERROR = 0xF010 PCD_VALIDATION_INFO_ERROR = 0xF011 PCD_VARIABLE_ATTRIBUTES_ERROR = 0xF012 PCD_VARIABLE_ATTRIBUTES_CONFLICT_ERROR = 0xF013 -PCD_STRUCTURE_PCD_ERROR = 0xF014 +PCD_STRUCTURE_PCD_INVALID_FIELD_ERROR = 0xF014 +PCD_STRUCTURE_PCD_ERROR = 0xF015 ABORT_ERROR = 0xFFFE UNKNOWN_ERROR = 0xFFFF diff --git a/BaseTools/Source/Python/Common/DataType.py b/BaseTools/Source/Python/Common/DataType.py index ce8c50c4c4..0bc2306ea6 100644 --- a/BaseTools/Source/Python/Common/DataType.py +++ b/BaseTools/Source/Python/Common/DataType.py @@ -283,6 +283,8 @@ TAB_DEPEX_EBC = TAB_DEPEX + TAB_SPLIT + TAB_ARCH_EBC TAB_DEPEX_AARCH64 = TAB_DEPEX + TAB_SPLIT + TAB_ARCH_AARCH64 TAB_SKUIDS = 'SkuIds' +TAB_DEFAULT_STORES = 'DefaultStores' +TAB_DEFAULT_STORES_DEFAULT = 'STANDARD' TAB_LIBRARIES = 'Libraries' TAB_LIBRARIES_COMMON = TAB_LIBRARIES + TAB_SPLIT + TAB_ARCH_COMMON diff --git a/BaseTools/Source/Python/Common/Misc.py b/BaseTools/Source/Python/Common/Misc.py index 3ae2ec5b59..8b9eed8a09 100644 --- a/BaseTools/Source/Python/Common/Misc.py +++ b/BaseTools/Source/Python/Common/Misc.py @@ -2093,30 +2093,55 @@ class PeImageClass(): Value = (Value << 8) | int(ByteList[index]) return Value - +class DefaultStore(): + def __init__(self,DefaultStores ): + + self.DefaultStores = DefaultStores + def DefaultStoreID(self,DefaultStoreName): + for key,value in self.DefaultStores.items(): + if value == DefaultStoreName: + return key + return None + def GetDefaultDefault(self): + if not self.DefaultStores or "0" in self.DefaultStores: + return "0",TAB_DEFAULT_STORES_DEFAULT + else: + minvalue = min([int(value_str) for value_str in self.DefaultStores.keys()]) + return (str(minvalue), self.DefaultStores[str(minvalue)]) + def GetMin(self,DefaultSIdList): + if not DefaultSIdList: + return "STANDARD" + minid = min({storeid for storeid, storename in self.DefaultStores.values() if storename in DefaultSIdList} ) + for sid,name in self.DefaultStores.values(): + if sid == minid: + return name class SkuClass(): DEFAULT = 0 SINGLE = 1 MULTIPLE =2 - def __init__(self,SkuIdentifier='', SkuIds={}): + def __init__(self,SkuIdentifier='', SkuIds=None): + if SkuIds is None: + SkuIds = {} self.AvailableSkuIds = sdict() self.SkuIdSet = [] self.SkuIdNumberSet = [] + self.SkuData = SkuIds + self.__SkuInherit = {} if SkuIdentifier == '' or SkuIdentifier is None: self.SkuIdSet = ['DEFAULT'] self.SkuIdNumberSet = ['0U'] elif SkuIdentifier == 'ALL': self.SkuIdSet = SkuIds.keys() - self.SkuIdNumberSet = [num.strip() + 'U' for num in SkuIds.values()] + self.SkuIdNumberSet = [num[0].strip() + 'U' for num in SkuIds.values()] else: r = SkuIdentifier.split('|') - self.SkuIdSet=[r[k].strip() for k in range(len(r))] + self.SkuIdSet=[(r[k].strip()).upper() for k in range(len(r))] k = None try: - self.SkuIdNumberSet = [SkuIds[k].strip() + 'U' for k in self.SkuIdSet] + self.SkuIdNumberSet = [SkuIds[k][0].strip() + 'U' for k in self.SkuIdSet] except Exception: EdkLogger.error("build", PARAMETER_INVALID, ExtraData = "SKU-ID [%s] is not supported by the platform. [Valid SKU-ID: %s]" @@ -2126,11 +2151,19 @@ class SkuClass(): self.SkuIdNumberSet.remove('0U') for each in self.SkuIdSet: if each in SkuIds: - self.AvailableSkuIds[each] = SkuIds[each] + self.AvailableSkuIds[each] = SkuIds[each][0] else: EdkLogger.error("build", PARAMETER_INVALID, ExtraData="SKU-ID [%s] is not supported by the platform. [Valid SKU-ID: %s]" % (each, " | ".join(SkuIds.keys()))) + if self.SkuUsageType != self.SINGLE: + self.AvailableSkuIds.update({'DEFAULT':0, 'COMMON':0}) + def GetNextSkuId(self, skuname): + if not self.__SkuInherit: + self.__SkuInherit = {} + for item in self.SkuData.values(): + self.__SkuInherit[item[1]]=item[2] if item[2] else "DEFAULT" + return self.__SkuInherit.get(skuname,"DEFAULT") def __SkuUsageType(self): @@ -2141,7 +2174,21 @@ class SkuClass(): return SkuClass.SINGLE else: return SkuClass.MULTIPLE + def DumpSkuIdArrary(self): + ArrayStrList = [] + if self.SkuUsageType == SkuClass.SINGLE: + ArrayStr = "{0x0}" + else: + for skuname in self.AvailableSkuIds: + if skuname == "COMMON": + continue + while skuname != "DEFAULT": + ArrayStrList.append(hex(int(self.AvailableSkuIds[skuname]))) + skuname = self.GetNextSkuId(skuname) + ArrayStrList.append("0x0") + ArrayStr = "{" + ",".join(ArrayStrList) + "}" + return ArrayStr def __GetAvailableSkuIds(self): return self.AvailableSkuIds diff --git a/BaseTools/Source/Python/CommonDataClass/CommonClass.py b/BaseTools/Source/Python/CommonDataClass/CommonClass.py index 5a924ec2d6..e6c4495c95 100644 --- a/BaseTools/Source/Python/CommonDataClass/CommonClass.py +++ b/BaseTools/Source/Python/CommonDataClass/CommonClass.py @@ -270,19 +270,22 @@ class PpiClass(GuidProtocolPpiCommonClass): # class SkuInfoClass(object): def __init__(self, SkuIdName = '', SkuId = '', VariableName = '', VariableGuid = '', VariableOffset = '', - HiiDefaultValue = '', VpdOffset = '', DefaultValue = '', VariableGuidValue = '', VariableAttribute = ''): + HiiDefaultValue = '', VpdOffset = '', DefaultValue = '', VariableGuidValue = '', VariableAttribute = '', DefaultStore = None): self.SkuIdName = SkuIdName self.SkuId = SkuId # # Used by Hii # + if DefaultStore is None: + DefaultStore = {} self.VariableName = VariableName self.VariableGuid = VariableGuid self.VariableGuidValue = VariableGuidValue self.VariableOffset = VariableOffset self.HiiDefaultValue = HiiDefaultValue self.VariableAttribute = VariableAttribute + self.DefaultStoreDict = DefaultStore # # Used by Vpd diff --git a/BaseTools/Source/Python/CommonDataClass/DataClass.py b/BaseTools/Source/Python/CommonDataClass/DataClass.py index efeba3e5dc..31ed46c7ec 100644 --- a/BaseTools/Source/Python/CommonDataClass/DataClass.py +++ b/BaseTools/Source/Python/CommonDataClass/DataClass.py @@ -64,6 +64,7 @@ MODEL_EFI_BINARY_FILE = 3008 MODEL_EFI_SKU_ID = 3009 MODEL_EFI_INCLUDE = 3010 MODEL_EFI_DEPEX = 3011 +MODEL_EFI_DEFAULT_STORES = 3012 MODEL_PCD = 4000 MODEL_PCD_FIXED_AT_BUILD = 4001 diff --git a/BaseTools/Source/Python/Workspace/BuildClassObject.py b/BaseTools/Source/Python/Workspace/BuildClassObject.py index 6150557cfb..631c1c7b99 100644 --- a/BaseTools/Source/Python/Workspace/BuildClassObject.py +++ b/BaseTools/Source/Python/Workspace/BuildClassObject.py @@ -16,6 +16,7 @@ import Common.LongFilePathOs as os from Common.Misc import sdict from Common.Misc import RealPath2 from Common.BuildToolError import * +from Common.DataType import * import collections ## PcdClassObject @@ -108,11 +109,11 @@ class PcdClassObject(object): return hash((self.TokenCName, self.TokenSpaceGuidCName)) class StructurePcd(PcdClassObject): - def __init__(self, StructuredPcdIncludeFile="", Packages=None, Name=None, Guid=None, Type=None, DatumType=None, Value=None, Token=None, MaxDatumSize=None, SkuInfoList={}, IsOverrided=False, GuidValue=None, validateranges=[], validlists=[], expressions=[]): + def __init__(self, StructuredPcdIncludeFile="", Packages=None, Name=None, Guid=None, Type=None, DatumType=None, Value=None, Token=None, MaxDatumSize=None, SkuInfoList={}, IsOverrided=False, GuidValue=None, validateranges=[], validlists=[], expressions=[],default_store = TAB_DEFAULT_STORES_DEFAULT): super(StructurePcd, self).__init__(Name, Guid, Type, DatumType, Value, Token, MaxDatumSize, SkuInfoList, IsOverrided, GuidValue, validateranges, validlists, expressions) self.StructuredPcdIncludeFile = StructuredPcdIncludeFile self.PackageDecs = Packages - self.DefaultStoreName = ['STANDARD'] + self.DefaultStoreName = [default_store] self.DefaultValues = collections.OrderedDict({}) self.PcdMode = None self.SkuOverrideValues = collections.OrderedDict({}) @@ -127,13 +128,15 @@ class StructurePcd(PcdClassObject): self.DefaultValues[FieldName] = [Value.strip(), FileName, LineNo] return self.DefaultValues[FieldName] - def AddOverrideValue (self, FieldName, Value, SkuName, FileName="", LineNo=0): + def AddOverrideValue (self, FieldName, Value, SkuName, DefaultStoreName, FileName="", LineNo=0): if SkuName not in self.SkuOverrideValues: self.SkuOverrideValues[SkuName] = collections.OrderedDict({}) - if FieldName in self.SkuOverrideValues[SkuName]: - del self.SkuOverrideValues[SkuName][FieldName] - self.SkuOverrideValues[SkuName][FieldName] = [Value.strip(), FileName, LineNo] - return self.SkuOverrideValues[SkuName][FieldName] + if DefaultStoreName not in self.SkuOverrideValues[SkuName]: + self.SkuOverrideValues[SkuName][DefaultStoreName] = collections.OrderedDict({}) + if FieldName in self.SkuOverrideValues[SkuName][DefaultStoreName]: + del self.SkuOverrideValues[SkuName][DefaultStoreName][FieldName] + self.SkuOverrideValues[SkuName][DefaultStoreName][FieldName] = [Value.strip(), FileName, LineNo] + return self.SkuOverrideValues[SkuName][DefaultStoreName][FieldName] def SetPcdMode (self, PcdMode): self.PcdMode = PcdMode diff --git a/BaseTools/Source/Python/Workspace/DscBuildData.py b/BaseTools/Source/Python/Workspace/DscBuildData.py index 302de724b1..5b5dbb64f9 100644 --- a/BaseTools/Source/Python/Workspace/DscBuildData.py +++ b/BaseTools/Source/Python/Workspace/DscBuildData.py @@ -158,6 +158,9 @@ class DscBuildData(PlatformBuildClassObject): self.OutputPath = os.path.join(os.getenv("WORKSPACE"), 'Build', PcdValueInitName) else: self.OutputPath = os.path.dirname(self.DscFile) + self.DefaultStores = None + self.SkuIdMgr = SkuClass(self.SkuIdentifier, self.SkuIds) + arraystr = self.SkuIdMgr.DumpSkuIdArrary() ## XXX[key] = value def __setitem__(self, key, value): @@ -206,6 +209,7 @@ class DscBuildData(PlatformBuildClassObject): self._ISOLanguages = None self._VpdToolGuid = None self.__Macros = None + self.DefaultStores = None ## handle Override Path of Module @@ -214,8 +218,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 != []: @@ -587,12 +591,36 @@ 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$') + if Pattern.match(Record[0]) == None: + EdkLogger.error('build', FORMAT_INVALID, "The format of the Sku ID number is invalid. The correct format is '{(0-9)} {(1-9)(0-9)+}'", + 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]] = (Record[0],Record[1],Record[2]) 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]) + self.DefaultStores[Record[1]] = (self.ToInt(Record[0]),Record[1]) + if TAB_DEFAULT_STORES_DEFAULT not in self.DefaultStores: + self.DefaultStores[TAB_DEFAULT_STORES_DEFAULT] = (0,TAB_DEFAULT_STORES_DEFAULT) + return self.DefaultStores ## Retrieve [Components] section information def _GetModules(self): @@ -607,8 +635,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,7 +676,7 @@ 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: @@ -672,7 +700,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 +740,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 @@ -821,6 +849,18 @@ class DscBuildData(PlatformBuildClassObject): ExtraData="%s.%s" % (TokenSpaceGuid, PcdCName)) 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} + 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} + return Pcds ## Retrieve all PCD settings in platform def _GetPcds(self): if self._Pcds == None: @@ -835,9 +875,22 @@ 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.UpdateStructuredPcds(MODEL_PCD_TYPE_LIST, self._Pcds) + self._Pcds = self._FilterPcdBySkuUsage(self._Pcds) 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 +900,7 @@ 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: CurKey = (ToolChainFamily, ToolChain, CodeBase) # # Only flags can be appended @@ -867,7 +920,7 @@ class DscBuildData(PlatformBuildClassObject): 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: + for ToolChainFamily, ToolChain, Option, Arch, Type, Dummy3, Dummy4,Dummy5 in RecordList: if Type == DriverType or Type == CommonDriverType: Key = (ToolChainFamily, ToolChain, Edk) if Key not in options or not ToolChain.endswith('_FLAGS') or Option.startswith('='): @@ -879,15 +932,39 @@ class DscBuildData(PlatformBuildClassObject): 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 CompleteStructurePcdValue(self,pcdset): + skuset = set([item[3] for item in pcdset]) + pcddatamap = {(item[0],item[1],item[2],item[3]):item for item in pcdset} + FieldSet = {} + for item in pcdset: + if (item[0],item[1]) not in FieldSet: + FieldSet[(item[0],item[1])] = set() + FieldSet[(item[0],item[1])].add(item[2]) + completeset = [] + for tockenspacename,pcdname, in FieldSet: + for field in FieldSet[(tockenspacename,pcdname)]: + for skuid in skuset: + nextskuid = skuid + while (tockenspacename,pcdname,field,nextskuid) not in pcddatamap: + nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid) + if nextskuid == "DEFAULT": + break + if (tockenspacename,pcdname,field,nextskuid) not in pcddatamap: + continue + item = pcddatamap[tockenspacename,pcdname,field,nextskuid] + completeset.append((tockenspacename,pcdname,field,skuid, item[4],item[5], item[6])) + return completeset def UpdateStructuredPcds(self, TypeList, AllPcds): Pcds = AllPcds - SkuObj = SkuClass(self.SkuIdentifier, self.SkuIds) + DefaultStoreMgr = DefaultStore(self.DefaultStores) + SkuIds = set([skuid for pcdobj in AllPcds.values() for skuid in pcdobj.SkuInfoList.keys()]) + 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 @@ -895,17 +972,20 @@ class DscBuildData(PlatformBuildClassObject): 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: + if SkuName not in SkuIds: + continue 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 in SkuIds and "." in TokenSpaceGuid: + S_PcdSet.append(( TokenSpaceGuid.split(".")[0],TokenSpaceGuid.split(".")[1], PcdCName,SkuName, default_store,Dummy5, AnalyzePcdExpression(Setting)[0])) + S_PcdSet = self.CompleteStructurePcdValue(S_PcdSet) # handle pcd value override StrPcdSet = self.GetStructurePcdInfo(S_PcdSet) S_pcd_set = {} 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 str_pcd_dec: str_pcd_obj_str = StructurePcd() str_pcd_obj_str.copy(str_pcd_dec) @@ -914,9 +994,9 @@ class DscBuildData(PlatformBuildClassObject): if str_pcd_obj.DefaultValue: str_pcd_obj_str.DefaultFromDSC = str_pcd_obj.DefaultValue 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,LineNo=str_pcd_data[5]) + S_pcd_set[str_pcd[1], str_pcd[0]] = str_pcd_obj_str # Add the Structure PCD that only defined in DEC, don't have override in DSC file for Pcd in self._DecPcds: if type (self._DecPcds[Pcd]) is StructurePcd: @@ -931,29 +1011,67 @@ class DscBuildData(PlatformBuildClassObject): 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(): + if stru_pcd.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]]: + continue + 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 + if skuid not in stru_pcd.SkuOverrideValues: + while nextskuid not in stru_pcd.SkuOverrideValues: + nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid) + stru_pcd.SkuOverrideValues[skuid] = {} + PcdDefaultStoreSet = set([defaultstorename for defaultstorename in stru_pcd.SkuOverrideValues[skuid]]) + mindefaultstorename = DefaultStoreMgr.GetMin(PcdDefaultStoreSet) + for defaultstoreid in DefaultStores: + if defaultstoreid not in stru_pcd.SkuOverrideValues[skuid]: + stru_pcd.SkuOverrideValues[skuid][defaultstoreid] = stru_pcd.SkuOverrideValues[nextskuid][mindefaultstorename] + for skuid in SkuIds: + if skuid in stru_pcd.SkuOverrideValues: + continue + nextskuid = self.SkuIdMgr.GetNextSkuId(skuid) + while nextskuid not in stru_pcd.SkuOverrideValues: + nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid) + stru_pcd.SkuOverrideValues[skuid] = stru_pcd.SkuOverrideValues[nextskuid] 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: 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: + str_pcd_obj.SkuInfoList[skuname] = SkuInfoClass(SkuIdName=skuname, SkuId=self.SkuIds[skuname][0], DefaultValue=PcdValue) 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(): + if not str_pcd_obj.OverrideValues: + continue str_pcd_obj.MaxDatumSize = self.GetStructurePcdMaxSize(str_pcd_obj) Pcds[str_pcd_obj.TokenCName, str_pcd_obj.TokenSpaceGuidCName] = str_pcd_obj @@ -972,31 +1090,17 @@ class DscBuildData(PlatformBuildClassObject): # PCD settings for certain ARCH # - SkuObj = SkuClass(self.SkuIdentifier, 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: - 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)) + for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4,Dummy5 in RecordList: + if SkuName in (self.SkuIdMgr.SystemSkuId, 'DEFAULT', 'COMMON'): + if "." not in TokenSpaceGuid: + PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, Dummy4)) 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 +1123,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 +1142,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()] @@ -1100,120 +1224,130 @@ class DscBuildData(PlatformBuildClassObject): return Result def GenerateInitializeFunc(self, SkuName, DefaultStoreName, Pcd, InitByteValue, CApp): - OverrideValues = None + OverrideValues = {DefaultStoreName:""} 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) + 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 + ' UINT8 *Value;\n' + CApp = CApp + ' UINT32 OriginalSize;\n' + CApp = CApp + ' VOID *OriginalPcd;\n' + CApp = CApp + ' %s *Pcd;\n' % (Pcd.DatumType) + CApp = CApp + '\n' + Pcd.DefaultValue = Pcd.DefaultValue.strip() + if Pcd.DefaultValue.startswith('L"') and Pcd.DefaultValue.endswith('"'): + PcdDefaultValue = "{" + ",".join(self.__UNICODE2OCTList(Pcd.DefaultValue)) + "}" + elif Pcd.DefaultValue.startswith('"') and Pcd.DefaultValue.endswith('"'): + PcdDefaultValue = "{" + ",".join(self.__STRING2OCTList(Pcd.DefaultValue)) + "}" + else: + PcdDefaultValue = Pcd.DefaultValue + InitByteValue += '%s.%s.%s.%s|%s|%s\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType, PcdDefaultValue) - # - # Get current PCD value and size - # - CApp = CApp + ' OriginalPcd = PcdGetPtr (%s, %s, %s, %s, &OriginalSize);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName) + # + # 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]: - 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(".")) - else: - NewFieldName = '' - 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);\n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1) + # + # 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.get(DefaultStoreName)]: + 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));\n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip(".")); + else: + NewFieldName = '' + 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);\n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1) - # - # 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' + # + # 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' - CApp = CApp + ' free (OriginalPcd);\n' + # + # Copy current PCD value into allocated buffer. + # + CApp = CApp + ' memcpy (Pcd, OriginalPcd, OriginalSize);\n' - # - # Assign field values in PCD - # - for FieldList in [Pcd.DefaultValues, Pcd.DefaultFromDSC, OverrideValues]: - if not FieldList: - continue - if Pcd.DefaultFromDSC and FieldList == Pcd.DefaultFromDSC: - IsArray = self.IsFieldValueAnArray(FieldList) - Value, ValueSize = ParseFieldValue (FieldList) - if isinstance(Value, str): - CApp = CApp + ' Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DefaultFromDSC) - 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) - continue + # + # Assign field values in PCD + # + for FieldList in [Pcd.DefaultValues, Pcd.DefaultFromDSC,OverrideValues.get(DefaultStoreName)]: + if not FieldList: + continue + if Pcd.DefaultFromDSC and FieldList == Pcd.DefaultFromDSC: + IsArray = self.IsFieldValueAnArray(FieldList) + Value, ValueSize = ParseFieldValue (FieldList) + if isinstance(Value, str): + CApp = CApp + ' Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DefaultFromDSC) + 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) + continue - for FieldName in FieldList: - IsArray = self.IsFieldValueAnArray(FieldList[FieldName][0]) - Value, ValueSize = ParseFieldValue (FieldList[FieldName][0]) - 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[0], 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]) + for FieldName in FieldList: + IsArray = self.IsFieldValueAnArray(FieldList[FieldName][0]) + try: + Value, ValueSize = ParseFieldValue (FieldList[FieldName][0]) + except Exception: + print FieldList[FieldName][0] + 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[0], Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize) else: - CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) + 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]) - # - # Set new PCD value and size - # - CApp = CApp + ' PcdSetPtr (%s, %s, %s, %s, Size, (UINT8 *)Pcd);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName) + # + # 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' + # + # Free PCD + # + CApp = CApp + ' free (Pcd);\n' + CApp = CApp + '}\n' + CApp = CApp + '\n' return InitByteValue, CApp def GenerateByteArrayValue (self, StructuredPcds): @@ -1238,7 +1372,7 @@ class DscBuildData(PlatformBuildClassObject): for PcdName in StructuredPcds: Pcd = StructuredPcds[PcdName] if not Pcd.SkuOverrideValues: - InitByteValue, CApp = self.GenerateInitializeFunc('DEFAULT', 'STANDARD', Pcd, InitByteValue, CApp) + InitByteValue, CApp = self.GenerateInitializeFunc(self.SkuIdMgr.SystemSkuId, 'STANDARD', Pcd, InitByteValue, CApp) else: for SkuName in Pcd.SkuOverrideValues: for DefaultStoreName in Pcd.DefaultStoreName: @@ -1252,10 +1386,10 @@ class DscBuildData(PlatformBuildClassObject): 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) + 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 DefaultStoreName in Pcd.SkuOverrideValues[SkuName]: CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName) CApp = CApp + '}\n' @@ -1357,7 +1491,7 @@ 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 ## Retrieve dynamic PCD settings @@ -1368,7 +1502,6 @@ class DscBuildData(PlatformBuildClassObject): # def _GetDynamicPcd(self, Type): - SkuObj = SkuClass(self.SkuIdentifier, self.SkuIds) Pcds = sdict() # @@ -1379,13 +1512,12 @@ 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: if SkuName not in AvailableSkuIdSet: - EdkLogger.error('Build', OPTION_VALUE_INVALID, "The SKUID name %s is not supported by the platform." % SkuName) + continue if "." not in TokenSpaceGuid: PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy4)) PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting @@ -1398,7 +1530,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 @@ -1437,9 +1569,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'] + if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE: + if 'DEFAULT' in pcd.SkuInfoList.keys() and self.SkuIdMgr.SystemSkuId not in pcd.SkuInfoList.keys(): + pcd.SkuInfoList[self.SkuIdMgr.SystemSkuId] = pcd.SkuInfoList['DEFAULT'] del(pcd.SkuInfoList['DEFAULT']) return Pcds @@ -1455,6 +1587,40 @@ class DscBuildData(PlatformBuildClassObject): return True else: return False + def CompletePcdValues(self,PcdSet): + Pcds = {} + DefaultStoreObj = DefaultStore(self._GetDefaultStores()) + SkuIds = set([skuid for pcdobj in PcdSet.values() for skuid in pcdobj.SkuInfoList.keys()]) + 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)] + if PcdObj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT], + self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], + self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD], + self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_DEFAULT], + self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII], + self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]: + Pcds[PcdCName, TokenSpaceGuid]= PcdObj + continue + PcdType = PcdObj.Type + if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]: + for skuid in PcdObj.SkuInfoList: + skuobj = PcdObj.SkuInfoList[skuid] + mindefaultstorename = DefaultStoreObj.GetMin(set([defaultstorename for defaultstorename in skuobj.DefaultStoreDict])) + for defaultstorename in DefaultStores: + if defaultstorename not in skuobj.DefaultStoreDict: + skuobj.DefaultStoreDict[defaultstorename] = skuobj.DefaultStoreDict[mindefaultstorename] + skuobj.HiiDefaultValue = skuobj.DefaultStoreDict[mindefaultstorename] + for skuid in SkuIds: + if skuid not in PcdObj.SkuInfoList: + nextskuid = self.SkuIdMgr.GetNextSkuId(skuid) + while nextskuid not in PcdObj.SkuInfoList: + nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid) + PcdObj.SkuInfoList[skuid] = PcdObj.SkuInfoList[nextskuid] + 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 +1629,6 @@ class DscBuildData(PlatformBuildClassObject): # def _GetDynamicHiiPcd(self, Type): - SkuObj = SkuClass(self.SkuIdentifier, self.SkuIds) VariableAttrs = {} Pcds = sdict() @@ -1471,25 +1636,26 @@ 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) - 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: + 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) + continue if "." not in TokenSpaceGuid: - PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, Dummy4)) - PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting + PcdSet.add((PcdCName, TokenSpaceGuid, SkuName,DefaultStore, Dummy4)) + 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 +1692,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, @@ -1566,9 +1737,9 @@ 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'] + if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE: + if 'DEFAULT' in pcd.SkuInfoList.keys() and self.SkuIdMgr.SystemSkuId not in pcd.SkuInfoList.keys(): + pcd.SkuInfoList[self.SkuIdMgr.SystemSkuId] = pcd.SkuInfoList['DEFAULT'] del(pcd.SkuInfoList['DEFAULT']) if pcd.MaxDatumSize.strip(): @@ -1598,7 +1769,6 @@ class DscBuildData(PlatformBuildClassObject): # def _GetDynamicVpdPcd(self, Type): - SkuObj = SkuClass(self.SkuIdentifier, self.SkuIds) Pcds = sdict() # @@ -1610,12 +1780,11 @@ 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: if SkuName not in AvailableSkuIdSet: - EdkLogger.error('Build', OPTION_VALUE_INVALID, "The SKUID name %s is not supported by the platform." % SkuName) + continue if "." not in TokenSpaceGuid: PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy4)) PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting @@ -1632,7 +1801,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 @@ -1671,9 +1840,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'] + if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE: + if 'DEFAULT' in pcd.SkuInfoList.keys() and self.SkuIdMgr.SystemSkuId not in pcd.SkuInfoList.keys(): + pcd.SkuInfoList[self.SkuIdMgr.SystemSkuId] = pcd.SkuInfoList['DEFAULT'] del(pcd.SkuInfoList['DEFAULT']) return Pcds diff --git a/BaseTools/Source/Python/Workspace/MetaFileParser.py b/BaseTools/Source/Python/Workspace/MetaFileParser.py index 6a30d45b3d..13a08c8846 100644 --- a/BaseTools/Source/Python/Workspace/MetaFileParser.py +++ b/BaseTools/Source/Python/Workspace/MetaFileParser.py @@ -296,7 +296,7 @@ class MetaFileParser(object): for Item in GetSplitValueList(self._CurrentLine[1:-1], TAB_COMMA_SPLIT): if Item == '': continue - ItemList = GetSplitValueList(Item, TAB_SPLIT,2) + ItemList = GetSplitValueList(Item, TAB_SPLIT,3) # different section should not mix in one section if self._SectionName != '' and self._SectionName != ItemList[0].upper(): EdkLogger.error('Parser', FORMAT_INVALID, "Different section names in the same section", @@ -329,7 +329,11 @@ class MetaFileParser(object): S2 = ItemList[2].upper() else: S2 = 'COMMON' - self._Scope.append([S1, S2]) + if len(ItemList) > 3: + S3 = ItemList[3] + else: + S3 = "COMMON" + self._Scope.append([S1, S2, S3]) # 'COMMON' must not be used with specific ARCHs at the same section if 'COMMON' in ArchList and len(ArchList) > 1: @@ -410,7 +414,7 @@ class MetaFileParser(object): ## Construct section Macro dict def _ConstructSectionMacroDict(self, Name, Value): - ScopeKey = [(Scope[0], Scope[1]) for Scope in self._Scope] + ScopeKey = [(Scope[0], Scope[1],Scope[2]) for Scope in self._Scope] ScopeKey = tuple(ScopeKey) SectionDictKey = self._SectionType, ScopeKey # @@ -442,20 +446,20 @@ class MetaFileParser(object): continue for ActiveScope in self._Scope: - Scope0, Scope1 = ActiveScope[0], ActiveScope[1] - if(Scope0, Scope1) not in Scope: + Scope0, Scope1 ,Scope2= ActiveScope[0], ActiveScope[1],ActiveScope[2] + if(Scope0, Scope1,Scope2) not in Scope: break else: SpeSpeMacroDict.update(self._SectionsMacroDict[(SectionType, Scope)]) for ActiveScope in self._Scope: - Scope0, Scope1 = ActiveScope[0], ActiveScope[1] - if(Scope0, Scope1) not in Scope and (Scope0, "COMMON") not in Scope and ("COMMON", Scope1) not in Scope: + Scope0, Scope1,Scope2 = ActiveScope[0], ActiveScope[1],ActiveScope[2] + if(Scope0, Scope1,Scope2) not in Scope and (Scope0, "COMMON","COMMON") not in Scope and ("COMMON", Scope1,"COMMON") not in Scope: break else: ComSpeMacroDict.update(self._SectionsMacroDict[(SectionType, Scope)]) - if ("COMMON", "COMMON") in Scope: + if ("COMMON", "COMMON","COMMON") in Scope: ComComMacroDict.update(self._SectionsMacroDict[(SectionType, Scope)]) Macros.update(ComComMacroDict) @@ -627,7 +631,7 @@ class InfParser(MetaFileParser): # Model, Value1, Value2, Value3, Arch, Platform, BelongsToItem=-1, # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1 # - for Arch, Platform in self._Scope: + for Arch, Platform,_ in self._Scope: LastItem = self._Store(self._SectionType, self._ValueList[0], self._ValueList[1], @@ -804,6 +808,7 @@ class DscParser(MetaFileParser): # DSC file supported data types (one type per section) DataType = { TAB_SKUIDS.upper() : MODEL_EFI_SKU_ID, + TAB_DEFAULT_STORES.upper() : MODEL_EFI_DEFAULT_STORES, TAB_LIBRARIES.upper() : MODEL_EFI_LIBRARY_INSTANCE, TAB_LIBRARY_CLASSES.upper() : MODEL_EFI_LIBRARY_CLASS, TAB_BUILD_OPTIONS.upper() : MODEL_META_DATA_BUILD_OPTION, @@ -952,7 +957,7 @@ class DscParser(MetaFileParser): # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1, # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1 # - for Arch, ModuleType in self._Scope: + for Arch, ModuleType, DefaultStore in self._Scope: Owner = self._Owner[-1] if self._SubsectionType != MODEL_UNKNOWN: Owner = OwnerId[Arch] @@ -963,6 +968,7 @@ class DscParser(MetaFileParser): self._ValueList[2], Arch, ModuleType, + DefaultStore, Owner, self._From, self._LineIndex + 1, @@ -1015,7 +1021,7 @@ class DscParser(MetaFileParser): ExtraData=self._CurrentLine) ItemType = self.DataType[DirectiveName] - Scope = [['COMMON', 'COMMON']] + Scope = [['COMMON', 'COMMON','COMMON']] if ItemType == MODEL_META_DATA_INCLUDE: Scope = self._Scope if ItemType == MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF: @@ -1045,7 +1051,7 @@ class DscParser(MetaFileParser): # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1, # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1 # - for Arch, ModuleType in Scope: + for Arch, ModuleType, DefaultStore in Scope: self._LastItem = self._Store( ItemType, self._ValueList[0], @@ -1053,6 +1059,7 @@ class DscParser(MetaFileParser): self._ValueList[2], Arch, ModuleType, + DefaultStore, self._Owner[-1], self._From, self._LineIndex + 1, @@ -1088,6 +1095,13 @@ class DscParser(MetaFileParser): @ParseMacro def _SkuIdParser(self): + TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT) + if len(TokenList) not in (2,3): + EdkLogger.error('Parser', FORMAT_INVALID, "Correct format is '|[|]'", + ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1) + self._ValueList[0:len(TokenList)] = TokenList + @ParseMacro + def _DefaultStoresParser(self): TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT) if len(TokenList) != 2: EdkLogger.error('Parser', FORMAT_INVALID, "Correct format is '|'", @@ -1243,6 +1257,7 @@ class DscParser(MetaFileParser): MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF : self.__ProcessDirective, MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF : self.__ProcessDirective, MODEL_EFI_SKU_ID : self.__ProcessSkuId, + MODEL_EFI_DEFAULT_STORES : self.__ProcessDefaultStores, MODEL_EFI_LIBRARY_INSTANCE : self.__ProcessLibraryInstance, MODEL_EFI_LIBRARY_CLASS : self.__ProcessLibraryClass, MODEL_PCD_FIXED_AT_BUILD : self.__ProcessPcd, @@ -1276,7 +1291,7 @@ class DscParser(MetaFileParser): self._ContentIndex = 0 self._InSubsection = False while self._ContentIndex < len(self._Content) : - Id, self._ItemType, V1, V2, V3, S1, S2, Owner, self._From, \ + Id, self._ItemType, V1, V2, V3, S1, S2, S3,Owner, self._From, \ LineStart, ColStart, LineEnd, ColEnd, Enabled = self._Content[self._ContentIndex] if self._From < 0: @@ -1284,7 +1299,7 @@ class DscParser(MetaFileParser): self._ContentIndex += 1 - self._Scope = [[S1, S2]] + self._Scope = [[S1, S2, S3]] # # For !include directive, handle it specially, # merge arch and module type in case of duplicate items @@ -1293,9 +1308,9 @@ class DscParser(MetaFileParser): if self._ContentIndex >= len(self._Content): break Record = self._Content[self._ContentIndex] - if LineStart == Record[9] and LineEnd == Record[11]: - if [Record[5], Record[6]] not in self._Scope: - self._Scope.append([Record[5], Record[6]]) + if LineStart == Record[10] and LineEnd == Record[12]: + if [Record[5], Record[6],Record[7]] not in self._Scope: + self._Scope.append([Record[5], Record[6],Record[7]]) self._ContentIndex += 1 else: break @@ -1348,6 +1363,7 @@ class DscParser(MetaFileParser): self._ValueList[2], S1, S2, + S3, NewOwner, self._From, self._LineIndex + 1, @@ -1383,7 +1399,7 @@ class DscParser(MetaFileParser): MODEL_PCD_DYNAMIC_VPD, MODEL_PCD_DYNAMIC_EX_DEFAULT, MODEL_PCD_DYNAMIC_EX_HII, MODEL_PCD_DYNAMIC_EX_VPD): Records = self._RawTable.Query(PcdType, BelongsToItem= -1.0) - for TokenSpaceGuid, PcdName, Value, Dummy2, Dummy3, ID, Line in Records: + for TokenSpaceGuid, PcdName, Value, Dummy2, Dummy3, Dummy4,ID, Line in Records: Name = TokenSpaceGuid + '.' + PcdName if Name not in GlobalData.gPlatformOtherPcds: PcdLine = Line @@ -1549,6 +1565,9 @@ class DscParser(MetaFileParser): def __ProcessSkuId(self): self._ValueList = [ReplaceMacro(Value, self._Macros, RaiseError=True) for Value in self._ValueList] + def __ProcessDefaultStores(self): + self._ValueList = [ReplaceMacro(Value, self._Macros, RaiseError=True) + for Value in self._ValueList] def __ProcessLibraryInstance(self): self._ValueList = [ReplaceMacro(Value, self._Macros) for Value in self._ValueList] @@ -1598,6 +1617,7 @@ class DscParser(MetaFileParser): _SectionParser = { MODEL_META_DATA_HEADER : _DefineParser, MODEL_EFI_SKU_ID : _SkuIdParser, + MODEL_EFI_DEFAULT_STORES : _DefaultStoresParser, MODEL_EFI_LIBRARY_INSTANCE : _LibraryInstanceParser, MODEL_EFI_LIBRARY_CLASS : _LibraryClassParser, MODEL_PCD_FIXED_AT_BUILD : _PcdParser, diff --git a/BaseTools/Source/Python/Workspace/MetaFileTable.py b/BaseTools/Source/Python/Workspace/MetaFileTable.py index aedcacada1..d8549c9d66 100644 --- a/BaseTools/Source/Python/Workspace/MetaFileTable.py +++ b/BaseTools/Source/Python/Workspace/MetaFileTable.py @@ -23,6 +23,7 @@ from MetaDataTable import Table, TableFile from MetaDataTable import ConvertToSqlString from CommonDataClass.DataClass import MODEL_FILE_DSC, MODEL_FILE_DEC, MODEL_FILE_INF, \ MODEL_FILE_OTHERS +from Common.DataType import * class MetaFileTable(Table): # TRICK: use file ID as the part before '.' @@ -271,6 +272,7 @@ class PlatformTable(MetaFileTable): Value3 TEXT, Scope1 TEXT, Scope2 TEXT, + Scope3 TEXT, BelongsToItem REAL NOT NULL, FromItem REAL NOT NULL, StartLine INTEGER NOT NULL, @@ -280,7 +282,7 @@ class PlatformTable(MetaFileTable): Enabled INTEGER DEFAULT 0 ''' # used as table end flag, in case the changes to database is not committed to db file - _DUMMY_ = "-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1, -1" + _DUMMY_ = "-1, -1, '====', '====', '====', '====', '====','====', -1, -1, -1, -1, -1, -1, -1" ## Constructor def __init__(self, Cursor, MetaFile, Temporary): @@ -304,9 +306,9 @@ class PlatformTable(MetaFileTable): # @param EndColumn: EndColumn of a Dsc item # @param Enabled: If this item enabled # - def Insert(self, Model, Value1, Value2, Value3, Scope1='COMMON', Scope2='COMMON', BelongsToItem=-1, + def Insert(self, Model, Value1, Value2, Value3, Scope1='COMMON', Scope2='COMMON', Scope3=TAB_DEFAULT_STORES_DEFAULT,BelongsToItem=-1, FromItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=1): - (Value1, Value2, Value3, Scope1, Scope2) = ConvertToSqlString((Value1, Value2, Value3, Scope1, Scope2)) + (Value1, Value2, Value3, Scope1, Scope2,Scope3) = ConvertToSqlString((Value1, Value2, Value3, Scope1, Scope2,Scope3)) return Table.Insert( self, Model, @@ -315,6 +317,7 @@ class PlatformTable(MetaFileTable): Value3, Scope1, Scope2, + Scope3, BelongsToItem, FromItem, StartLine, @@ -336,7 +339,7 @@ class PlatformTable(MetaFileTable): # def Query(self, Model, Scope1=None, Scope2=None, BelongsToItem=None, FromItem=None): ConditionString = "Model=%s AND Enabled>0" % Model - ValueString = "Value1,Value2,Value3,Scope1,Scope2,ID,StartLine" + ValueString = "Value1,Value2,Value3,Scope1,Scope2,Scope3,ID,StartLine" if Scope1 != None and Scope1 != 'COMMON': ConditionString += " AND (Scope1='%s' OR Scope1='COMMON')" % Scope1 -- 2.39.2