From 47854fd598b73267d57594c5bac6a2326332b08c Mon Sep 17 00:00:00 2001 From: Liming Gao Date: Fri, 22 Dec 2017 20:14:29 +0800 Subject: [PATCH] BaseTools: Update NV Default Header format to include the max size Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Bob Feng Reviewed-by: Liming Gao --- BaseTools/Source/Python/AutoGen/AutoGen.py | 110 +++++++++++++----- BaseTools/Source/Python/AutoGen/GenVar.py | 55 ++++++--- .../Source/Python/Workspace/DscBuildData.py | 46 ++------ 3 files changed, 130 insertions(+), 81 deletions(-) diff --git a/BaseTools/Source/Python/AutoGen/AutoGen.py b/BaseTools/Source/Python/AutoGen/AutoGen.py index 5d6cce0dbb..eeeab951d1 100644 --- a/BaseTools/Source/Python/AutoGen/AutoGen.py +++ b/BaseTools/Source/Python/AutoGen/AutoGen.py @@ -1262,6 +1262,9 @@ class PlatformAutoGen(AutoGen): self._BuildCommand = None self._AsBuildInfList = [] self._AsBuildModuleList = [] + + self.VariableInfo = None + if GlobalData.gFdfParser != None: self._AsBuildInfList = GlobalData.gFdfParser.Profile.InfList for Inf in self._AsBuildInfList: @@ -1273,6 +1276,7 @@ class PlatformAutoGen(AutoGen): # get library/modules for build self.LibraryBuildDirectoryList = [] self.ModuleBuildDirectoryList = [] + return True def __repr__(self): @@ -1355,7 +1359,22 @@ class PlatformAutoGen(AutoGen): LibAuto.ConstPcd[key] = Pcd.DefaultValue def CollectVariables(self, DynamicPcdSet): + + VpdRegionSize = 0 + VpdRegionBase = 0 + if self.Workspace.FdfFile: + FdDict = self.Workspace.FdfProfile.FdDict[GlobalData.gFdfParser.CurrentFdName] + for FdRegion in FdDict.RegionList: + for item in FdRegion.RegionDataList: + if self.Platform.VpdToolGuid.strip() and self.Platform.VpdToolGuid in item: + VpdRegionSize = FdRegion.Size + VpdRegionBase = FdRegion.Offset + break + + VariableInfo = VariableMgr(self.DscBuildDataObj._GetDefaultStores(),self.DscBuildDataObj._GetSkuIds()) + VariableInfo.SetVpdRegionMaxSize(VpdRegionSize) + VariableInfo.SetVpdRegionOffset(VpdRegionBase) Index = 0 for Pcd in DynamicPcdSet: pcdname = ".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName)) @@ -1369,9 +1388,37 @@ class PlatformAutoGen(AutoGen): 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)) + VariableInfo.append_variable(var_info(Index,pcdname,StorageName,SkuName, StringToArray(Sku.VariableName),VariableGuid, Sku.VariableAttribute , Sku.HiiDefaultValue,Sku.DefaultStoreDict[StorageName],Pcd.DatumType)) Index += 1 return VariableInfo + + def UpdateNVStoreMaxSize(self,OrgVpdFile): + VpdMapFilePath = os.path.join(self.BuildDir, "FV", "%s.map" % self.Platform.VpdToolGuid) +# VpdFile = VpdInfoFile.VpdInfoFile() + PcdNvStoreDfBuffer = [item for item in self._DynamicPcdList if item.TokenCName == "PcdNvStoreDefaultValueBuffer" and item.TokenSpaceGuidCName == "gEfiMdeModulePkgTokenSpaceGuid"] + + if PcdNvStoreDfBuffer: + if os.path.exists(VpdMapFilePath): + OrgVpdFile.Read(VpdMapFilePath) + PcdItems = OrgVpdFile.GetOffset(PcdNvStoreDfBuffer[0]) + NvStoreOffset = PcdItems[0].strip() if PcdItems else 0 + else: + EdkLogger.error("build", FILE_READ_FAILURE, "Can not find VPD map file %s to fix up VPD offset." % VpdMapFilePath) + + NvStoreOffset = int(NvStoreOffset,16) if NvStoreOffset.upper().startswith("0X") else int(NvStoreOffset) + maxsize = self.VariableInfo.VpdRegionSize - NvStoreOffset + var_data = self.VariableInfo.PatchNVStoreDefaultMaxSize(maxsize) + default_skuobj = PcdNvStoreDfBuffer[0].SkuInfoList.get("DEFAULT") + + if var_data and default_skuobj: + default_skuobj.DefaultValue = var_data + PcdNvStoreDfBuffer[0].DefaultValue = var_data + PcdNvStoreDfBuffer[0].SkuInfoList.clear() + PcdNvStoreDfBuffer[0].SkuInfoList['DEFAULT'] = default_skuobj + PcdNvStoreDfBuffer[0].MaxDatumSize = str(len(default_skuobj.DefaultValue.split(","))) + + return OrgVpdFile + ## Collect dynamic PCDs # # Gather dynamic PCDs list from each module and their settings from platform @@ -1605,13 +1652,12 @@ class PlatformAutoGen(AutoGen): #Collect DynamicHii PCD values and assign it to DynamicExVpd PCD gEfiMdeModulePkgTokenSpaceGuid.PcdNvStoreDefaultValueBuffer PcdNvStoreDfBuffer = VpdPcdDict.get(("PcdNvStoreDefaultValueBuffer","gEfiMdeModulePkgTokenSpaceGuid")) if PcdNvStoreDfBuffer: - var_info = self.CollectVariables(self._DynamicPcdList) + self.VariableInfo = self.CollectVariables(self._DynamicPcdList) default_skuobj = PcdNvStoreDfBuffer.SkuInfoList.get("DEFAULT") - vardump = var_info.dump() - if vardump: + vardump = self.VariableInfo.dump() + if vardump and default_skuobj: default_skuobj.DefaultValue = vardump PcdNvStoreDfBuffer.DefaultValue = vardump - if default_skuobj: PcdNvStoreDfBuffer.SkuInfoList.clear() PcdNvStoreDfBuffer.SkuInfoList['DEFAULT'] = default_skuobj PcdNvStoreDfBuffer.MaxDatumSize = str(len(default_skuobj.DefaultValue.split(","))) @@ -1746,29 +1792,10 @@ class PlatformAutoGen(AutoGen): "Fail to get FLASH_DEFINITION definition in DSC file %s which is required when DSC contains VPD PCD." % str(self.Platform.MetaFile)) if VpdFile.GetCount() != 0: - FvPath = os.path.join(self.BuildDir, "FV") - if not os.path.exists(FvPath): - try: - os.makedirs(FvPath) - except: - EdkLogger.error("build", FILE_WRITE_FAILURE, "Fail to create FV folder under %s" % self.BuildDir) - - VpdFilePath = os.path.join(FvPath, "%s.txt" % self.Platform.VpdToolGuid) - - if VpdFile.Write(VpdFilePath): - # retrieve BPDG tool's path from tool_def.txt according to VPD_TOOL_GUID defined in DSC file. - BPDGToolName = None - for ToolDef in self.ToolDefinition.values(): - if ToolDef.has_key("GUID") and ToolDef["GUID"] == self.Platform.VpdToolGuid: - if not ToolDef.has_key("PATH"): - EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "PATH attribute was not provided for BPDG guid tool %s in tools_def.txt" % self.Platform.VpdToolGuid) - BPDGToolName = ToolDef["PATH"] - break - # Call third party GUID BPDG tool. - if BPDGToolName != None: - VpdInfoFile.CallExtenalBPDGTool(BPDGToolName, VpdFilePath) - else: - 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.") + + self.FixVpdOffset(VpdFile) + + self.FixVpdOffset(self.UpdateNVStoreMaxSize(VpdFile)) # Process VPD map file generated by third party BPDG tool if NeedProcessVpdMapFile: @@ -1800,7 +1827,32 @@ class PlatformAutoGen(AutoGen): continue pcd.SkuInfoList[SkuName] = pcd.SkuInfoList['DEFAULT'] self.AllPcdList = self._NonDynamicPcdList + self._DynamicPcdList - + + def FixVpdOffset(self,VpdFile ): + FvPath = os.path.join(self.BuildDir, "FV") + if not os.path.exists(FvPath): + try: + os.makedirs(FvPath) + except: + EdkLogger.error("build", FILE_WRITE_FAILURE, "Fail to create FV folder under %s" % self.BuildDir) + + VpdFilePath = os.path.join(FvPath, "%s.txt" % self.Platform.VpdToolGuid) + + if VpdFile.Write(VpdFilePath): + # retrieve BPDG tool's path from tool_def.txt according to VPD_TOOL_GUID defined in DSC file. + BPDGToolName = None + for ToolDef in self.ToolDefinition.values(): + if ToolDef.has_key("GUID") and ToolDef["GUID"] == self.Platform.VpdToolGuid: + if not ToolDef.has_key("PATH"): + EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "PATH attribute was not provided for BPDG guid tool %s in tools_def.txt" % self.Platform.VpdToolGuid) + BPDGToolName = ToolDef["PATH"] + break + # Call third party GUID BPDG tool. + if BPDGToolName != None: + VpdInfoFile.CallExtenalBPDGTool(BPDGToolName, VpdFilePath) + else: + 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.") + ## Return the platform build data object def _GetPlatform(self): if self._Platform == None: diff --git a/BaseTools/Source/Python/AutoGen/GenVar.py b/BaseTools/Source/Python/AutoGen/GenVar.py index 7ee39796e3..47569d4894 100644 --- a/BaseTools/Source/Python/AutoGen/GenVar.py +++ b/BaseTools/Source/Python/AutoGen/GenVar.py @@ -51,10 +51,32 @@ class VariableMgr(object): self.VarInfo = [] self.DefaultStoreMap = DefaultStoreMap self.SkuIdMap = SkuIdMap + self.VpdRegionSize = 0 + self.VpdRegionOffset = 0 + self.NVHeaderBuff = None + self.VarDefaultBuff = None + self.VarDeltaBuff = None def append_variable(self,uefi_var): self.VarInfo.append(uefi_var) + def SetVpdRegionMaxSize(self,maxsize): + self.VpdRegionSize = maxsize + + def SetVpdRegionOffset(self,vpdoffset): + self.VpdRegionOffset = vpdoffset + + def PatchNVStoreDefaultMaxSize(self,maxsize): + if not self.NVHeaderBuff: + return "" + self.NVHeaderBuff = self.NVHeaderBuff[:8] + pack("=L",maxsize) + default_var_bin = self.format_data(self.NVHeaderBuff + self.VarDefaultBuff + self.VarDeltaBuff) + value_str = "{" + default_var_bin_strip = [ data.strip("""'""") for data in default_var_bin] + value_str += ",".join(default_var_bin_strip) + value_str += "}" + return value_str + def process_variable_data(self): var_data = dict() @@ -118,7 +140,7 @@ class VariableMgr(object): if not var_data: return [] - pcds_default_data = var_data.get(("DEFAULT","STANDARD")) + pcds_default_data = var_data.get(("DEFAULT","STANDARD"),{}) NvStoreDataBuffer = "" var_data_offset = collections.OrderedDict() offset = NvStorageHeaderSize @@ -132,11 +154,6 @@ class VariableMgr(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) @@ -151,8 +168,6 @@ class VariableMgr(object): 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 skuname,defaultstore in var_data: if (skuname,defaultstore) == ("DEFAULT","STANDARD"): @@ -166,11 +181,15 @@ class VariableMgr(object): delta_data_set.extend(delta_data) data_delta_structure_buffer += self.AlignData(self.PACK_DELTA_DATA(skuname,defaultstore,delta_data_set)) -# print "delta data" -# print delta_data_set -# print self.format_data(self.AlignData(self.PACK_DELTA_DATA(skuname,defaultstore,delta_data_set))) - return self.format_data(nv_default_part + data_delta_structure_buffer) + size = len(nv_default_part + data_delta_structure_buffer) + 12 + maxsize = self.VpdRegionSize if self.VpdRegionSize else size + NV_Store_Default_Header = self.PACK_NV_STORE_DEFAULT_HEADER(size,maxsize) + + self.NVHeaderBuff = NV_Store_Default_Header + self.VarDefaultBuff =nv_default_part + self.VarDeltaBuff = data_delta_structure_buffer + return self.format_data(NV_Store_Default_Header + nv_default_part + data_delta_structure_buffer) def format_data(self,data): @@ -184,8 +203,6 @@ class VariableMgr(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 = [] @@ -219,6 +236,16 @@ class VariableMgr(object): return GuidBuffer + SizeBuffer + FormatBuffer + StateBuffer + reservedBuffer + def PACK_NV_STORE_DEFAULT_HEADER(self,size,maxsize): + Signature = pack('=B',ord('N')) + Signature += pack("=B",ord('S')) + Signature += pack("=B",ord('D')) + Signature += pack("=B",ord('B')) + + SizeBuffer = pack("=L",size) + MaxSizeBuffer = pack("=L",maxsize) + + return Signature + SizeBuffer + MaxSizeBuffer def PACK_VARIABLE_HEADER(self,attribute,namesize,datasize,vendorguid): diff --git a/BaseTools/Source/Python/Workspace/DscBuildData.py b/BaseTools/Source/Python/Workspace/DscBuildData.py index 2e5834bc69..a5fceb9e2b 100644 --- a/BaseTools/Source/Python/Workspace/DscBuildData.py +++ b/BaseTools/Source/Python/Workspace/DscBuildData.py @@ -1246,13 +1246,10 @@ class DscBuildData(PlatformBuildClassObject): 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 + PcdDefaultValue = StringToArray(Pcd.DefaultValue) + InitByteValue += '%s.%s.%s.%s|%s|%s\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType, PcdDefaultValue) # @@ -1457,32 +1454,6 @@ class DscBuildData(PlatformBuildClassObject): else: StdOut, StdErr = self.ExecuteCommand ('make clean & make -f %s' % (MakeFileName)) Messages = StdOut.split('\r') - for Message in Messages: - if " error " in Message: - FileInfo = Message.strip().split('(') - if len (FileInfo) > 0: - FileName = FileInfo [0] - FileLine = FileInfo [1].split (')')[0] - else: - FileInfo = Message.strip().split(':') - FileName = FileInfo [0] - FileLine = FileInfo [1] - - File = open (FileName, 'r') - FileData = File.readlines() - File.close() - error_line = FileData[int (FileLine) - 1] - if r"//" in error_line: - c_line,dsc_line = error_line.split(r"//") - else: - dsc_line = error_line - - message_itmes = Message.split(":") - for item in message_itmes: - if "PcdValueInit.c" in item: - message_itmes[message_itmes.index(item)] = dsc_line.strip() - - EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, ":".join(message_itmes[1:])) PcdValueInitExe = PcdValueInitName if not sys.platform == "win32": @@ -1772,14 +1743,13 @@ class DscBuildData(PlatformBuildClassObject): if pcdDecObject.DatumType == 'VOID*': for (_, skuobj) in pcd.SkuInfoList.items(): datalen = 0 - if skuobj.HiiDefaultValue.startswith("L"): - datalen = (len(skuobj.HiiDefaultValue) - 3 + 1) * 2 - elif skuobj.HiiDefaultValue.startswith("{"): - datalen = len(skuobj.HiiDefaultValue.split(",")) - else: - datalen = len(skuobj.HiiDefaultValue) - 2 + 1 + skuobj.HiiDefaultValue = StringToArray(skuobj.HiiDefaultValue) + datalen = len(skuobj.HiiDefaultValue.split(",")) if datalen > MaxSize: MaxSize = datalen + for defaultst in skuobj.DefaultStoreDict: + skuobj.DefaultStoreDict[defaultst] = StringToArray(skuobj.DefaultStoreDict[defaultst]) + pcd.DefaultValue = StringToArray(pcd.DefaultValue) pcd.MaxDatumSize = str(MaxSize) rt, invalidhii = self.CheckVariableNameAssignment(Pcds) if not rt: -- 2.39.2