From 6a147d6dae733f3a1d5ddf9af9adce5fb8504a53 Mon Sep 17 00:00:00 2001 From: "bob.c.feng@intel.com" Date: Tue, 25 Sep 2018 10:55:30 +0800 Subject: BaseTool: Support different PCDs that refers to the same EFI variable. If Structure PCD and Normal Pcd refer to the same EFI variable, do EFI variable merge, otherwise, do EFI variable combination. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Bob Feng Cc: Liming Gao Reviewed-by: Liming Gao --- BaseTools/Source/Python/AutoGen/AutoGen.py | 3 +- BaseTools/Source/Python/AutoGen/GenVar.py | 71 ++++++++++++++++------ .../Source/Python/Workspace/BuildClassObject.py | 2 + BaseTools/Source/Python/Workspace/DscBuildData.py | 2 + 4 files changed, 60 insertions(+), 18 deletions(-) diff --git a/BaseTools/Source/Python/AutoGen/AutoGen.py b/BaseTools/Source/Python/AutoGen/AutoGen.py index 38f1260..7c0bb47 100644 --- a/BaseTools/Source/Python/AutoGen/AutoGen.py +++ b/BaseTools/Source/Python/AutoGen/AutoGen.py @@ -1168,7 +1168,7 @@ class PlatformAutoGen(AutoGen): VariableGuidStructure = Sku.VariableGuidValue VariableGuid = GuidStructureStringToGuidString(VariableGuidStructure) for StorageName in Sku.DefaultStoreDict: - VariableInfo.append_variable(var_info(Index, pcdname, StorageName, SkuName, StringToArray(Sku.VariableName), VariableGuid, Sku.VariableOffset, Sku.VariableAttribute, Sku.HiiDefaultValue, Sku.DefaultStoreDict[StorageName], Pcd.DatumType)) + VariableInfo.append_variable(var_info(Index, pcdname, StorageName, SkuName, StringToArray(Sku.VariableName), VariableGuid, Sku.VariableOffset, Sku.VariableAttribute, Sku.HiiDefaultValue, Sku.DefaultStoreDict[StorageName], Pcd.DatumType, Pcd.CustomAttribute['DscPosition'], Pcd.CustomAttribute.get('IsStru',False))) Index += 1 return VariableInfo @@ -2057,6 +2057,7 @@ class PlatformAutoGen(AutoGen): ToPcd.validateranges = FromPcd.validateranges ToPcd.validlists = FromPcd.validlists ToPcd.expressions = FromPcd.expressions + ToPcd.CustomAttribute = FromPcd.CustomAttribute if FromPcd is not None and ToPcd.DatumType == TAB_VOID and not ToPcd.MaxDatumSize: EdkLogger.debug(EdkLogger.DEBUG_9, "No MaxDatumSize specified for PCD %s.%s" \ diff --git a/BaseTools/Source/Python/AutoGen/GenVar.py b/BaseTools/Source/Python/AutoGen/GenVar.py index 75d455b..036f00e 100644 --- a/BaseTools/Source/Python/AutoGen/GenVar.py +++ b/BaseTools/Source/Python/AutoGen/GenVar.py @@ -22,7 +22,7 @@ from Common.Misc import * import collections import Common.DataType as DataType -var_info = collections.namedtuple("uefi_var", "pcdindex,pcdname,defaultstoragename,skuname,var_name, var_guid, var_offset,var_attribute,pcd_default_value, default_value, data_type") +var_info = collections.namedtuple("uefi_var", "pcdindex,pcdname,defaultstoragename,skuname,var_name, var_guid, var_offset,var_attribute,pcd_default_value, default_value, data_type,PcdDscLine,StructurePcd") NvStorageHeaderSize = 28 VariableHeaderSize = 32 @@ -56,6 +56,51 @@ class VariableMgr(object): value_str += ",".join(default_var_bin_strip) value_str += "}" return value_str + def Do_combine(self,sku_var_info_offset_list): + newvalue = {} + for item in sku_var_info_offset_list: + data_type = item.data_type + value_list = item.default_value.strip("{").strip("}").split(",") + if data_type in DataType.TAB_PCD_NUMERIC_TYPES: + data_flag = DataType.PACK_CODE_BY_SIZE[MAX_SIZE_TYPE[data_type]] + data = value_list[0] + value_list = [] + for data_byte in pack(data_flag, int(data, 16) if data.upper().startswith('0X') else int(data)): + value_list.append(hex(unpack("B", data_byte)[0])) + newvalue[int(item.var_offset, 16) if item.var_offset.upper().startswith("0X") else int(item.var_offset)] = value_list + try: + newvaluestr = "{" + ",".join(VariableMgr.assemble_variable(newvalue)) +"}" + except: + EdkLogger.error("build", AUTOGEN_ERROR, "Variable offset conflict in PCDs: %s \n" % (" and ".join(item.pcdname for item in sku_var_info_offset_list))) + return newvaluestr + def Do_Merge(self,sku_var_info_offset_list): + StructrurePcds = sorted([item for item in sku_var_info_offset_list if item.StructurePcd], key = lambda x: x.PcdDscLine, reverse =True ) + Base = StructrurePcds[0] + BaseValue = Base.default_value.strip("{").strip("}").split(",") + Override = [item for item in sku_var_info_offset_list if not item.StructurePcd and item.PcdDscLine > Base.PcdDscLine] + newvalue = {} + for item in Override: + data_type = item.data_type + value_list = item.default_value.strip("{").strip("}").split(",") + if data_type in DataType.TAB_PCD_NUMERIC_TYPES: + data_flag = DataType.PACK_CODE_BY_SIZE[MAX_SIZE_TYPE[data_type]] + data = value_list[0] + value_list = [] + for data_byte in pack(data_flag, int(data, 16) if data.upper().startswith('0X') else int(data)): + value_list.append(hex(unpack("B", data_byte)[0])) + newvalue[int(item.var_offset, 16) if item.var_offset.upper().startswith("0X") else int(item.var_offset)] = (value_list,item.pcdname,item.PcdDscLine) + for offset in newvalue: + value_list,itemPcdname,itemPcdDscLine = newvalue[offset] + if offset > len(BaseValue) or (offset + len(value_list) > len(BaseValue)): + EdkLogger.error("build", AUTOGEN_ERROR, "The EFI Variable referred by PCD %s in line %s exceeds variable size: %s\n" % (itemPcdname,itemPcdDscLine,hex(len(BaseValue)))) + for i in xrange(len(value_list)): + BaseValue[offset + i] = value_list[i] + newvaluestr = "{" + ",".join(BaseValue) +"}" + return newvaluestr + def NeedMerge(self,sku_var_info_offset_list): + if [item for item in sku_var_info_offset_list if item.StructurePcd]: + return True + return False def combine_variable(self): indexedvarinfo = collections.OrderedDict() for item in self.VarInfo: @@ -66,23 +111,15 @@ class VariableMgr(object): sku_var_info_offset_list = indexedvarinfo[key] if len(sku_var_info_offset_list) == 1: continue - newvalue = {} - for item in sku_var_info_offset_list: - data_type = item.data_type - value_list = item.default_value.strip("{").strip("}").split(",") - if data_type in DataType.TAB_PCD_NUMERIC_TYPES: - data_flag = DataType.PACK_CODE_BY_SIZE[MAX_SIZE_TYPE[data_type]] - data = value_list[0] - value_list = [] - for data_byte in pack(data_flag, int(data, 16) if data.upper().startswith('0X') else int(data)): - value_list.append(hex(unpack("B", data_byte)[0])) - newvalue[int(item.var_offset, 16) if item.var_offset.upper().startswith("0X") else int(item.var_offset)] = value_list - try: - newvaluestr = "{" + ",".join(VariableMgr.assemble_variable(newvalue)) +"}" - except: - EdkLogger.error("build", AUTOGEN_ERROR, "Variable offset conflict in PCDs: %s \n" % (" and ".join(item.pcdname for item in sku_var_info_offset_list))) + n = sku_var_info_offset_list[0] - indexedvarinfo[key] = [var_info(n.pcdindex, n.pcdname, n.defaultstoragename, n.skuname, n.var_name, n.var_guid, "0x00", n.var_attribute, newvaluestr, newvaluestr, DataType.TAB_VOID)] + + if self.NeedMerge(sku_var_info_offset_list): + newvaluestr = self.Do_Merge(sku_var_info_offset_list) + else: + newvaluestr = self.Do_combine(sku_var_info_offset_list) + + indexedvarinfo[key] = [var_info(n.pcdindex, n.pcdname, n.defaultstoragename, n.skuname, n.var_name, n.var_guid, "0x00", n.var_attribute, newvaluestr, newvaluestr, DataType.TAB_VOID,n.PcdDscLine,n.StructurePcd)] self.VarInfo = [item[0] for item in indexedvarinfo.values()] @staticmethod diff --git a/BaseTools/Source/Python/Workspace/BuildClassObject.py b/BaseTools/Source/Python/Workspace/BuildClassObject.py index 57ba73c..95edc37 100644 --- a/BaseTools/Source/Python/Workspace/BuildClassObject.py +++ b/BaseTools/Source/Python/Workspace/BuildClassObject.py @@ -70,6 +70,7 @@ class PcdClassObject(object): self.DscDefaultValue = Value self.PcdValueFromComm = "" self.PcdValueFromFdf = "" + self.CustomAttribute = {} self.UserDefinedDefaultStoresFlag = UserDefinedDefaultStoresFlag @staticmethod @@ -224,6 +225,7 @@ class StructurePcd(PcdClassObject): self.DscRawValue = PcdObject.DscRawValue if PcdObject.DscRawValue else self.DscRawValue self.PcdValueFromComm = PcdObject.PcdValueFromComm if PcdObject.PcdValueFromComm else self.PcdValueFromComm self.PcdValueFromFdf = PcdObject.PcdValueFromFdf if PcdObject.PcdValueFromFdf else self.PcdValueFromFdf + self.CustomAttribute = PcdObject.CustomAttribute if PcdObject.CustomAttribute else self.CustomAttribute self.UserDefinedDefaultStoresFlag = PcdObject.UserDefinedDefaultStoresFlag if PcdObject.UserDefinedDefaultStoresFlag else self.UserDefinedDefaultStoresFlag if isinstance(PcdObject, StructurePcd): self.StructuredPcdIncludeFile = PcdObject.StructuredPcdIncludeFile if PcdObject.StructuredPcdIncludeFile else self.StructuredPcdIncludeFile diff --git a/BaseTools/Source/Python/Workspace/DscBuildData.py b/BaseTools/Source/Python/Workspace/DscBuildData.py index ca782ae..39db945 100644 --- a/BaseTools/Source/Python/Workspace/DscBuildData.py +++ b/BaseTools/Source/Python/Workspace/DscBuildData.py @@ -1536,6 +1536,7 @@ class DscBuildData(PlatformBuildClassObject): str_pcd_obj.MaxDatumSize = self.GetStructurePcdMaxSize(str_pcd_obj) Pcds[str_pcd_obj.TokenCName, str_pcd_obj.TokenSpaceGuidCName] = str_pcd_obj + Pcds[str_pcd_obj.TokenCName, str_pcd_obj.TokenSpaceGuidCName].CustomAttribute['IsStru']=True for pcdkey in Pcds: pcd = Pcds[pcdkey] @@ -2680,6 +2681,7 @@ class DscBuildData(PlatformBuildClassObject): PcdClassObj.UserDefinedDefaultStoresFlag = True Pcds[PcdCName, TokenSpaceGuid] = PcdClassObj + Pcds[PcdCName, TokenSpaceGuid].CustomAttribute['DscPosition'] = int(Dummy4) if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue: Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {} Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][DefaultStore] = DefaultValue -- cgit v1.1