]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/AutoGen/AutoGen.py
Sync EDKII BaseTools to BaseTools project r2042.
[mirror_edk2.git] / BaseTools / Source / Python / AutoGen / AutoGen.py
index 3b8024c199bd93e2ee4271bc127d3995880ad8d9..d95f40bf82ae52c4c5820617289fe8f956e134a2 100644 (file)
@@ -34,6 +34,7 @@ import Common.GlobalData as GlobalData
 from GenFds.FdfParser import *\r
 from CommonDataClass.CommonClass import SkuInfoClass\r
 from Workspace.BuildClassObject import *\r
+import Common.VpdInfoFile as VpdInfoFile\r
 \r
 ## Regular expression for splitting Dependency Expression stirng into tokens\r
 gDepexTokenPattern = re.compile("(\(|\)|\w+| \S+\.inf)")\r
@@ -244,7 +245,7 @@ class WorkspaceAutoGen(AutoGen):
             self._BuildCommand = self.AutoGenObjectList[0].BuildCommand\r
         return self._BuildCommand\r
 \r
-    ## Create makefile for the platform and mdoules in it\r
+    ## Create makefile for the platform and modules in it\r
     #\r
     #   @param      CreateDepsMakeFile      Flag indicating if the makefile for\r
     #                                       modules will be created as well\r
@@ -476,19 +477,141 @@ class PlatformAutoGen(AutoGen):
         UnicodePcdArray = []\r
         HiiPcdArray     = []\r
         OtherPcdArray   = []\r
