BaseTools: Update NV Default Header format to include the max size
authorLiming Gao <liming.gao@intel.com>
Fri, 22 Dec 2017 12:14:29 +0000 (20:14 +0800)
committerLiming Gao <liming.gao@intel.com>
Mon, 25 Dec 2017 03:05:48 +0000 (11:05 +0800)
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Bob Feng <bob.c.feng@Intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
BaseTools/Source/Python/AutoGen/AutoGen.py
BaseTools/Source/Python/AutoGen/GenVar.py
BaseTools/Source/Python/Workspace/DscBuildData.py

index 5d6cce0..eeeab95 100644 (file)
@@ -1262,6 +1262,9 @@ class PlatformAutoGen(AutoGen):
         self._BuildCommand = None\r
         self._AsBuildInfList = []\r
         self._AsBuildModuleList = []\r
+\r
+        self.VariableInfo = None\r
+\r
         if GlobalData.gFdfParser != None:\r
             self._AsBuildInfList = GlobalData.gFdfParser.Profile.InfList\r
             for Inf in self._AsBuildInfList:\r
@@ -1273,6 +1276,7 @@ class PlatformAutoGen(AutoGen):
         # get library/modules for build\r
         self.LibraryBuildDirectoryList = []\r
         self.ModuleBuildDirectoryList = []\r
+\r
         return True\r
 \r
     def __repr__(self):\r
@@ -1355,7 +1359,22 @@ class PlatformAutoGen(AutoGen):
                     LibAuto.ConstPcd[key] = Pcd.DefaultValue\r
 \r
     def CollectVariables(self, DynamicPcdSet):\r
+\r
+        VpdRegionSize = 0\r
+        VpdRegionBase = 0\r
+        if self.Workspace.FdfFile:\r
+            FdDict = self.Workspace.FdfProfile.FdDict[GlobalData.gFdfParser.CurrentFdName]\r
+            for FdRegion in FdDict.RegionList:\r
+                for item in FdRegion.RegionDataList:\r
+                    if self.Platform.VpdToolGuid.strip() and self.Platform.VpdToolGuid in item:\r
+                        VpdRegionSize = FdRegion.Size\r
+                        VpdRegionBase = FdRegion.Offset\r
+                        break\r
+\r
+\r
         VariableInfo = VariableMgr(self.DscBuildDataObj._GetDefaultStores(),self.DscBuildDataObj._GetSkuIds())\r
+        VariableInfo.SetVpdRegionMaxSize(VpdRegionSize)\r
+        VariableInfo.SetVpdRegionOffset(VpdRegionBase)\r
         Index = 0\r
         for Pcd in DynamicPcdSet:\r
             pcdname = ".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName))\r
@@ -1369,9 +1388,37 @@ class PlatformAutoGen(AutoGen):
                     VariableGuid = GuidStructureStringToGuidString(VariableGuidStructure)\r
                     if Pcd.Phase == "DXE":\r
                         for StorageName in Sku.DefaultStoreDict:\r
-                            VariableInfo.append_variable(var_info(Index,pcdname,StorageName,SkuName, StringToArray(Sku.VariableName),VariableGuid, Sku.VariableAttribute , Pcd.DefaultValue,Sku.DefaultStoreDict[StorageName],Pcd.DatumType))\r
+                            VariableInfo.append_variable(var_info(Index,pcdname,StorageName,SkuName, StringToArray(Sku.VariableName),VariableGuid, Sku.VariableAttribute , Sku.HiiDefaultValue,Sku.DefaultStoreDict[StorageName],Pcd.DatumType))\r
             Index += 1\r
         return VariableInfo\r
