]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/Common/VpdInfoFile.py
BaseTools: Optimize VPD PCD value for the different SKUs
[mirror_edk2.git] / BaseTools / Source / Python / Common / VpdInfoFile.py
index 1a68e9bee1725c658ae9b533ef882e248ca9b5cd..130d5c7e0cdec42cec504e98b62e834af1b881e1 100644 (file)
@@ -6,7 +6,7 @@
 # is pointed by *_*_*_VPD_TOOL_GUID in conf/tools_def.txt \r
 #\r
 #\r
-# Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>\r
 # This program and the accompanying materials\r
 # are licensed and made available under the terms and conditions of the BSD License\r
 # which accompanies this distribution.  The full text of the license may be found at\r
@@ -20,7 +20,9 @@ import re
 import Common.EdkLogger as EdkLogger\r
 import Common.BuildToolError as BuildToolError\r
 import subprocess\r
+import Common.GlobalData as GlobalData\r
 from Common.LongFilePathSupport import OpenLongFilePath as open\r
+from Common.Misc import SaveFileOnChange\r
 \r
 FILE_COMMENT_TEMPLATE = \\r
 """\r
@@ -77,6 +79,7 @@ class VpdInfoFile:
         #           @see BuildClassObject.PcdClassObject\r
         #  Value  : offset in different SKU such as [sku1_offset, sku2_offset]\r
         self._VpdArray = {}\r
+        self._VpdInfo = {}\r
     \r
     ## Add a VPD PCD collected from platform's autogen when building.\r
     #\r
@@ -100,8 +103,9 @@ class VpdInfoFile:
             if Vpd.MaxDatumSize == None or Vpd.MaxDatumSize == "":\r
                 Vpd.MaxDatumSize = VpdInfoFile._MAX_SIZE_TYPE[Vpd.DatumType]\r
         else:\r
-            EdkLogger.error("VpdInfoFile", BuildToolError.PARAMETER_INVALID,  \r
-                            "Invalid DatumType %s for VPD PCD %s.%s" % (Vpd.DatumType, Vpd.TokenSpaceGuidCName, Vpd.TokenCName))\r
+            if Vpd.MaxDatumSize <= 0:\r
+                EdkLogger.error("VpdInfoFile", BuildToolError.PARAMETER_INVALID,\r
+                                "Invalid max datum size for VPD PCD %s.%s" % (Vpd.TokenSpaceGuidCName, Vpd.TokenCName))\r
             \r
         if Vpd not in self._VpdArray.keys():\r
             #\r
@@ -124,34 +128,25 @@ class VpdInfoFile:
         if not (FilePath != None or len(FilePath) != 0):\r
             EdkLogger.error("VpdInfoFile", BuildToolError.PARAMETER_INVALID,  \r
                             "Invalid parameter FilePath: %s." % FilePath)        \r
-        try:\r
-            fd = open(FilePath, "w")\r
-        except:\r
-            EdkLogger.error("VpdInfoFile", \r
-                            BuildToolError.FILE_OPEN_FAILURE, \r
-                            "Fail to open file %s for written." % FilePath)\r
-        \r
-        try:\r
-            # write file header\r
-            fd.write(FILE_COMMENT_TEMPLATE)\r
 \r
-            # write each of PCD in VPD type\r
-            Pcds = self._VpdArray.keys()\r
-            Pcds.sort()\r
-            for Pcd in Pcds:\r
-                i = 0\r
-                for Offset in self._VpdArray[Pcd]:\r
-                    PcdValue = str(Pcd.SkuInfoList[Pcd.SkuInfoList.keys()[i]].DefaultValue).strip()\r
-                    if PcdValue == "" :\r
-                        PcdValue  = Pcd.DefaultValue\r
-                        \r
-                    fd.write("%s.%s|%s|%s|%s|%s  \n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, str(Pcd.SkuInfoList.keys()[i]),str(Offset).strip(), str(Pcd.MaxDatumSize).strip(),PcdValue))\r
-                    i += 1\r
-        except:\r
-            EdkLogger.error("VpdInfoFile",\r
-                            BuildToolError.FILE_WRITE_FAILURE,\r
-                            "Fail to write file %s" % FilePath) \r
-        fd.close()\r
+        Content = FILE_COMMENT_TEMPLATE\r
+        Pcds = self._VpdArray.keys()\r
+        Pcds.sort()\r
+        for Pcd in Pcds:\r
+            i = 0\r
+            PcdTokenCName = Pcd.TokenCName\r
+            for PcdItem in GlobalData.MixedPcd:\r
+                if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem]:\r
+                    PcdTokenCName = PcdItem[0]\r
+            for Offset in self._VpdArray[Pcd]:\r
+                PcdValue = str(Pcd.SkuInfoList[Pcd.SkuInfoList.keys()[i]].DefaultValue).strip()\r
+                if PcdValue == "" :\r
+                    PcdValue  = Pcd.DefaultValue\r
+\r
+                Content += "%s.%s|%s|%s|%s|%s  \n" % (Pcd.TokenSpaceGuidCName, PcdTokenCName, str(Pcd.SkuInfoList.keys()[i]),str(Offset).strip(), str(Pcd.MaxDatumSize).strip(),PcdValue)\r
+                i += 1\r
+\r
+        return SaveFileOnChange(FilePath, Content, False)\r
 \r
     ## Read an existing VPD PCD info file.\r
     #\r
@@ -185,9 +180,16 @@ class VpdInfoFile:
             \r
             Found = False\r
             \r
+            if (TokenSpaceName, PcdTokenName) not in self._VpdInfo:\r
+                self._VpdInfo[(TokenSpaceName, PcdTokenName)] = []\r
+            self._VpdInfo[(TokenSpaceName, PcdTokenName)].append((SkuId,Offset, Value))\r
             for VpdObject in self._VpdArray.keys():\r
-                for sku in VpdObject.SkuInfoList.keys(): \r
-                    if VpdObject.TokenSpaceGuidCName == TokenSpaceName and VpdObject.TokenCName == PcdTokenName.strip() and sku == SkuId:\r
+                VpdObjectTokenCName = VpdObject.TokenCName\r
+                for PcdItem in GlobalData.MixedPcd:\r
+                    if (VpdObject.TokenCName, VpdObject.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem]:\r
+                        VpdObjectTokenCName = PcdItem[0]\r
+                for sku in VpdObject.SkuInfoList.keys():\r
+                    if VpdObject.TokenSpaceGuidCName == TokenSpaceName and VpdObjectTokenCName == PcdTokenName.strip() and sku == SkuId:\r
                         if self._VpdArray[VpdObject][VpdObject.SkuInfoList.keys().index(sku)] == "*":\r
                             if Offset == "*":\r
                                 EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID, "The offset of %s has not been fixed up by third-party BPDG tool." % PcdName)                              \r
@@ -219,6 +221,8 @@ class VpdInfoFile:
             return None\r
         \r
         return self._VpdArray[vpd]\r
+    def GetVpdInfo(self,(PcdTokenName,TokenSpaceName)):\r
+        return self._VpdInfo.get((TokenSpaceName, PcdTokenName))\r
     \r
 ## Call external BPDG tool to process VPD file\r
 #    \r
@@ -236,14 +240,15 @@ def CallExtenalBPDGTool(ToolPath, VpdFileName):
     OutputBinFileName = os.path.join(OutputDir, "%s.bin" % BaseName)\r
           \r
     try:\r
-        PopenObject = subprocess.Popen([ToolPath,\r
+        PopenObject = subprocess.Popen(' '.join([ToolPath,\r
                                         '-o', OutputBinFileName, \r
                                         '-m', OutputMapFileName,\r
                                         '-q',\r
                                         '-f',\r
-                                        VpdFileName],\r
+                                        VpdFileName]),\r
                                         stdout=subprocess.PIPE, \r
-                                        stderr= subprocess.PIPE)\r
+                                        stderr= subprocess.PIPE,\r
+                                        shell=True)\r
     except Exception, X:\r
         EdkLogger.error("BPDG", BuildToolError.COMMAND_FAILURE, ExtraData="%s" % (str(X)))\r
     (out, error) = PopenObject.communicate()\r