-        for Pcd in self._DynamicPcdList:\r
-            # just pick the a value to determine whether is unicode string type\r
-            Sku      = Pcd.SkuInfoList[Pcd.SkuInfoList.keys()[0]]\r
-            PcdValue = Sku.DefaultValue\r
-            if Pcd.DatumType == 'VOID*' and PcdValue.startswith("L"):\r
-                # if found PCD which datum value is unicode string the insert to left size of UnicodeIndex\r
-                UnicodePcdArray.append(Pcd)\r
-            elif len(Sku.VariableName) > 0:\r
-                # if found HII type PCD then insert to right of UnicodeIndex\r
-                HiiPcdArray.append(Pcd)\r
-            else:\r
-                OtherPcdArray.append(Pcd)\r
-        del self._DynamicPcdList[:]\r
+        VpdFile               = VpdInfoFile.VpdInfoFile()\r
+        NeedProcessVpdMapFile = False                    \r
+        \r
+        if (self.Workspace.ArchList[-1] == self.Arch): \r
+            for Pcd in self._DynamicPcdList:\r
+\r
+                # just pick the a value to determine whether is unicode string type\r
+                Sku      = Pcd.SkuInfoList[Pcd.SkuInfoList.keys()[0]]\r
+                Sku.VpdOffset = Sku.VpdOffset.strip()\r
+                \r
+                PcdValue = Sku.DefaultValue\r
+                if Pcd.DatumType == 'VOID*' and PcdValue.startswith("L"):\r
+                    # if found PCD which datum value is unicode string the insert to left size of UnicodeIndex\r
+                    UnicodePcdArray.append(Pcd)\r
+                elif len(Sku.VariableName) > 0:\r
+                    # if found HII type PCD then insert to right of UnicodeIndex\r
+                    HiiPcdArray.append(Pcd)\r
+                else:\r
+                    OtherPcdArray.append(Pcd)\r
+                    \r
+                if Pcd.Type in [TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_EX_VPD]:\r
+                    if not (self.Platform.VpdToolGuid == None or self.Platform.VpdToolGuid == ''):\r
+                        #\r
+                        # Fix the optional data of VPD PCD.\r
+                        #\r
+                        if (Pcd.DatumType.strip() != "VOID*"):\r
+                            if Sku.DefaultValue == '':\r
+                                Pcd.SkuInfoList[Pcd.SkuInfoList.keys()[0]].DefaultValue = Pcd.MaxDatumSize\r
+                                Pcd.MaxDatumSize = None\r
+                            else:\r
+                                EdkLogger.error("build", AUTOGEN_ERROR, "PCD setting error",\r
+                                                File=self.MetaFile,\r
+                                                ExtraData="\n\tPCD: %s.%s format incorrect in DSC: %s\n\t\t\n"\r
+                                                          % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, self.Platform.MetaFile.Path))                                                                            \r
+                        \r
+                        VpdFile.Add(Pcd, Sku.VpdOffset)\r
+                        # if the offset of a VPD is *, then it need to be fixed up by third party tool.\r
+                        if not NeedProcessVpdMapFile and Sku.VpdOffset == "*":\r
+                            NeedProcessVpdMapFile = True\r
+                                   \r
+            #\r
+            # Fix the PCDs define in VPD PCD section that never referenced by module.\r
+            # An example is PCD for signature usage.\r
+            #              \r
+            for DscPcd in self.Platform.Pcds:\r
+                DscPcdEntry = self.Platform.Pcds[DscPcd]\r
+                if DscPcdEntry.Type in [TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_EX_VPD]:\r
+                    if not (self.Platform.VpdToolGuid == None or self.Platform.VpdToolGuid == ''):\r
+                        FoundFlag = False\r
+                        for VpdPcd in VpdFile._VpdArray.keys():\r
+                            # This PCD has been referenced by module\r
+                            if (VpdPcd.TokenSpaceGuidCName == DscPcdEntry.TokenSpaceGuidCName) and \\r
+                               (VpdPcd.TokenCName == DscPcdEntry.TokenCName):\r
+                                    FoundFlag = True\r
+                        \r
+                        # Not found, it should be signature\r
+                        if not FoundFlag :\r
+                            # just pick the a value to determine whether is unicode string type\r
+                            Sku           = DscPcdEntry.SkuInfoList[DscPcdEntry.SkuInfoList.keys()[0]]\r
+                            Sku.VpdOffset = Sku.VpdOffset.strip() \r
+                            \r
+                            # Need to iterate DEC pcd information to get the value & datumtype\r
+                            for eachDec in self.PackageList:\r
+                                for DecPcd in eachDec.Pcds:\r
+                                    DecPcdEntry = eachDec.Pcds[DecPcd]\r
+                                    if (DecPcdEntry.TokenSpaceGuidCName == DscPcdEntry.TokenSpaceGuidCName) and \\r
+                                       (DecPcdEntry.TokenCName == DscPcdEntry.TokenCName):\r
+                                        DscPcdEntry.DatumType    = DecPcdEntry.DatumType\r
+                                        DscPcdEntry.DefaultValue = DecPcdEntry.DefaultValue\r
+                                        Sku.DefaultValue         = DecPcdEntry.DefaultValue                                                                    \r
+                                                       \r
+                            VpdFile.Add(DscPcdEntry, Sku.VpdOffset)\r
+                            # if the offset of a VPD is *, then it need to be fixed up by third party tool.\r
+                            if not NeedProcessVpdMapFile and Sku.VpdOffset == "*":\r
+                                NeedProcessVpdMapFile = True                        \r
+                    \r
+                    \r
+            if (self.Platform.FlashDefinition == None or self.Platform.FlashDefinition == '') and \\r
+               VpdFile.GetCount() != 0:\r
+                EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, \r
+                                "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
+                WorkspaceDb = self.BuildDatabase.WorkspaceDb\r
+                DscTimeStamp = WorkspaceDb.GetTimeStamp(WorkspaceDb.GetFileId(str(self.Platform.MetaFile)))\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
+                VpdFileName = self.Platform.VpdFileName           \r
+                if VpdFileName == None or VpdFileName == "" :\r
+                    VpdFilePath = os.path.join(FvPath, "%s.txt" % self.Platform.VpdToolGuid)\r
+                else :\r
+                    VpdFilePath = os.path.join(FvPath, "%s.txt" % VpdFileName)  \r
+                \r
+                if not os.path.exists(VpdFilePath) or os.path.getmtime(VpdFilePath) < DscTimeStamp:\r
+                    VpdFile.Write(VpdFilePath)\r
+        \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, VpdFileName)\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
+                # Process VPD map file generated by third party BPDG tool\r
+                if NeedProcessVpdMapFile:\r
+                    if VpdFileName == None or VpdFileName == "" :\r
+                        VpdMapFilePath = os.path.join(self.BuildDir, "FV", "%s.map" % self.Platform.VpdToolGuid)\r
+                    else :\r
+                        VpdMapFilePath = os.path.join(self.BuildDir, "FV", "%s.map" % VpdFileName)\r
+                    if os.path.exists(VpdMapFilePath):\r
+                        VpdFile.Read(VpdMapFilePath)\r
+                \r
+                        # Fixup "*" offset\r
+                        for Pcd in self._DynamicPcdList:\r
+                            # just pick the a value to determine whether is unicode string type\r
+                            Sku = Pcd.SkuInfoList[Pcd.SkuInfoList.keys()[0]]                        \r
+                            if Sku.VpdOffset == "*":\r
+                                    Sku.VpdOffset = VpdFile.GetOffset(Pcd)[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
+            # Delete the DynamicPcdList At the last time enter into this function \r
+            del self._DynamicPcdList[:]                        \r
         self._DynamicPcdList.extend(UnicodePcdArray)\r
         self._DynamicPcdList.extend(HiiPcdArray)\r
         self._DynamicPcdList.extend(OtherPcdArray)\r
@@ -709,10 +832,14 @@ class PlatformAutoGen(AutoGen):
 \r
     ## Get list of non-dynamic PCDs\r
     def _GetNonDynamicPcdList(self):\r
+        if self._NonDynamicPcdList == None:\r
+            self.CollectPlatformDynamicPcds()\r
         return self._NonDynamicPcdList\r
 \r
     ## Get list of dynamic PCDs\r
     def _GetDynamicPcdList(self):\r
+        if self._DynamicPcdList == None:\r
+            self.CollectPlatformDynamicPcds()\r
         return self._DynamicPcdList\r
 \r
     ## Generate Token Number for all PCD\r
@@ -952,6 +1079,10 @@ class PlatformAutoGen(AutoGen):
         if FromPcd != None:\r
             if ToPcd.Pending and FromPcd.Type not in [None, '']:\r
                 ToPcd.Type = FromPcd.Type\r
+            elif (ToPcd.Type not in [None, '']) and (FromPcd.Type not in [None, ''])\\r
+                and (ToPcd.Type != FromPcd.Type) and (ToPcd.Type in FromPcd.Type):\r
+                if ToPcd.Type.strip() == "DynamicEx":\r
+                    ToPcd.Type = FromPcd.Type             \r
             elif ToPcd.Type not in [None, ''] and FromPcd.Type not in [None, ''] \\r
                 and ToPcd.Type != FromPcd.Type:\r
                 EdkLogger.error("build", OPTION_CONFLICT, "Mismatched PCD type",\r