+\r
+    def UpdateNVStoreMaxSize(self,OrgVpdFile):\r
+        VpdMapFilePath = os.path.join(self.BuildDir, "FV", "%s.map" % self.Platform.VpdToolGuid)\r
+#         VpdFile = VpdInfoFile.VpdInfoFile()\r
+        PcdNvStoreDfBuffer = [item for item in self._DynamicPcdList if item.TokenCName == "PcdNvStoreDefaultValueBuffer" and item.TokenSpaceGuidCName == "gEfiMdeModulePkgTokenSpaceGuid"]\r
+\r
+        if PcdNvStoreDfBuffer:\r
+            if os.path.exists(VpdMapFilePath):\r
+                OrgVpdFile.Read(VpdMapFilePath)\r
+                PcdItems = OrgVpdFile.GetOffset(PcdNvStoreDfBuffer[0])\r
+                NvStoreOffset = PcdItems[0].strip() if PcdItems else 0\r
+            else:\r
+                EdkLogger.error("build", FILE_READ_FAILURE, "Can not find VPD map file %s to fix up VPD offset." % VpdMapFilePath)\r
+\r
+            NvStoreOffset = int(NvStoreOffset,16) if NvStoreOffset.upper().startswith("0X") else int(NvStoreOffset)\r
+            maxsize = self.VariableInfo.VpdRegionSize  - NvStoreOffset\r
+            var_data = self.VariableInfo.PatchNVStoreDefaultMaxSize(maxsize)\r
+            default_skuobj = PcdNvStoreDfBuffer[0].SkuInfoList.get("DEFAULT")\r
+\r
+            if var_data and default_skuobj:\r
+                default_skuobj.DefaultValue = var_data\r
+                PcdNvStoreDfBuffer[0].DefaultValue = var_data\r
+                PcdNvStoreDfBuffer[0].SkuInfoList.clear()\r
+                PcdNvStoreDfBuffer[0].SkuInfoList['DEFAULT'] = default_skuobj\r
+                PcdNvStoreDfBuffer[0].MaxDatumSize = str(len(default_skuobj.DefaultValue.split(",")))\r
+\r
+        return OrgVpdFile\r
+\r
     ## Collect dynamic PCDs\r
     #\r
     #  Gather dynamic PCDs list from each module and their settings from platform\r
@@ -1605,13 +1652,12 @@ class PlatformAutoGen(AutoGen):
             #Collect DynamicHii PCD values and assign it to DynamicExVpd PCD gEfiMdeModulePkgTokenSpaceGuid.PcdNvStoreDefaultValueBuffer\r
             PcdNvStoreDfBuffer = VpdPcdDict.get(("PcdNvStoreDefaultValueBuffer","gEfiMdeModulePkgTokenSpaceGuid"))\r
             if PcdNvStoreDfBuffer:\r
-                var_info = self.CollectVariables(self._DynamicPcdList)\r
+                self.VariableInfo = self.CollectVariables(self._DynamicPcdList)\r
                 default_skuobj = PcdNvStoreDfBuffer.SkuInfoList.get("DEFAULT")\r
-                vardump = var_info.dump()\r
-                if vardump:\r
+                vardump = self.VariableInfo.dump()\r
+                if vardump and default_skuobj:\r
                     default_skuobj.DefaultValue = vardump\r
                     PcdNvStoreDfBuffer.DefaultValue = vardump\r
-                if default_skuobj:\r
                     PcdNvStoreDfBuffer.SkuInfoList.clear()\r
                     PcdNvStoreDfBuffer.SkuInfoList['DEFAULT'] = default_skuobj\r
                     PcdNvStoreDfBuffer.MaxDatumSize = str(len(default_skuobj.DefaultValue.split(",")))\r
@@ -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))\r
 \r
             if VpdFile.GetCount() != 0:\r
