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 <bob.c.feng@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
This commit is contained in:
bob.c.feng@intel.com 2018-09-25 10:55:30 +08:00 committed by Liming Gao
parent 57ee97c01c
commit 6a147d6dae
4 changed files with 60 additions and 18 deletions

View File

@ -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" \

View File

@ -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

View File

@ -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

View File

@ -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