BaseTools: Optimize VPD PCD value for the different SKUs

If VPD PCD value is same in the different SKUs, the different SKUs will
save the same offset for this PCD in VPD region. That means there is only
one PCD value copy in VPD region to save VPD space.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Feng Bob C <bob.c.feng@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
This commit is contained in:
Liming Gao
2017-12-22 20:19:20 +08:00
parent 7e6e459a3d
commit 626bece451
2 changed files with 50 additions and 27 deletions

View File

@ -1637,15 +1637,8 @@ class PlatformAutoGen(AutoGen):
if Pcd.DatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, TAB_VOID, "BOOLEAN"]: if Pcd.DatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, TAB_VOID, "BOOLEAN"]:
Pcd.DatumType = "VOID*" Pcd.DatumType = "VOID*"
PcdValue = Sku.DefaultValue
if Pcd.DatumType == 'VOID*' and PcdValue.startswith("L"):
# if found PCD which datum value is unicode string the insert to left size of UnicodeIndex # if found PCD which datum value is unicode string the insert to left size of UnicodeIndex
UnicodePcdArray.append(Pcd)
elif len(Sku.VariableName) > 0:
# if found HII type PCD then insert to right of UnicodeIndex # if found HII type PCD then insert to right of UnicodeIndex
HiiPcdArray.append(Pcd)
else:
OtherPcdArray.append(Pcd)
if Pcd.Type in [TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_EX_VPD]: if Pcd.Type in [TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_EX_VPD]:
VpdPcdDict[(Pcd.TokenCName, Pcd.TokenSpaceGuidCName)] = Pcd VpdPcdDict[(Pcd.TokenCName, Pcd.TokenSpaceGuidCName)] = Pcd
@ -1653,25 +1646,25 @@ class PlatformAutoGen(AutoGen):
PcdNvStoreDfBuffer = VpdPcdDict.get(("PcdNvStoreDefaultValueBuffer","gEfiMdeModulePkgTokenSpaceGuid")) PcdNvStoreDfBuffer = VpdPcdDict.get(("PcdNvStoreDefaultValueBuffer","gEfiMdeModulePkgTokenSpaceGuid"))
if PcdNvStoreDfBuffer: if PcdNvStoreDfBuffer:
self.VariableInfo = self.CollectVariables(self._DynamicPcdList) self.VariableInfo = self.CollectVariables(self._DynamicPcdList)
default_skuobj = PcdNvStoreDfBuffer.SkuInfoList.get("DEFAULT")
vardump = self.VariableInfo.dump() vardump = self.VariableInfo.dump()
if vardump and default_skuobj: if vardump:
default_skuobj.DefaultValue = vardump
PcdNvStoreDfBuffer.DefaultValue = vardump PcdNvStoreDfBuffer.DefaultValue = vardump
PcdNvStoreDfBuffer.SkuInfoList.clear() for skuname in PcdNvStoreDfBuffer.SkuInfoList:
PcdNvStoreDfBuffer.SkuInfoList['DEFAULT'] = default_skuobj PcdNvStoreDfBuffer.SkuInfoList[skuname].DefaultValue = vardump
PcdNvStoreDfBuffer.MaxDatumSize = str(len(default_skuobj.DefaultValue.split(","))) PcdNvStoreDfBuffer.MaxDatumSize = str(len(vardump.split(",")))
PlatformPcds = self._PlatformPcds.keys() PlatformPcds = self._PlatformPcds.keys()
PlatformPcds.sort() PlatformPcds.sort()
# #
# Add VPD type PCD into VpdFile and determine whether the VPD PCD need to be fixed up. # Add VPD type PCD into VpdFile and determine whether the VPD PCD need to be fixed up.
# #
VpdSkuMap = {}
for PcdKey in PlatformPcds: for PcdKey in PlatformPcds:
Pcd = self._PlatformPcds[PcdKey] Pcd = self._PlatformPcds[PcdKey]
if Pcd.Type in [TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_EX_VPD] and \ if Pcd.Type in [TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_EX_VPD] and \
PcdKey in VpdPcdDict: PcdKey in VpdPcdDict:
Pcd = VpdPcdDict[PcdKey] Pcd = VpdPcdDict[PcdKey]
SkuValueMap = {}
for (SkuName,Sku) in Pcd.SkuInfoList.items(): for (SkuName,Sku) in Pcd.SkuInfoList.items():
Sku.VpdOffset = Sku.VpdOffset.strip() Sku.VpdOffset = Sku.VpdOffset.strip()
PcdValue = Sku.DefaultValue PcdValue = Sku.DefaultValue
@ -1696,7 +1689,10 @@ class PlatformAutoGen(AutoGen):
EdkLogger.warn("build", "The offset value of PCD %s.%s is not 8-byte aligned!" %(Pcd.TokenSpaceGuidCName, Pcd.TokenCName), File=self.MetaFile) EdkLogger.warn("build", "The offset value of PCD %s.%s is not 8-byte aligned!" %(Pcd.TokenSpaceGuidCName, Pcd.TokenCName), File=self.MetaFile)
else: else:
EdkLogger.error("build", FORMAT_INVALID, 'The offset value of PCD %s.%s should be %s-byte aligned.' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Alignment)) EdkLogger.error("build", FORMAT_INVALID, 'The offset value of PCD %s.%s should be %s-byte aligned.' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Alignment))
VpdFile.Add(Pcd, Sku.VpdOffset) if PcdValue not in SkuValueMap:
SkuValueMap[PcdValue] = []
VpdFile.Add(Pcd, Sku.VpdOffset)
SkuValueMap[PcdValue].append(Sku)
# if the offset of a VPD is *, then it need to be fixed up by third party tool. # if the offset of a VPD is *, then it need to be fixed up by third party tool.
if not NeedProcessVpdMapFile and Sku.VpdOffset == "*": if not NeedProcessVpdMapFile and Sku.VpdOffset == "*":
NeedProcessVpdMapFile = True NeedProcessVpdMapFile = True
@ -1704,7 +1700,7 @@ class PlatformAutoGen(AutoGen):
EdkLogger.error("Build", FILE_NOT_FOUND, \ EdkLogger.error("Build", FILE_NOT_FOUND, \
"Fail to find third-party BPDG tool to process VPD PCDs. BPDG Guid tool need to be defined in tools_def.txt and VPD_TOOL_GUID need to be provided in DSC file.") "Fail to find third-party BPDG tool to process VPD PCDs. BPDG Guid tool need to be defined in tools_def.txt and VPD_TOOL_GUID need to be provided in DSC file.")
VpdSkuMap[PcdKey] = SkuValueMap
# #
# Fix the PCDs define in VPD PCD section that never referenced by module. # Fix the PCDs define in VPD PCD section that never referenced by module.
# An example is PCD for signature usage. # An example is PCD for signature usage.
@ -1723,6 +1719,7 @@ class PlatformAutoGen(AutoGen):
# Not found, it should be signature # Not found, it should be signature
if not FoundFlag : if not FoundFlag :
# just pick the a value to determine whether is unicode string type # just pick the a value to determine whether is unicode string type
SkuValueMap = {}
for (SkuName,Sku) in DscPcdEntry.SkuInfoList.items(): for (SkuName,Sku) in DscPcdEntry.SkuInfoList.items():
Sku.VpdOffset = Sku.VpdOffset.strip() Sku.VpdOffset = Sku.VpdOffset.strip()
@ -1748,7 +1745,6 @@ class PlatformAutoGen(AutoGen):
if DscPcdEntry not in self._DynamicPcdList: if DscPcdEntry not in self._DynamicPcdList:
self._DynamicPcdList.append(DscPcdEntry) self._DynamicPcdList.append(DscPcdEntry)
# Sku = DscPcdEntry.SkuInfoList[DscPcdEntry.SkuInfoList.keys()[0]]
Sku.VpdOffset = Sku.VpdOffset.strip() Sku.VpdOffset = Sku.VpdOffset.strip()
PcdValue = Sku.DefaultValue PcdValue = Sku.DefaultValue
if PcdValue == "": if PcdValue == "":
@ -1772,7 +1768,10 @@ class PlatformAutoGen(AutoGen):
EdkLogger.warn("build", "The offset value of PCD %s.%s is not 8-byte aligned!" %(DscPcdEntry.TokenSpaceGuidCName, DscPcdEntry.TokenCName), File=self.MetaFile) EdkLogger.warn("build", "The offset value of PCD %s.%s is not 8-byte aligned!" %(DscPcdEntry.TokenSpaceGuidCName, DscPcdEntry.TokenCName), File=self.MetaFile)
else: else:
EdkLogger.error("build", FORMAT_INVALID, 'The offset value of PCD %s.%s should be %s-byte aligned.' % (DscPcdEntry.TokenSpaceGuidCName, DscPcdEntry.TokenCName, Alignment)) EdkLogger.error("build", FORMAT_INVALID, 'The offset value of PCD %s.%s should be %s-byte aligned.' % (DscPcdEntry.TokenSpaceGuidCName, DscPcdEntry.TokenCName, Alignment))
VpdFile.Add(DscPcdEntry, Sku.VpdOffset) if PcdValue not in SkuValueMap:
SkuValueMap[PcdValue] = []
VpdFile.Add(DscPcdEntry, Sku.VpdOffset)
SkuValueMap[PcdValue].append(Sku)
if not NeedProcessVpdMapFile and Sku.VpdOffset == "*": if not NeedProcessVpdMapFile and Sku.VpdOffset == "*":
NeedProcessVpdMapFile = True NeedProcessVpdMapFile = True
if DscPcdEntry.DatumType == 'VOID*' and PcdValue.startswith("L"): if DscPcdEntry.DatumType == 'VOID*' and PcdValue.startswith("L"):
@ -1783,9 +1782,7 @@ class PlatformAutoGen(AutoGen):
OtherPcdArray.append(DscPcdEntry) OtherPcdArray.append(DscPcdEntry)
# if the offset of a VPD is *, then it need to be fixed up by third party tool. # if the offset of a VPD is *, then it need to be fixed up by third party tool.
VpdSkuMap[DscPcd] = SkuValueMap
if (self.Platform.FlashDefinition == None or self.Platform.FlashDefinition == '') and \ if (self.Platform.FlashDefinition == None or self.Platform.FlashDefinition == '') and \
VpdFile.GetCount() != 0: VpdFile.GetCount() != 0:
EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE,
@ -1804,17 +1801,37 @@ class PlatformAutoGen(AutoGen):
VpdFile.Read(VpdMapFilePath) VpdFile.Read(VpdMapFilePath)
# Fixup "*" offset # Fixup "*" offset
for Pcd in self._DynamicPcdList: for pcd in VpdSkuMap:
vpdinfo = VpdFile.GetVpdInfo(pcd)
if vpdinfo is None:
# just pick the a value to determine whether is unicode string type # just pick the a value to determine whether is unicode string type
i = 0 continue
for (SkuName,Sku) in Pcd.SkuInfoList.items(): for pcdvalue in VpdSkuMap[pcd]:
if Sku.VpdOffset == "*": for sku in VpdSkuMap[pcd][pcdvalue]:
Sku.VpdOffset = VpdFile.GetOffset(Pcd)[i].strip() for item in vpdinfo:
i += 1 if item[2] == pcdvalue:
sku.VpdOffset = item[1]
else: else:
EdkLogger.error("build", FILE_READ_FAILURE, "Can not find VPD map file %s to fix up VPD offset." % VpdMapFilePath) EdkLogger.error("build", FILE_READ_FAILURE, "Can not find VPD map file %s to fix up VPD offset." % VpdMapFilePath)
# Delete the DynamicPcdList At the last time enter into this function # Delete the DynamicPcdList At the last time enter into this function
for Pcd in self._DynamicPcdList:
# just pick the a value to determine whether is unicode string type
Sku = Pcd.SkuInfoList[Pcd.SkuInfoList.keys()[0]]
Sku.VpdOffset = Sku.VpdOffset.strip()
if Pcd.DatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, TAB_VOID, "BOOLEAN"]:
Pcd.DatumType = "VOID*"
PcdValue = Sku.DefaultValue
if Pcd.DatumType == 'VOID*' and PcdValue.startswith("L"):
# if found PCD which datum value is unicode string the insert to left size of UnicodeIndex
UnicodePcdArray.append(Pcd)
elif len(Sku.VariableName) > 0:
# if found HII type PCD then insert to right of UnicodeIndex
HiiPcdArray.append(Pcd)
else:
OtherPcdArray.append(Pcd)
del self._DynamicPcdList[:] del self._DynamicPcdList[:]
self._DynamicPcdList.extend(UnicodePcdArray) self._DynamicPcdList.extend(UnicodePcdArray)
self._DynamicPcdList.extend(HiiPcdArray) self._DynamicPcdList.extend(HiiPcdArray)