-                FvPath = os.path.join(self.BuildDir, "FV")\r
-                if not os.path.exists(FvPath):\r
-                    try:\r
-                        os.makedirs(FvPath)\r
-                    except:\r
-                        EdkLogger.error("build", FILE_WRITE_FAILURE, "Fail to create FV folder under %s" % self.BuildDir)\r
-\r
-                VpdFilePath = os.path.join(FvPath, "%s.txt" % self.Platform.VpdToolGuid)\r
-\r
-                if VpdFile.Write(VpdFilePath):\r
-                    # retrieve BPDG tool's path from tool_def.txt according to VPD_TOOL_GUID defined in DSC file.\r
-                    BPDGToolName = None\r
-                    for ToolDef in self.ToolDefinition.values():\r
-                        if ToolDef.has_key("GUID") and ToolDef["GUID"] == self.Platform.VpdToolGuid:\r
-                            if not ToolDef.has_key("PATH"):\r
-                                EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "PATH attribute was not provided for BPDG guid tool %s in tools_def.txt" % self.Platform.VpdToolGuid)\r
-                            BPDGToolName = ToolDef["PATH"]\r
-                            break\r
-                    # Call third party GUID BPDG tool.\r
-                    if BPDGToolName != None:\r
-                        VpdInfoFile.CallExtenalBPDGTool(BPDGToolName, VpdFilePath)\r
-                    else:\r
-                        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.")\r
+\r
+                self.FixVpdOffset(VpdFile)\r
+\r
+                self.FixVpdOffset(self.UpdateNVStoreMaxSize(VpdFile))\r
 \r
                 # Process VPD map file generated by third party BPDG tool\r
                 if NeedProcessVpdMapFile:\r
@@ -1800,7 +1827,32 @@ class PlatformAutoGen(AutoGen):
                         continue\r
                     pcd.SkuInfoList[SkuName] = pcd.SkuInfoList['DEFAULT']\r
         self.AllPcdList = self._NonDynamicPcdList + self._DynamicPcdList\r
-        \r
+\r
+    def FixVpdOffset(self,VpdFile ):\r
+        FvPath = os.path.join(self.BuildDir, "FV")\r
+        if not os.path.exists(FvPath):\r
+            try:\r
+                os.makedirs(FvPath)\r
+            except:\r
+                EdkLogger.error("build", FILE_WRITE_FAILURE, "Fail to create FV folder under %s" % self.BuildDir)\r
+\r
+        VpdFilePath = os.path.join(FvPath, "%s.txt" % self.Platform.VpdToolGuid)\r
+\r
+        if VpdFile.Write(VpdFilePath):\r
+            # retrieve BPDG tool's path from tool_def.txt according to VPD_TOOL_GUID defined in DSC file.\r
+            BPDGToolName = None\r
+            for ToolDef in self.ToolDefinition.values():\r
+                if ToolDef.has_key("GUID") and ToolDef["GUID"] == self.Platform.VpdToolGuid:\r
+                    if not ToolDef.has_key("PATH"):\r
+                        EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "PATH attribute was not provided for BPDG guid tool %s in tools_def.txt" % self.Platform.VpdToolGuid)\r
+                    BPDGToolName = ToolDef["PATH"]\r
+                    break\r
+            # Call third party GUID BPDG tool.\r
+            if BPDGToolName != None:\r
+                VpdInfoFile.CallExtenalBPDGTool(BPDGToolName, VpdFilePath)\r
+            else:\r
+                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.")\r
+\r
     ## Return the platform build data object\r
     def _GetPlatform(self):\r
         if self._Platform == None:\r
index 7ee3979..47569d4 100644 (file)
@@ -51,10 +51,32 @@ class VariableMgr(object):
         self.VarInfo = []\r
         self.DefaultStoreMap = DefaultStoreMap\r
         self.SkuIdMap = SkuIdMap\r
+        self.VpdRegionSize = 0\r
+        self.VpdRegionOffset = 0\r
+        self.NVHeaderBuff = None\r
+        self.VarDefaultBuff = None\r
+        self.VarDeltaBuff = None\r
 \r
     def append_variable(self,uefi_var):\r
         self.VarInfo.append(uefi_var)\r
 \r
+    def SetVpdRegionMaxSize(self,maxsize):\r
+        self.VpdRegionSize = maxsize\r
+\r
+    def SetVpdRegionOffset(self,vpdoffset):\r
+        self.VpdRegionOffset = vpdoffset\r
+\r
+    def PatchNVStoreDefaultMaxSize(self,maxsize):\r
+        if not self.NVHeaderBuff:\r
+            return ""\r
+        self.NVHeaderBuff = self.NVHeaderBuff[:8] + pack("=L",maxsize)\r
+        default_var_bin = self.format_data(self.NVHeaderBuff + self.VarDefaultBuff + self.VarDeltaBuff)\r
+        value_str = "{"\r
+        default_var_bin_strip = [ data.strip("""'""") for data in default_var_bin]\r
+        value_str += ",".join(default_var_bin_strip)\r
+        value_str += "}"\r
+        return value_str\r
+\r
     def process_variable_data(self):\r
 \r
         var_data = dict()\r
