+ VpdPcdDict = {}\r
+ VpdFile = VpdInfoFile.VpdInfoFile()\r
+ NeedProcessVpdMapFile = False \r
+ \r
+ if (self.Workspace.ArchList[-1] == self.Arch): \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
+ 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
+ if Pcd.Type in [TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_EX_VPD]:\r
+ VpdPcdDict[(Pcd.TokenCName, Pcd.TokenSpaceGuidCName)] = Pcd \r
+ \r
+ PlatformPcds = self.Platform.Pcds.keys()\r
+ PlatformPcds.sort() \r
+ #\r
+ # Add VPD type PCD into VpdFile and determine whether the VPD PCD need to be fixed up.\r
+ #\r
+ for PcdKey in PlatformPcds:\r
+ Pcd = self.Platform.Pcds[PcdKey] \r
+ if Pcd.Type in [TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_EX_VPD]:\r
+ Pcd = VpdPcdDict[PcdKey]\r
+ Sku = Pcd.SkuInfoList[Pcd.SkuInfoList.keys()[0]]\r
+ Sku.VpdOffset = Sku.VpdOffset.strip() \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
+ if self.Platform.VpdToolGuid == None or self.Platform.VpdToolGuid == '':\r
+ EdkLogger.error("Build", FILE_NOT_FOUND, \\r
+ "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
+ \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 PlatformPcds:\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
+ # Print warning message to let the developer make a determine.\r
+ EdkLogger.warn("build", "Unreferenced vpd pcd used!",\r
+ File=self.MetaFile, \\r
+ ExtraData = "PCD: %s.%s used in the DSC file %s is unreferenced." \\r
+ %(DscPcdEntry.TokenSpaceGuidCName, DscPcdEntry.TokenCName, self.Platform.MetaFile.Path)) \r
+ \r
+ DscPcdEntry.DatumType = DecPcdEntry.DatumType\r
+ DscPcdEntry.DefaultValue = DecPcdEntry.DefaultValue\r
+ # Only fix the value while no value provided in DSC file.\r
+ if (Sku.DefaultValue == "" or Sku.DefaultValue==None):\r
+ DscPcdEntry.SkuInfoList[DscPcdEntry.SkuInfoList.keys()[0]].DefaultValue = DecPcdEntry.DefaultValue\r
+ \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
+ \r
+ VpdFilePath = os.path.join(FvPath, "%s.txt" % self.Platform.VpdToolGuid)\r
+\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)\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
+ VpdMapFilePath = os.path.join(self.BuildDir, "FV", "%s.map" % self.Platform.VpdToolGuid)\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