View File

@ -79,6 +79,7 @@ class VpdInfoFile:
# @see BuildClassObject.PcdClassObject # @see BuildClassObject.PcdClassObject
# Value : offset in different SKU such as [sku1_offset, sku2_offset] # Value : offset in different SKU such as [sku1_offset, sku2_offset]
self._VpdArray = {} self._VpdArray = {}
self._VpdInfo = {}
## Add a VPD PCD collected from platform's autogen when building. ## Add a VPD PCD collected from platform's autogen when building.
# #
@ -179,6 +180,9 @@ class VpdInfoFile:
Found = False Found = False
if (TokenSpaceName, PcdTokenName) not in self._VpdInfo:
self._VpdInfo[(TokenSpaceName, PcdTokenName)] = []
self._VpdInfo[(TokenSpaceName, PcdTokenName)].append((SkuId,Offset, Value))
for VpdObject in self._VpdArray.keys(): for VpdObject in self._VpdArray.keys():
VpdObjectTokenCName = VpdObject.TokenCName VpdObjectTokenCName = VpdObject.TokenCName
for PcdItem in GlobalData.MixedPcd: for PcdItem in GlobalData.MixedPcd:
@ -217,6 +221,8 @@ class VpdInfoFile:
return None return None
return self._VpdArray[vpd] return self._VpdArray[vpd]
def GetVpdInfo(self,(PcdTokenName,TokenSpaceName)):
return self._VpdInfo.get((TokenSpaceName, PcdTokenName))
## Call external BPDG tool to process VPD file ## Call external BPDG tool to process VPD file
# #