@@ -118,7 +140,7 @@ class VariableMgr(object):
         if not var_data:\r
             return []\r
 \r
-        pcds_default_data = var_data.get(("DEFAULT","STANDARD"))\r
+        pcds_default_data = var_data.get(("DEFAULT","STANDARD"),{})\r
         NvStoreDataBuffer = ""\r
         var_data_offset = collections.OrderedDict()\r
         offset = NvStorageHeaderSize\r
@@ -132,11 +154,6 @@ class VariableMgr(object):
             else:\r
                 var_attr_value = 0x07\r
 \r
-#             print "default var_name_buffer"\r
-#             print self.format_data(var_name_buffer)\r
-#             print "default var_buffer"\r
-#             print self.format_data(default_data)\r
-\r
             DataBuffer = self.AlignData(var_name_buffer + default_data)\r
 \r
             data_size = len(DataBuffer)\r
@@ -151,8 +168,6 @@ class VariableMgr(object):
 \r
         nv_default_part = self.AlignData(self.PACK_DEFAULT_DATA(0, 0, self.unpack_data(variable_storage_header_buffer+NvStoreDataBuffer)))\r
 \r
-#         print "default whole data \n",self.format_data(nv_default_part)\r
-\r
         data_delta_structure_buffer = ""\r
         for skuname,defaultstore in var_data:\r
             if (skuname,defaultstore) == ("DEFAULT","STANDARD"):\r
@@ -166,11 +181,15 @@ class VariableMgr(object):
                 delta_data_set.extend(delta_data)\r
 \r
             data_delta_structure_buffer += self.AlignData(self.PACK_DELTA_DATA(skuname,defaultstore,delta_data_set))\r
-#             print "delta data"\r
-#             print delta_data_set\r
-#             print self.format_data(self.AlignData(self.PACK_DELTA_DATA(skuname,defaultstore,delta_data_set)))\r
 \r
-        return self.format_data(nv_default_part + data_delta_structure_buffer)\r
+        size = len(nv_default_part + data_delta_structure_buffer) + 12\r
+        maxsize = self.VpdRegionSize if self.VpdRegionSize else size\r
+        NV_Store_Default_Header = self.PACK_NV_STORE_DEFAULT_HEADER(size,maxsize)\r
+\r
+        self.NVHeaderBuff =  NV_Store_Default_Header\r
+        self.VarDefaultBuff =nv_default_part\r
+        self.VarDeltaBuff =  data_delta_structure_buffer\r
+        return self.format_data(NV_Store_Default_Header + nv_default_part + data_delta_structure_buffer)\r
 \r
 \r
     def format_data(self,data):\r
@@ -184,8 +203,6 @@ class VariableMgr(object):
         return final_data\r
 \r
     def calculate_delta(self, default, theother):\r
-#         print "default data \n", default\r
-#         print "other data \n",theother\r
         if len(default) - len(theother) != 0:\r
             EdkLogger.error("build", FORMAT_INVALID, 'The variable data length is not the same for the same PCD.')\r
         data_delta = []\r
@@ -219,6 +236,16 @@ class VariableMgr(object):
 \r
         return GuidBuffer + SizeBuffer + FormatBuffer + StateBuffer + reservedBuffer\r
 \r
+    def PACK_NV_STORE_DEFAULT_HEADER(self,size,maxsize):\r
+        Signature = pack('=B',ord('N'))\r
+        Signature += pack("=B",ord('S'))\r
+        Signature += pack("=B",ord('D'))\r
+        Signature += pack("=B",ord('B'))\r
+\r
+        SizeBuffer = pack("=L",size)\r
+        MaxSizeBuffer = pack("=L",maxsize)\r
+\r
+        return Signature + SizeBuffer + MaxSizeBuffer\r
 \r
     def PACK_VARIABLE_HEADER(self,attribute,namesize,datasize,vendorguid):\r
 \r
index 2e5834b..a5fceb9 100644 (file)
@@ -1246,13 +1246,10 @@ class DscBuildData(PlatformBuildClassObject):
             CApp = CApp + '  VOID    *OriginalPcd;\n'\r
             CApp = CApp + '  %s      *Pcd;\n' % (Pcd.DatumType)\r
             CApp = CApp + '\n'\r
+\r
             Pcd.DefaultValue = Pcd.DefaultValue.strip()\r
-            if Pcd.DefaultValue.startswith('L"') and Pcd.DefaultValue.endswith('"'):\r
-                PcdDefaultValue = "{" + ",".join(self.__UNICODE2OCTList(Pcd.DefaultValue)) + "}"\r
-            elif Pcd.DefaultValue.startswith('"') and Pcd.DefaultValue.endswith('"'):\r
-                PcdDefaultValue = "{" + ",".join(self.__STRING2OCTList(Pcd.DefaultValue)) + "}"\r
-            else:\r
-                PcdDefaultValue = Pcd.DefaultValue\r
+            PcdDefaultValue = StringToArray(Pcd.DefaultValue)\r
+\r
             InitByteValue += '%s.%s.%s.%s|%s|%s\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType, PcdDefaultValue)\r
 \r
             #\r
@@ -1457,32 +1454,6 @@ class DscBuildData(PlatformBuildClassObject):
         else:\r
             StdOut, StdErr = self.ExecuteCommand ('make clean & make -f %s' % (MakeFileName))\r
         Messages = StdOut.split('\r')\r
-        for Message in Messages:\r
-            if " error " in Message:\r
-                FileInfo = Message.strip().split('(')\r
-                if len (FileInfo) > 0:\r
-                    FileName = FileInfo [0]\r
-                    FileLine = FileInfo [1].split (')')[0]\r
-                else:\r
-                    FileInfo = Message.strip().split(':')\r
-                    FileName = FileInfo [0]\r
-                    FileLine = FileInfo [1]\r
-\r
-                File = open (FileName, 'r')\r
-                FileData = File.readlines()\r
-                File.close()\r
-                error_line = FileData[int (FileLine) - 1]\r
-                if r"//" in error_line:\r
-                    c_line,dsc_line = error_line.split(r"//")\r
-                else:\r
-                    dsc_line = error_line\r
-\r
-                message_itmes = Message.split(":")\r
-                for item in message_itmes:\r
-                    if "PcdValueInit.c" in item:\r
-                        message_itmes[message_itmes.index(item)] = dsc_line.strip()\r
-\r
-                EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, ":".join(message_itmes[1:]))\r
 \r
         PcdValueInitExe = PcdValueInitName\r
         if not sys.platform == "win32":\r
@@ -1772,14 +1743,13 @@ class DscBuildData(PlatformBuildClassObject):
             if pcdDecObject.DatumType == 'VOID*':\r
                 for (_, skuobj) in pcd.SkuInfoList.items():\r
                     datalen = 0\r
-                    if skuobj.HiiDefaultValue.startswith("L"):\r
-                        datalen = (len(skuobj.HiiDefaultValue) - 3 + 1) * 2\r
-                    elif skuobj.HiiDefaultValue.startswith("{"):\r
-                        datalen = len(skuobj.HiiDefaultValue.split(","))\r
-                    else:\r
-                        datalen = len(skuobj.HiiDefaultValue) - 2 + 1\r
+                    skuobj.HiiDefaultValue = StringToArray(skuobj.HiiDefaultValue)\r
+                    datalen = len(skuobj.HiiDefaultValue.split(","))\r
                     if datalen > MaxSize:\r
                         MaxSize = datalen\r
+                    for defaultst in skuobj.DefaultStoreDict:\r
+                        skuobj.DefaultStoreDict[defaultst] = StringToArray(skuobj.DefaultStoreDict[defaultst])\r
+                pcd.DefaultValue = StringToArray(pcd.DefaultValue)\r
                 pcd.MaxDatumSize = str(MaxSize)\r
         rt, invalidhii = self.CheckVariableNameAssignment(Pcds)\r
         if not rt:\r